Feedback
Sheet
A mobile-first bottom sheet with swipe to dismiss that becomes a centered dialog from 768px.
<script>
import { Sheet, Button } from "@codeatlasdev/ui";
let open = $state(false);
</script>
<Sheet bind:open title="Switch session" description="Choose the active account">
...
{#snippet footer()}<Button>New session</Button>{/snippet}
</Sheet>
Below 768px the sheet rises from the bottom edge with a drag handle, safe-area padding and rounded top corners. From 768px up it renders as a centered dialog. Focus trap, focus restore, Escape, overlay dismissal and scroll lock come from the native modal <dialog> the sheet renders.
Swipe to dismiss. Drag the handle or the header down. Releasing past 30% of the panel height, or faster than 0.5 px/ms, closes the sheet; otherwise it springs back. The gesture is off under prefers-reduced-motion and in the centered desktop layout. Keyboard users close it with Escape or the close button. Open the demos below on a phone or in a mobile viewport to try the gesture.
Swipe to dismiss
Drag the handle or header down on a viewport below 768px. Above that, it is a centered dialog.
Code
Footer and swipeToDismiss
A pinned footer, and swipeToDismiss set to false so only the close button, Escape and the overlay dismiss it.
Code
Props
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | false | Bindable open state. |
title | string | – | Header title. Without it the panel falls back to a localized generic aria-label. |
description | string | – | Supporting text under the title. |
swipeToDismiss | boolean | true | Drag the handle or header down to dismiss in the bottom-sheet layout. Ignored under reduced motion and on desktop. |
onclose | () => void | – | Called when the sheet closes by swipe, close button, Escape or overlay. |
children | Snippet | – | Required. Scrollable body. |
footer | Snippet | – | Pinned footer below the body. |