Rebar UI

1.0

opinionnew

Puppet

A character as a rigid paper cut-out: it sways, glances, blinks, and talks back when poked. The art here is Con; the rig knows nothing about him.

ConHover or poke him
rest
glance-left
glance-right
blink
eye-roll
wobble

Props

PropTypeRequiredDefault
layersPuppetLayersYes—
canvas[number, number] | undefinedNo[1, 1]
sizenumber | undefinedNo240
motion"idle" | "hop" | "still" | undefinedNoidle
weight"light" | "heavy" | undefinedNolight
pivotnumber | undefinedNo—
phasenumber | undefinedNo—
posePuppetPose | undefinedNo—
lidLinenumber | undefinedNo35
lookRangenumber | undefinedNo1.7
labelstring | undefinedNo—
saysstring[] | undefinedNo—
sayEverynumber | undefinedNo7000
bubble"start" | "end" | undefinedNostart
onPoke(() => void) | undefinedNo—

Cutting a character into layers

Every layer is a transparent PNG on the same canvas as the body, so they line up 1:1 with no positioning data; canvas only supplies the aspect ratio. wobble[].pivot is where a part hinges, in percent of the canvas. eyesMask is the white of the eyes as an alpha mask: pupils and lids are clipped to it, which keeps a glancing pupil inside the eye. lidLine is how far down the canvas the lids start, because a blink drops them from that line. Only body is required; each other layer switches on one behaviour.

A white sticker outline baked into the body (and each wobble part) gives the die-cut look and lets the character sit on any background. Outline the gaps too, between legs for example, so the cut-out reads as one piece of paper.

Weight, speech, poking

weight="light" (the default) is a paper book: big loose swings and a springy pop-up. weight="heavy" is a concrete block: swings a third the size and nearly twice as slow, with a thud when it lands. says is a list of lines shown in turn every sayEvery ms (paused while the tab is hidden); poking the puppet skips to the next line and restarts the timer. A pose holds one expression and stops all motion, for an empty state or a screenshot.

Accessibility

Under prefers-reduced-motion the body, parts and pupils stop and the blink slows right down. The puppet is decorative by default (aria-hidden); pass label to make it an image with a name when the character itself carries meaning. The speech bubble is flavour and hidden from assistive technology; put anything the user needs to read in the page itself.

data-rebar-* attributes

data-rebar-component="puppet" on the root; data-rebar-motion is idle, hop or still; data-rebar-weight is light or heavy; data-rebar-pose is the held expression, when there is one; data-rebar-poked is present for a moment after a poke. Parts: rise, sway, paper, wobble, body, eyes, pupils, lids, bubble (with data-rebar-side).

Migrating to Ant Design

Not codemod-covered: Ant Design has no mascot component. The component is stacked images and CSS keyframes, so it carries over unchanged.