Word Roll

A short label that becomes its next wording one word at a time. The words that changed leave upward and blur, the new ones rise from below, and the words that stayed do not move.

Examples

Billing period switch

Only "every month" and "$144 once a year" roll; "Billed" stays. Switching to yearly rolls up, back to monthly rolls down.

Studio plan

$16per month

Billed every month

Seat stepper

The seat count rolls as a word in the direction of the change. Going from 1 to 2 also rolls "seat" into "seats". The phrase eases to its new width, so the price beside it slides.

Seats

Per month$54for 3 seats

City clock

Every four seconds the next city and its time roll in; when the minute turns, only the time rolls. labels reserves the widest city, so nothing around the clock moves. Screen readers hear one sentence with every time.

Remote team

Status label

A status that moves forward rolls up, and one that goes back rolls down.

Walnut desk lampOrder packed

Installation

npx shadcn@latest add https://ui.ndekocode.dev/r/motion-word-roll.json

Component API

WordRoll

PropTypeDefaultDescription
textstringThe label to show, split into words on spaces. Use either text or words.
wordsWordRollWord[]The words as a list. An entry may hold several words that roll together, or { key, text, node } to place a node in the phrase.
labelsstring[]Every label the component can show. The widest one sets the width, so nothing around it moves.
direction'up' | 'down'Forces the direction of the roll. up sends the old words up and brings the new ones from below.
valuenumberA number the label follows, such as a seat count: when it grows the words roll up, when it shrinks they roll down.
accessibleTextstringThe sentence read by screen readers instead of the visible words, for a label that changes on its own.
classNamestringOptional CSS class for the wrapper. The font size, weight and colour are inherited.

Without labels, the width eases to the new words, so a longer label pushes what follows it smoothly instead of all at once. With neither direction nor value, the words roll up.

A node word keeps its place while its own content changes and rolls only when its key changes. That is how a figure stays a Motion Number inside a rolling phrase: in words={[{ key: 'amount', text: '€150', node: <MotionNumber value={150} /> }, 'a', 'month']}, a new amount rolls its digits, and switching to words={['No', 'cap']} rolls the whole phrase.

Screen readers hear the whole label once, never the rolling copy. Wrap a label that changes on a press in a polite live region to announce it. Under reduced motion the words fade to their new wording without moving.

Compared with Motion Number and Text Roll

Motion Number rolls the digits of a figure on a wheel; Word Roll rolls whole words, so use it for the wording around a figure and keep the figure itself in a Motion Number. Text Roll flips every letter of a label on hover, while Word Roll answers a change of the label.

Credits

The roll is inspired by the rotating city clock of the maintainer's portfolio.