YaVendio Registry
Components

YA Sheet

A sliding panel component for displaying content in a drawer or side panel

The YaSheet is a sliding panel component in the YaVendio Design System. It can appear from the right, left, or bottom of the screen, making it perfect for navigation menus, detail panels, mobile drawers, and any content that needs to slide in without replacing the current view.

Quick Start

pnpm dlx shadcn@latest add @yavendio/ya-sheet
npx shadcn@latest add @yavendio/ya-sheet
yarn dlx shadcn@latest add @yavendio/ya-sheet
import {
  YaSheet,
  YaSheetTrigger,
  YaSheetContent,
  YaSheetTopBar,
  YaSheetHeader,
  YaSheetTitle,
  YaSheetDescription,
  YaSheetBody,
  YaSheetFooter,
  YaSheetClose,
} from '@/components/ui/ya-sheet'

export default function Example() {
  return (
    <YaSheet>
      <YaSheetTrigger asChild>
        <button>Open Sheet</button>
      </YaSheetTrigger>
      <YaSheetContent showCloseButton={false}>
        <YaSheetTopBar />
        <YaSheetHeader>
          <YaSheetTitle>Sheet Title</YaSheetTitle>
          <YaSheetDescription>
            Sheet description goes here.
          </YaSheetDescription>
        </YaSheetHeader>
        <YaSheetBody>
          Your content here
        </YaSheetBody>
        <YaSheetFooter>
          <YaSheetClose asChild>
            <button>Close</button>
          </YaSheetClose>
        </YaSheetFooter>
      </YaSheetContent>
    </YaSheet>
  )
}

Basic Usage

<YaSheet>
  <YaSheetTrigger asChild>
    <YaButton variant="primary">Open Sheet</YaButton>
  </YaSheetTrigger>
  <YaSheetContent showCloseButton={false}>
    <YaSheetTopBar
      actionsRight={
        <>
          <YaSheetActionButton icon={<Printer className="size-3" />} />
          <YaSheetActionButton icon={<Search className="size-3" />} />
        </>
      }
    />
    <YaSheetHeader>
      <YaSheetTitle>Edit profile</YaSheetTitle>
      <YaSheetDescription>
        Make changes to your profile here. Click save when you're done.
      </YaSheetDescription>
    </YaSheetHeader>
    <YaSheetBody>
      <YaInput label="Name" orientation="horizontal" placeholder="Enter your name" />
      <YaInput label="Username" orientation="horizontal" placeholder="Enter your username" />
    </YaSheetBody>
    <YaSheetFooter>
      <YaSheetClose asChild>
        <YaButton variant="secondary">Save</YaButton>
      </YaSheetClose>
    </YaSheetFooter>
  </YaSheetContent>
</YaSheet>

Sides

YaSheet supports three different sides for desktop and mobile use cases:

SideUsageDescription
rightDesktop panelsDefault, slides from right edge
leftNavigationSlides from left edge
bottomMobile drawerSlides from bottom with drag handle
<YaSheetContent side="right">...</YaSheetContent>
<YaSheetContent side="left">...</YaSheetContent>
<YaSheetContent side="bottom">...</YaSheetContent>

Left Side Sheet

Perfect for navigation panels and menus:

<YaSheet>
  <YaSheetTrigger asChild>
    <YaButton variant="tertiary">Open Left Sheet</YaButton>
  </YaSheetTrigger>
  <YaSheetContent side="left" showCloseButton={false}>
    <YaSheetTopBar />
    <YaSheetHeader>
      <YaSheetTitle>Navigation</YaSheetTitle>
      <YaSheetDescription>
        Browse through your application sections.
      </YaSheetDescription>
    </YaSheetHeader>
    <YaSheetBody>
      {/* Navigation items */}
    </YaSheetBody>
  </YaSheetContent>
</YaSheet>

Bottom Sheet (Mobile Drawer)

The bottom sheet includes a drag handle for mobile-friendly interactions:

<YaSheet>
  <YaSheetTrigger asChild>
    <YaButton variant="tertiary">Open Bottom Drawer</YaButton>
  </YaSheetTrigger>
  <YaSheetContent side="bottom" showCloseButton={false}>
    <YaSheetTopBar />
    <YaSheetHeader>
      <YaSheetTitle>Edit profile</YaSheetTitle>
      <YaSheetDescription>
        Make changes to your profile here.
      </YaSheetDescription>
    </YaSheetHeader>
    <YaSheetBody>
      {/* Form content */}
    </YaSheetBody>
    <YaSheetFooter>
      <YaSheetClose asChild>
        <YaButton variant="secondary">Save</YaButton>
      </YaSheetClose>
    </YaSheetFooter>
  </YaSheetContent>
</YaSheet>

Sizes

YaSheet supports multiple sizes for different content needs:

SizeWidth (Side Sheets)Max Height (Bottom)
sm320px50vh
default384px85vh
lg480px90vh
full100%100vh
<YaSheetContent size="sm">...</YaSheetContent>
<YaSheetContent size="default">...</YaSheetContent>
<YaSheetContent size="lg">...</YaSheetContent>

With Form

A common pattern for sheets with form inputs:

<YaSheet>
  <YaSheetTrigger asChild>
    <YaButton variant="primary">Edit Profile</YaButton>
  </YaSheetTrigger>
  <YaSheetContent showCloseButton={false}>
    <YaSheetTopBar
      actionsRight={
        <>
          <YaSheetActionButton icon={<Printer className="size-3" />} />
          <YaSheetActionButton icon={<Search className="size-3" />} />
        </>
      }
    />
    <YaSheetHeader>
      <YaSheetTitle>Edit profile</YaSheetTitle>
      <YaSheetDescription>
        Make changes to your profile here. Click save when you're done.
      </YaSheetDescription>
    </YaSheetHeader>
    <YaSheetBody>
      <YaInput label="Name" orientation="horizontal" placeholder="Enter your name" />
      <YaInput label="Username" orientation="horizontal" placeholder="Enter your username" />
    </YaSheetBody>
    <YaSheetFooter>
      <YaSheetClose asChild>
        <YaButton variant="tertiary">Cancel</YaButton>
      </YaSheetClose>
      <YaSheetClose asChild>
        <YaButton variant="secondary">Save</YaButton>
      </YaSheetClose>
    </YaSheetFooter>
  </YaSheetContent>
</YaSheet>

Custom Content (Blanket)

Add any custom content to the sheet body:

<YaSheetBody>
  <div className="border border-dashed border-primary rounded-lg p-6 flex items-center justify-center">
    <span className="text-sm text-muted-foreground italic">
      Place your content here
    </span>
  </div>
</YaSheetBody>

Controlled State

Control the sheet programmatically:

Sheet is closed

'use client'

import { useState } from 'react'

export default function ControlledSheet() {
  const [open, setOpen] = useState(false)

  return (
    <>
      <YaButton onClick={() => setOpen(true)}>Open Sheet</YaButton>
      
      <YaSheet open={open} onOpenChange={setOpen}>
        <YaSheetContent showCloseButton={false}>
          <YaSheetTopBar />
          <YaSheetHeader>
            <YaSheetTitle>Controlled Sheet</YaSheetTitle>
            <YaSheetDescription>
              This sheet is controlled via external state.
            </YaSheetDescription>
          </YaSheetHeader>
          <YaSheetBody>
            <p>You can programmatically open or close this sheet.</p>
          </YaSheetBody>
          <YaSheetFooter>
            <YaButton variant="secondary" onClick={() => setOpen(false)}>
              Close
            </YaButton>
          </YaSheetFooter>
        </YaSheetContent>
      </YaSheet>
    </>
  )
}

With X Close Button

Show an X button instead of the top bar close button:

<YaSheetContent showCloseButton={true}>
  <YaSheetHeader className="mt-6">
    <YaSheetTitle>Close with X</YaSheetTitle>
    <YaSheetDescription>
      This sheet has an X button in the top right corner.
    </YaSheetDescription>
  </YaSheetHeader>
  {/* ... */}
</YaSheetContent>

Props

YaSheet

PropTypeDefaultDescription
openboolean-Controlled open state
onOpenChange(open: boolean) => void-Callback when open state changes
defaultOpenbooleanfalseInitial open state (uncontrolled)
modalbooleantrueWhether to render as modal

YaSheetContent

PropTypeDefaultDescription
side'right' | 'left' | 'bottom''right'Side from which the sheet appears
size'sm' | 'default' | 'lg' | 'full''default'Sheet size
showCloseButtonbooleantrueShow the X close button
classNamestring-Additional classes

YaSheetTopBar

PropTypeDefaultDescription
showBackButtonbooleantrueShow the back/close button
backButtonLabelstring'Close'Label for the back button
onBack() => void-Callback when back button is clicked
actionsRightReact.ReactNode-Action buttons for the right side

YaSheetHeader

PropTypeDefaultDescription
classNamestring-Additional classes

YaSheetTitle

PropTypeDefaultDescription
classNamestring-Additional classes

YaSheetDescription

PropTypeDefaultDescription
classNamestring-Additional classes

YaSheetBody

PropTypeDefaultDescription
classNamestring-Additional classes

YaSheetFooter

PropTypeDefaultDescription
classNamestring-Additional classes

YaSheetActionButton

PropTypeDefaultDescription
iconReact.ReactNode-Icon to display
classNamestring-Additional classes

YaSheetClose

Wraps any element to make it a close trigger. Use asChild to compose with your own button.

PropTypeDefaultDescription
asChildbooleanfalseMerge props onto child

Accessibility

Best Practices

DoDon't
Use sheets for secondary contentUse for primary navigation paths
Use side="bottom" for mobileUse side sheets on small screens
Keep sheet content scrollableForce users to scroll the entire page
Provide clear close actionsLeave users without a way to close
Use size="sm" for simple contentUse full-width for minimal content

TypeScript

import { type VariantProps } from 'class-variance-authority'
import { yaSheetContentVariants } from '@/components/ui/ya-sheet'

type SheetSide = VariantProps<typeof yaSheetContentVariants>['side']
type SheetSize = VariantProps<typeof yaSheetContentVariants>['size']

On this page