The airport board, in the browser. SplitFlapDisplay renders each character as a
mechanical flap that spins through the charset — the old top leaf hinges away, the
new bottom leaf rises into place — until it lands on your value. Columns start on a
staggered wave, so the whole board resolves like a real Solari. It reveals from
blanks the first time it scrolls into view, then re-flips whenever value changes.
pnpm dlx shadcn@latest add "https://godui.design/r/split-flap-display.json"
import { SplitFlapDisplay } from "@/components/godui/split-flap-display";
Point it at a value — it reveals from blank flaps on scroll-in, then flips to any
new value:
<SplitFlapDisplay value="BOARDING" />
Pad to a fixed width and align the content inside it, so a changing value never
reflows the board:
<SplitFlapDisplay value="GATE 22" length={12} align="left" />
Restrict the flap sequence to just the glyphs you need, and pass an array to
give each column its own reel by position. A clock's seconds-tens digit only
cycles 0–5, so 5 → 0 wraps in a single flip instead of climbing 6 7 8 9;
the : columns get a reel of just ":" so they never spin:
const CLOCK = ["012", "0123456789", ":", "012345", "0123456789", ":", "012345", "0123456789"];
<SplitFlapDisplay value="12:45:07" size="sm" charset={CLOCK} />
| Prop | Type | Default | Description |
|---|
value | string | — | The text the board settles on. Uppercased against charset. |
length | number | value length | Fixed flap count — shorter values pad, longer ones truncate. |
align | "left" | "center" | "right" | "left" | How the value sits inside a wider length. |
size | "sm" | "md" | "lg" | "md" | Flap size preset. |
charset | string | string[] | A–Z 0–9 … | Glyphs the flaps rotate through. An array gives each column its own reel by position. Leading space is the blank flap. |
stagger | number | 0.06 | Seconds each successive column waits before it starts — the wave. |
maxFlaps | number | 12 | Cap on how many flips one column spins before settling. |
SplitFlapDisplay forwards every standard <div> attribute and exposes the
current value as an aria-label. Motion is compositor-only (rotateX) and
respects prefers-reduced-motion — reduced-motion viewers get the settled value
with no flip.