Ticket tear
ProPull a ticket stub and it tears along the perforation hole by hole, then drops away.
Live · keyboard ready
Oct 14, 2026
Arc Conf
Teatro Tivoli, Lisbon
Admit oneRow FSeat 12
- Event tickets, boarding passes, and coupons that are used once.
- A playful confirmation step where tearing means committing.
- Use hold-to-confirm or a dialog for destructive actions that need clear wording.
- Use a plain card for tickets that are only displayed, not redeemed.
Installation
Pro source and install commands unlock with a Pro plan.
example.tsx
import { TicketTear } from "@/components/arc/ticket-tear/ticket-tear"; export function Ticket() { const [torn, setTorn] = useState(false); return ( <TicketTear torn={torn} onTornChange={setTorn} label="Tear off stub to check in" stub={<div className="stub">Row F, seat 12</div>}> <div className="ticket"> <p>Arc Conf</p> <p>Teatro Tivoli, Lisbon</p> </div> </TicketTear> );}TicketTear
An event ticket with a perforated stub. Pulling the stub rips it along the dotted line from the top with ragged, fibrous edges; torn through or flicked, the rip races to the bottom and the stub peels away with a spin.
PropTypeDefaultDescription
childrenRequiredReactNode–The main ticket body.stubRequiredReactNode–The stub right of the perforation.tornboolean–Controlled torn state. Setting it back to false puts a fresh stub on; setting it to true tears it off.defaultTornbooleanfalseInitial state when uncontrolled.onTornChange(torn: boolean) => void–Called once the stub comes off.stubWidthnumber104Stub width in px.labelstring"Tear off stub"Accessible name of the stub control.classNamestring–Extra class on the root.styleCSSProperties–Inline styles on the root. Set --ticket-paper to change the paper color.- Tab
- Focuses the stub.
- EnterorSpace
- Tears the stub all the way and drops it.
- The stub is role="button" with the label as its name.
- The flap copy of the stub used for the bend is aria-hidden, so the stub is read once.
- A polite status announces "Stub torn off".
- Pulling down or away tears the perforation from the top, tracking the pointer directly; the tear only grows, like real paper.
- The edge passes through the center of each hole and wanders between them, coarse and fine, with loose paper fibers just past it on both sides.
- The loose flap follows the pull on a spring, so it has weight, and springs most of the way back when released mid-tear.
- Enter, Space or the torn prop rip the rest on their own, accelerating like a perforation that has started to give; a flick finishes it even faster.
- Freed, the stub pops up a hair, falls with gravity, drifts with the release speed, spins on a spring, and fades in about half a second.
- Touch devices get a tiny vibration as the tear crosses each hole, where supported.
- Reduced motion removes the bend, the fibers and the fall; the stub fades out.
- The ticket fills its width; the stub keeps a fixed width and the body shrinks, down to 320px screens.
- Pointer capture keeps the tear tracking outside the stub, and touch-action is disabled on the stub only.
- The tear is clip-path polygons driven by motion values; React does not re-render while dragging.
- Notches and holes are CSS masks, so the paper stays one element per piece.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Choose it for check-in, redeeming a pass, or any one-time confirmation that should feel final.
- Keep the stub content short: a seat, a gate, a code.
- Control torn to reset it (a New ticket button) or to tear it from a server event.
The full library index for assistants is at /llms.txt.