Ticket tear

Pro

Pull 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

Guest
Emma Collins
Doors
18:30
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.