Detail Drawer
Show record details in a right-side drawer.
Pick a customer in the list to open the detail view. The header names the record and its status, and the body groups the account, the primary contact and the recent activity into cards.
Installation
pnpm dlx shadcn@4.18.0 add @siteplane/detail-drawerComplete the one-time setup first. Registry JSON lists source files and dependencies.
For this page’s examples, also install:
pnpm dlx shadcn@4.18.0 add @siteplane/avatar @siteplane/badge @siteplane/button @siteplane/card @siteplane/data-list @siteplane/form @siteplane/input @siteplane/resource-list @siteplane/table @siteplane/timelineField is installed with Input.
Usage
import { Button } from "@/siteplane/components/button";
import {
DetailDrawer,
DetailDrawerTrigger,
DetailDrawerPopup,
DetailDrawerHeader,
DetailDrawerTitle,
DetailDrawerDescription,
DetailDrawerBody,
DetailDrawerFooter,
DetailDrawerClose,
} from "@/siteplane/components/detail-drawer";
<DetailDrawer>
<DetailDrawerTrigger render={<Button variant="outline" />}>
View account
</DetailDrawerTrigger>
<DetailDrawerPopup>
<DetailDrawerHeader>
<DetailDrawerTitle>Northstar Studio</DetailDrawerTitle>
<DetailDrawerDescription>
Active customer since 2024.
</DetailDrawerDescription>
</DetailDrawerHeader>
<DetailDrawerBody>Details</DetailDrawerBody>
<DetailDrawerFooter>
<DetailDrawerClose render={<Button variant="ghost" />}>
Close
</DetailDrawerClose>
</DetailDrawerFooter>
</DetailDrawerPopup>
</DetailDrawer>;Composition
DetailDrawer
├── DetailDrawerTrigger
└── DetailDrawerPopup
├── DetailDrawerHeader
│ ├── DetailDrawerTitle
│ └── DetailDrawerDescription
├── DetailDrawerBody
└── DetailDrawerFooter
└── DetailDrawerCloseEdit form
Wrap the header, body and footer in a form so Save submits and closes the drawer. DetailDrawerBody keeps longer forms scrollable between the header and footer.
Scrollable content
DetailDrawerBody scrolls long record content while the header and footer stay visible. This example lists the invoices of a customer: summary cards on top, then a Table in a card with a status badge, an amount aligned to the end with tabular figures, and a download action in every row.
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
Detail | right | left | top | bottom | right | Overrides Drawer’s bottom default. |
Detail | right | left | top | bottom | root position | Popup edge. Leave it unset, so the content follows the position of DetailDrawer, which also sets the swipe direction. |
Detail | default | straight | inset | straight | Straight side panel. |
Detail | string | max-w-md plus supplied classes | Maximum width. |
Detail | string | min-h-0 flex-1 plus supplied classes | Flexible scrolling body. |
All inherited props and defaults are those of Drawer. DetailDrawer wraps Drawer; Popup wraps DrawerPopup; Header wraps DrawerHeader; Body wraps DrawerPanel; Footer wraps DrawerFooter. Trigger, Close, Title and Description are direct aliases to Drawer’s parts. Popup takes its position from the root, so set position once on DetailDrawer; its variant default can be overridden. Body inherits scrollFade=true, scrollable=true and allowSelection=true; Footer inherits allowSelection=true; Header inherits allowSelection=false. Popup inherits showCloseButton=false and showBar=false. The component supplies no selected-record, fetching, saving or error API.
DetailDrawerContent is the earlier name of DetailDrawerPopup. It is the same part and keeps working until 2.0; write DetailDrawerPopup in new code.
open/defaultOpen choose controlled/initial state (closed by default); onOpenChange(open, eventDetails) requests a transition and onOpenChangeComplete(open) reports motion completion. Initial/final focus and dismissal behavior belong to the underlying foundation.
Usage notes
Provide a title, clear close action and meaningful focus target. Escape and focus restoration follow the foundation. Application loading, errors and async confirmation must be represented explicitly in the content. Do not treat swipe dismissal as the only way to close.