Design System

PinInput

Pin inputs are specialized input components designed for entering a sequence of characters, typically used for verification codes, PIN numbers, or other short sequences.

Design guidance

When and how to use this

Use a PinInput when the user needs to enter a short sequence of characters, such as:

  • One-time verification codes
  • PIN numbers
  • Security codes
  • ZIP/postal codes
  • Authentication tokens

The PinInput provides a focused, dedicated input experience that makes it clear to users they're entering a specific format.

When to consider something else

For longer free-form text input, use a TextInput instead. If the user needs to enter sensitive information that should be masked, consider using a PasswordInput with appropriate security measures.


React

The PinInput component provides a focused experience for entering sequences of characters with automatic focus management between fields.

live

<Stack spacing="600">
<VStack align="start" spacing="400">
<Label>Default</Label>
<HStack align="start" spacing="400">
<PinInput>
<PinInputField />
<PinInputField />
<PinInputField />
<PinInputField />
</PinInput>
</HStack>
</VStack>
<VStack align="start" spacing="400">
<Label>Custom placeholder</Label>
<HStack align="start" spacing="400">
<PinInput placeholder="🤯">
<PinInputField />
<PinInputField />
<PinInputField />
<PinInputField />
</PinInput>
</HStack>
</VStack>
<VStack align="start" spacing="400">
<Label>With Error State</Label>
<HStack align="start" spacing="400">
<PinInput isInvalid>
<PinInputField />
<PinInputField />
<PinInputField />
<PinInputField />
</PinInput>
</HStack>
</VStack>
<VStack align="start" spacing="400">
<Label>Disabled State</Label>
<HStack align="start" spacing="400">
<PinInput isDisabled>
<PinInputField />
<PinInputField />
<PinInputField />
<PinInputField />
</PinInput>
</HStack>
</VStack>
<VStack align="start" spacing="400">
<Label>Different sizes</Label>
<HStack>
<Label size="small">Tiny:</Label>
<PinInput size="tiny">
<PinInputField />
<PinInputField />
</PinInput>
</HStack>
<HStack>
<Label size="small">Small:</Label>
<PinInput size="small">
<PinInputField />
<PinInputField />
</PinInput>
</HStack>
<HStack>
<Label size="small">Default:</Label>
<PinInput size="default">
<PinInputField />
<PinInputField />
</PinInput>
</HStack>
</VStack>
</Stack>

Usage

The PinInput component ships with all the features you'd expect:

  • Automatic focus management between fields
  • Support for various input types (numeric, alphanumeric)
  • Paste support across multiple fields
  • Accessibility features
  • Custom styling options

Basic Usage


<PinInput>
<PinInputField />
<PinInputField />
<PinInputField />
<PinInputField />
</PinInput>

Props

PinInput Props

PropTypeDefaultDescription
autoFocusbooleanfalseIf true, the first input will be focused on mount
isDisabledbooleanfalseIf true, all inputs will be disabled
isInvalidbooleanfalseIf true, all inputs will have error styling
manageFocusbooleantrueIf true, focus will move automatically to the next input once filled
maskbooleanfalseIf true, input characters are masked (●)
onCompletefunctionFunction called when all inputs have been filled
onChangefunctionFunction called when any input value changes
otpbooleanfalseIf true, adds the "one-time-code" autocomplete value
placeholderstringPlaceholder for each input field
size'default', 'small', 'tiny''default'Size of inputs
type'alphanumeric', 'number''number'The type of values the pin input should allow
valuestringThe value of the pin input

PinInputField Props

The PinInputField component extends Blueprint's Input component, so all Input props are supported.

Examples

With Controlled Values


function Example() {
const [value, setValue] = React.useState('');
return (
<HStack>
<PinInput value={value} onChange={setValue}>
<PinInputField />
<PinInputField />
<PinInputField />
<PinInputField />
</PinInput>
</HStack>
);
}

Alphanumeric Input


<PinInput type="alphanumeric">
<PinInputField />
<PinInputField />
<PinInputField />
<PinInputField />
</PinInput>

With Completion Handler


<PinInput onComplete={(value) => console.log(value)}>
<PinInputField />
<PinInputField />
<PinInputField />
<PinInputField />
</PinInput>

Masked Input


<PinInput mask>
<PinInputField />
<PinInputField />
<PinInputField />
<PinInputField />
</PinInput>

Accessibility

  • When a value is added to an input, focus automatically moves to the next input
  • When a value is removed, focus moves to the previous input
  • The component is keyboard navigable, allowing users to use the Tab key to move between inputs
  • The component supports screen readers, providing appropriate ARIA roles and properties

For optimal accessibility, always include appropriate labeling to describe what the user is entering, such as "Verification code" or "PIN number".


Copyright © 2025 Hover Inc. All Rights Reserved.