npm install @abhivarde/svelte-drawer Basic setup with a bottom drawer.
import { Drawer, DrawerOverlay, DrawerContent } from '@abhivarde/svelte-drawer';
<script>
let open = $state(false);
</script>
<button onclick={() => open = true}>Open Drawer</button>
<Drawer bind:open>
<DrawerOverlay />
<DrawerContent class="bg-white rounded-t-lg p-6">
<div class="mx-auto w-12 h-1.5 rounded-full bg-gray-300 mb-8" />
<h2 class="text-lg font-medium">Drawer Title</h2>
<p class="text-gray-600">Drawer content goes here.</p>
</DrawerContent>
</Drawer> Change direction with the direction prop.
<Drawer direction="bottom"> <!-- Default: from bottom --> </Drawer>
<Drawer direction="top"> <!-- From top --> </Drawer>
<Drawer direction="left"> <!-- From left --> </Drawer>
<Drawer direction="right"> <!-- From right --> </Drawer> <Drawer bind:open={defaultOpen}>
<DrawerOverlay />
<DrawerContent class="bg-gray-100 flex flex-col rounded-t-[10px] mt-24 h-fit fixed bottom-0 left-0 right-0 outline-none">
<div class="p-4 bg-white rounded-t-[10px] flex-1">
<div aria-hidden="true" class="mx-auto w-12 h-1.5 flex-shrink-0 rounded-full bg-gray-300 mb-8"></div>
<div class="max-w-md mx-auto">
<h2 class="font-medium mb-4 text-gray-900">Drawer for Svelte.</h2>
<p class="text-gray-600 mb-2">This component can be used as a Dialog replacement on mobile and tablet devices.</p>
<p class="text-gray-600 mb-2">This is the simplest setup.</p>
</div>
</div>
<div class="p-4 bg-gray-100 border-t border-gray-200 mt-auto">
<div class="flex gap-6 justify-end max-w-md mx-auto">
<a class="text-xs text-gray-600 flex items-center gap-0.5 hover:text-gray-900" href="https://github.com/AbhiVarde/svelte-drawer" target="_blank" rel="noopener noreferrer">
GitHub {@html externalLinkIcon}
</a>
<a class="text-xs text-gray-600 flex items-center gap-0.5 hover:text-gray-900" href="https://x.com/varde_abhi" target="_blank" rel="noopener noreferrer">
X {@html externalLinkIcon}
</a>
</div>
</div>
</DrawerContent>
</Drawer> <Drawer bind:open={sideOpen} direction="right">
<DrawerOverlay />
<DrawerContent class="right-2 top-2 bottom-2 fixed outline-none w-[310px] flex">
<div class="bg-zinc-50 h-full w-full grow p-5 flex flex-col rounded-[16px]">
<div class="max-w-md mx-auto">
<h2 class="font-medium mb-2 text-zinc-900">It supports all directions.</h2>
<p class="text-zinc-600 mb-2">This drawer is positioned on the right side.</p>
</div>
<div class="mt-auto pt-8">
<div class="flex gap-6 justify-center">
<a class="text-xs text-zinc-600 flex items-center gap-0.5 hover:text-zinc-900" href="https://github.com/AbhiVarde/svelte-drawer" target="_blank" rel="noopener noreferrer">
GitHub {@html externalLinkIcon}
</a>
<a class="text-xs text-zinc-600 flex items-center gap-0.5 hover:text-zinc-900" href="https://x.com/varde_abhi" target="_blank" rel="noopener noreferrer">
X {@html externalLinkIcon}
</a>
</div>
</div>
</div>
</DrawerContent>
</Drawer> <Drawer bind:open={nested1Open}>
<DrawerOverlay />
<DrawerContent class="bg-gray-100 flex flex-col rounded-t-[10px] h-full mt-24 lg:h-fit max-h-[96%] fixed bottom-0 left-0 right-0">
<div class="p-4 bg-white rounded-t-[10px] flex-1">
<div class="mx-auto w-12 h-1.5 flex-shrink-0 rounded-full bg-gray-300 mb-8"></div>
<div class="max-w-md mx-auto">
<h2 class="font-medium mb-4 text-gray-900">Nested Drawers.</h2>
<p class="text-gray-600 mb-2">Nesting drawers creates a stacking effect.</p>
<p class="text-gray-600 mb-4">Open the second drawer to see it in action.</p>
<button onclick={() => nested2Open = true} class="rounded-md w-full bg-gray-900 px-4 py-2.5 text-sm font-medium text-white hover:bg-gray-800">
Open Second Drawer
</button>
</div>
</div>
<div class="p-4 bg-gray-100 border-t border-gray-200 mt-auto">
<div class="flex gap-6 justify-end max-w-md mx-auto">
<a class="text-xs text-gray-600 flex items-center gap-0.5 hover:text-gray-900" href="https://github.com/AbhiVarde/svelte-drawer" target="_blank" rel="noopener noreferrer">
GitHub {@html externalLinkIcon}
</a>
<a class="text-xs text-gray-600 flex items-center gap-0.5 hover:text-gray-900" href="https://x.com/varde_abhi" target="_blank" rel="noopener noreferrer">
X {@html externalLinkIcon}
</a>
</div>
</div>
</DrawerContent>
</Drawer>
<Drawer bind:open={nested2Open}>
<DrawerOverlay class="z-[60]" />
<DrawerContent class="bg-gray-100 flex flex-col rounded-t-[10px] h-full mt-24 max-h-[94%] fixed bottom-0 left-0 right-0 z-[70]">
<div class="p-4 bg-white rounded-t-[10px] flex-1">
<div class="mx-auto w-12 h-1.5 flex-shrink-0 rounded-full bg-gray-300 mb-8"></div>
<div class="max-w-md mx-auto">
<h2 class="font-medium mb-4 text-gray-900">This drawer is nested.</h2>
<p class="text-gray-600 mb-2">Pull down to see the scaling effect.</p>
</div>
</div>
<div class="p-4 bg-gray-100 border-t border-gray-200 mt-auto">
<div class="flex gap-6 justify-end max-w-md mx-auto">
<a class="text-xs text-gray-600 flex items-center gap-0.5 hover:text-gray-900" href="https://github.com/AbhiVarde/svelte-drawer" target="_blank" rel="noopener noreferrer">
GitHub {@html externalLinkIcon}
</a>
<a class="text-xs text-gray-600 flex items-center gap-0.5 hover:text-gray-900" href="https://x.com/varde_abhi" target="_blank" rel="noopener noreferrer">
X {@html externalLinkIcon}
</a>
</div>
</div>
</DrawerContent>
</Drawer> <Drawer bind:open={scrollableOpen}>
<DrawerOverlay />
<DrawerContent class="bg-gray-100 flex flex-col rounded-t-[10px] mt-24 h-[80%] lg:h-[320px] fixed bottom-0 left-0 right-0 outline-none">
<div class="p-4 bg-white rounded-t-[10px] flex-1 overflow-y-auto">
<div class="max-w-md mx-auto space-y-4">
<div aria-hidden="true" class="mx-auto w-12 h-1.5 flex-shrink-0 rounded-full bg-gray-300 mb-8"></div>
<h2 class="font-medium mb-4 text-gray-900">Scrollable Drawer</h2>
<!-- Long content here -->
</div>
</div>
<div class="p-4 bg-gray-100 border-t border-gray-200 mt-auto">
<div class="flex gap-6 justify-end max-w-md mx-auto">
<a class="text-xs text-gray-600 flex items-center gap-0.5 hover:text-gray-900" href="https://github.com/AbhiVarde/svelte-drawer" target="_blank" rel="noopener noreferrer">
GitHub {@html externalLinkIcon}
</a>
<a class="text-xs text-gray-600 flex items-center gap-0.5 hover:text-gray-900" href="https://x.com/varde_abhi" target="_blank" rel="noopener noreferrer">
X {@html externalLinkIcon}
</a>
</div>
</div>
</DrawerContent>
</Drawer> <Drawer bind:open={controlledOpen} onOpenChange={(isOpen) => console.log('Drawer is now:', isOpen ? 'open' : 'closed')}>
<DrawerOverlay />
<DrawerContent class="bg-gray-100 flex flex-col rounded-t-[10px] mt-24 h-fit fixed bottom-0 left-0 right-0 outline-none">
<div class="p-4 bg-white rounded-t-[10px] flex-1">
<div class="mx-auto w-12 h-1.5 flex-shrink-0 rounded-full bg-gray-300 mb-8"></div>
<div class="max-w-md mx-auto">
<h2 class="font-medium mb-4 text-gray-900">A controlled drawer.</h2>
<p class="text-gray-600 mb-2">Control the state externally while still reacting to user gestures via onOpenChange.</p>
</div>
</div>
<div class="p-4 bg-gray-100 border-t border-gray-200 mt-auto">
<div class="flex gap-6 justify-end max-w-md mx-auto">
<a class="text-xs text-gray-600 flex items-center gap-0.5 hover:text-gray-900" href="https://github.com/AbhiVarde/svelte-drawer" target="_blank" rel="noopener noreferrer">
GitHub {@html externalLinkIcon}
</a>
<a class="text-xs text-gray-600 flex items-center gap-0.5 hover:text-gray-900" href="https://x.com/varde_abhi" target="_blank" rel="noopener noreferrer">
X {@html externalLinkIcon}
</a>
</div>
</div>
</DrawerContent>
</Drawer>