Skip to content
WANCRAFT

C.71Typography & Text

Split-Flap Display

A Solari departure board: hinged flaps fall cell by cell until the new text is spelled out.

NewReactCSSTailwindintermediate

Overview

Split-Flap Display renders text as a row of mechanical tiles. When the value changes, each tile's top flap falls with a 3D rotateX, revealing the next character on its drum, and keeps flipping until it reaches the target — neighbouring cells start a few milliseconds apart, so the board ripples into place. Flips continue from whatever is on screen, so a new value mid-animation simply redirects the drum. One requestAnimationFrame loop writes transforms and glyphs straight to the DOM, the final text is announced once through a polite live region, and with reduced motion the text swaps instantly.

01Installation

Method 01 · Registry

CLI verified

Uses the shadcn CLI in a project initialised with shadcn init. Installs the file to components/ui/split-flap.tsx and adds its dependencies.

npx shadcn@latest add https://wancraft.my/r/split-flap.json

Method 02 · Copy and paste

  1. 1. No extra dependencies — React and Tailwind CSS only.
  2. 2. Copy the source from the Code tab into components/ui/split-flap.tsx.
  3. 3. Import it and adjust props.
Dependencies
None
Peer
react ≥ 18, tailwindcss ≥ 4
Added
13 Oct 2026
Updated
—

02Usage

The default configuration. Change properties above to generate a tailored example in the Usage tab.

example.tsx
import { SplitFlap } from "@/components/ui/split-flap";

export function SplitFlapExample() {
  return (
    <SplitFlap />
  );
}

03Props

PropTypeDefaultDescription
valuestring"Kuching 0915"Text to show. Changing it flips every cell from what is on screen to the new text.
lengthnumber12Minimum number of cells; shorter values are padded with blanks.
align"left" | "right""left"Where short values sit inside `length`.
charsetstring" ABC…XYZ0123456789:.-/"Ordered drum each cell steps through. Characters outside it flip directly in one step.
flipDurationnumber80Duration of a single flap flip, in ms.
staggernumber30Delay between neighbouring cells starting, in ms.
size"sm" | "md" | "lg""md"Tile size (18, 28 or 44px type).
theme"dark" | "light" | "auto""dark"Classic dark tiles, light tiles, or follow the page theme via the dark: variant.
uppercasebooleantrueUpper-case the value, like a real board.
...propsHTMLAttributes<HTMLDivElement>—Forwarded to the root element.

04Features

  • 01Hinged top flap falls with rotateX and the lower flap lands with a small overshoot
  • 02Each cell steps through the drum until it reaches its target character
  • 03Staggered start per cell; a new value mid-flip redirects from what is on screen
  • 04One rAF loop writes transforms and glyphs directly — no React render per frame
  • 05Classic dark, light, or theme-following tiles in three sizes
motion · staggermotion · tweeninput · viewport

05Accessibility

  • The tiles are aria-hidden; the final text sits in a visually hidden aria-live="polite" region, so a change is announced once — never the intermediate characters.
  • With prefers-reduced-motion (or a flip duration of 0) the text swaps instantly without flaps.
  • Tiles are not interactive and add no tab stops.

06Limitations

  • Sounds are out of scope; add your own click sample if you want the clatter.
  • Each character is a fixed-width tile, so proportional spacing and kerning are not applied.