Sheet
Installation
npx @mielui/svelte add sheetyarn dlx @mielui/svelte add sheetbunx @mielui/svelte add sheetUsage
Compose Root, Trigger, and Content with a Header that holds the Title and an optional Description. side on Content picks the left or right edge, right by default. Focus stays within the open sheet and returns to its trigger when it closes.
<script lang="ts">
import { Button } from '@mielui/svelte/components/button';
import * as Sheet from '@mielui/svelte/components/sheet';
let open = $state(false);
</script>
<Sheet.Root bind:open>
<Sheet.Trigger>Open</Sheet.Trigger>
<Sheet.Content side="right">
<Sheet.Header>
<Sheet.Title>Title</Sheet.Title>
<Sheet.Description>Describe what lives here.</Sheet.Description>
</Sheet.Header>
<!-- Panel content -->
<Sheet.Footer>
<Sheet.Close>Cancel</Sheet.Close>
<Button
onclick={() => {
open = false;
}}
>
Save
</Button>
</Sheet.Footer>
</Sheet.Content>
</Sheet.Root>Bind open on Root when another control needs to open or close the panel. onOpenChange reports changes made inside the component; updating your bound value does not call it again. Each Root keeps its own state.
Footer renders on the outer frame below the inner surface, like Dialog.Footer, wherever you place it inside Content. Its actions sit in one row; a Close in the footer moves to the start so the other actions line up at the end. The theme setting chrome.borders chooses single or double framing, single by default.
Examples
Issue form
A full form with selects in the body and the submit action in the footer.
Left side
Right side
Glass surface
surface="glass" on Content gives the panel a translucent, blurred background. Omit surface to inherit --mielui-surface from your theme, or set surface="solid" to override it. Glass keeps an opaque fallback when backdrop filtering is unavailable and respects reduced-transparency preferences.
Stay open on outside press
allowClickOutside={false} on Content keeps the sheet open when the page behind it is pressed, and showClose={false} on Header leaves the footer buttons as the only way out besides Escape.
Dismissal
A sheet closes from its corner button, Escape, a Close button, or a press on the page behind it. Set allowClickOutside={false} on Content to ignore that last one, which suits a form the person could lose by a stray click. Header shows the corner button by default; pass showClose={false} when your own Close button is enough.
Buttons and text parts
Trigger and Close are built on Button, so they accept its props: variant, size, disabled, href, loading with its labels, unstyled, and bind:element. onclick runs before the part does its own work; call event.preventDefault() there to keep the sheet as it is.
Content, Header, Title, Description and Footer render their children and accept class.
Labels
Built-in text is English by default. Pass a labels object of type SheetLabels to Sheet.Root to translate the accessible name of the close button in the header. Every key is optional; omitted keys keep their default.
<script lang="ts">
import * as Sheet from '@mielui/svelte/components/sheet';
import type { SheetLabels } from '@mielui/svelte/components/sheet';
const labels: SheetLabels = {
close: 'Fermer'
};
</script>
<Sheet.Root {labels}>
โฆ
</Sheet.Root>API reference
Sheet.Root
Controls sheet state.
labelsSheetLabelsOverrides the built-in text and accessible names. Every key is optional and English is the fallback.
openBindablebooleanWhether it is open. Bind it to control the state from outside.
Default
falseonOpenChange((open: boolean) => void)Called with the new state whenever it opens or closes.
childrenSnippet<[]>Content rendered inside.
Sheet.Close
Closes the sheet.
disabledbooleanPrevents activation. A disabled link loses its destination and is skipped by Tab.
variantButtonVariantVisual style. Choose it for what the action means, not for decoration.
size"sm" | "md" | "lg" | "icon"Control height.
iconis a square button for a single icon.childrenSnippet<[]>Content rendered inside.
elementBindableHTMLButtonElement | HTMLAnchorElementBindable reference to the rendered DOM element. Type is the union of the two possible element types -- narrow at the use site:
unstyledbooleanSkip the variant/size base classes and render with
classalone.statusButtonStatusControlled visual state. Loading remains focusable and refuses activation.
loadingbooleanConvenience alias for
status="loading".labelsButtonLabelsOverrides the built-in text and accessible names. Every key is optional and English is the fallback.
onclick((event: MouseEvent) => void)Called when the button is activated. Loading and disabled buttons do not call it.
onkeydown((event: KeyboardEvent) => void)Called on key down, before the button handles the key itself.
hrefstringRenders a link to this address instead of a button.
Sheet.Content
Renders the sheet surface.
surface"solid" | "glass"Surface treatment. Omit it to inherit
--mielui-surfacefrom the theme.allowClickOutsidebooleanCloses when the pointer is pressed outside it. Set false to keep it open until it is dismissed another way.
Default
trueside"left" | "right"Viewport edge the sheet slides in from.
Default
'right'classstringClasses added to the element.
childrenSnippet<[]>Content rendered inside.
Sheet.Description
Renders the sheet description.
classstringClasses added to the element.
childrenSnippet<[]>Content rendered inside.
Sheet.Footer
Groups sheet actions.
classstringClasses added to the element.
childrenSnippet<[]>Content rendered inside.
Sheet.Header
Groups sheet heading content.
classstringClasses added to the element.
childrenSnippet<[]>Content rendered inside.
showClosebooleanShows the close button in the corner. Defaults to true.
Default
true
Sheet.Title
Renders the sheet title.
classstringClasses added to the element.
childrenSnippet<[]>Content rendered inside.
Sheet.Trigger
Opens the sheet.
disabledbooleanPrevents activation. A disabled link loses its destination and is skipped by Tab.
variantButtonVariantVisual style. Choose it for what the action means, not for decoration.
size"sm" | "md" | "lg" | "icon"Control height.
iconis a square button for a single icon.childrenSnippet<[]>Content rendered inside.
elementBindableHTMLButtonElement | HTMLAnchorElementBindable reference to the rendered DOM element. Type is the union of the two possible element types -- narrow at the use site:
unstyledbooleanSkip the variant/size base classes and render with
classalone.statusButtonStatusControlled visual state. Loading remains focusable and refuses activation.
loadingbooleanConvenience alias for
status="loading".labelsButtonLabelsOverrides the built-in text and accessible names. Every key is optional and English is the fallback.
onclick((event: MouseEvent) => void)Called when the button is activated. Loading and disabled buttons do not call it.
onkeydown((event: KeyboardEvent) => void)Called on key down, before the button handles the key itself.
hrefstringRenders a link to this address instead of a button.
pnpm dlx @mielui/svelte add sheet