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.
pnpm npm yarn
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 >
)
}
< 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 >
YaSheet supports three different sides for desktop and mobile use cases:
Side Usage Description rightDesktop panels Default, slides from right edge leftNavigation Slides from left edge bottomMobile drawer Slides from bottom with drag handle
< YaSheetContent side = "right" >...</ YaSheetContent >
< YaSheetContent side = "left" >...</ YaSheetContent >
< YaSheetContent side = "bottom" >...</ YaSheetContent >
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 >
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 >
YaSheet supports multiple sizes for different content needs:
Size Width (Side Sheets) Max Height (Bottom) sm320px 50vh default384px 85vh lg480px 90vh full100% 100vh
Small (320px) Default (384px) Large (480px)
< YaSheetContent size = "sm" >...</ YaSheetContent >
< YaSheetContent size = "default" >...</ YaSheetContent >
< YaSheetContent size = "lg" >...</ YaSheetContent >
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 >
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 >
Control the sheet programmatically:
Open Sheet Close Sheet
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 >
</>
)
}
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 >
Prop Type Default Description openboolean- Controlled open state onOpenChange(open: boolean) => void- Callback when open state changes defaultOpenbooleanfalseInitial open state (uncontrolled) modalbooleantrueWhether to render as modal
Prop Type Default Description 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
Prop Type Default Description 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
Prop Type Default Description classNamestring- Additional classes
Prop Type Default Description classNamestring- Additional classes
Prop Type Default Description classNamestring- Additional classes
Prop Type Default Description classNamestring- Additional classes
Prop Type Default Description classNamestring- Additional classes
Prop Type Default Description iconReact.ReactNode- Icon to display classNamestring- Additional classes
Wraps any element to make it a close trigger. Use asChild to compose with your own button.
Prop Type Default Description asChildbooleanfalseMerge props onto child
Do Don't Use sheets for secondary content Use for primary navigation paths Use side="bottom" for mobile Use side sheets on small screens Keep sheet content scrollable Force users to scroll the entire page Provide clear close actions Leave users without a way to close Use size="sm" for simple content Use full-width for minimal content
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' ]