# Pin Input URL: https://ark-ui.com/docs/components/pin-input Source: https://raw.githubusercontent.com/chakra-ui/ark/refs/heads/main/website/src/content/pages/components/pin-input.mdx 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: **Example: basic** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' export const Basic = () => ( alert(e.valueAsString)}> Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' export const Basic = () => ( alert(e.valueAsString)}> Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte alert(details.valueAsString)}> Label {#each [0, 1, 2] as index} {/each} ``` ### Setting a default value To set the initial value of the pin input, set the `defaultValue` prop. **Example: initial-value** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' export const InitialValue = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' export const InitialValue = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Enter your PIN (default: 123) {#each [0, 1, 2] as index} {/each} ``` ### Changing the placeholder To customize the default pin input placeholder `○` for each input, pass the placeholder prop and set it to your desired value. **Example: customized** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' export const Customized = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' export const Customized = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte
{JSON.stringify({ value }, null, 2)}
Enter PIN {#each [0, 1, 2, 3] as index} {/each}
``` ### 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`. **Example: blurred** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' export const Blurred = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' export const Blurred = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte PIN (blurs on complete) {#each [0, 1, 2] as index} {/each} ``` ### 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. **Example: otp-mode** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' export const OTPMode = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' export const OTPMode = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Enter verification code {#each [0, 1, 2, 3, 4, 5] as index} {/each} ``` ### Securing the text input When collecting private or sensitive information using the pin input, you might need to mask the value entered, similar to ``. Pass the `mask` prop to `true`. **Example: with-mask** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' export const WithMask = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' export const WithMask = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Enter your secure PIN {#each [0, 1, 2, 3] as index} {/each} ``` ### 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". ### Using the Field Component The `Field` component helps manage form-related state and accessibility attributes of a pin input. It includes handling ARIA labels, helper text, and error text to ensure proper accessibility. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { PinInput } from '@ark-ui/react/pin-input' export const WithField = (props: Field.RootProps) => ( Label {[0, 1, 2].map((id, index) => ( ))} Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' export const WithField = (props: Field.RootProps) => ( Label {(id) => } Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} Additional Info Error Info ``` ### Using the Root Provider The `RootProvider` component provides a context for the pin-input. It accepts the value of the `usePin-input` hook. You can leverage it to access the component state and methods from outside the pin-input. **Example: root-provider** #### React ```tsx import { PinInput, usePinInput } from '@ark-ui/react/pin-input' export const RootProvider = () => { const pinInput = usePinInput({ onValueComplete: (e) => alert(e.valueAsString) }) return ( <> Label {[0, 1, 2].map((id, index) => ( ))} ) } ``` #### Solid ```tsx import { PinInput, usePinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' export const RootProvider = () => { const pinInput = usePinInput({ onValueComplete: (e) => alert(e.valueAsString) }) return ( <> Label {(id) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
PIN (with external control) {#each [0, 1, 2] as index} {/each}
``` > If you're using the `RootProvider` component, you don't need to use the `Root` component. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input: (id: string) => string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called on input change | | `onValueComplete` | `(details: ValueChangeDetails) => void` | No | Function called when all inputs have valid values | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function called when an invalid value is entered | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphabetic' | 'alphanumeric'` | No | The type of value the pin-input should allow | | `value` | `string[]` | No | The controlled value of the the pin input. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePinInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input: (id: string) => string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called on input change | | `onValueComplete` | `(details: ValueChangeDetails) => void` | No | Function called when all inputs have valid values | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function called when an invalid value is entered | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphabetic' | 'alphanumeric'` | No | The type of value the pin-input should allow | | `value` | `string[]` | No | The controlled value of the the pin input. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePinInputReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input(id: string): string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `modelValue` | `string[]` | No | The v-model value of the pin input | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphabetic' | 'alphanumeric'` | No | The type of value the pin-input should allow | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PinInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input: (id: string) => string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called on input change | | `onValueComplete` | `(details: ValueChangeDetails) => void` | No | Function called when all inputs have valid values | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function called when an invalid value is entered | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphabetic' | 'alphanumeric'` | No | The type of value the pin-input should allow | | `value` | `string[]` | No | The controlled value of the the pin input. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePinInputContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePinInputReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context These are the properties available when using `UpinUinput.Context`, `useUpinUinputContext` hook or `useUpinUinput` hook. **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string[]` | The value of the input as an array of strings. | | `valueAsString` | `string` | The value of the input as a string. | | `complete` | `boolean` | Whether all inputs are filled. | | `count` | `number` | The number of inputs to render | | `items` | `number[]` | The array of input values. | | `setValue` | `(value: string[]) => void` | Function to set the value of the inputs. | | `clearValue` | `VoidFunction` | Function to clear the value of the inputs. | | `setValueAtIndex` | `(index: number, value: string) => void` | Function to set the value of the input at a specific index. | | `focus` | `VoidFunction` | Function to focus the pin-input. This will focus the first input. | ## Accessibility ### Keyboard Support