Overlay · astro-ui · Sheet
SheetJS
Dialog panel that slides in from a screen edge.
Sheet is a dialog panel that slides in from a screen edge — built on the same native <dialog> foundation as Dialog: modality, ::backdrop, Escape-to-close, and focus containment come from the platform and the component ships zero JS. Closing needs no JS: any <form method=“dialog”> button, the optional built-in close button, or Escape dismisses natively. When id is set, the title slot gets {id}-title and the sheet points aria-labelledby at it.
Features
- Slides from any edge: left / right / top / bottom
- Native <dialog> modality, backdrop, Escape — zero JS in the component
- Backdrop-click dismiss (opt-out with closeOnBackdrop={false})
- Built-in zero-JS close button (showClose, closeLabel)
- sm / md / lg / xl panel sizes (width for sides, height for top/bottom)
Usage
---
import { Button, Sheet } from "astro-ui";
---
<Button id="open-menu">Menu</Button>
<Sheet id="menu" side="left">
<h2 slot="title">Menu</h2>
<p>Sheet body…</p>
</Sheet>
<script>
document.getElementById("open-menu")?.addEventListener("click", () => {
document.getElementById("menu")?.showModal();
});
</script>Demos
Slide-in panel
<Button id="open-sheet">Open sheet</Button>
<Sheet id="sheet">
<h2 slot="title">Sheet title</h2>
<p>Sheet body…</p>
</Sheet>From any edge
<Button id="open-left">Left</Button>
<Sheet id="left" side="left"><h2 slot="title">Left</h2></Sheet>
<Button id="open-top">Top</Button>
<Sheet id="top" side="top"><h2 slot="title">Top</h2></Sheet>
<!-- sides: left | right | top | bottom -->Backdrop dismiss
{/* Default: click the dark layer to close (Escape too) */}
<Button id="open-sheet">Open sheet</Button>
<Sheet id="sheet">…</Sheet>
{/* Opt out: force an explicit close action */}
<Sheet id="critical" closeOnBackdrop={false}
ariaLabel="Critical settings">…</Sheet>API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
side | "left" | "right" | "top" | "bottom" | "right" | Which screen edge the panel slides in from. |
size | "sm" | "md" | "lg" | "xl" | "md" | Panel scale (width for left/right, height for top/bottom). |
id | string | — | Required for automatic title labelling (and the trigger script). |
showClose | boolean | true | Render the native (zero-JS) close button. |
closeLabel | string | "Close sheet" | Accessible label for the built-in close button. |
closeOnBackdrop | boolean | true | Close when the dark backdrop layer is clicked. |
class | string | — | Merged via cn(); Tailwind classes welcome. |
id | string | — | Element id. |
Slots
| Slot | Description |
|---|---|
title | Heading (auto-wired to aria-labelledby). |
default | Panel body content. |
Accessibility
Implemented accessibility features — semantics, ARIA wiring, and keyboard behavior that ship with the component.
- Native
<dialog>: focus containment, Escape, and modality from the platform aria-labelledbyauto-wired to the title slot ({id}-title);aria-labelalternative- Built-in close button is a real button with
closeLabel
FAQ
How do I open it?
One line: document.getElementById("open-menu") triggers showModal() on the sheet with a matching id — same trigger recipe as Dialog.
Does clicking the dark backdrop close it?
Yes by default. Set closeOnBackdrop={false} for flows where an accidental dismiss would lose work — the user then closes via the × button, a <form method="dialog"> action, or Escape.
Can the panel overflow the screen?
No — left/right panels are width: min(100%, 100vw) and top/bottom panels cap at max-height: 85vh; the size prop just tunes the base scale.
Changelog
Version history mentioning Sheet.
- Overlay (8): Dialog, AlertDialog, Sheet, Tooltip, Popover, HoverCard, Lightbox, Menu.
- Native-first interactive behavior: Dialog, AlertDialog, and Sheet on
<dialog>; Accordion and Collapsible on<details>; Tabs, Menu, Tree, and Combobox with WAI-ARIA roles and scoped keyboard scripts.
- Dialog, Lightbox, Sheet, and AlertDialog backdrops, Progress stripes, Carousel shadows, and Chart SVG shadows resolve through tokens instead of hard-coded colors.