Skip to content

OTPInput

One-time password input with auto-focus and paste support.

import { OTPInput } from 'asterui'

Basic OTP Input

Simple 6-digit OTP input.

import { OTPInput } from 'asterui'
import { useState } from 'react'

function App() {
  const [value, setValue] = useState('')
  
  return (
      <OTPInput
        value={value}
        onChange={setValue}
        onComplete={(otp) => console.log('Complete:', otp)}
      />
    )
}

export default App

Four Digit

Custom length OTP input.

import { OTPInput } from 'asterui'
import { useState } from 'react'

function App() {
  const [value, setValue] = useState('')
  
  return (
      <OTPInput
        length={4}
        value={value}
        onChange={setValue}
      />
    )
}

export default App

Sizes

Different size variants.

import { OTPInput, Space } from 'asterui'

function App() {
  return (
      <Space direction="vertical" size="lg">
        <OTPInput length={4} size="xs" />
        <OTPInput length={4} size="sm" />
        <OTPInput length={4} size="md" />
        <OTPInput length={4} size="lg" />
      </Space>
    )
}

export default App

Masked Input

Hide entered values with dots.

import { OTPInput } from 'asterui'
import { useState } from 'react'

function App() {
  const [value, setValue] = useState('')
  
  return (
      <OTPInput
        value={value}
        onChange={setValue}
        mask
      />
    )
}

export default App

Alphanumeric

Accept both letters and numbers.

import { OTPInput } from 'asterui'
import { useState } from 'react'

function App() {
  const [value, setValue] = useState('')
  
  return (
      <OTPInput
        value={value}
        onChange={setValue}
        type="text"
        length={5}
      />
    )
}

export default App

Error State

Show error styling for invalid input.

import { OTPInput } from 'asterui'
import { useState } from 'react'

function App() {
  const [value, setValue] = useState('123')
  
  return (
      <OTPInput
        value={value}
        onChange={setValue}
        error
        length={4}
      />
    )
}

export default App

Disabled State

Non-interactive disabled input.

import { OTPInput } from 'asterui'

function App() {
  return (
      <OTPInput
        value="123456"
        disabled
      />
    )
}

export default App
PropertyDescriptionTypeDefault
lengthNumber of input fieldsnumber6
valueCurrent valuestring-
onChangeCallback when value changes(value: string) => void-
onCompleteCallback when all fields are filled(value: string) => void-
sizeInput size'xs' | 'sm' | 'md' | 'lg' | 'xl''md'
typeInput type - number only or alphanumeric'number' | 'text''number'
maskMask input (show dots instead of characters)booleanfalse
disabledDisabled statebooleanfalse
errorError statebooleanfalse
autoFocusAuto focus first input on mountbooleanfalse
placeholderPlaceholder characterstring-
data-testidTest ID prefix for child elementsstring-
classNameAdditional CSS classesstring-
PropertyDescriptionTypeDefault
focusFocus the first input() => void-
clearClear all inputs and focus first() => void-
  • Each input has an aria-label indicating its position
  • Supports keyboard navigation with arrow keys
  • Backspace moves focus to previous input
  • Supports pasting full OTP codes