Sheet
A dialog docked to an edge: the detail of one thing, opened from the list it sits in. It has the dialog's parts, a header, a scrolling body and a footer of cells, at full height. On a phone it takes the whole width.
Loading the live example…
"use client"
import { useState } from "react"
import { Button } from "@/components/keyline/ui/button"
import { Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from "@/components/keyline/ui/sheet"
import { Status } from "@/components/keyline/ui/status"
export function OrderSheet() {
const [delivered, setDelivered] = useState(false)
return (
<div className="flex flex-wrap items-center gap-3 text-[14px]">
<span className="font-kl-mono text-[13px]">DM-4107</span>
<span>Lackawanna County</span>
<Status kind={delivered ? "done" : "normal"}>{delivered ? "Delivered" : "Out for delivery"}</Status>
<Sheet>
<SheetTrigger render={<Button size="compact" />}>Details</SheetTrigger>
<SheetContent side="end" size={420}>
<SheetHeader>
<SheetTitle>DM-4107</SheetTitle>
<SheetDescription>Lackawanna County · Dwight Schrute</SheetDescription>
</SheetHeader>
<SheetBody>
<dl className="m-0 grid grid-cols-[auto_1fr] gap-x-6 gap-y-2 text-[14px]">
<dt className="text-kl-ink-3">Paper</dt>
<dd className="m-0">Copy paper, letter, 20 lb</dd>
<dt className="text-kl-ink-3">Quantity</dt>
<dd className="m-0">120 cases</dd>
<dt className="text-kl-ink-3">Deliver to</dt>
<dd className="m-0">200 North Washington Avenue, loading dock</dd>
<dt className="text-kl-ink-3">Status</dt>
<dd className="m-0">
<Status kind={delivered ? "done" : "normal"}>{delivered ? "Delivered" : "Out for delivery"}</Status>
</dd>
</dl>
</SheetBody>
<SheetFooter>
<SheetClose render={<Button layout="cell" />}>Close</SheetClose>
<Button layout="cell" variant="primary" disabled={delivered} onClick={() => setDelivered(true)}>
{delivered ? "Delivered" : "Mark delivered"}
</Button>
</SheetFooter>
</SheetContent>
</Sheet>
</div>
)
}Installation
npx shadcn@latest add @keyline-ui/sheetRun it where your components.json is. The first time, map the @keyline-ui registry: one command, in Installation.
Usage
import { Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from "@/components/keyline/ui/sheet"<Sheet>
<SheetTrigger render={<Button size="compact" />}>Details</SheetTrigger>
<SheetContent side="end" size={420}>
<SheetHeader>
<SheetTitle>DM-4107</SheetTitle>
<SheetDescription>Lackawanna County</SheetDescription>
</SheetHeader>
<SheetBody>…</SheetBody>
<SheetFooter>…</SheetFooter>
</SheetContent>
</Sheet>Props
| Prop | Type | Default | Description |
|---|---|---|---|
side | "end" | "start" | "bottom" | Default "end" | On SheetContent. end is the right edge in left-to-right text and mirrors in right-to-left. |
size | number | string | Default — | Width from a side, height from the bottom. |
container | HTMLElement | ref | Default document.body | Where the sheet is portalled. |
open · onOpenChange | boolean | Default — | On Sheet: control it. |
Built on Base UI Dialog. For something to swipe away on a phone, use Drawer.