npm install input-otpimport {
InputOTPGroup as GroupPrimitive,
InputOTPRoot as RootPrimitive,
InputOTPSeparator as SeparatorPrimitive,
InputOTPSlot as SlotPrimitive,
} from '@pallas-ui/input-otp'
import type { InputOTPProps } from '@pallas-ui/input-otp'
import { type Assign, createStyleContext } from '@pallas-ui/style-context'
import { type InputOTPVariantProps, inputOTP } from '@styled-system/recipes'
import type { JsxStyleProps } from '@styled-system/types'
import type { ComponentProps } from 'react'
import type React from 'react'
const { withProvider, withContext } = createStyleContext(inputOTP)
// root component
type RootProps = Assign<JsxStyleProps, InputOTPProps>
const InputOTPRoot = withProvider<
React.ComponentRef<typeof RootPrimitive>,
RootProps & InputOTPVariantProps
>(RootPrimitive, 'root')
// group component
type GroupProps = Assign<JsxStyleProps, ComponentProps<typeof GroupPrimitive>>
const InputOTPGroup = withContext<React.ComponentRef<typeof GroupPrimitive>, GroupProps>(
GroupPrimitive,
'group',
)
// slot component
const InputOTPSlot = withContext<
React.ComponentRef<typeof SlotPrimitive>,
React.ComponentProps<typeof SlotPrimitive>
>(SlotPrimitive, 'slot')
// separator component
const InputOTPSep = withContext<
React.ComponentRef<typeof SeparatorPrimitive>,
React.ComponentProps<typeof SeparatorPrimitive>
>(SeparatorPrimitive, 'separator')
// compose the InputOTP object
export default {
Root: InputOTPRoot,
Group: InputOTPGroup,
Slot: InputOTPSlot,
Separator: InputOTPSep,
}import { Input } from '@/components/ui/input-otp'
// Basic otp input
<InputOTP.Root maxLength={6}>
<InputOTP.Group>
<InputOTP.Slot index={0} />
<InputOTP.Slot index={1} />
<InputOTP.Slot index={2} />
</InputOTP.Group>
<InputOTP.Separator />
<InputOTP.Group>
<InputOTP.Slot index={3} />
<InputOTP.Slot index={4} />
<InputOTP.Slot index={5} />
</InputOTP.Group>
</InputOTP.Root>The root element that wraps the entire component.
| Property | Type | Default | Description | Options |
|---|---|---|---|---|
styling | string | box | Visual style of the otp input field | box, filled, underlined, borderless |
slotSize | string | md | Size of the slots | sm, md, lg |
shape | string | default | Shape of the slots | default, rounded |
maxLength | number | 6 | Number of slots/size of input | - |
pattern | string | ^[a-zA-Z0-9]*$ | Regular expression to specify pattern of input code | - |
dataStatus | string | none | Validation state of the input | none, success, error, warning |
disabled | boolean | - | Disabled state of the input | true, false |
placeholder | string | - | Specify a custom placeholder in the slots | - |
InputOTP.Root also accepts props by the OTPInput component from input-otp:
| Property | Type | Default | Description | Options |
|---|---|---|---|---|
value | string | - | Controlled value | - |
onChange | (newValue:string) => unknown | - | Change handler | - |
onComplete | (...args:any[])=> unknown | - | Called when the input is complete | - |
textAlign | string | left | WText alignment | left, center, right |
inputMode | string | numeric | Mobile keyboard type | numeric, text, decimal, tel, search, email, url |
pasteTransformer | (pastedText:string)=> string | - | Paste transform function | - |
pushPassword-ManagerStrategy | string | increase-width | Password manager badge strategy | increase-width, none |
noScriptCSS-Fallback | string | - | Fallback for no-JS pages | - |
The group wrapper element that wraps multiple slots.
The slot element that represents each individual character input.
| Property | Type | Default | Description | Options |
|---|---|---|---|---|
index | number | - | Index of the slot | - |
A separator element that visually separates groups of slots.