Componentregistry:component
Tear Reveal
A sheet of paper over any content that you tear open by dragging from a notch. The tear follows your path with a jagged edge and a pale fibrous rim, the halves fall away with gravity and spin past a threshold, and an early release springs it shut. Enter or Space tears it in one pass.
Installation
$ npx shadcn@latest add @creative-ui/tear-revealOn an older shadcn CLI, use the URL: npx shadcn@latest add https://ui.krutikraut.com/r/tear-reveal.json
Preview
The Water Carrier
Oil on canvas, gallery four
Direction
Paper
Usage
Example.tsx
import { TearReveal } from "@/components/tear-reveal"
export function Ticket() {
return (
<TearReveal
cover={<p className="grid size-full place-items-center font-serif text-2xl">Admit one</p>}
className="aspect-[3/4] w-72 rounded-md"
>
<img src="/painting.jpg" alt="The painting behind the ticket" className="size-full rounded-md object-cover" />
</TearReveal>
)
}
// Controlled, with a reset.
const [torn, setTorn] = React.useState(false)
<TearReveal torn={torn} onTear={() => setTorn(true)} direction="corner" paper="#387478">
<Prize />
</TearReveal>
<button onClick={() => setTorn(false)}>Reset</button>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| cover | React.ReactNode | — | What is printed on the paper: a label, an image, any node. It fills the sheet and inherits an ink colour that reads on paper, so currentColor works for text and rules. Omit for blank paper. |
| children | React.ReactNode | — | The content under the paper. It is inert until the paper is torn. |
| direction | "down" | "across" | "corner" | "down" | Where the tear starts. down runs from a notch in the top edge, across from the left edge, corner from the top-right corner. |
| paper | string | "#f4f1ea" | Paper colour, as hex. The torn rim is a lighter mix of it, the way coloured paper is white inside. |
| threshold | number | 0.4 | How far the tear must run before letting go tears it free, 0 to 1 of the way across. A quick flick in the tear direction also counts. |
| torn | boolean | — | Controlled torn state. Set it back to false to put the paper back. |
| defaultTorn | boolean | false | Initial torn state when uncontrolled. |
| onTear | () => void | — | Called when the paper tears free by drag or keyboard. Not called when torn is set from outside. |
| seed | number | 5 | Seed for the jagged edge and the way the halves fall. Change it on reset for a fresh tear. |
| label | string | "Tear to reveal" | Accessible name for the cover. |
Also accepts every div prop, which is spread onto the root element.
Notes
- Size the component with className, or let
childrensize it. The cover always matches the content box. - Only the notch handle captures touch, with
touch-action: none, so the rest of the card still scrolls the page. - The cover is a button. Enter or Space tears it in one automatic pass and moves focus to the content.
- With reduced motion the drag still works, but the paper fades out instead of falling.
- The halves fall outside the component's box. Add
overflow-hiddento the root if they must stay inside. coveris rendered twice, once per half, so keep it presentational. Images in it load once and are reused from cache.- When controlled, set
tornto true inonTear. If it stays false, a fresh sheet comes back after the fall.
Dependencies
shadcn/utils
