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,
SheetPopup,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet"
export default function SheetDemo() {
return (
<Sheet>
<SheetTrigger render={<Button variant="outline" />}>
Open Sheet
</SheetTrigger>
<SheetPopup>
<Form className="flex-1">
<SheetHeader>
<SheetTitle>Edit profile</SheetTitle>
<SheetDescription>
Make changes to your profile here. Click save when you're
done.
</SheetDescription>
</SheetHeader>
<div className="flex flex-col gap-4 px-4">
<Field>
<FieldLabel>Name</FieldLabel>
<Input type="text" defaultValue="Margaret Welsh" />
</Field>
<Field>
<FieldLabel>Username</FieldLabel>
<Input type="text" defaultValue="@maggie.welsh" />
</Field>
</div>
<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,
SheetHeader,
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>
</SheetPopup>
</Sheet>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,
SheetPopup,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet"
export default function SheetInset() {
return (
<Sheet>
<SheetTrigger render={<Button variant="outline" />}>
Open Sheet
</SheetTrigger>
<SheetPopup inset>
<Form className="flex-1">
<SheetHeader>
<SheetTitle>Edit profile</SheetTitle>
<SheetDescription>
Make changes to your profile here. Click save when you're
done.
</SheetDescription>
</SheetHeader>
<div className="flex flex-col gap-4 px-4">
<Field>
<FieldLabel>Name</FieldLabel>
<Input type="text" defaultValue="Margaret Welsh" />
</Field>
<Field>
<FieldLabel>Username</FieldLabel>
<Input type="text" defaultValue="@maggie.welsh" />
</Field>
</div>
<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,
SheetPopup,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet"
export default function SheetPosition() {
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>
</SheetPopup>
</Sheet>
<Sheet>
<SheetTrigger render={<Button variant="outline" />}>
Open Left
</SheetTrigger>
<SheetPopup side="left" showCloseButton={false}>
<SheetHeader>
<SheetTitle>Left</SheetTitle>
<SheetDescription>Left side of the screen.</SheetDescription>
</SheetHeader>
</SheetPopup>
</Sheet>
<Sheet>
<SheetTrigger render={<Button variant="outline" />}>
Open Top
</SheetTrigger>
<SheetPopup side="top" showCloseButton={false}>
<SheetHeader>
<SheetTitle>Top</SheetTitle>
<SheetDescription>Top of the screen.</SheetDescription>
</SheetHeader>
</SheetPopup>
</Sheet>
<Sheet>
<SheetTrigger render={<Button variant="outline" />}>
Open Bottom
</SheetTrigger>
<SheetPopup side="bottom" showCloseButton={false}>
<SheetHeader>
<SheetTitle>Bottom</SheetTitle>
<SheetDescription>Bottom of the screen.</SheetDescription>
</SheetHeader>
</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 - If you used
asChildon any other parts, switch to therenderprop SheetPopupsupports aninsetprop for adding internal padding
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>
<SheetFooter>
<SheetClose render={<Button variant="ghost" />}>Cancel</SheetClose>
</SheetFooter>
</SheetPopup>
</Sheet>