Demos
How to import
import { PinCode } from '@fibrous/semi-ui-react';
Basic usage
Code
import { PinCode } from '@fibrous/semi-ui-react';
export default function PinCodeDemo() {
return (
<>
<PinCode
aria-label="Verification code, small"
size="small"
defaultValue="123456"
onComplete={(value) => console.log('pincode: ', value)}
onChange={(value) => {
console.log(value);
}}
/>
<br />
<PinCode
aria-label="Verification code, default"
size="default"
defaultValue="123456"
onComplete={(value) => console.log('pincode: ', value)}
onChange={(value) => {
console.log(value);
}}
/>
<br />
<PinCode
aria-label="Verification code, large"
size="large"
defaultValue="123456"
onComplete={(value) => console.log('pincode: ', value)}
onChange={(value) => {
console.log(value);
}}
/>
</>
);
}Controlled
Use value to pass in the verification code string and use it with onChange for controlled use
Code
import { useState } from 'react';
import { PinCode, Button } from '@fibrous/semi-ui-react';
export default function PinCodeDemo() {
const [value, setValue] = useState('69af41');
return (
<>
<Button onClick={() => setValue(String(Math.floor(Math.random() * 100000000)).slice(0, 6))}>Set Random Value</Button>
<br />
<br />
<PinCode
aria-label="Verification code"
format="mixed"
onComplete={(value) => console.log('pincode: ', value)}
value={value}
onChange={(v) => {
console.log(v);
setValue(v);
}}
/>
</>
);
}Limit verification code format
Set the number of digits
Set the number of digits through count, the default is 6 digits, the demo below is set to 4 digits
Code
import { PinCode } from '@fibrous/semi-ui-react';
export default function PinCodeDemo() {
return (
<>
<PinCode
aria-label="Verification code"
size="large"
defaultValue="6688"
count={4}
onComplete={(value) => console.log('pincode: ', value)}
onChange={(value) => {
console.log(value);
}}
/>
</>
);
}Set character range
Use format to control the character range that can be entered
- Pass "number" to only allow numbers
- Pass "mixed" to allow numbers and letters
- Pass in a regular expression to only allow characters that can be judged by the regular expression
- Pass in a function, and the verification code will be passed in as parameters in units of characters for verification when entering. When the function returns true, the character is allowed to be entered into the PinCode
字母和数字
只大写字母
只小写字母(函数判断)
Code
import { PinCode, Typography } from '@fibrous/semi-ui-react';
export default function PinCodeDemo() {
return (
<>
<Typography.Text id="pincode-format-number">纯数字</Typography.Text>
<PinCode aria-labelledby="pincode-format-number" format="number" onComplete={(value) => console.log('pincode: ', value)} />
<br />
<Typography.Text id="pincode-format-mixed">字母和数字</Typography.Text>
<PinCode aria-labelledby="pincode-format-mixed" format="mixed" onComplete={(value) => console.log('pincode: ', value)} />
<br />
<Typography.Text id="pincode-format-upper">只大写字母</Typography.Text>
<PinCode aria-labelledby="pincode-format-upper" format={/[A-Z]/} onComplete={(value) => console.log('pincode: ', value)} />
<br />
<Typography.Text id="pincode-format-lower">只小写字母(函数判断)</Typography.Text>
<PinCode
aria-labelledby="pincode-format-lower"
format={(char) => {
return /[a-z]/.test(char);
}}
onComplete={(value) => console.log('pincode: ', value)}
/>
</>
);
}Manual focus and blur
Use the focus and blur methods on Ref, and the input parameter is the serial number of the corresponding Input, counted from 0
Code
import { useState, useRef } from 'react';
import { PinCode, Button, type PinCodeHandle } from '@fibrous/semi-ui-react';
export default function PinCodeDemo() {
const [value, setValue] = useState('69af41');
const ref = useRef<PinCodeHandle>(null);
return (
<>
<Button onClick={() => ref.current?.focus(2)}>Focus Third Input</Button>
<br />
<br />
<PinCode
aria-label="Verification code"
format="mixed"
ref={ref}
onComplete={(value) => console.log('pincode: ', value)}
value={value}
onChange={(v) => {
console.log(v);
setValue(v);
}}
/>
</>
);
}API Reference
Props
| Property | Description | Type | Default |
|---|---|---|---|
| autoFocus | Whether the first input receives focus on mount. Turn it on only when the user has explicitly entered the code step, because focusing on page load makes screen readers skip earlier content. | boolean | false |
| className | Class name of the root element (role="group"). | string | - |
| count | Number of digits, which is also the number of inputs. | number | 6 |
| defaultValue | Initial content when uncontrolled. | string | - |
| disabled | Whether every input is disabled. | boolean | - |
| format | Format limit for a single character: number allows digits only, mixed allows digits and letters, and a regular expression or function judges each character, and a function allows the character by returning true. | Type'number' | 'mixed' | RegExp | ((value: string) => boolean) | "number" |
| onChange | Called when the content changes, with the current content as a string. | Type(value: string) => void | - |
| onComplete | Called once every digit is filled, with the current content as a string. | Type(value: string) => void | - |
| ref | Reference to the handle, through which the methods below are called. | TypeReact.Ref<PinCodeHandle> | - |
| size | Input size: large, default or small. Falls back to the default size of Input when omitted. | InputProps['size'] | - |
| style | Style of the root element. | React.CSSProperties | - |
| validateStatus | Validation status, passed to every input; error shows the error style. Form.PinCode injects it automatically. | InputProps['validateStatus'] | - |
| value | Input content. Passing it makes the component controlled, so update it in onChange. | string | - |
Methods
| Method | Description | Type |
|---|---|---|
| blur | Removes focus from the input at index; index starts from 0 and out-of-range values are ignored. | Type(index: number) => void |
| focus | Focuses the input at index with the caret after its character; index starts from 0 and out-of-range values are ignored. | Type(index: number) => void |
aria-label, aria-labelledby, data-* and other undeclared attributes land on the role="group" root element. onBlur fires once when focus leaves the whole code, not when it moves between input boxes. aria-describedby, aria-errormessage, aria-invalid, aria-required and tabIndex land on every input box. id lands on the first input box, and clicking the Form label focuses it. name, insetLabel and insetLabelId are discarded. onFocus passes through to the root element and fires whenever any input box gains focus; use onBlur to tell when focus leaves the whole code.
Accessibility
ARIA
- The root element is
role="group", named througharia-labeloraria-labelledby; passaria-labelwhen there is no visible label, otherwise the group has no name. - Each input box takes its accessible name from the locale, for example "Digit 1 of 6", which follows
countand the box index, so nothing needs to be set by hand. aria-describedby,aria-errormessage,aria-invalidandaria-requiredland on every input box;validateStatusis passed to every input box.- With
formatset to"number"the input boxes use the numeric soft keyboard (inputmode="numeric"); otherwise the text keyboard.
Keyboard and Focus
- Each box is its own input; after a valid character is entered, focus moves to the next box, and entering the last box blurs it. The filled characters always run from the first box without gaps, so a character typed after an empty box lands in the first empty box.
TabandShift+Tabmove between boxes. Left ArrowandRight Arrowmove focus between boxes.BackspaceandDeleteboth delete the character in the current box and the following characters move forward;Backspacealso moves focus to the previous box.- Pasting a whole code fills the boxes by character from the current box, and stops at the first invalid character.
autoFocus(autofocusin Vue) should be turned on only when the user has just entered the code step: focus moving at page load makes screen readers skip the content before it.