Pin Input
For pin or verification codes with auto-focus transfer and masking options.
For pin or verification codes with auto-focus transfer and masking options.
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.
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>
)
import { PinInput } from '@ark-ui/solid'
import { Index } from 'solid-js'
const Basic = () => (
<PinInput.Root onValueComplete={(e) => alert(e.valueAsString)}>
<PinInput.Label>Label</PinInput.Label>
<PinInput.Control>
<Index each={[0, 1, 2]}>{(id) => <PinInput.Input index={id()} />}</Index>
</PinInput.Control>
</PinInput.Root>
)
<script setup lang="ts">
import { PinInput } from '@ark-ui/vue'
</script>
<template>
<PinInput.Root @value-complete="(e) => console.log(e.valueAsString)">
<PinInput.Label>Label</PinInput.Label>
<PinInput.Control>
<PinInput.Input v-for="id in [0, 1, 2]" :key="id" :index="id" />
</PinInput.Control>
</PinInput.Root>
</template>
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>
)
import { PinInput } from '@ark-ui/solid'
import { Index } from 'solid-js'
const InitialValue = () => (
<PinInput.Root value={['1', '2', '3']}>
<PinInput.Label>Label</PinInput.Label>
<PinInput.Control>
<Index each={[0, 1, 2]}>{(id) => <PinInput.Input index={id()} />}</Index>
</PinInput.Control>
</PinInput.Root>
)
<script setup lang="ts">
import { PinInput } from '@ark-ui/vue'
</script>
<template>
<PinInput.Root :model-value="['1', '2', '3']">
<PinInput.Label>Label</PinInput.Label>
<PinInput.Control>
<PinInput.Input v-for="id in [0, 1, 2]" :key="id" :index="id" />
</PinInput.Control>
</PinInput.Root>
</template>
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>
)
import { PinInput } from '@ark-ui/solid'
import { Index } from 'solid-js'
const Customized = () => (
<PinInput.Root placeholder="*">
<PinInput.Label>Label</PinInput.Label>
<PinInput.Control>
<Index each={[0, 1, 2]}>{(id) => <PinInput.Input index={id()} />}</Index>
</PinInput.Control>
</PinInput.Root>
)
<script setup lang="ts">
import { PinInput } from '@ark-ui/vue'
</script>
<template>
<PinInput.Root placeholder="*">
<PinInput.Label>Label</PinInput.Label>
<PinInput.Control>
<PinInput.Input v-for="id in [0, 1, 2]" :key="id" :index="id" />
</PinInput.Control>
</PinInput.Root>
</template>
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>
)
import { PinInput } from '@ark-ui/solid'
import { Index } from 'solid-js'
const Blurred = () => (
<PinInput.Root blurOnComplete>
<PinInput.Label>Label</PinInput.Label>
<PinInput.Control>
<Index each={[0, 1, 2]}>{(id) => <PinInput.Input index={id()} />}</Index>
</PinInput.Control>
</PinInput.Root>
)
<script setup lang="ts">
import { PinInput } from '@ark-ui/vue'
</script>
<template>
<PinInput.Root blurOnComplete>
<PinInput.Label>Label</PinInput.Label>
<PinInput.Control>
<PinInput.Input v-for="id in [0, 1, 2]" :key="id" :index="id" />
</PinInput.Control>
</PinInput.Root>
</template>
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>
)
import { PinInput } from '@ark-ui/solid'
import { Index } from 'solid-js'
const OTPMode = () => (
<PinInput.Root otp>
<PinInput.Label>Label</PinInput.Label>
<PinInput.Control>
<Index each={[0, 1, 2]}>{(id) => <PinInput.Input index={id()} />}</Index>
</PinInput.Control>
</PinInput.Root>
)
<script setup lang="ts">
import { PinInput } from '@ark-ui/vue'
</script>
<template>
<PinInput.Root otp>
<PinInput.Label>Label</PinInput.Label>
<PinInput.Control>
<PinInput.Input v-for="id in [0, 1, 2]" :key="id" :index="id" />
</PinInput.Control>
</PinInput.Root>
</template>
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>
)
import { PinInput } from '@ark-ui/solid'
import { Index } from 'solid-js'
const WithMask = () => (
<PinInput.Root mask>
<PinInput.Label>Label</PinInput.Label>
<PinInput.Control>
<Index each={[0, 1, 2]}>{(id) => <PinInput.Input index={id()} />}</Index>
</PinInput.Control>
</PinInput.Root>
)
<script setup lang="ts">
import { PinInput } from '@ark-ui/vue'
</script>
<template>
<PinInput.Root mask>
<PinInput.Label>Label</PinInput.Label>
<PinInput.Control>
<PinInput.Input v-for="id in [0, 1, 2]" :key="id" :index="id" />
</PinInput.Control>
</PinInput.Root>
</template>
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”.Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean | |
autoFocus Whether to auto-focus the first input. | boolean | |
blurOnComplete Whether to blur the input when the value is complete | boolean | |
defaultValue The initial value of the pin input. | string[] | |
dir The document's text/writing direction. | 'ltr' | 'rtl' | "ltr" |
disabled Whether the inputs are disabled | boolean | |
form The associate form of the underlying input element. | string | |
getRootNode A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | () => Node | ShadowRoot | Document | |
id The unique identifier of the machine. | string | |
ids The ids of the elements in the pin input. Useful for composition. | Partial<{
root: string
hiddenInput: string
label: string
control: string
input(id: string): string
}> | |
invalid Whether the pin input is in the invalid state | boolean | |
mask If `true`, the input's value will be masked just like `type=password` | boolean | |
name The name of the input element. Useful for form submission. | string | |
onValueChange Function called on input change | (details: ValueChangeDetails) => void | |
onValueComplete Function called when all inputs have valid values | (details: ValueChangeDetails) => void | |
onValueInvalid Function called when an invalid value is entered | (details: ValueInvalidDetails) => void | |
otp If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | boolean | |
pattern The regular expression that the user-entered input value is checked against. | string | |
placeholder The placeholder text for the input | string | |
selectOnFocus Whether to select input value when input is focused | boolean | |
translations Specifies the localized strings that identifies the accessibility elements and their states | IntlTranslations | |
type The type of value the pin-input should allow | 'alphabetic' | 'numeric' | 'alphanumeric' | |
value The value of the the pin input. | string[] |
Prop | Type | Default |
---|---|---|
index | number | |
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Previous
PaginationNext
Popover