Cards & Grids

Ticket Stub Card

A ticket card with a perforated dotted line and side notches; click to tear off the stub.

A two-part ticket card of main ticket and stub, with semicircular notches and a perforated dotted line at the seam to mimic a real ticket stub; clicking the stub tears it along the perforation, spinning and fluttering away as an admitted stamp lands on the main ticket. A good fit for event tickets, coupons, boarding passes, and similar cases.

Bring this into your project

Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.

npx webberui@latest add ticket-stub-card.en

New project or installation trouble? Start here →

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

128
12
0
Active edited usageDefault props
<TicketStubCard/>

The complete example includes the preview layout and data. Install the component first, then paste this file into your project.

Installation

npx webberui@latest add https://webberui.com/r/ticket-stub-card.en.json

Or, once registries are configured in components.json, install it as @webberui/ticket-stub-card.

Usage

import { TicketStubCard } from "@/components/ui/ticket-stub-card";

<TicketStubCard
  stub={<span className="font-bold">A-12</span>}
  onTear={() => console.log("Torn off!")}
>
  <h3 className="text-xl font-bold">A Night of Jazz Under the Moon</h3>
  <p className="text-sm text-neutral-500">2026/08/22 19:30</p>
</TicketStubCard>

Props

PropTypeDefaultDescription
childrenReact.ReactNode—Content of the main ticket area (event name, time, venue, and so on)
stubReact.ReactNode—Content of the stub area (seat, ticket number, and so on)
onTear() => void—Callback fired when the stub is torn off
tornboolean—Controlled torn state; when omitted, the component manages it internally
stubWidthnumber128Stub width (px)
notchRadiusnumber12Radius of the semicircular perforation notches (px)
tearHintstring"Click to Tear Off"Tear hint text at the top of the stub (the English source includes this default — pass this prop to word it in your own language)
stampTextstring"Entered"Stamp text applied to the main ticket after tearing (the English source includes this default); an empty string hides it
showBarcodebooleantrueWhether to show the decorative barcode at the bottom of the stub
tiltbooleanfalseEnables pointer-following 3D tilt (perspective 1100px, ±6°, 1.018 hover scale, 220ms); only applies to fine pointers without reduced motion
notchSizenumber—Semicircle notch radius cut with clip-path (px); replaces the mask approach when set, and clicks pass through the notches
cornerSizenumber0Chamfer size of the outer corners (px); above 0 switches to clip-path, with notches from notchSize (or notchRadius if unset)
classNamestring—Forwarded to the outermost container

How it works

3D tilt

With tilt, the whole ticket leans toward the pointer as it moves (up to ±6°, 1100px perspective) and scales to 1.018; on leave it settles back on the same 220ms curve. Whether it turns on is read with useSyncExternalStore from (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference); the server always treats it as off, and touch devices or users with reduced motion never see the tilt.

<TicketStubCard tilt stub={<span className="font-bold">A-12</span>}>
  …
</TicketStubCard>

clip-path notches and chamfers

By default the notches are drawn with a CSS mask; setting notchSize or cornerSize switches to a clip-path polygon (positioned with calc(100% - Npx), so nothing is measured). clip-path also clips the hit area, so clicks pass through the notches to whatever sits below; cornerSize chamfers the outer corners for a boarding-pass or voucher outline. Without these two props the visuals are identical to earlier versions.

<TicketStubCard notchSize={14} cornerSize={10} stub={<span>B12</span>}>
  …
</TicketStubCard>

Accessibility

  • The stub is a native button element, focusable with Tab and tearable with Enter / Space, with a focus-visible focus ring
  • When the user has "reduce motion" enabled at the system level, the tear becomes a plain fade out with no spin-and-flutter animation
  • The stamp shown after tearing carries role="status", so assistive technology announces the change in admission state
  • The barcode, the perforated dotted line, and the paper texture are all decorative elements, hidden from assistive technology with aria-hidden
  • tilt only turns on for hover-capable fine pointers when the system "reduce motion" setting is off; with reduced motion there is no tilt or scale at all