From 5469f6c846b9ac8f039886a32df5897731e7c5b6 Mon Sep 17 00:00:00 2001 From: nite-knite Date: Tue, 16 Sep 2025 21:25:34 +0800 Subject: [PATCH 1/3] feat: remove leading zeros in number input --- web/app/components/base/input/index.tsx | 27 +++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/web/app/components/base/input/index.tsx b/web/app/components/base/input/index.tsx index 63ba0e89af..fd4a888e2b 100644 --- a/web/app/components/base/input/index.tsx +++ b/web/app/components/base/input/index.tsx @@ -1,4 +1,4 @@ -import type { CSSProperties } from 'react' +import type { CSSProperties, ChangeEventHandler } from 'react' import React from 'react' import { useTranslation } from 'react-i18next' import { RiCloseCircleFill, RiErrorWarningLine, RiSearchLine } from '@remixicon/react' @@ -46,11 +46,33 @@ const Input = ({ value, placeholder, onChange = noop, + onBlur = noop, unit, ref, ...props }: InputProps) => { const { t } = useTranslation() + const handleNumberChange: ChangeEventHandler = (e) => { + if (value === 0) { + // remove leading zeros + const formattedValue = e.target.value.replace(/^(-?)0+(?=\d)/, '$1') + if (e.target.value !== formattedValue) + e.target.value = formattedValue + } + onChange(e) + } + const handleNumberCommit: React.FocusEventHandler = (e) => { + // remove leading zeros + const formattedValue = e.target.value.replace(/^(-?)0+(?=\d)/, '$1') + if (e.target.value !== formattedValue) { + e.target.value = formattedValue + onChange({ + ...e, + type: 'change', + }) + } + onBlur(e) + } return (
{showLeftIcon && } @@ -74,7 +96,8 @@ const Input = ({ ? (t('common.operation.search') || '') : (t('common.placeholder.input') || ''))} value={value} - onChange={onChange} + onChange={props.type === 'number' ? handleNumberChange : onChange} + onBlur={props.type === 'number' ? handleNumberCommit : onBlur} disabled={disabled} {...props} /> From 496f87e028f44670a41d60d9b9307a8fdb5e4c48 Mon Sep 17 00:00:00 2001 From: nite-knite Date: Tue, 16 Sep 2025 21:29:55 +0800 Subject: [PATCH 2/3] chore: clean up --- web/app/components/base/input/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/app/components/base/input/index.tsx b/web/app/components/base/input/index.tsx index fd4a888e2b..68db39d687 100644 --- a/web/app/components/base/input/index.tsx +++ b/web/app/components/base/input/index.tsx @@ -1,4 +1,4 @@ -import type { CSSProperties, ChangeEventHandler } from 'react' +import type { CSSProperties, ChangeEventHandler, FocusEventHandler } from 'react' import React from 'react' import { useTranslation } from 'react-i18next' import { RiCloseCircleFill, RiErrorWarningLine, RiSearchLine } from '@remixicon/react' @@ -61,7 +61,7 @@ const Input = ({ } onChange(e) } - const handleNumberCommit: React.FocusEventHandler = (e) => { + const handleNumberBlur: FocusEventHandler = (e) => { // remove leading zeros const formattedValue = e.target.value.replace(/^(-?)0+(?=\d)/, '$1') if (e.target.value !== formattedValue) { @@ -97,7 +97,7 @@ const Input = ({ : (t('common.placeholder.input') || ''))} value={value} onChange={props.type === 'number' ? handleNumberChange : onChange} - onBlur={props.type === 'number' ? handleNumberCommit : onBlur} + onBlur={props.type === 'number' ? handleNumberBlur : onBlur} disabled={disabled} {...props} /> From 4f3abc3ae5efd578af10b991a9e6d1cf9ed57a1d Mon Sep 17 00:00:00 2001 From: nite-knite Date: Tue, 16 Sep 2025 21:37:57 +0800 Subject: [PATCH 3/3] chore: extract regex logic --- web/app/components/base/input/index.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/web/app/components/base/input/index.tsx b/web/app/components/base/input/index.tsx index 68db39d687..881aa1d610 100644 --- a/web/app/components/base/input/index.tsx +++ b/web/app/components/base/input/index.tsx @@ -33,6 +33,8 @@ export type InputProps = { ref?: React.Ref } & Omit, 'size'> & VariantProps +const removeLeadingZeros = (value: string) => value.replace(/^(-?)0+(?=\d)/, '$1') + const Input = ({ size, disabled, @@ -55,7 +57,7 @@ const Input = ({ const handleNumberChange: ChangeEventHandler = (e) => { if (value === 0) { // remove leading zeros - const formattedValue = e.target.value.replace(/^(-?)0+(?=\d)/, '$1') + const formattedValue = removeLeadingZeros(e.target.value) if (e.target.value !== formattedValue) e.target.value = formattedValue } @@ -63,12 +65,16 @@ const Input = ({ } const handleNumberBlur: FocusEventHandler = (e) => { // remove leading zeros - const formattedValue = e.target.value.replace(/^(-?)0+(?=\d)/, '$1') + const formattedValue = removeLeadingZeros(e.target.value) if (e.target.value !== formattedValue) { e.target.value = formattedValue onChange({ ...e, type: 'change', + target: { + ...e.target, + value: formattedValue, + }, }) } onBlur(e)