”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 让我们用 React 创建一个更好的数字输入

让我们用 React 创建一个更好的数字输入

发布于2024-11-06
浏览:119

HTML 输入的可怕。关于此输入的投诉很多。

数字输入问题

  • 不一致。不同的浏览器对它们的处理方式不同。您只能在基于 Chromium 的浏览器中输入数字。但是您可以在 Firefox 和 Safari 中输入任何符号,尽管它们会显示错误弹出窗口。

  • 复杂。有效数字不仅仅是数字。数字输入允许负数(-100)和浮点(0.01)值,以及科学记数法(-2.3e4)。这有时很有帮助,但并非每次都有。

  • 意外行为。数字输入不会报告它认为无效的值。相反,会报告空白字符串。此外,具有比步骤属性更多有效数字的值被视为无效。

幸运的是,HTML 允许我们解决大部分此类问题。那么让我们创建一个更好的数字输入。以下是要支持的基本功能的列表。

数字输入功能

  • 在所有现代浏览器中一致地验证用户输入。

  • 设置屏幕键盘的十进制输入模式

  • 按下向上或向下键时可以递增和递减。

设置输入属性

首先,我们应用本机输入属性以使其按我们想要的方式运行。我将使用模式属性来清理用户的文本输入。

可用图案

  • (?:0|[1-9]\d*) - 只允许数字,1234567890

  • [ \-]?(?:0|[1-9]\d*) - 允许正整数和负整数,例如1, -2, 3

  • [ \-]?(?:0|[1-9]\d*)(?:\.\d )? - 允许浮动整数,例如1.001, -123.9

  • [ \-]?(?:0|[1-9]\d*)(?:\.\d )?(?:[eE][ \-]?\d )? - 允许科学记数法,例如-1.314e12

现在我们的 HTML 应该是这样的。

                

inputMode="decimal" 为触摸设备设置正确的键盘。

Let

autoComplete="off" 需要禁用烦人的浏览器自动完成功能,通常类似名称的输入需要此类功能。

反应组件接口

// List of available numeric modes
enum Modes {
    natural = 'natural',
    integer = 'integer',
    floating = 'floating',
    scientific = 'scientific',
}

type Value = string;

export type Props = {
    /** Set controlled value */
    value?: Value;
    /** Provide a callback to capture changes */
    onChange?: (value?: Value) => void;
    /**
     * Define a number to increase or decrease input value
     * when user clicks arrow keys
     */
    step?: number;
    /** Set a maximum value available for arrow stepping */
    max?: number;
    /** Set a minimum value available for arrow stepping */
    min?: number;
    /** Select a mode of numeric input */
    mode?: keyof typeof Modes;
};

export const InputNumeric: FC = ({
    value,
    step = 1,
    max = Infinity,
    min = -Infinity,
    onChange = () => {},
    mode = Modes.scientific,
}) => {
    //...
}

现在我们需要根据模式设置来管理pattern属性。

const patternMapping = {
    [Modes.natural]: '(?:0|[1-9]\\d*)',
    [Modes.integer]: '[ \\-]?(?:0|[1-9]\\d*)',
    [Modes.floating]: '[ \\-]?(?:0|[1-9]\\d*)(?:\\.\\d )?',
    [Modes.scientific]: '[ \\-]?(?:0|[1-9]\\d*)(?:\\.\\d )?(?:[eE][ \\-]?\\d )?',
};

const pattern = patternMapping[mode];

Let

处理击键

这是如何处理箭头键按下的情况。

const handleKeyDown = useCallback(
    (event: KeyboardEvent) => {
        const inputValue = (event.target as HTMLInputElement).value;
        // handle increment
        if (event.key === 'ArrowUp') {
            // empty input value has to be normalized to zero
            const nextValue = Number(inputValue || 0)   step;
            if (nextValue = min) {
                onChange(nextValue.toString());
            }
        }
    },
    [max, min, onChange, step]
);

用户输入验证

我们将通过输入边框颜色和输入下方的选项提示通知用户预期的数字格式违规。

Let

我们将使用 Tailwind CSS 来创建此设计和错误报告功能。

同级类名是为下面的输入错误消息创建 CSS 选择器所必需的。 invalid:border-red-600 类名在输入无效时用红色绘制边框。

invisible 类默认设置提示消息的visibility:hidden。 peer-[:invalid]:visible 类解包到以下选择器 .peer:invalid ~ .peer-\[\:invalid\]\:visible ,这使得提示在 input.peer 前面处于 :invalid 状态时可见。

export const InputNumeric: FC = () => {
    const id = useId();
    return (
        
Please provide valid decimal number
); }

这是完整的数字输入代码:

编码愉快!

版本声明 本文转载于:https://dev.to/morewings/lets-create-a-better-number-input-with-react-1j0m?1如有侵犯,请联系[email protected]删除
最新教程 更多>

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3