输入类

验证码输入

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

代码演示

如何引入

import { Button, PinCode, Typography } from '@fibrous/semi-ui-solid';

基本使用



代码
import { PinCode } from '@fibrous/semi-ui-solid';

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 { createSignal } from 'solid-js';
import { Button, PinCode } from '@fibrous/semi-ui-solid';

export default function PinCodeDemo() {
    const [value, setValue] = createSignal('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={(code) => console.log('pincode: ', code)}
                value={value()}
                onChange={(code) => {
                    console.log(code);
                    setValue(code);
                }}
            />
        </>
    );
}

限制验证码格式

设置位数

通过 count 设置位数,默认 6 位,下方 Demo 设置为 4 位

代码
import { PinCode } from '@fibrous/semi-ui-solid';

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-solid';

const isLowerCase = (char: string) => /[a-z]/.test(char);

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={isLowerCase} onComplete={(value) => console.log('pincode: ', value)} />
        </>
    );
}

手动聚焦失焦

ref 指向分组根元素(role="group")。调用 focus() 聚焦第一个空格,全部填满时聚焦最后一格;调用 blur() 移出焦点。目前不能按序号聚焦某一格,需要时直接取根元素下的输入框,例如 ref.querySelectorAll('input')[2].focus() 聚焦第三格,序号从 0 开始。



代码
import { createSignal } from 'solid-js';
import { Button, PinCode } from '@fibrous/semi-ui-solid';

export default function PinCodeDemo() {
    const [value, setValue] = createSignal('69af41');
    let pinCode: HTMLDivElement | undefined;
    return (
        <>
            <Button onClick={() => pinCode?.querySelectorAll<HTMLInputElement>('input').item(2)?.focus()}>Focus Third Input</Button>
            <br />
            <br />
            <PinCode
                aria-label="Verification code"
                format="mixed"
                ref={(node) => (pinCode = node)}
                onComplete={(code) => console.log('pincode: ', code)}
                value={value()}
                onChange={(code) => {
                    console.log(code);
                    setValue(code);
                }}
            />
        </>
    );
}

API 参考

Props

属性说明类型默认值
count验证码位数。number6
defaultValue非受控时的初始内容。string-
disabled是否禁用。boolean-
format单个字符的格式限制:number 只允许数字,mixed 允许数字和字母,正则或函数按字符判定。Type'number' | 'mixed' | RegExp | ((value: string) => boolean)"number"
onBlur焦点离开整个验证码时调用,参数为原生 FocusEvent。Type(e: FocusEvent) => void-
onChange内容变化时调用,参数为当前内容。Type(value: string) => void-
onComplete所有位数输入完毕时调用,参数为当前内容。Type(value: string) => void-
onFocus焦点进入整个验证码时调用,参数为原生 FocusEvent;在输入框之间移动不调用。Type(e: FocusEvent) => void-
size输入框大小,可选 large、default、small。InputSize-
validateStatus校验状态,传给每个输入框;error 时显示错误样式。ValidateStatus-
value输入框内容。传入即为受控,需配合 onChange 更新。string-

class、style、aria-label、aria-labelledby、data-* 落在 role="group" 的根元素上。id 落在第一个输入框上,<label for> 指向第一格。aria-describedby、aria-errormessage、aria-invalid、aria-required、tabindex 落在每个输入框上。name 被丢弃。autofocus 挂载时聚焦第一个输入框,默认 false,只在用户明确进入验证码输入步骤时开启。

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)只在用户明确进入验证码输入步骤时开启,页面加载时自动聚焦会让读屏跳过之前的内容。

属性名写作 autofocus,行为同上。