Sticker Drop
The backing paper itself: dragging lights the cut lines and each accepted file lands as its own sticker.
InputsClient componentlucide-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-dropPulls in @duck/theme. Already installed items are skipped.
Usage
import { StickerDrop } from "@/components/ui/sticker-drop"The file lands in components/ui/sticker-drop.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 |
|---|---|---|---|
| accept | string | - | Same syntax as the native input. Extensions, MIME types and image/* all work. |
| multiple | boolean | false | Keep more than one file. |
| maxSize | number | - | Largest file allowed, in bytes. Rejections say which file and why. |
| onFilesChange | (files: File[]) => void | - | Called with the full list every time it changes. |
| label / hint | string | - | Zone copy. The hint is where the accepted types and size limit belong. |
Rules
What keeps this component from turning into noise.
- The file input is clipped, never display:none — a hidden input cannot take focus and the zone stops being keyboard operable.
- Dragging is not the only way in. The picker is the single-pointer alternative WCAG 2.5.7 asks for, so say so in the label.
- The drag-active edge is lime, not a brighter --cut. Cut lines on the sheet are about 1.8:1 and cannot carry a status.
