Pathfinderby Commenda
Components

OTP

One accessible input with visual code slots and application-owned verification.

Enter the 6-digit code from your authenticator app.

Installation

Import the component in your screen:

Example.tsx
import { OTP } from '@commenda/pathfinder/otp';

Load the stylesheet once in your app root, after host styles:

Example.tsx
import '@commenda/pathfinder/styles.css';

Pathfinder ships precompiled CSS; no Tailwind setup is required. In Next.js App Router, put interactive state and callbacks in a client component. See installation for the workspace setup.

API reference

PropTypeBehavior
valueConditionalstringKeep leading zeros; controlled mode requires onValueChange
defaultValuestringKeep leading zeros; controlled mode requires onValueChange
length4|5|6|7|86 numeric characters
groupConfigObjectView fieldsSix digits use [3, 3]; other lengths use one group. Sizes must sum to length
onComplete(code: string) => voidFires after an edit completes the code; never on mount or blur
loadingConfigObjectView fieldsLocks edits, retains form value, announces verification
labelConditionalstringVisible field label. Supply an accessible name when it is omitted.
hideLabelbooleanVisually hide the label while preserving its accessible name.
aria-labelConditionalstringAccessible name when the field has no visible label.
requiredConditionalbooleanMark the field as required. See validation guidance for the component.
labelConfigObjectView fields · 2 shapesChoose either optionalLabel or help, never both. never excludes the other field.
descriptionstringSupporting guidance associated with the field.
errorConfigObjectView fieldsValidation message and when it becomes visible.
disableConfigDisableConfigView fieldsDisabled state with an optional explanation.
onValueChangeConditional(value: string) => void—
groupConfigObject fields
FieldTypeRequirement
sizesreadonly number[]Required
loadingConfigObject fields
FieldTypeRequirement
isLoadingbooleanRequired
labelstringOptional
labelConfigObject fields

Choose one of these 2 shapes. Do not combine fields excluded by the selected shape.

Option 1

FieldTypeRequirement
optionalLabelstringRequired

Do not supply: help.

Option 2

FieldTypeRequirement
helpstringRequired

Do not supply: optionalLabel.

errorConfigObject fields
FieldTypeRequirement
messagestringRequired
reveal"after-blur" | "immediate"Optional
disableConfigObject fields
FieldTypeRequirement
isDisabledbooleanRequired
reasonstringOptional

Shared label, hideLabel, description, required, errorConfig, disableConfig, and readOnly follow Input. The underlying input-otp primitive is private.

Grouping

Verification

The application starts verification from onComplete, owns pending/error state, and clears its previous server error in onValueChange. Do not submit a form automatically from both onComplete and a separate input handler. Guard against a previous request completing after the user has edited the code; associate the response with the submitted code or request ID.

Demo verification: enter 012345. Your application owns the real request.

States

Verifying code…
Request a new code before continuing.
That code has expired. Request a new one.

Paste fills the code, Backspace edits the previous slot, and leading zeros remain strings. Read composite field rules for Figma provenance and accessibility rules.

Design rules

Figma guidance and reviewed implementation decisions for this component. Rule IDs remain stable for source comments and AI references.

OTP

  • OTP-001: Default six 36px slots in two groups of three; radius 6, 15px medium digits. Other supported lengths are 4–8.
  • OTP-002: One accessible native input; numeric string values preserve leading zeros, paste, and one-time-code autocomplete. Slots are presentational.
  • OTP-003: Completion emits an event. The application verifies the code, handles stale responses, and clears server errors on edit. Figma's auto-submit wording is implemented as onComplete, with no implicit form submission.
  • OTP-004: Loading makes the input read-only and announces verification without dropping its native form value. Disabled fields do not submit.

Shared rules

Labels activate the first input. Descriptions, disabled reasons, and validation messages stay associated with the field. Error icons center on the first 18px text line, including wrapped messages. Controlled values require callbacks; uncontrolled form resets restore defaults. Public props expose application values, never private primitive or calendar objects. Styles ship precompiled for React 18/19 and Next.js consumers.

On this page