Drawer
The Drawer component provides a sliding panel that emerges from any edge of
the screen.
It is useful for displaying menus, options, or additional content without
leaving the current view.
- Flexible positioning: Supports
top,bottom,left, andright. - Overlay support: Click outside the drawer to close it.
- Customizable content: Include headers, links, forms, or interactive elements.
- Fixed or dynamic: Can be used as a fixed drawer or controlled programmatically.
Usage Example
Section titled “Usage Example”<script lang="ts"> import { Button, Drawer, Window } from "@fefade-ui/svelte"
let drawerStates = $state({ top: false, left: false, right: false, bottom: false })
type DrawerPosition = keyof typeof drawerStates
let isOpenFixed = $state(false)
function handleToggle(position: DrawerPosition) { drawerStates[position] = !drawerStates[position] }
function handleClose(position: DrawerPosition) { drawerStates[position] = false }</script>
{#snippet header(handleClose?: () => void)} <Drawer.Header {handleClose}> <span>logo</span> </Drawer.Header>{/snippet}
{#snippet content()} <Drawer.Content> <a href="/">label</a> </Drawer.Content>{/snippet}
<Drawer.Overlay isOpen={isOpenFixed} onclick={() => { isOpenFixed = false }}/><Drawer isOpen={isOpenFixed} position="right"> {@render header()} {@render content()}</Drawer>
<Button onclick={() => { isOpenFixed = !isOpenFixed }}> Right Fixed</Button>
<br /><br />
<Window style="position: relative; min-height: 500px;"> <Drawer.Overlay isOpen={drawerStates.top} onclick={() => { handleClose("top") }} style="position: absolute;" /> <Drawer isOpen={drawerStates.top} position="top" style="position: absolute;"> {@render header(() => { handleClose("top") })} {@render content()} </Drawer>
<Drawer.Overlay isOpen={drawerStates.left} onclick={() => { handleClose("left") }} style="position: absolute;" /> <Drawer isOpen={drawerStates.left} position="left" style="position: absolute;" > {@render header(() => { handleClose("left") })} {@render content()} </Drawer>
<Drawer isOpen={drawerStates.right} position="right" style="position: absolute;" > {@render header(() => { handleClose("right") })} {@render content()} </Drawer>
<Drawer isOpen={drawerStates.bottom} position="bottom" style="position: absolute;" > {@render header(() => { handleClose("bottom") })} {@render content()} </Drawer> <div style="display:flex; gap:1rem; flex-wrap: wrap;"> <Button onclick={() => handleToggle("top")}>Top</Button> <Button onclick={() => handleToggle("left")}>Left</Button> <Button onclick={() => handleToggle("right")}>Right</Button> <Button onclick={() => handleToggle("bottom")}>Bottom</Button> </div></Window>| Prop / Slot | Type | Default | Description |
|---|---|---|---|
isOpen | boolean | false | Controls whether the drawer is visible. |
position | "top" | "bottom" | "left" | "right" | "right" | Side of the screen from which the drawer slides in. |
Drawer.Header | component | Optional | Header content of the drawer (title, logo, close button). |
Drawer.Content | component | Optional | Main content inside the drawer (links, forms, interactive elements). |
Drawer.Overlay | component | Optional | Background overlay that detects clicks to close the drawer. |
Best Practices
Section titled “Best Practices”- Use overlay to focus attention and allow easy dismissal.
- Keep drawer content concise for better user experience.
- Combine with buttons or triggers to open drawers programmatically.
- Ensure drawers do not block important content on mobile screens.
- Use consistent positioning to avoid user confusion.