diff --git a/.changeset/cool-melons-bathe.md b/.changeset/cool-melons-bathe.md new file mode 100644 index 0000000000..dc951b0bd9 --- /dev/null +++ b/.changeset/cool-melons-bathe.md @@ -0,0 +1,5 @@ +--- +'@alfalab/core-components-input': minor +--- + +Запрещен ввод и вставка символов `[eE]` в input[type=number] diff --git a/packages/input/src/components/base-input/Component.tsx b/packages/input/src/components/base-input/Component.tsx index 5415a1fe69..03c8a62599 100644 --- a/packages/input/src/components/base-input/Component.tsx +++ b/packages/input/src/components/base-input/Component.tsx @@ -5,6 +5,7 @@ import React, { Fragment, HTMLAttributes, InputHTMLAttributes, + KeyboardEvent, MouseEvent, ReactNode, RefAttributes, @@ -268,6 +269,7 @@ export const BaseInput = React.forwardRef( }, ref, ) => { + const { onKeyDown } = restProps; const uncontrolled = value === undefined; const readOnly = readOnlyProp || disableUserInput; @@ -327,17 +329,50 @@ export const BaseInput = React.forwardRef( const handleInputChange = useCallback( (event: React.ChangeEvent) => { + let inputValue = event.target.value; + const target = event.target as HTMLInputElement; + const isInputTypeNumber = target.getAttribute('type') === 'number'; + const pattern = /[eE]/g; + + if (isInputTypeNumber && pattern.test(inputValue)) { + inputValue = inputValue.replace(pattern, ''); + } + if (onChange) { - onChange(event, { value: event.target.value }); + onChange(event, { value: inputValue }); } if (uncontrolled) { - setStateValue(event.target.value); + setStateValue(inputValue); } }, [onChange, uncontrolled], ); + const handleKeyDown = useCallback( + (event: KeyboardEvent) => { + /** + * По умолчанию в input[type=number] можно вводить числа типа 2e5 (200 000) + * Это ломает некоторое поведение, поэтому запрещаем ввод символов [eE] + * @see DS-6808 + */ + const { key, target } = event; + const eventTarget = target as HTMLInputElement; + const isInputTypeNumber = eventTarget.getAttribute('type') === 'number'; + + if (isInputTypeNumber && (key === 'e' || key === 'E')) { + event.preventDefault(); + + return; + } + + if (onKeyDown) { + onKeyDown(event); + } + }, + [onKeyDown], + ); + const handleClear = useCallback( (event: MouseEvent) => { if (!clearButtonVisible) return; @@ -457,6 +492,7 @@ export const BaseInput = React.forwardRef( onBlur={handleInputBlur} onFocus={handleInputFocus} onChange={handleInputChange} + onKeyDown={handleKeyDown} onAnimationStart={handleAnimationStart} ref={mergeRefs([ref, inputRef])} type={type}