Drawer
A panel that slides in from the edge of the screen, typically used for navigation or additional content.
Anatomy
<script>
import {
Drawer,
DrawerTrigger,
DrawerContent,
DrawerHeader,
DrawerTitle,
DrawerBody,
DrawerFooter,
DrawerCloseButton,
DrawerActionTrigger,
} from "@saas-ui/svelte/components/drawer";
</script>
<Drawer.Root>
<Drawer.Trigger>Open Drawer</Drawer.Trigger>
<Drawer.Content>
<Drawer.Header>
<Drawer.Title>Drawer Title</Drawer.Title>
<Drawer.CloseButton />
</Drawer.Header>
<Drawer.Body>
Drawer content goes here...
</Drawer.Body>
<Drawer.Footer>
<Drawer.ActionTrigger>Cancel</Drawer.ActionTrigger>
<Button>Save</Button>
</Drawer.Footer>
</Drawer.Content>
</Drawer.Root>Examples
Attached Accessibility
attached prop to render the drawer attached to the edge of the viewport without padding or rounded corners.
<Drawer.Root attached>
<Drawer.Trigger variant="outline" size="sm">Open Drawer</Drawer.Trigger>
<Drawer.Content>
<Drawer.Header>
<Drawer.Title>Drawer Title</Drawer.Title>
<Drawer.CloseButton />
</Drawer.Header>
<Drawer.Body>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed
do eiusmod tempor incididunt ut labore et dolore magna
aliqua.
</p>
</Drawer.Body>
<Drawer.Footer>
<Drawer.ActionTrigger variant="ghost"
>Cancel</Drawer.ActionTrigger>
<Button variant="glass" colour="indigo" class={focusClass}
>Save</Button>
</Drawer.Footer>
</Drawer.Content>
</Drawer.Root> Basic Accessibility
<Drawer.Root>
<Drawer.Trigger variant="outline" size="sm">Open Drawer</Drawer.Trigger>
<Drawer.Content>
<Drawer.Header>
<Drawer.Title>Drawer Title</Drawer.Title>
<Drawer.CloseButton />
</Drawer.Header>
<Drawer.Body>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed
do eiusmod tempor incididunt ut labore et dolore magna
aliqua.
</p>
<p class="text-fg-muted mt-4">
Press the <Kbd>esc</Kbd> key to close the drawer.
</p>
</Drawer.Body>
<Drawer.Footer>
<Drawer.ActionTrigger variant="ghost"
>Cancel</Drawer.ActionTrigger>
<Button variant="glass" colour="indigo" class={focusClass}
>Save</Button>
</Drawer.Footer>
</Drawer.Content>
</Drawer.Root> Initial Focus Accessibility
initialFocusEl prop to set which element receives focus when the drawer opens. This is useful for directing user attention to a specific input field.
{@const state = new FocusState()}
<Drawer.Root initialFocusEl={() => state.inputRef}>
<Drawer.Trigger variant="outline" size="sm">Open Drawer</Drawer.Trigger>
<Drawer.Content>
<Drawer.Header>
<Drawer.Title>User Information</Drawer.Title>
<Drawer.CloseButton />
</Drawer.Header>
<Drawer.Body>
<Stack gap={4}>
<Input placeholder="First Name" />
<Input placeholder="Last Name" />
<Input
bind:ref={state.inputRef}
placeholder="Email (Focused First)"
/>
</Stack>
</Drawer.Body>
<Drawer.Footer>
<Drawer.ActionTrigger variant="ghost"
>Cancel</Drawer.ActionTrigger>
<Button variant="glass" colour="indigo" class={focusClass}
>Save</Button>
</Drawer.Footer>
</Drawer.Content>
</Drawer.Root> Offset Accessibility
offset prop to the Drawer.Content to add spacing around the drawer. You can also use the rounded prop to customize the border radius.
<Drawer.Root>
<Drawer.Trigger variant="outline" size="sm">Open Drawer</Drawer.Trigger>
<Drawer.Content offset="1rem" rounded="rounded-md">
<Drawer.Header>
<Drawer.Title>Drawer Title</Drawer.Title>
<Drawer.CloseButton />
</Drawer.Header>
<Drawer.Body>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed
do eiusmod tempor incididunt ut labore et dolore magna
aliqua.
</p>
</Drawer.Body>
<Drawer.Footer>
<Drawer.ActionTrigger variant="ghost"
>Cancel</Drawer.ActionTrigger>
<Button variant="glass" colour="indigo" class={focusClass}
>Save</Button>
</Drawer.Footer>
</Drawer.Content>
</Drawer.Root> Placement Accessibility
placement prop to change the position of the drawer. Options include start (left), end (right), top, and bottom.
<HStack align="start" gap={6} wrap="wrap">
{#each ["bottom", "top", "start", "end"] as const as placement}
<Drawer.Root {placement}>
<Drawer.Trigger variant="outline" size="sm">
Open ({placement})
</Drawer.Trigger>
<Drawer.Content
rounded={placement === "bottom"
? "rounded-t-lg"
: placement === "top"
? "rounded-b-lg"
: undefined}
>
<Drawer.Header>
<Drawer.Title>Drawer Title</Drawer.Title>
<Drawer.CloseButton />
</Drawer.Header>
<Drawer.Body>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua.
</p>
</Drawer.Body>
<Drawer.Footer>
<Drawer.ActionTrigger variant="ghost"
>Cancel</Drawer.ActionTrigger>
<Button
variant="glass"
colour="indigo"
class={focusClass}>Save</Button>
</Drawer.Footer>
</Drawer.Content>
</Drawer.Root>
{/each}
</HStack> Sizes Accessibility
size prop to change the size of the drawer. Options include xs, sm, md, lg, xl, and full.
<HStack align="start" gap={6} wrap="wrap">
{#each ["xs", "sm", "md", "lg", "xl", "full"] as const as size}
<Drawer.Root {size}>
<Drawer.Trigger variant="outline" size="sm">
Open ({size})
</Drawer.Trigger>
<Drawer.Content>
<Drawer.Header>
<Drawer.Title>Drawer Title</Drawer.Title>
<Drawer.CloseButton />
</Drawer.Header>
<Drawer.Body>
Press the <Kbd>esc</Kbd> key to close the drawer.
</Drawer.Body>
<Drawer.Footer>
<Drawer.ActionTrigger variant="ghost"
>Cancel</Drawer.ActionTrigger>
<Button
variant="glass"
colour="indigo"
class={focusClass}>Save</Button>
</Drawer.Footer>
</Drawer.Content>
</Drawer.Root>
{/each}
</HStack>Props
Drawer.Root
The root container component for the drawer.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet | - | The drawer content. |
open | boolean | false | Whether the drawer is open. |
onOpenChange | (details: { open: boolean }) => void | - | Handler called when the open state changes. |
size | "xs" | "sm" | "md" | "lg" | "xl" | "full" | "sm" | The size of the drawer. |
placement | "start" | "end" | "top" | "bottom" | "end" | The placement of the drawer. |
attached | boolean | false | Whether the drawer is attached to the edge of the viewport (no padding/rounded corners). |
role | "dialog" | "alertdialog" | "dialog" | The role of the drawer. |
initialFocusEl | () => HTMLElement | null | - | Element to receive focus when the drawer is opened. |
finalFocusEl | () => HTMLElement | null | - | Element to receive focus when the drawer is closed. |
restoreFocus | boolean | true | Whether to restore focus to the element that had focus before the drawer was opened. |
lazyMount | boolean | - | Whether to lazily mount the drawer content. |
unmountOnExit | boolean | - | Whether to unmount the drawer on exit. |
onPrefetch | () => void | - | Callback invoked when hovering over the trigger (for prefetching content). Similar to Astro's link prefetching, this allows preloading data before opening. |
Drawer.Content
The content container that renders inside a portal with backdrop.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet | - | The drawer content. |
class | string | - | Additional CSS classes to apply. |
offset | string | - | The offset from the edge of the viewport (in spacing units). Overrides the attached prop when set. |
rounded | string | - | Custom border radius class (e.g., "rounded-md", "rounded-lg"). When used with offset, applies rounding to the drawer. |
Drawer.Header
The header section of the drawer.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet | - | The header content. |
class | string | - | Additional CSS classes to apply. |
Drawer.Title
The title element for the drawer.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet | - | The title content. |
class | string | - | Additional CSS classes to apply. |
Drawer.Body
The main body content area with scrolling support.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet | - | The body content. |
class | string | - | Additional CSS classes to apply. |
Drawer.Footer
The footer section for action buttons.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet | - | The footer content. |
class | string | - | Additional CSS classes to apply. |
Drawer.Trigger
Button that opens the drawer.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet | - | The trigger content. |
class | string | - | Additional CSS classes to apply. |
asChild | boolean | false | Whether to render as a child element. |
variant | "solid" | "outline" | "ghost" | "subtle" | "surface" | "plain" | "outline" | The button variant. |
size | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "md" | The button size. |
colour | ColourName | "gray" | The colour theme of the button. |
style | string | - | Additional inline styles. |
Drawer.CloseButton
Close button positioned in the top-right corner.
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | - | Additional CSS classes to apply. |
Drawer.ActionTrigger
Action button that closes the drawer when clicked.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet | - | The action trigger content. |
class | string | - | Additional CSS classes to apply. |
asChild | boolean | false | Whether to render as a child element. |
variant | "solid" | "outline" | "ghost" | "subtle" | "surface" | "plain" | "surface" | The button variant. |
size | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "md" | The button size. |
colour | ColourName | "gray" | The colour theme of the button. |
style | string | - | Additional inline styles. |