Getting Started
Components
- Accordion
- Alert
- Alert Dialog
- Avatar
- Badge
- Button
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Circular Progress
- Collapsible
- Compare Slider
- Dialog
- Dropdown Menu
- Gauge
- Input
- Label
- Marquee
- Navigation Menu
- Number Field
- Pagination
- Popover
- Progress
- Radio Group
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Switch
- Table
- Tabs
- Textarea
- Toggle
- Tooltip
Demos
A sheet that slides in from the right.
"use client"
import { Button } from "@workspace/ui/components/button"
import { Input } from "@workspace/ui/components/input"
import {
Sheet,
SheetClose,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@workspace/ui/components/sheet"
export function SheetDemo() {
return (
<Sheet>
<SheetTrigger render={<Button variant="outline" />}>Add a note</SheetTrigger>
<SheetContent>
<SheetHeader>
<SheetTitle>Add a note</SheetTitle>
<SheetDescription>
Notes stay with this panel and show up in your report.
</SheetDescription>
</SheetHeader>
<div className="grid gap-3 px-6">
<label className="grid gap-1.5 text-xs font-medium">
Note
<Input placeholder="Slept 5 hours before the draw" />
</label>
</div>
<SheetFooter>
<SheetClose render={<Button size="sm" />}>Save note</SheetClose>
<SheetClose render={<Button variant="outline" size="sm" />}>Cancel</SheetClose>
</SheetFooter>
</SheetContent>
</Sheet>
)
}
Usage
Use a sheet for a task or detail that needs more room than a dialog but should keep the page in view: a filter panel, a note form, record details. Right is the usual side. Use bottom for short actions on mobile.
Import it from @workspace/ui/components/sheet.
Anatomy
- Sheet — Holds the open state.
- SheetTrigger — Opens the sheet. Pass a button through
render. - SheetContent — The panel, with backdrop and a close button.
sidesets the edge. - SheetHeader — Holds the title and description.
- SheetTitle — Names the sheet for screen readers. Always include it.
- SheetDescription — Supporting text.
- SheetFooter — Actions, pinned to the bottom.
- SheetClose — Closes the sheet. Pass a button through
render.
Notes
- The sheet is a modal. Focus is trapped inside until it closes.
- Left and right sheets take three quarters of the width on small screens.
Examples
Side
Set side on SheetContent to open from any edge.
"use client"
import { Button } from "@workspace/ui/components/button"
import {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@workspace/ui/components/sheet"
const sides = ["top", "right", "bottom", "left"] as const
export function SheetSide() {
return (
<div className="flex flex-wrap items-center justify-center gap-3">
{sides.map((side) => (
<Sheet key={side}>
<SheetTrigger render={<Button variant="outline" className="capitalize" />}>
{side}
</SheetTrigger>
<SheetContent side={side}>
<SheetHeader>
<SheetTitle className="capitalize">{side} sheet</SheetTitle>
<SheetDescription>This sheet opens from the {side} edge.</SheetDescription>
</SheetHeader>
</SheetContent>
</Sheet>
))}
</div>
)
}
Without close button
Set showCloseButton={false} and give the reader explicit actions instead.
"use client"
import { Button } from "@workspace/ui/components/button"
import {
Sheet,
SheetClose,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@workspace/ui/components/sheet"
export function SheetNoCloseButton() {
return (
<Sheet>
<SheetTrigger render={<Button variant="outline" />}>Review consent</SheetTrigger>
<SheetContent side="bottom" showCloseButton={false}>
<SheetHeader>
<SheetTitle>Share data for research?</SheetTitle>
<SheetDescription>
Your results are anonymised before they leave PREDICT. You can opt out at
any time.
</SheetDescription>
</SheetHeader>
<SheetFooter>
<SheetClose render={<Button size="sm" />}>Agree</SheetClose>
<SheetClose render={<Button variant="outline" size="sm" />}>Not now</SheetClose>
</SheetFooter>
</SheetContent>
</Sheet>
)
}
Props
These are the props you set most often. Unlisted props pass through to the underlying element.
Sheet
| Prop | Type | Default | Description |
|---|---|---|---|
defaultOpen | boolean | false | Open on first render. |
open | boolean | — | Open state when controlled. |
onOpenChange | (open) => void | — | Called when the sheet opens or closes. |
SheetContent
| Prop | Type | Default | Description |
|---|---|---|---|
side | "top", "right", "bottom", or "left" | right | Edge the sheet slides from. |
showCloseButton | boolean | true | Show the X button in the corner. |
className | string | — | Classes merged onto the panel. |