Components
- Accordion
- Alert
- Alert Dialog
- Autocomplete
- Avatar
- Badge
- Breadcrumb
- Button
- Card
- Checkbox
- Checkbox Group
- Collapsible
- Combobox
- Dialog
- EmptyNew
- Field
- Fieldset
- Form
- Frame
- Group
- Input
- Input GroupNew
- KbdNew
- Label
- Menu
- Meter
- Number Field
- Pagination
- Popover
- Preview Card
- Progress
- Radio Group
- Scroll Area
- Select
- Separator
- Sheet
- SkeletonNew
- Slider
- SpinnerNew
- Switch
- Table
- Tabs
- Textarea
- Toast
- Toggle
- Toggle Group
- Toolbar
- Tooltip
Resources
Sheet
A flyout that opens from the side of the screen, based on the dialog component.
import { Button } from "@/components/ui/button";
import { Field, FieldLabel } from "@/components/ui/field";
import { Form } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import {
Sheet,
SheetClose,
SheetDescription,
SheetFooter,
SheetHeader,
SheetPanel,
SheetPopup,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet";
export default function Particle() {
return (
<Sheet>
<SheetTrigger render={<Button variant="outline" />}>
Open Sheet
</SheetTrigger>
<SheetPopup>
<Form className="contents">
<SheetHeader>
<SheetTitle>Edit profile</SheetTitle>
<SheetDescription>
Make changes to your profile here. Click save when you're
done.
</SheetDescription>
</SheetHeader>
<SheetPanel className="grid gap-4">
<Field>
<FieldLabel>Name</FieldLabel>
<Input defaultValue="Margaret Welsh" type="text" />
</Field>
<Field>
<FieldLabel>Username</FieldLabel>
<Input defaultValue="@maggie.welsh" type="text" />
</Field>
</SheetPanel>
<SheetFooter>
<SheetClose render={<Button variant="ghost" />}>Cancel</SheetClose>
<Button type="submit">Save</Button>
</SheetFooter>
</Form>
</SheetPopup>
</Sheet>
);
}
Installation
pnpm dlx shadcn@latest add @coss/sheet
Usage
import {
Sheet,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetPanel,
SheetPopup,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet"<Sheet>
<SheetTrigger>Open</SheetTrigger>
<SheetPopup>
<SheetHeader>
<SheetTitle>Are you absolutely sure?</SheetTitle>
<SheetDescription>
This action cannot be undone. This will permanently delete your account
and remove your data from our servers.
</SheetDescription>
</SheetHeader>
<SheetPanel>Content</SheetPanel>
<SheetFooter>
<SheetClose>Close</SheetClose>
</SheetFooter>
</SheetPopup>
</Sheet>SheetPanel Scrolling
The SheetPanel component automatically wraps its content in a ScrollArea component. This means that if the content exceeds the sheet's maximum height, it will become scrollable automatically. The scrollbar will appear when needed, providing a smooth scrolling experience.
<SheetPanel>
{/* Long content that will scroll if it exceeds the sheet height */}
<div>...</div>
</SheetPanel>SheetPopup Props
The SheetPopup component supports the following props:
side: Controls which side of the screen the sheet opens from. Options:"top","bottom","left","right"(default:"right")inset: Whentrue, adds spacing around the sheet on desktop screens (default:false)
// Right side sheet (default)
<SheetPopup side="right">
...
</SheetPopup>
// Left side sheet
<SheetPopup side="left">
...
</SheetPopup>
// Top sheet
<SheetPopup side="top">
...
</SheetPopup>
// Bottom sheet
<SheetPopup side="bottom">
...
</SheetPopup>
// Sheet with inset spacing
<SheetPopup side="right" inset>
...
</SheetPopup>Examples
Sheet with Inset
import { Button } from "@/components/ui/button";
import { Field, FieldLabel } from "@/components/ui/field";
import { Form } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import {
Sheet,
SheetClose,
SheetDescription,
SheetFooter,
SheetHeader,
SheetPanel,
SheetPopup,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet";
export default function Particle() {
return (
<Sheet>
<SheetTrigger render={<Button variant="outline" />}>
Open Sheet
</SheetTrigger>
<SheetPopup inset>
<Form className="h-full gap-0">
<SheetHeader>
<SheetTitle>Edit profile</SheetTitle>
<SheetDescription>
Make changes to your profile here. Click save when you're
done.
</SheetDescription>
</SheetHeader>
<SheetPanel className="grid gap-4">
<Field>
<FieldLabel>Name</FieldLabel>
<Input defaultValue="Margaret Welsh" type="text" />
</Field>
<Field>
<FieldLabel>Username</FieldLabel>
<Input defaultValue="@maggie.welsh" type="text" />
</Field>
</SheetPanel>
<SheetFooter>
<SheetClose render={<Button variant="ghost" />}>Cancel</SheetClose>
<Button type="submit">Save</Button>
</SheetFooter>
</Form>
</SheetPopup>
</Sheet>
);
}
Side sheets
import { Button } from "@/components/ui/button";
import {
Sheet,
SheetDescription,
SheetHeader,
SheetPanel,
SheetPopup,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet";
export default function Particle() {
return (
<div className="flex flex-wrap gap-2">
<Sheet>
<SheetTrigger render={<Button variant="outline" />}>
Open Right
</SheetTrigger>
<SheetPopup showCloseButton={false}>
<SheetHeader>
<SheetTitle>Right</SheetTitle>
<SheetDescription>Right side of the screen.</SheetDescription>
</SheetHeader>
<SheetPanel>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</SheetPanel>
</SheetPopup>
</Sheet>
<Sheet>
<SheetTrigger render={<Button variant="outline" />}>
Open Left
</SheetTrigger>
<SheetPopup showCloseButton={false} side="left">
<SheetHeader>
<SheetTitle>Left</SheetTitle>
<SheetDescription>Left side of the screen.</SheetDescription>
</SheetHeader>
<SheetPanel>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</SheetPanel>
</SheetPopup>
</Sheet>
<Sheet>
<SheetTrigger render={<Button variant="outline" />}>
Open Top
</SheetTrigger>
<SheetPopup showCloseButton={false} side="top">
<SheetHeader>
<SheetTitle>Top</SheetTitle>
<SheetDescription>Top of the screen.</SheetDescription>
</SheetHeader>
<SheetPanel>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</SheetPanel>
</SheetPopup>
</Sheet>
<Sheet>
<SheetTrigger render={<Button variant="outline" />}>
Open Bottom
</SheetTrigger>
<SheetPopup showCloseButton={false} side="bottom">
<SheetHeader>
<SheetTitle>Bottom</SheetTitle>
<SheetDescription>Bottom of the screen.</SheetDescription>
</SheetHeader>
<SheetPanel>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</SheetPanel>
</SheetPopup>
</Sheet>
</div>
);
}
Comparing with Radix / shadcn
If you’re already familiar with Radix UI and shadcn/ui, this guide highlights the small differences and similarities so you can get started with coss ui quickly.
Quick Checklist
- Replace
asChild→renderonSheetTriggerand closing buttons - Prefer
SheetPopup;SheetContentremains for legacy - Use
SheetPanelto wrap main content betweenSheetHeaderandSheetFooter - If you used
asChildon any other parts, switch to therenderprop SheetPopupsupportssideandinsetprops for positioning and spacing
Comparison Example
<Sheet>
<SheetTrigger asChild>
<Button variant="outline">Show Sheet</Button>
</SheetTrigger>
<SheetContent>
<SheetHeader>
<SheetTitle>Sheet Title</SheetTitle>
<SheetDescription>Sheet Description</SheetDescription>
</SheetHeader>
<SheetFooter>
<SheetClose asChild>
<Button variant="ghost">Cancel</Button>
</SheetClose>
</SheetFooter>
</SheetContent>
</Sheet><Sheet>
<SheetTrigger render={<Button variant="outline" />}>
Show Sheet
</SheetTrigger>
<SheetPopup>
<SheetHeader>
<SheetTitle>Sheet Title</SheetTitle>
<SheetDescription>Sheet Description</SheetDescription>
</SheetHeader>
<SheetPanel>Content</SheetPanel>
<SheetFooter>
<SheetClose render={<Button variant="ghost" />}>Cancel</SheetClose>
</SheetFooter>
</SheetPopup>
</Sheet>