CJK Number Roller
Numbers rolling between three forms — lowercase Chinese numerals, formal (financial) Chinese numerals, and Arabic digits — with automatic conversion to the formal amount form.
Numbers roll between three formats: Arabic digits, lowercase Chinese numerals, and formal Chinese amount numerals. A built-in converter turns 123456 into 「十二萬三千四百五十六」 or 「壹拾貳萬參仟肆佰伍拾陸元整」. When the value changes, each position scrolls up or down individually (odometer style — unit characters that did not change stay put), and switching formats cross-fades the whole set.
npx shadcn@latest add https://webberui.com/r/cjk-number-roller.jsonPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<CjkNumberRoller />
Installation
npx shadcn@latest add https://webberui.com/r/cjk-number-roller.jsonOr, once registries are configured in components.json, install it as @webberui/cjk-number-roller.
Usage
import {
CjkNumberRoller,
numberToChinese,
} from "@/components/ui/cjk-number-roller";
<CjkNumberRoller value={123456} format="arabic" prefix="NT$" />
<CjkNumberRoller value={123456} format="lower" />
<CjkNumberRoller value={123456} format="upper" className="text-4xl font-semibold" />
// The converter can also be called on its own
numberToChinese(123456, "lower"); // 十二萬三千四百五十六
numberToChinese(123456, "upper"); // 壹拾貳萬參仟肆佰伍拾陸Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | — | The value to display; it is rounded and clamped to 0 ~ Number.MAX_SAFE_INTEGER |
format | CjkNumberFormat | "arabic" | Display format: arabic (Arabic digits with thousands separators), lower (lowercase Chinese numerals), upper (formal amount numerals) |
prefix | string | — | Prefix before the number (such as NT$), shown at a smaller size on the left |
animate | boolean | true | Whether the rolling animation is enabled |
currencySuffix | boolean | true | Whether the upper format automatically appends 「元整」 |
className | string | — | Forwarded to the outer container |
There is also a named export for the pure function numberToChinese(value, style) (with style being "lower" or "upper"): gaps between groups get a 「零」 as convention dictates (10500 → 一萬零五百), and a leading 「一十」 in the lowercase form is shortened to 「十」. The unit table goes up to 「兆」, which already covers the JS safe integer range.
Accessibility
- The fully formatted result is exposed
sr-onlyfor screen readers, while the per-position animated characters are hidden from assistive technology (aria-hidden) - When the user has "reduce motion" enabled at the system level, or
animateis set tofalse, static text is rendered directly and no animation is mounted at all - The animation only starts after the client mounts, so the first SSR output matches the client and there is no hydration difference
Bopomofo Ruby Text (React ruby typography component)
A React ruby typography component that annotates Chinese characters with Bopomofo (Zhuyin) or Hanyu Pinyin above them — switch between Bopomofo and Pinyin, highlight a character on hover, adjust the annotation size and spacing. Suited to teaching materials, dictionaries, and children's sites.
Lunar / Gregorian Date Picker (React)
A React calendar component showing the Gregorian and lunar calendars side by side — every cell is annotated with the lunar day, the 24 solar terms, and traditional festivals, and one click switches the primary axis between lunar and Gregorian.