import { PinInput } from "@/components/ui/pin-input"
const Demo = () => {
return <PinInput />
}
Setup
If you don't already have the snippet, run the following command to add the
pin-input
snippet
npx @chakra-ui/cli snippet add pin-input
The snippet includes a closed component composition for the PinInput
component.
Usage
import { PinInput } from "@/components/ui/pin-input"
<PinInput />
Examples
Sizes
Use the size
prop to change the size of the pin input component.
import { Stack } from "@chakra-ui/react"
import { PinInput } from "@/components/ui/pin-input"
const Demo = () => {
return (
<Stack gap="4">
<PinInput size="sm" />
<PinInput size="md" />
<PinInput size="lg" />
</Stack>
)
}
One time code
Use the otp
prop to make the pin input component behave like a one-time code
input. This helps improve the user experience when entering OTP codes.
import { PinInput } from "@/components/ui/pin-input"
const Demo = () => {
return <PinInput otp />
}
Mask
Use the mask
prop to obscure the entered pin code.
import { PinInput } from "@/components/ui/pin-input"
const Demo = () => {
return <PinInput mask />
}
Placeholder
Use the placeholder
prop to add a placeholder to the pin input component.
import { PinInput } from "@/components/ui/pin-input"
const Demo = () => {
return <PinInput placeholder="🥳" />
}
Field
Here's an example of how to compose the Field
and the PinInput
components
import { Field } from "@/components/ui/field"
import { PinInput } from "@/components/ui/pin-input"
const Demo = () => {
return (
<Field label="Enter otp">
<PinInput />
</Field>
)
}
Hook Form
Here's an example of how to compose the Field
and the PinInput
components
with react-hook-form
"use client"
import { Button, Stack } from "@chakra-ui/react"
import { zodResolver } from "@hookform/resolvers/zod"
import { Field } from "@/components/ui/field"
import { PinInput } from "@/components/ui/pin-input"
import { Controller, useForm } from "react-hook-form"
import { z } from "zod"
const formSchema = z.object({
pin: z
.array(z.string().min(1), { required_error: "Pin is required" })
.length(4, { message: "Pin must be 4 digits long" }),
})
type FormValues = z.infer<typeof formSchema>
const Demo = () => {
const { handleSubmit, control, formState } = useForm<FormValues>({
resolver: zodResolver(formSchema),
})
const onSubmit = handleSubmit((data) => console.log(data))
return (
<form onSubmit={onSubmit}>
<Stack gap="4" align="flex-start" maxW="sm">
<Field
invalid={!!formState.errors.pin}
errorText={formState.errors.pin?.message}
>
<Controller
control={control}
name="pin"
render={({ field }) => (
<PinInput
value={field.value}
onValueChange={(e) => field.onChange(e.value)}
/>
)}
/>
</Field>
<Button type="submit">Submit</Button>
</Stack>
</form>
)
}
Controlled
Use the value
and onValueChange
props to control the value of the pin input
"use client"
import { PinInput } from "@/components/ui/pin-input"
import { useState } from "react"
const Demo = () => {
const [value, setValue] = useState(["", "", "", ""])
return <PinInput value={value} onValueChange={(e) => setValue(e.value)} />
}
Attached
Use the attached
prop to attach the pin input to the input field
import { PinInput } from "@/components/ui/pin-input"
const Demo = () => {
return <PinInput attached />
}
Alphanumeric
Use the type
prop to allow the user to enter alphanumeric characters. Values
can be either alphanumeric
, numeric
, or alphabetic
import { PinInput } from "@/components/ui/pin-input"
const Demo = () => {
return <PinInput type="alphanumeric" />
}
Without Snippet
If you don't want to use the snippet, you can use the PinInput
component from
the @chakra-ui/react
package.
import { PinInput } from "@chakra-ui/react"
const Demo = () => {
return (
<PinInput.Root>
<PinInput.Label>Enter your OTP</PinInput.Label>
<PinInput.HiddenInput />
<PinInput.Control>
{Array.from({ length: 4 }).map((_, index) => (
<PinInput.Input key={index} index={index} />
))}
</PinInput.Control>
</PinInput.Root>
)
}
Props
Root
Prop | Default | Type |
---|---|---|
placeholder | '\'â—‹\'' | string The placeholder text for the input |
type | '\'numeric\'' | 'numeric' | 'alphabetic' | 'alphanumeric' The type of value the pin-input should allow |
colorPalette | 'gray' | 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink' | 'accent' The color palette of the component |
size | 'md' | 'lg' | 'md' | 'sm' | 'xs' The size of the component |
variant | 'outline' | 'outline' | 'filled' | 'flushed' The variant of the component |
asChild | boolean Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
autoFocus | boolean Whether to auto-focus the first input. | |
blurOnComplete | boolean Whether to blur the input when the value is complete | |
defaultValue | string[] The initial value of the pin input when it is first rendered. Use when you do not need to control the state of the pin input | |
disabled | boolean Whether the inputs are disabled | |
form | string The associate form of the underlying input element. | |
id | string The unique identifier of the machine. | |
ids | Partial<{
root: string
hiddenInput: string
label: string
control: string
input(id: string): string
}> The ids of the elements in the pin input. Useful for composition. | |
invalid | boolean Whether the pin input is in the invalid state | |
mask | boolean If `true`, the input's value will be masked just like `type=password` | |
name | string The name of the input element. Useful for form submission. | |
onValueChange | (details: ValueChangeDetails) => void Function called on input change | |
onValueComplete | (details: ValueChangeDetails) => void Function called when all inputs have valid values | |
onValueInvalid | (details: ValueInvalidDetails) => void Function called when an invalid value is entered | |
otp | boolean If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | |
pattern | string The regular expression that the user-entered input value is checked against. | |
readOnly | boolean Whether the pin input is in the valid state | |
required | boolean Whether the pin input is required | |
selectOnFocus | boolean Whether to select input value when input is focused | |
translations | IntlTranslations Specifies the localized strings that identifies the accessibility elements and their states | |
value | string[] The value of the the pin input. |