OTPField | Dashforge-UI
DocsStarter Kits
v0.1.0-alpha

OTPField

A slot-based input component for one-time passwords, verification codes, 2FA tokens, and SMS confirmations. Supports numeric, alphanumeric, and alpha modes with keyboard navigation, paste handling, and mobile SMS autofill. Works standalone or with DashForm integration.

Quick Start

Copy & Paste

For verification codes—OTP, 2FA, SMS codes, and security tokens

import { OTPField } from '@dashforge/ui';

<OTPField name="otp" length={6} />

Examples

Common OTPField patterns and configurations

Basic Numeric

Standard 6-digit OTP for verification codes

<OTPField name="otp" length={6} />
Short 4-Digit

4-digit PIN code entry

<OTPField name="pin" length={4} />
Alphanumeric Mode

Accept letters and numbers for complex codes

<OTPField
  name="token"
  length={6}
  mode="alphanumeric"
/>
Alpha Only

Letter-only verification codes

<OTPField
  name="code"
  length={4}
  mode="alpha"
/>
With Label

Display a label above the OTP slots

<OTPField
  name="verification"
  length={6}
  label="Enter verification code"
/>
Error State

Show validation errors

Invalid code. Please try again.

<OTPField
  name="invalid"
  length={6}
  error
  helperText="Invalid code. Please try again."
/>
Controlled

Manage state externally with value/onChange

Current value: (empty)

const [value, setValue] = useState('');

<OTPField
  name="controlled"
  length={6}
  value={value}
  onChange={setValue}
/>
Completion Callback

Fire callback when all slots are filled

Fill all slots to trigger callback

const [completed, setCompleted] = useState('');

<OTPField
  name="complete"
  length={6}
  onComplete={setCompleted}
/>

Dashforge Capabilities

Progressive adoption from controlled components to reactive forms

Use OTPField as a controlled component, integrate with React Hook Form, or leverage reactive capabilities. Choose the adoption level that fits your workflow.

Controlled

Available Now

Works as a standard React controlled component with value and onChange. No proprietary lock-in—use familiar patterns for OTP entry.

Standard value and onChange props (string-based)

Integrate with any state management solution

onComplete callback for submission triggers

const [otp, setOtp] = useState('');

<OTPField
  name="otp"
  length={6}
  value={otp}
  onChange={setOtp}
  onComplete={(value) => submitCode(value)}
/>

React Hook Form Ready

Integration-Friendly

Integrates with React Hook Form via DashForm. Automatic validation, error handling, and touch tracking for OTP fields.

Works with RHF through DashFormBridge

Automatic validation and error gating

Touch state managed automatically on blur

<DashForm>
  <OTPField 
    name="otp"
    length={6}
    rules={{
      required: 'Verification code is required',
      minLength: {
        value: 6,
        message: 'Code must be 6 digits',
      },
    }}
  />
</DashForm>

Reactive Visibility

Available Now

Conditional rendering via visibleWhen. Show OTP field only when needed based on form state, like after phone number entry.

Conditional rendering via visibleWhen

Engine evaluates the predicate reactively

Perfect for multi-step verification flows

<OTPField
  name="otp"
  length={6}
  visibleWhen={(engine) => 
    engine.getNode('phoneNumber')?.value?.length === 10
  }
/>

API Reference

Complete props and type definitions

Explicit vs Auto-Bound Props: When inside DashForm, OTPField receives value, error, helperText, onChange, and onBlur automatically through field binding. Explicit props always take precedence over form-provided values.

PropTypeDefaultDescription
namestring-Field name for form integration (required)
lengthnumber6Number of OTP slots to render
mode'numeric' | 'alphanumeric' | 'alpha''numeric'Character entry mode. numeric: 0-9 only. alphanumeric: 0-9, a-z, A-Z. alpha: a-z, A-Z only.
valuestring-Controlled value of the OTP field (complete string, e.g., "123456")
onChange(value: string) => void-Callback fired when the value changes. Receives the complete OTP string.
onComplete(value: string) => void-Callback fired when all slots are filled. Useful for auto-submit on completion.
autoFocusbooleanfalseAuto-focus first slot on mount
labelReactNode-Label text displayed above the OTP slots
errorbooleanfalseIf true, displays error state. Explicit error prop overrides form-provided error state. When inside DashForm without explicit prop, error is gated (shows only when touched OR submitted).
helperTextReactNode-Helper text displayed below slots. Explicit helperText prop overrides form-provided validation error message. When inside DashForm, validation errors display as helperText (gated by touched/submitted state).
disabledbooleanfalseIf true, the OTP field is disabled
requiredbooleanfalseIf true, displays required indicator in label
fullWidthbooleanfalseIf true, the container takes up the full width
rulesValidationRules-Validation rules for DashForm integration. Format follows React Hook Form rules contract. Only used when inside DashForm—ignored in standalone mode.
visibleWhen(engine: Engine) => boolean-Component-level conditional rendering predicate. Receives engine instance with access to all field state via getNode(name). When false, component renders null. Re-evaluates on dependency changes. Only works inside DashForm (requires engine).
accessAccessRequirement-RBAC access control configuration. Controls field visibility and interaction based on user permissions. Fields can be hidden, disabled, or readonly when users lack access.

Under the hood

How OTPField behaves and why it works this way

Form integration

Automatically binds to form state inside DashForm. Single onChange handler with string value. Works standalone with controlled value/onChange props when outside DashForm.

Behavior model

Single accessible input with visual slot representation. Keyboard navigation (arrow keys, backspace) and paste handling built-in. Mobile SMS autofill via autoComplete="one-time-code". Errors gated by Form Closure v1 (touch + submit).

Architecture

Built on slot-based UI primitive with single input for accessibility. Supports numeric, alphanumeric, and alpha modes. Fully typed with TypeScript. Caret management for seamless UX.


On This Page