Sheet
A neo-brutalist side panel component that can slide in from any edge. Built on top of reka-ui's Dialog primitive.
Demo
Installation
pnpm dlx brutx-vue@latest add sheetUsage
<script setup>
import { DialogRoot as Sheet, DialogTrigger as SheetTrigger, DialogClose as SheetClose } from 'reka-ui'
import {
SheetContent,
SheetHeader,
SheetFooter,
SheetTitle,
SheetDescription,
Button,
} from 'brutx-ui-vue'
</script>
<template>
<Sheet>
<SheetTrigger as-child>
<Button variant="outline">Open Sheet</Button>
</SheetTrigger>
<SheetContent side="right">
<SheetHeader>
<SheetTitle>Edit Profile</SheetTitle>
<SheetDescription>
Make changes to your profile here.
</SheetDescription>
</SheetHeader>
<div class="py-4">
<p class="text-sm">Sheet content goes here.</p>
</div>
<SheetFooter>
<SheetClose as-child>
<Button variant="outline">Cancel</Button>
</SheetClose>
<Button variant="primary">Save</Button>
</SheetFooter>
</SheetContent>
</Sheet>
</template>Direction Variants
| Direction | Description |
|---|---|
top | Slides in from the top |
bottom | Slides in from the bottom |
left | Slides in from the left (max sm:max-w-sm) |
right | Slides in from the right (default, max sm:max-w-sm) |
<script setup>
import { DialogRoot as Sheet, DialogTrigger as SheetTrigger } from 'reka-ui'
import { SheetContent, Button } from 'brutx-ui-vue'
</script>
<template>
<Sheet>
<SheetTrigger as-child>
<Button>Open Left Sheet</Button>
</SheetTrigger>
<SheetContent side="left">
<p>Content slides in from the left.</p>
</SheetContent>
</Sheet>
</template>Sub-components
| Component | Description |
|---|---|
Sheet | Root primitive (DialogRoot imported from reka-ui as Sheet) |
SheetTrigger | Trigger primitive (DialogTrigger imported from reka-ui) |
SheetPortal | Portal primitive (DialogPortal imported from reka-ui) |
SheetContent | Panel content with direction variants, built-in close button |
SheetHeader | Header container |
SheetFooter | Footer container |
SheetTitle | Styled panel title wrapping Reka UI DialogTitle |
SheetDescription | Styled panel description wrapping Reka UI DialogDescription |
SheetClose | Close primitive (DialogClose imported from reka-ui) |
Reka UI Primitives
Sheet, SheetTrigger, SheetPortal, and SheetClose are local aliases for DialogRoot, DialogTrigger, DialogPortal, and DialogClose, imported from reka-ui. The five styled components listed in the generated API below are imported from BrutxUI.
Sheet accepts the boolean open value for controlled state with v-model:open, and emits update:open with the new boolean state. defaultOpen initializes uncontrolled state and defaults to false; modal defaults to true. Its default slot contains the trigger and panel, and receives the current open state and a close() function.
SheetContent forwards additional attributes and event listeners to DialogContent. Event names such as openAutoFocus can be listened to using @open-auto-focus in templates. The built-in close button uses localized sheet.close text and sits at the top-left for side="left", or at the top-right for other sides.
API Reference
SheetContent
| Name | Type | Default | Description |
|---|---|---|---|
side | "bottom" | "left" | "right" | "top" | undefined | "right" | The viewport edge from which the panel enters, controlling position, border, and transition direction. The close button is top-left for left and top-right otherwise. |
DetailsDeclared typeNonNullable<"right" | "bottom" | "left" | "top" | null | undefined> | undefined Literal values
Default value details
Sourcepackages/ui/src/components/sheet/SheetContent.vue | |||
class | string | undefined | undefined | CSS classes merged onto the floating content panel. Other attributes and listeners are forwarded through $attrs to Reka UI DialogContent. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/sheet/SheetContent.vue | |||
| Name | Signature or type | Description |
|---|---|---|
@openAutoFocus | [event: Event] | A Reka UI event forwarded through $attrs before automatic focus on opening. Call preventDefault() to handle focus yourself. |
DetailsDeclared type[event: Event] Sourcepackages/ui/src/components/sheet/SheetContent.vue | ||
@closeAutoFocus | [event: Event] | A Reka UI event forwarded through $attrs before restoring focus on closing. Its default focus behavior can be prevented. |
DetailsDeclared type[event: Event] Sourcepackages/ui/src/components/sheet/SheetContent.vue | ||
@interactOutside | [event: PointerDownOutsideEvent | FocusOutsideEvent] | A Reka UI event forwarded through $attrs for a pointer press or focus interaction outside the panel. It can prevent dismissal caused by that interaction. |
DetailsDeclared type[event: PointerDownOutsideEvent | FocusOutsideEvent] Sourcepackages/ui/src/components/sheet/SheetContent.vue | ||
@escapeKeyDown | [event: KeyboardEvent] | A Reka UI event forwarded through $attrs when the topmost panel receives Escape. It can prevent the default dismissal. |
DetailsDeclared type[event: KeyboardEvent] Sourcepackages/ui/src/components/sheet/SheetContent.vue | ||
@pointerDownOutside | [event: PointerDownOutsideEvent] | A Reka UI event forwarded through $attrs when the pointer is pressed outside the panel. It can prevent the default dismissal. |
DetailsDeclared type[event: PointerDownOutsideEvent] Sourcepackages/ui/src/components/sheet/SheetContent.vue | ||
@focusOutside | [event: FocusOutsideEvent] | A Reka UI event forwarded through $attrs when focus moves outside the panel. It can prevent the default handling of that outside interaction. |
DetailsDeclared type[event: FocusOutsideEvent] Sourcepackages/ui/src/components/sheet/SheetContent.vue | ||
| Name | Signature or type | Description |
|---|---|---|
#default | {} | The panel body, typically composing SheetHeader, content, and SheetFooter. A localized built-in close button follows the content. |
DetailsDeclared type{}Sourcepackages/ui/src/components/sheet/SheetContent.vue | ||
SheetDescription
| Name | Type | Default | Description |
|---|---|---|---|
class | string | undefined | — | CSS classes merged onto the Reka UI description primitive, styled as supporting text by default. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/sheet/SheetDescription.vue | |||
| Name | Signature or type | Description |
|---|---|---|
#default | {} | Supporting panel text used for its accessible description. The description element is omitted when the slot has no meaningful content. |
DetailsDeclared type{}Sourcepackages/ui/src/components/sheet/SheetDescription.vue | ||
SheetHeader
| Name | Type | Default | Description |
|---|---|---|---|
class | string | undefined | — | CSS classes merged onto the panel header container. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/sheet/SheetHeader.vue | |||
| Name | Signature or type | Description |
|---|---|---|
#default | {} | The panel title, description, and other header content. |
DetailsDeclared type{}Sourcepackages/ui/src/components/sheet/SheetHeader.vue | ||
SheetTitle
| Name | Type | Default | Description |
|---|---|---|---|
class | string | undefined | — | CSS classes merged onto the Reka UI title primitive, styled as a bold heading by default. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/sheet/SheetTitle.vue | |||
| Name | Signature or type | Description |
|---|---|---|
#default | {} | The panel title used for its accessible name. The title element is omitted when the slot has no meaningful content. |
DetailsDeclared type{}Sourcepackages/ui/src/components/sheet/SheetTitle.vue | ||
Accessibility
- Keyboard: Supports
Escapeto close the panel - ARIA Attributes: Automatically manages
aria-labelledby(linked toSheetTitle) andaria-describedby(linked toSheetDescription) - Focus Management: Focus is locked inside the panel when open; focus is restored to the trigger when closed