Overlays
Sheet
A modal panel anchored to an edge of the screen, for forms and filters that need more room than a popover but shouldn’t take over the centre of the page.
Installation #
With the Nuxt module, every component is auto-imported — there is nothing to add. In a plain Vue project, import what you use:
Copy
import { JSheet } from '@juxtui/ui'Usage #
Copy
<JButton @click="open = true">Edit profile</JButton>
<JSheet v-model:open="open" title="Edit profile" description="Changes are visible to your team.">
<JInput v-model="name" label="Name" />
<template #footer="{ close }">
<JButton variant="ghost" @click="close">Cancel</JButton>
<JButton @click="save">Save</JButton>
</template>
</JSheet>Sheet shares Dialog’s focus trap, scroll lock and backdrop handling — it just slides in from an edge instead of appearing centred.
Variants & examples #
Sides#
side controls which edge it slides in from: left, right or bottom.
Required decision#
With close-on-overlay and close-on-escape off, dismissal attempts get a small nudge instead.
API #
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | false | Bound with v-model:open. |
| title | string | — | Heading. Labels the sheet. |
| description | string | — | Supporting text. Describes the sheet. |
| side | 'right' | 'left' | 'bottom' | 'right' | Edge the sheet slides in from. |
| size | 'sm' | 'md' | 'lg' | 'md' | Width (or height for bottom): 320, 400 or 560px. |
| closeOnOverlay | boolean | true | Close when the backdrop is clicked. |
| closeOnEscape | boolean | true | Close when Escape is pressed. |
| hideClose | boolean | false | Hide the close button in the corner. |
| ariaLabel | string | — | Accessible name when there is no visible title. |
Events
| Event | Payload | Description |
|---|---|---|
| update:open | boolean | Emitted when the sheet asks to close. |
| afterClose | — | After the leave transition — a good moment to reset form state. |
Slots
| Slot | Props | Description |
|---|---|---|
| default | { close } | Body content. |
| footer | { close } | Actions, right-aligned. |
| header | { titleId, descriptionId } | Replace the header. Put titleId on your heading to keep the sheet labelled. |
Methods
| Method | Signature | Description |
|---|---|---|
| close() | () => void | Close the sheet programmatically. |
Accessibility #
role="dialog"witharia-modal, labelled by the title and described by the description.- On open, focus moves to an element marked
autofocus, else the first form field, else the sheet itself. - On close, focus returns to whatever opened it.
- A click only dismisses when it both starts and ends on the backdrop — dragging a text selection out of the sheet never closes it.
- Under reduced motion, the sheet fades in place instead of sliding from its edge.
Keyboard #
| Key | Action |
|---|---|
| Tab | Moves focus to the next element inside the sheet, wrapping at the end. |
| ShiftTab | Moves focus backwards, wrapping at the start. |
| Esc | Closes the sheet (unless `close-on-escape` is off, in which case it nudges instead). |