@xsolla/xui-input-pin
v0.108.0
Published
A cross-platform React PIN/OTP input component with individual cells for each digit. Features auto-advance between cells, paste support, and completion callbacks.
Readme
Input Pin
A cross-platform React PIN/OTP input component with individual cells for each digit. Features auto-advance between cells, paste support, and completion callbacks.
Installation
npm install @xsolla/xui-input-pin
# or
yarn add @xsolla/xui-input-pinDemo
Basic PIN Input
import * as React from 'react';
import { InputPin } from '@xsolla/xui-input-pin';
export default function BasicPinInput() {
const handleComplete = ({ value, isComplete }) => {
if (isComplete) {
console.log('PIN entered:', value);
}
};
return (
<InputPin
codeLength={4}
onComplete={handleComplete}
/>
);
}Six-Digit Code
import * as React from 'react';
import { InputPin } from '@xsolla/xui-input-pin';
export default function SixDigitPin() {
return (
<InputPin
codeLength={6}
label="Enter verification code"
onComplete={({ value }) => console.log('Code:', value)}
/>
);
}Controlled PIN Input
import * as React from 'react';
import { InputPin } from '@xsolla/xui-input-pin';
export default function ControlledPinInput() {
const [pin, setPin] = React.useState('');
return (
<div>
<InputPin
value={pin}
codeLength={4}
onChange={({ value }) => setPin(value)}
/>
<p>Current value: {pin}</p>
</div>
);
}Secure Entry
import * as React from 'react';
import { InputPin } from '@xsolla/xui-input-pin';
export default function SecurePinInput() {
return (
<InputPin
codeLength={4}
secureTextEntry={true}
label="Enter your PIN"
/>
);
}Anatomy
import { InputPin } from '@xsolla/xui-input-pin';
<InputPin
value={pinValue} // Controlled value
onChange={handleChange} // Change handler with {value, isComplete}
onComplete={handleComplete} // Called when all digits entered
codeLength={4} // Number of digits
size="md" // Size variant
label="Label" // Label above input
secureTextEntry={false} // Hide entered digits
showPlaceholderDots={true} // Show dot placeholders
flexibleWidth={false} // Expand cells to fill width
disabled={false} // Disabled state
error={false} // Error state
errorMessage="Error" // Error message text
/>Examples
Full Width
import * as React from 'react';
import { InputPin } from '@xsolla/xui-input-pin';
export default function FullWidthPin() {
return (
<div style={{ width: 300 }}>
<InputPin
codeLength={6}
flexibleWidth={true}
label="Verification Code"
/>
</div>
);
}With Error
import * as React from 'react';
import { InputPin } from '@xsolla/xui-input-pin';
export default function ErrorPinInput() {
return (
<InputPin
codeLength={4}
error={true}
errorMessage="Invalid PIN. Please try again."
label="Enter PIN"
/>
);
}PIN Input Sizes
import * as React from 'react';
import { InputPin } from '@xsolla/xui-input-pin';
export default function PinInputSizes() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>
<InputPin size="xs" codeLength={4} />
<InputPin size="sm" codeLength={4} />
<InputPin size="md" codeLength={4} />
<InputPin size="lg" codeLength={4} />
<InputPin size="xl" codeLength={4} />
</div>
);
}API Reference
InputPin
InputPin Props:
| Prop | Type | Default | Description |
| :--- | :--- | :------ | :---------- |
| value | string | "" | Current PIN value. |
| onChange | (props: OnInputPinCompleteProps) => void | - | Called on every change. |
| onComplete | (props: OnInputPinCompleteProps) => void | - | Called when all digits entered. |
| codeLength | number | 4 | Number of PIN digits. |
| size | "xl" \| "lg" \| "md" \| "sm" \| "xs" | "md" | Component size. |
| label | string | - | Label above input. |
| secureTextEntry | boolean | false | Hide entered digits. |
| showPlaceholderDots | boolean | true | Show dot placeholders. |
| flexibleWidth | boolean | false | Expand cells to fill container. |
| disabled | boolean | false | Disabled state. |
| error | boolean | false | Error state. |
| errorMessage | string | - | Error message text. |
| testID | string | - | Test identifier. |
| aria-label | string | - | Accessible label for screen readers. |
OnInputPinCompleteProps:
interface OnInputPinCompleteProps {
isComplete: boolean; // Whether all digits are filled
value: string; // Current PIN value
}Keyboard Navigation
| Key | Action | | :-- | :----- | | 0-9, A-Z | Enter character and advance | | Backspace | Clear current cell and move back | | Arrow Left | Move to previous cell | | Arrow Right | Move to next cell | | Ctrl/Cmd + V | Paste and auto-fill cells |
Behavior
- Auto-advances to next cell after input
- Supports paste to fill multiple cells
- Backspace clears current or moves to previous
- Only alphanumeric characters are accepted
- Uses
inputMode="numeric"for mobile keyboards
Accessibility
- Each cell has
aria-labelindicating digit position role="group"on container witharia-labelledbyaria-invalidwhen in error state- Error messages linked via
aria-describedby
