Sticker Drawer
The sticker slid in from the edge. Same Radix Dialog base as StickerDialog, anchored to any of the four sides, with the die-cut edge on the side that faces the content.
SurfacesClient componentclass-variance-authority@radix-ui/react-dialoglucide-react
Preview
Installation
The CLI writes the source into your project and pulls in whatever it depends on.
$
pnpm dlx shadcn@latest add @duck/sticker-drawerPulls in @duck/theme. Already installed items are skipped.
Usage
import { StickerDrawer, StickerDrawerTrigger, StickerDrawerClose, StickerDrawerPortal, StickerDrawerOverlay, StickerDrawerContent, StickerDrawerHeader, StickerDrawerTitle, StickerDrawerDescription, StickerDrawerBody, StickerDrawerFooter } from "@/components/ui/sticker-drawer"The file lands in components/ui/sticker-drawer.tsx and belongs to you from that point on. Edit it in place rather than wrapping it.
Props
Everything not listed here is forwarded to the underlying element.
| Prop | Type | Default | Description |
|---|---|---|---|
| side | "left" | "right" | "top" | "bottom" | "right" | On StickerDrawerContent: the edge it is anchored to. The die-cut edge, the inner radius and the slide all follow it. |
| size | "sm" | "default" | "lg" | "full" | "default" | Width on left and right; a ceiling on the height on top and bottom, so a short sheet stays short. full fills the axis and drops the radius. |
| holo | boolean | false | Iridescent edge instead of the solid die-cut one. |
| hideClose | boolean | false | Drop the built-in close button. Escape and the scrim still dismiss unless you intercept them too. |
| closeLabel | string | "Close" | Accessible name for the close button. |
| open / onOpenChange | boolean / (open: boolean) => void | - | On StickerDrawer. Radix Dialog props — a drawer opened from a list row is almost always controlled. |
Rules
What keeps this component from turning into noise.
- Always render a StickerDrawerTitle. Radix warns without one, and a modal with no accessible name is announced as nothing.
- Put the scrolling content in StickerDrawerBody. The panel is as tall as the viewport, so the overflow has to belong to an element the header and footer sit outside of.
- The edge is on the side facing the content, and there is no radius against the viewport edge. Do not add one back — a rounded outer corner shows the page through the gap.
- Use a drawer for a place, a dialog for a decision. If the panel exists to ask one question, StickerDialog is the smaller thing.
- Under reduced motion the theme collapses both animation durations, so the panel appears in place. Do not swap the keyframes for a transition to get that; it is already handled.
