React adapter
new@love-rox/ptpt-react
Split-flap displays for React: <Patapata> (one cell), <PatapataBoard> (a row of them), and the useFlipCell hook. Client components, so they work in RSC setups like Waku and Next.js.
Install
Install
@love-rox/ptpt-core comes along as a dependency. react (>=18) is a peer dependency. Import @love-rox/ptpt-core/styles.css once for the default look.
bun
bun add @love-rox/ptpt-reactpnpm
pnpm add @love-rox/ptpt-reactnpm
npm i @love-rox/ptpt-reactyarn
yarn add @love-rox/ptpt-reactUsage
Usage
Render <PatapataBoard> with a targets string — the cell count comes from its length — and cellOptions shared by every cell. Each character flips to its place; the board staggers them. Changing targets triggers a new flip.
import { PatapataBoard } from "@love-rox/ptpt-react";
import { alphanumericPreset } from "@love-rox/ptpt-core/presets/alphanumeric";
import "@love-rox/ptpt-core/styles.css";
export function Departures() {
return (
<PatapataBoard
cellOptions={{ preset: alphanumericPreset }}
targets="TOKYO "
flipMode="replace"
/>
);
}Options
Options
<Patapata> accepts every CellOptions field plus the component props below. The shared options behave identically to the Vue, rehype, and Astro adapters.
Shared cell options
| Option | Type | Default | Description |
|---|---|---|---|
| preset | PresetDefinition | string | defaultPreset | The flap set. Pass a PresetDefinition (its recommendedDuration / locale become defaults) or a string of characters whose order is the flap order. Mutually exclusive with frames. |
| frames | FrameInput[] | undefined | An explicit frame set — text, images, or arbitrary elements. Mutually exclusive with preset. |
| durationPerFlap | number | preset's recommendation, else 200 | Milliseconds for one flap. Overrides the preset's recommendedDuration. |
| direction | 'forward' | 'shortest' | 'forward' | Direction taken through the frame ring. shortest may reverse to reach a nearer flap. |
| reducedMotion | 'instant' | 'minimal' | 'ignore' | 'instant' | Behaviour when the OS prefers reduced motion. instant snaps to the target without animating. |
Component-only props
| Option | Type | Default | Description |
|---|---|---|---|
| target | string | — | Slug to flip to whenever it changes. |
| flipMode | 'replace' | 'queue' | undefined | Behaviour when target changes rapidly. replace coalesces to the latest; queue runs each in order. |
| onFlipComplete | () => void | undefined | Called after each flip settles. |
| className / style | string / CSSProperties | undefined | Applied to the cell's host element. |
Behaviour
Behavior notes
- Structural options are read on mount — pass a
keyto rebuild a cell with new ones; changingtarget/targetsjust triggers a flip. flipMode="replace"(default) coalesces rapid updates to the latest target;flipMode="queue"runs each in order.- The board is one
role="status"live region;onFlipCompletefires after each flip settles. - Pass preset objects (
preset={digitsPreset}), not strings — a string is treated as the literal flap characters, not a preset name.
Related
Other adapters
On Vue? The Vue adapter has the same API. Rendering Markdown or building a static site? The rehype and Astro adapters do this at build time, with no React in the bundle.