Westy Design Systemv0.2.7
OverviewComponentsExamplesStorybook

Foundations

  • Typography
  • Colors
  • Spacing
  • Radius
  • Shadows
  • Icons

Components

  • Accordion
  • Alert
  • Alert Dialog
  • Aspect Ratio
  • Avatar
  • Badge
  • Breadcrumb
  • Button
  • Button Group
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Collapsible
  • Combobox
  • Command
  • Context Menu
  • Data Table
  • Date Picker
  • Dialog
  • Direction
  • Drawer
  • Dropdown Menu
  • Empty
  • Field
  • Hover Card
  • Input
  • Input Group
  • Input OTP
  • Item
  • Kbd
  • Label
  • Menubar
  • Native Select
  • Navigation Menu
  • Pagination
  • Popover
  • Progress
  • Questionnaire
  • Radio Group
  • Resizable
  • Scroll Area
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Skeleton
  • Slider
  • Sonner
  • Spinner
  • Switch
  • Table
  • Tabs
  • Textarea
  • Toggle
  • Toggle Group
  • Tooltip

Chat

  • Attachment
  • Bubble
  • Marker
  • Message
  • Message Scroller

Components

Sheet

Extends the Dialog component to display content that complements the main content of the screen.

Playground

—side
—SheetTitle children
—SheetDescription children
—showCloseButton
—modal
Usage
Sheet wraps a SheetTrigger and a SheetContent that slides in from an edge of the screen. Inside the content, SheetHeader groups SheetTitle and SheetDescription, and SheetFooter sticks to the bottom via mt-auto. SheetClose closes from anywhere via asChild; the top-corner close button ships by default.
import {
  Sheet,
  SheetClose,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from "@workspace/ui/components/sheet"

<Sheet>
  <SheetTrigger asChild>
    <Button variant="outline">Open sheet</Button>
  </SheetTrigger>
  <SheetContent>
    <SheetHeader>
      <SheetTitle>Edit profile</SheetTitle>
      <SheetDescription>
        Make changes to your profile here. Click save when you're done.
      </SheetDescription>
    </SheetHeader>
    <SheetFooter>
      <Button>Save changes</Button>
      <SheetClose asChild>
        <Button variant="outline">Close</Button>
      </SheetClose>
    </SheetFooter>
  </SheetContent>
</Sheet>
Side
The side prop on SheetContent picks the edge the panel slides in from: top, right (the default), bottom or left. Horizontal sides span the full height and cap at sm:max-w-sm; vertical sides span the full width and size to their content.
<SheetContent side="top">…</SheetContent>
<SheetContent side="right">…</SheetContent>
<SheetContent side="bottom">…</SheetContent>
<SheetContent side="left">…</SheetContent>
Form
Compose Field parts inside the content for edit-in-place flows. SheetContent is a flex column, so give the field group px-4 to align with the header and footer padding — the footer stays pinned to the bottom regardless of the content height.
<Sheet>
  <SheetTrigger asChild>
    <Button variant="outline">Edit profile</Button>
  </SheetTrigger>
  <SheetContent>
    <SheetHeader>
      <SheetTitle>Edit profile</SheetTitle>
      <SheetDescription>
        Make changes to your profile here. Click save when you're done.
      </SheetDescription>
    </SheetHeader>
    <FieldGroup className="px-4">
      <Field>
        <FieldLabel htmlFor="sheet-name">Name</FieldLabel>
        <Input id="sheet-name" defaultValue="Pedro Duarte" />
      </Field>
      <Field>
        <FieldLabel htmlFor="sheet-username">Username</FieldLabel>
        <Input id="sheet-username" defaultValue="@peduarte" />
      </Field>
    </FieldGroup>
    <SheetFooter>
      <Button type="submit">Save changes</Button>
      <SheetClose asChild>
        <Button variant="outline">Cancel</Button>
      </SheetClose>
    </SheetFooter>
  </SheetContent>
</Sheet>
Size
Adjust the panel size with utility classes on SheetContent. For horizontal sides, override the default width and sm:max-w-sm cap; for vertical sides, set a height.
<SheetContent className="w-full sm:max-w-lg">
  {/* wider right-hand panel */}
</SheetContent>

<SheetContent side="bottom" className="h-1/3">
  {/* taller bottom panel */}
</SheetContent>
RTL
SheetContent draws its edge border with logical properties (border-s, border-e) and places the close button with end-4, so passing dir="rtl" mirrors the panel chrome without extra classes. The side prop stays physical — choose it for the layout, not the language.
<Sheet>
  <SheetTrigger asChild>
    <Button variant="outline">فتح اللوحة</Button>
  </SheetTrigger>
  <SheetContent side="left" dir="rtl">
    <SheetHeader>
      <SheetTitle>تعديل الملف الشخصي</SheetTitle>
      <SheetDescription>
        قم بإجراء تغييرات على ملفك الشخصي هنا. انقر على حفظ عند الانتهاء.
      </SheetDescription>
    </SheetHeader>
    <SheetFooter>
      <Button>حفظ</Button>
      <SheetClose asChild>
        <Button variant="outline">إلغاء</Button>
      </SheetClose>
    </SheetFooter>
  </SheetContent>
</Sheet>
Accessibility
Built on the Radix Dialog primitive: focus is trapped inside the panel, Escape and overlay clicks close it, and focus returns to the trigger on close. SheetTitle labels the sheet via aria-labelledby and is required — if the design hides it, keep it in the tree with sr-only. SheetDescription wires up aria-describedby, and the built-in close button carries a screen-reader-only label.
<SheetContent>
  <SheetHeader>
    <SheetTitle className="sr-only">Navigation</SheetTitle>
    <SheetDescription className="sr-only">
      Browse the site sections
    </SheetDescription>
  </SheetHeader>
  {/* visually title-less content */}
</SheetContent>
API Reference
Eight parts re-export the Radix Dialog primitive with Westy styling: Sheet as the stateful root, SheetTrigger and SheetClose as behavior wrappers (use asChild to keep your own markup), the portal and overlay handled automatically by SheetContent, plus the SheetHeader / SheetTitle / SheetDescription / SheetFooter layout parts. All accept their underlying element props.
ComponentPropDefault
Sheetopen?: boolean, onOpenChange?: (open: boolean) => void—
Sheetmodal?: booleantrue
SheetContentside?: "top" | "right" | "bottom" | "left""right"
SheetContentshowCloseButton?: booleantrue
SheetTrigger / SheetCloseasChild?: booleanfalse
<Sheet data-slot="sheet" />
<SheetTrigger data-slot="sheet-trigger" />
<SheetContent data-slot="sheet-content" data-side data-open data-closed />
<SheetOverlay data-slot="sheet-overlay" />
<SheetHeader data-slot="sheet-header" />
<SheetTitle data-slot="sheet-title" />
<SheetDescription data-slot="sheet-description" />
<SheetFooter data-slot="sheet-footer" />
<SheetClose data-slot="sheet-close" />

Tokens used

9 design tokens consumed by the Sheet component.

  • --popover

    Popover

    bg-popover
  • --popover-foreground

    Popover Foreground

    text-popover-foreground
  • --foreground

    Foreground

    text-foreground
  • --muted-foreground

    Muted Foreground

    text-muted-foreground
  • --border

    Border

    border-tborder-eborder-bborder-s
  • --font-heading

    GT Alpina Condensed

    font-heading
  • --text-sm

    Text Small (14px)

    text-sm
  • --font-weight-medium

    Font weight Medium (500)

    font-medium
  • --spacing

    Spacing unit (4px)

    p-4gap-4gap-2gap-1.5top-4end-4