Pin Input

For pin or verification codes with auto-focus transfer and masking options.

Anatomy

To set up the pin input correctly, you’ll need to understand its anatomy and how we name its parts.

Each part includes a data-part attribute to help identify them in the DOM.

Examples

Learn how to use the PinInput component in your project. Let’s take a look at the most basic example:

import { PinInput } from '@ark-ui/react'

const Basic = () => (
  <PinInput.Root onValueComplete={(e) => alert(e.valueAsString)}>
    <PinInput.Label>Label</PinInput.Label>
    <PinInput.Control>
      {[0, 1, 2].map((id, index) => (
        <PinInput.Input key={id} index={index} />
      ))}
    </PinInput.Control>
  </PinInput.Root>
)

Setting a default value

To set the initial value of the pin input, set the defaultValue prop.

import { PinInput } from '@ark-ui/react'

const InitialValue = () => (
  <PinInput.Root defaultValue={['1', '2', '3']}>
    <PinInput.Label>Label</PinInput.Label>
    <PinInput.Control>
      {[0, 1, 2].map((id, index) => (
        <PinInput.Input key={id} index={index} />
      ))}
    </PinInput.Control>
  </PinInput.Root>
)

Changing the placeholder

To customize the default pin input placeholder for each input, pass the placeholder prop and set it to your desired value.

import { PinInput } from '@ark-ui/react'

const Customized = () => (
  <PinInput.Root placeholder="*">
    <PinInput.Label>Label</PinInput.Label>
    <PinInput.Control>
      {[0, 1, 2].map((id, index) => (
        <PinInput.Input key={id} index={index} />
      ))}
    </PinInput.Control>
  </PinInput.Root>
)

Blur on complete

By default, the last input maintains focus when filled, and we invoke the onValueComplete callback. To blur the last input when the user completes the input, set the prop blurOnComplete to true.

import { PinInput } from '@ark-ui/react'

const Blurred = () => (
  <PinInput.Root blurOnComplete>
    <PinInput.Label>Label</PinInput.Label>
    <PinInput.Control>
      {[0, 1, 2].map((id, index) => (
        <PinInput.Input key={id} index={index} />
      ))}
    </PinInput.Control>
  </PinInput.Root>
)

Using OTP mode

To trigger smartphone OTP auto-suggestion, it is recommended to set the autocomplete attribute to “one-time-code”. The pin input component provides support for this automatically when you set the otp prop to true.

import { PinInput } from '@ark-ui/react'

const OTPMode = () => (
  <PinInput.Root otp>
    <PinInput.Label>Label</PinInput.Label>
    <PinInput.Control>
      {[0, 1, 2].map((id, index) => (
        <PinInput.Input key={id} index={index} />
      ))}
    </PinInput.Control>
  </PinInput.Root>
)

Securing the text input

When collecting private or sensitive information using the pin input, you might need to mask the value entered, similar to <input type="password"/>. Pass the mask prop to true.

import { PinInput } from '@ark-ui/react'

const WithMask = () => (
  <PinInput.Root mask>
    <PinInput.Label>Label</PinInput.Label>
    <PinInput.Control>
      {[0, 1, 2].map((id, index) => (
        <PinInput.Input key={id} index={index} />
      ))}
    </PinInput.Control>
  </PinInput.Root>
)

Listening for changes

The pin input component invokes several callback functions when the user enters:

  • onValueChange — Callback invoked when the value is changed.
  • onValueComplete — Callback invoked when all fields have been completed (by typing or pasting).
  • onValueInvalid — Callback invoked when an invalid value is entered into the input. An invalid value is any value that doesn’t match the specified “type”.

API Reference

Root

PropTypeDefault
asChild
boolean
autoFocus
boolean
blurOnComplete
boolean
defaultValue
string[]
dir
'ltr' | 'rtl'"ltr"
disabled
boolean
form
string
getRootNode
() => Node | ShadowRoot | Document
id
string
ids
Partial<{ root: string hiddenInput: string label: string control: string input(id: string): string }>
invalid
boolean
mask
boolean
name
string
onValueChange
(details: ValueChangeDetails) => void
onValueComplete
(details: ValueChangeDetails) => void
onValueInvalid
(details: ValueInvalidDetails) => void
otp
boolean
pattern
string
placeholder
string
selectOnFocus
boolean
translations
IntlTranslations
type
'alphabetic' | 'numeric' | 'alphanumeric'
value
string[]

Input

PropTypeDefault
index
number
asChild
boolean

Label

PropTypeDefault
asChild
boolean

Control

PropTypeDefault
asChild
boolean