OTP Field
OTP Field is segmented one-time-code entry backed by Atom OTP Field. Atom owns accepted characters, focus movement, paste, masking, completion, validation, reset, and one-value form participation; Brick owns cell recipes and the static Group layout part.
Built from the published package
Know when OTP Field is the right part
Use it when
Use it for short verification, recovery, or pairing codes delivered through another channel.
Choose another path when
Do not use it for passwords, permanent PIN storage, arbitrary serial numbers, or unrelated fields. It does not send codes, manage expiry, or submit automatically unless autoSubmit is explicitly enabled.
Installation and imports
The complete stylesheet above is the recommended default. For a measured route-aware build, replace it with the shared foundation and this component's stylesheet:
Add the modular stylesheet for every other Brick component the route renders.
Do not combine modular styles with styles.css or tokens.css.
Quick start
Visual recipes and states
Outline, soft, and underline follow the form-family paint. Size changes every cell. Shape changes cell geometry. Attached removes gaps and joins adjacent cells; separated retains individual boundaries. State paint derives from Atom data attributes.
Examples
Use mask for shoulder-surfing resistance, type="alphanumeric" for mixed codes, and getInputLabel={(index, length) => ...} for localization.
API
Start with the public parts and root options below. Components with multiple parts separate each area into its own named subsection.
Public exports are OTPField, OTPFieldRoot, OTPFieldGroup, OTPFieldInput,
OTPFieldSeparator, OTPFieldRootProps, OTPFieldGroupProps,
OTPFieldInputProps, OTPFieldSeparatorProps, OTPFieldVariant,
OTPFieldSize, OTPFieldShape, and OTPFieldLayout.
| Root prop | Values | Default |
|---|---|---|
variant | outline, soft, underline | outline |
size | sm, md, lg | md |
shape | sharp, rounded | rounded |
layout | separated, attached | separated |
underline rejects shape. Root preserves Atom's controlled/uncontrolled value, completion, length (default 6), type (default numeric), pattern, mask (default false), state, autoFocus/autoSubmit (both false), name, form, inputId, localized getInputLabel, and validation props. Input accepts an optional explicit index. Separator defaults visually to an en dash; Group has static div props.
Accessibility
Use Field for the visible group label. Each cell receives a position-aware accessible name; localize it with getInputLabel. Only the first cell owns native required validity so the segmented control contributes one validation target and one named form value. Masking is visual privacy, not secure storage.
Responsive behavior
Groups use logical flex layout and may wrap only at group boundaries. Keep code length appropriate for the available width. RTL preserves authored cell order while logical groups and separators remain contained.
Styling and tokens
Customization
Prefer recipe props and semantic tokens, then the two component variables. Compose Groups and Separators to express readable code grouping; do not alter cell order visually.
Tokens and CSS hooks
Public variables are --brick-otp-size and --brick-otp-radius. Root exposes data-variant, data-size, data-shape, data-layout, and data-slot. Stable classes and slots are listed above.
Advanced reference
Open these details only when you need to inspect DOM ownership, native forwarding, or lower-level composition.