输入类

验证码输入

用于便捷直观地输入验证码

代码演示

如何引入

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挂载时是否聚焦第一个输入框。只在用户明确进入验证码输入步骤时开启,页面加载时自动聚焦会让读屏跳过之前的内容。booleanfalse
className根元素(role="group")的类名。string-
count验证码位数,即输入框的个数。number6
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)只在用户明确进入验证码输入步骤时开启,页面加载时自动聚焦会让读屏跳过之前的内容。