🍙 Onigiri

The Crunchyroll design system, rendered live from its own tokens and components. It cannot drift from what ships.

Docs draft

Input

When to use it

useSingle-line text entry: email, username, list names.
avoidPasswords — the show toggle and meter are its own anatomy. password-input
avoidSearch — the header bar at display scale with its own affordances. search-input

Anatomy

floating labelStarts in-field at body-lg in color.text.entry — white on dark, exactly the old Forms page — and floats to caption in color.text.secondary. It IS the placeholder; there is no separate placeholder prop.

valuetype.body-lg.

trailing control slotOptional (clear, show); boolean + swap in Figma, ReactNode in code.

underline2px; the only state-bearing boundary.

States

emptyNo value entered yet.

focusHolds keyboard focus and shows the focus ring.

filledHolds an entered value.

errorSignals a failed or invalid value.

read onlyValue shown but not editable.

disabledNot interactive; rendered with the lifted disabled tokens so it stays perceivable.

Guidelines

mustThe error message never replaces the label; it renders in FormField's message row.The old pattern swapped the label for the message, destroying which field was erroring. Deliberate deviation, ruled at rebuild.
mustFocus underline uses color.accent.text, never raw brand orange.Orange is 2.7:1 on cream — below the 3:1 UI floor for the only focus indicator.

API

PropTypeDescription
labelstringFloating label and accessible name.
trailingReactNodeTrailing adornment rendered inside the field.
...restInputHTMLAttributes minus placeholderaria-invalid drives the error state; readOnly and disabled are native.

Design specifications

widthfills its container; Figma shows 400
valuetype.body-lg in color.text.entry — entered text reads white on dark, one step brighter than reading text (Robin's ruling)
label-floatedtype.caption
label-colorcolor.text.secondary
underline-restcolor.border.strong
underline-focuscolor.accent.text
underline-errorcolor.text.negative
underline-quietcolor.border.subtle (read-only, disabled)
value-read-onlycolor.text.secondary
value-disabledcolor.text.disabled

Accessibility

TabNative focus; the underline color change plus caret are the indicators.

color.border.strong on color.bg.primaryContracted at ≥ 3:1 by the build gate.

color.accent.text on color.bg.primaryContracted at ≥ 4.5:1 by the build gate.

Label wraps the native input, so the floating label is the accessible name. Error pairs aria-invalid with a FormField message and aria-describedby.