代码演示
如何引入
import { PinCode } from '@fibrous/semi-ui-react';
基本使用
代码
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);
}}
/>
</>
);
}受控
使用 value 传入验证码字符串,配合 onChange 受控使用
代码
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);
}}
/>
</>
);
}限制验证码格式
设置位数
通过 count 设置位数,默认 6 位,下方 Demo 设置为 4 位
代码
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);
}}
/>
</>
);
}设置字符范围
使用 format 控制可输入的字符范围
- 传入 "number" 只允许设置数字
- 传入 "mixed" 允许数字和字母
- 传入正则表达式,只允许输入可通过正则判定的字符
- 传入函数,验证码会在输入的时候以字符为单位被依次作为参数分别单独传入进行校验,当函数返回 true 时,允许该字符被输入进 PinCode
字母和数字
只大写字母
只小写字母(函数判断)
代码
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)}
/>
</>
);
}手动聚焦失焦
使用 Ref 上方法 focus 与 blur,入参为对应 Input 的序号,序号从 0 开始
代码
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 参考
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| autoFocus | 挂载时是否聚焦第一个输入框。只在用户明确进入验证码输入步骤时开启,页面加载时自动聚焦会让读屏跳过之前的内容。 | boolean | false |
| className | 根元素(role="group")的类名。 | string | - |
| count | 验证码位数,即输入框的个数。 | number | 6 |
| defaultValue | 非受控时的初始内容。 | string | - |
| disabled | 是否禁用所有输入框。 | boolean | - |
| format | 单个字符的格式限制:number 只允许数字,mixed 允许数字和字母,正则或函数按字符判定,函数返回 true 时允许该字符输入。 | Type'number' | 'mixed' | RegExp | ((value: string) => boolean) | "number" |
| onChange | 内容变化时调用,参数为当前内容的字符串。 | Type(value: string) => void | - |
| onComplete | 所有位数输入完毕时调用,参数为当前内容的字符串。 | Type(value: string) => void | - |
| ref | 句柄的引用,通过它调用下方 Methods 中的方法。 | TypeReact.Ref<PinCodeHandle> | - |
| size | 输入框大小,可选 large、default 或 small。未设置时使用 Input 的默认尺寸。 | InputProps['size'] | - |
| style | 根元素的样式。 | React.CSSProperties | - |
| validateStatus | 校验状态,传给每个输入框;error 时显示错误样式。Form.PinCode 会自动注入。 | InputProps['validateStatus'] | - |
| value | 输入框内容。传入即为受控,需配合 onChange 更新。 | string | - |
Methods
| 方法 | 说明 | 类型 |
|---|---|---|
| blur | 移出第 index 位输入框的焦点;序号从 0 开始,超出范围时忽略。 | Type(index: number) => void |
| focus | 聚焦第 index 位输入框,光标放在该位字符之后;序号从 0 开始,超出范围时忽略。 | Type(index: number) => void |
aria-label、aria-labelledby、data-* 与其余未声明的属性落在根元素(role="group")上,onBlur 只在焦点离开整个验证码时触发一次,格子之间移动时不触发。aria-describedby、aria-errormessage、aria-invalid、aria-required、tabIndex 落在每个输入框上。id 落在第一个输入框上,Form 的 label 点击后聚焦它。name、insetLabel、insetLabelId 被丢弃。onFocus 经透传落在根元素上,每格获得焦点都会触发,需要判断焦点是否离开整个验证码时用 onBlur。
Accessibility
ARIA
- 根元素为
role="group",名称通过aria-label或aria-labelledby提供;没有可见标签时请传aria-label,否则分组没有名称。 - 每格输入框的可访问名称来自语言包,形如「第 1 位,共 6 位」,随
count与格子序号变化,无需手动设置。 aria-describedby、aria-errormessage、aria-invalid、aria-required落在每个输入框上;validateStatus传给每个输入框。format为"number"时输入框使用数字软键盘(inputmode="numeric"),其余为文本键盘。
键盘和焦点
- 每个格子是独立的输入框,输入一个合法字符后焦点移到下一格,在最后一格输入后失焦;已填内容总是从第一格起连续,在空格子之后输入的字符落在第一个空格子上。
Tab与Shift+Tab在格子之间切换。 左箭头、右箭头在格子之间移动焦点;Backspace与Delete都删除当前格字符,后面的字符依次前移,Backspace还会把焦点移到上一格。- 粘贴整段验证码时,从当前格起按字符依次填入各格,遇到不合法字符即停止。
autoFocus(Vue 为autofocus)只在用户明确进入验证码输入步骤时开启,页面加载时自动聚焦会让读屏跳过之前的内容。