Overlays Core Stable
Drawer
A modal bottom sheet with a grab handle, draggable shut with a downward swipe — for filters, quick actions, or any touch-first task
Preview
svelte
<script lang="ts">
import { Drawer } from "fancy-ui-svelte";
import { Button } from "fancy-ui-svelte";
let open = $state(false);
let sortBy = $state("recent");
</script>
<Button onclick={() => (open = true)}>Open filters</Button>
<Drawer bind:open title="Filters" description="Drag down to close.">
<div class="flex flex-col gap-2">
<label class="text-muted-foreground flex items-center gap-2 text-[13px]">
<input type="radio" name="sort" value="recent" bind:group={sortBy} />
Most recent
</label>
<label class="text-muted-foreground flex items-center gap-2 text-[13px]">
<input type="radio" name="sort" value="popular" bind:group={sortBy} />
Most popular
</label>
</div>
</Drawer>Installation
pnpm add fancy-ui-svelte
import { Drawer } from 'fancy-ui-svelte'
Usage
svelte
<script lang="ts">
import { Drawer } from 'fancy-ui-svelte';
</script>
<Drawer />Examples
Basic Usage
svelte
<script lang="ts">
import { Drawer } from "$lib/fancy-ui/drawer";
import { Button } from "$lib/fancy-ui/button";
let open = $state(false);
let sortBy = $state("recent");
</script>
<Button onclick={() => (open = true)}>Open filters</Button>
<Drawer bind:open title="Filters" description="Drag down to close.">
<div class="flex flex-col gap-2">
<label class="text-muted-foreground flex items-center gap-2 text-[13px]">
<input type="radio" name="sort" value="recent" bind:group={sortBy} />
Most recent
</label>
<label class="text-muted-foreground flex items-center gap-2 text-[13px]">
<input type="radio" name="sort" value="popular" bind:group={sortBy} />
Most popular
</label>
</div>
</Drawer>With Form
House form fields with a pinned footer.
svelte
<script lang="ts">
import { Drawer } from "$lib/fancy-ui/drawer";
import { Button } from "$lib/fancy-ui/button";
import { FormField } from "$lib/fancy-ui/form-field";
import { Input } from "$lib/fancy-ui/input";
import { Textarea } from "$lib/fancy-ui/textarea";
let open = $state(false);
let subject = $state("");
let message = $state("");
function submit() {
open = false;
}
</script>
<Button onclick={() => (open = true)}>Send feedback</Button>
<Drawer bind:open title="Send feedback" {footer}>
<div class="flex flex-col gap-4">
<FormField label="Subject">
<Input bind:value={subject} placeholder="What's this about?" />
</FormField>
<FormField label="Message">
<Textarea bind:value={message} placeholder="Tell us more..." />
</FormField>
</div>
</Drawer>
{#snippet footer()}
<Button variant="outline" onclick={() => (open = false)}>Cancel</Button>
<Button onclick={submit}>Submit</Button>
{/snippet}No Swipe
Disable the drag-to-close gesture.
svelte
<script lang="ts">
import { Drawer } from "$lib/fancy-ui/drawer";
import { Button } from "$lib/fancy-ui/button";
let open = $state(false);
</script>
<Button onclick={() => (open = true)}>Open drawer</Button>
<Drawer
bind:open
swipeToClose={false}
title="Filters"
description="Swipe is off here — close with Escape, the scrim, or the close button."
>
<p class="text-muted-foreground text-[13px]">Body content goes here.</p>
</Drawer>Props
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | false | Whether the drawer is open. Bindable |
onOpenChange | (open: boolean) => void | - | Called with the new value whenever the drawer opens or closes |
title | string | - | Heading rendered in the header and wired to aria-labelledby |
description | string | - | Supporting text under the title, wired to aria-describedby |
dismissible | boolean | true | Whether Escape, the scrim, the close button and the swipe gesture can close the drawer |
swipeToClose | boolean | true | Whether dragging the handle down past the threshold closes the drawer |
class | string | - | Additional CSS classes merged onto the panel |
ref | HTMLDivElement | null | null | Bindable element reference to the panel |
Slots
| Slot | Description |
|---|---|
children | Panel body content |
footer | Content pinned below the body, e.g. actions |
Links
Related components
Al
AlertDialog
A confirmation dialog for consequential, hard-to-undo actions — fixed confirm/cancel actions, never dismissed by an outside click
Overlays Stable
Di
Dialog
A modal panel with a title, description, body and free-form footer — portals out, traps focus, and locks the page's scroll while open
Overlays Stable
Ho
HoverCard
An anchored panel that opens on hover or focus with a short delay, for richer previews than a tooltip — a profile card, a link preview
Overlays Stable