@xsolla/xui-input-pin
v0.162.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-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 |
| :------------------ | :----------------------------------------- | :------ | :------------------------------------------------------------------------------------------------------------ |
| testID | string | — | Test ID for testing frameworks. On web this renders as data-testid; on React Native it renders as testID. |
| 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
