From b93312c68749e74c2e16605724802cc17c9da4bc Mon Sep 17 00:00:00 2001 From: GoldGroove06 <73437174+GoldGroove06@users.noreply.github.com> Date: Fri, 26 Sep 2025 16:48:00 +0530 Subject: [PATCH 1/8] add: smallStep, snapOnStep --- .../fragments/NumberFieldDecrement.tsx | 2 +- .../fragments/NumberFieldIncrement.tsx | 2 +- .../fragments/NumberFieldInput.tsx | 4 ++-- .../NumberField/fragments/NumberFieldRoot.tsx | 24 +++++++++++++++---- .../stories/NumberField.stories.tsx | 2 +- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/components/ui/NumberField/fragments/NumberFieldDecrement.tsx b/src/components/ui/NumberField/fragments/NumberFieldDecrement.tsx index d578a5ad9..80d7af3c1 100644 --- a/src/components/ui/NumberField/fragments/NumberFieldDecrement.tsx +++ b/src/components/ui/NumberField/fragments/NumberFieldDecrement.tsx @@ -15,7 +15,7 @@ const NumberFieldDecrement = forwardRef handleStep({ direction: 'decrement', type: 'small' })} + onClick={() => handleStep({ direction: 'decrement', type: 'normal' })} className={clsx(`${rootClass}-decrement`, className)} disabled={disabled || readOnly} type="button" diff --git a/src/components/ui/NumberField/fragments/NumberFieldIncrement.tsx b/src/components/ui/NumberField/fragments/NumberFieldIncrement.tsx index 3cbd34033..8c2a2c609 100644 --- a/src/components/ui/NumberField/fragments/NumberFieldIncrement.tsx +++ b/src/components/ui/NumberField/fragments/NumberFieldIncrement.tsx @@ -16,7 +16,7 @@ const NumberFieldIncrement = forwardRef handleStep({ direction: 'increment', type: 'small' })} + onClick={() => handleStep({ direction: 'increment', type: 'normal' })} className={clsx(`${rootClass}-increment`, className)} disabled={disabled || readOnly} type="button" diff --git a/src/components/ui/NumberField/fragments/NumberFieldInput.tsx b/src/components/ui/NumberField/fragments/NumberFieldInput.tsx index b52c20bbf..e5374fde5 100644 --- a/src/components/ui/NumberField/fragments/NumberFieldInput.tsx +++ b/src/components/ui/NumberField/fragments/NumberFieldInput.tsx @@ -26,11 +26,11 @@ const NumberFieldInput = forwardRef) => { if (event.key === 'ArrowUp' && !event.shiftKey) { event.preventDefault(); - handleStep({ direction: 'increment', type: 'small' }); + handleStep({ direction: 'increment', type: 'normal' }); } if (event.key === 'ArrowDown' && !event.shiftKey) { event.preventDefault(); - handleStep({ direction: 'decrement', type: 'small' }); + handleStep({ direction: 'decrement', type: 'normal' }); } if (event.key === 'ArrowUp' && event.shiftKey) { event.preventDefault(); diff --git a/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx b/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx index 0110ce7b2..38b04a13a 100644 --- a/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx +++ b/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx @@ -14,6 +14,8 @@ export type NumberFieldRootProps = { onValueChange?: (value: number | '') => void step?: number largeStep?: number + smallStep?: number + snapOnStep?: boolean min?: number max?: number disabled?: boolean @@ -21,7 +23,7 @@ export type NumberFieldRootProps = { required?: boolean } & ComponentPropsWithoutRef<'div'>; -const NumberFieldRoot = forwardRef(({ children, name, defaultValue = '', value, onValueChange, largeStep, step, min, max, disabled, readOnly, required, id, className, ...props }, ref) => { +const NumberFieldRoot = forwardRef(({ children, name, defaultValue = '', value, onValueChange, largeStep = 10, step = 1, smallStep = 0.1, snapOnStep = false, min, max, disabled, readOnly, required, id, className, ...props }, ref) => { const rootClass = customClassSwitcher(className, COMPONENT_NAME); const [inputValue, setInputValue] = useControllableState( value, @@ -55,7 +57,14 @@ const NumberFieldRoot = forwardRef temp = -1; } } - const nextValue = temp + amount; + + const tempDec = (temp.toString().split('.')[1] || '').length; + const amountDec = (amount.toString().split('.')[1] || '').length; + const decimals = Math.max(tempDec, amountDec); + const factor = Math.pow(10, decimals); + const scaled = Math.round(temp * factor) + amount * factor; + let nextValue = scaled / factor; + nextValue = snapOnStep ? Math.round(nextValue / step) * step : nextValue; if (max !== undefined && nextValue > max) { return max; @@ -69,11 +78,11 @@ const NumberFieldRoot = forwardRef }); }; - const handleStep = ({ type, direction } : {type: 'small'| 'large', direction: 'increment' | 'decrement' }) => { + const handleStep = ({ type, direction } : {type: 'small'| 'normal' | 'large', direction: 'increment' | 'decrement' }) => { let amount = 0; switch (type) { - case 'small': + case 'normal': if (!step) return; amount = step; break; @@ -81,10 +90,15 @@ const NumberFieldRoot = forwardRef if (!largeStep) return; amount = largeStep; break; + case 'small': + if (!smallStep) return; + amount = smallStep; + break; } if (direction === 'decrement') { - amount *= -1; + amount = -amount; + console.log(amount); } applyStep(amount); diff --git a/src/components/ui/NumberField/stories/NumberField.stories.tsx b/src/components/ui/NumberField/stories/NumberField.stories.tsx index 69ecd8feb..63b66c507 100644 --- a/src/components/ui/NumberField/stories/NumberField.stories.tsx +++ b/src/components/ui/NumberField/stories/NumberField.stories.tsx @@ -21,7 +21,7 @@ export const Controlled = () => { const [value, setValue] = React.useState(3); return ( - + - + From c2ce6ca7727f1f132553dec50d10adcf0e7bce36 Mon Sep 17 00:00:00 2001 From: GoldGroove06 <73437174+GoldGroove06@users.noreply.github.com> Date: Fri, 26 Sep 2025 17:45:26 +0530 Subject: [PATCH 2/8] fixes --- .../fragments/NumberFieldInput.tsx | 10 ++++- .../NumberField/fragments/NumberFieldRoot.tsx | 39 +++++++++---------- .../stories/NumberField.stories.tsx | 2 +- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/components/ui/NumberField/fragments/NumberFieldInput.tsx b/src/components/ui/NumberField/fragments/NumberFieldInput.tsx index e5374fde5..c49bb5ac1 100644 --- a/src/components/ui/NumberField/fragments/NumberFieldInput.tsx +++ b/src/components/ui/NumberField/fragments/NumberFieldInput.tsx @@ -40,13 +40,21 @@ const NumberFieldInput = forwardRef { const val = e.target.value; handleOnChange(val === '' ? '' : Number(val)); }} id={id} name={name} diff --git a/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx b/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx index 38b04a13a..121f6978f 100644 --- a/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx +++ b/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx @@ -49,30 +49,29 @@ const NumberFieldRoot = forwardRef }; const applyStep = (amount: number) => { setInputValue((prev) => { - let temp = prev; - if (temp === '') { - if (min !== undefined) { - temp = min; - } else { - temp = -1; - } + let temp: number; + + // Handle empty input + if (prev === '' || prev === null) { + temp = min !== undefined ? min : 0; + } else { + temp = Number(prev); } - const tempDec = (temp.toString().split('.')[1] || '').length; - const amountDec = (amount.toString().split('.')[1] || '').length; - const decimals = Math.max(tempDec, amountDec); - const factor = Math.pow(10, decimals); - const scaled = Math.round(temp * factor) + amount * factor; - let nextValue = scaled / factor; - nextValue = snapOnStep ? Math.round(nextValue / step) * step : nextValue; + console.log(temp % largeStep); + if (temp % largeStep != 0 && snapOnStep && largeStep === Math.abs(amount)) { temp = Math.round(temp / largeStep) * largeStep; } - if (max !== undefined && nextValue > max) { - return max; - } + // Find decimal places in amount only + const amountDecimals = (amount.toString().split('.')[1] || '').length; + const factor = Math.pow(10, amountDecimals); - if (min !== undefined && nextValue < min) { - return min; - } + // Scale value to integer, apply step, then scale back + const scaledValue = temp * factor + amount; + const nextValue = scaledValue / factor; + + // Clamp to min/max + if (max !== undefined && nextValue > max) return max; + if (min !== undefined && nextValue < min) return min; return nextValue; }); diff --git a/src/components/ui/NumberField/stories/NumberField.stories.tsx b/src/components/ui/NumberField/stories/NumberField.stories.tsx index 63b66c507..6097238ca 100644 --- a/src/components/ui/NumberField/stories/NumberField.stories.tsx +++ b/src/components/ui/NumberField/stories/NumberField.stories.tsx @@ -21,7 +21,7 @@ export const Controlled = () => { const [value, setValue] = React.useState(3); return ( - + - + From f307d9fe580f134cb79d4bedbcb6b4a876b5ea27 Mon Sep 17 00:00:00 2001 From: GoldGroove06 <73437174+GoldGroove06@users.noreply.github.com> Date: Fri, 26 Sep 2025 18:05:57 +0530 Subject: [PATCH 3/8] changes --- .../ui/NumberField/fragments/NumberFieldInput.tsx | 1 + .../ui/NumberField/fragments/NumberFieldRoot.tsx | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/components/ui/NumberField/fragments/NumberFieldInput.tsx b/src/components/ui/NumberField/fragments/NumberFieldInput.tsx index c49bb5ac1..f5773edd3 100644 --- a/src/components/ui/NumberField/fragments/NumberFieldInput.tsx +++ b/src/components/ui/NumberField/fragments/NumberFieldInput.tsx @@ -20,6 +20,7 @@ const NumberFieldInput = forwardRef; -const NumberFieldRoot = forwardRef(({ children, name, defaultValue = '', value, onValueChange, largeStep = 10, step = 1, smallStep = 0.1, snapOnStep = false, min, max, disabled, readOnly, required, id, className, ...props }, ref) => { +const NumberFieldRoot = forwardRef(({ children, name, defaultValue = '', value, onValueChange, largeStep = 10, step = 1, smallStep = 0.1, snapOnStep = false, locale, min, max, disabled, readOnly, required, id, className, ...props }, ref) => { const rootClass = customClassSwitcher(className, COMPONENT_NAME); const [inputValue, setInputValue] = useControllableState( value, @@ -50,6 +51,7 @@ const NumberFieldRoot = forwardRef const applyStep = (amount: number) => { setInputValue((prev) => { let temp: number; + let nextValue: number; // Handle empty input if (prev === '' || prev === null) { @@ -58,16 +60,20 @@ const NumberFieldRoot = forwardRef temp = Number(prev); } - console.log(temp % largeStep); if (temp % largeStep != 0 && snapOnStep && largeStep === Math.abs(amount)) { temp = Math.round(temp / largeStep) * largeStep; } // Find decimal places in amount only const amountDecimals = (amount.toString().split('.')[1] || '').length; + if (amountDecimals === 0) { + nextValue = temp + amount; + } + else{ const factor = Math.pow(10, amountDecimals); // Scale value to integer, apply step, then scale back - const scaledValue = temp * factor + amount; - const nextValue = scaledValue / factor; + let scaledValue = Math.round(temp * factor) + Math.round(amount * factor); + nextValue = scaledValue / factor; + } // Clamp to min/max if (max !== undefined && nextValue > max) return max; @@ -112,6 +118,7 @@ const NumberFieldRoot = forwardRef disabled, readOnly, required, + locale, rootClass }; From a3d39ef2239c9e9f65e442f783e5226e0d7f4b52 Mon Sep 17 00:00:00 2001 From: GoldGroove06 <73437174+GoldGroove06@users.noreply.github.com> Date: Fri, 26 Sep 2025 19:11:19 +0530 Subject: [PATCH 4/8] context --- src/components/ui/NumberField/contexts/NumberFieldContext.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/ui/NumberField/contexts/NumberFieldContext.tsx b/src/components/ui/NumberField/contexts/NumberFieldContext.tsx index b2ffc4594..b71ce3f83 100644 --- a/src/components/ui/NumberField/contexts/NumberFieldContext.tsx +++ b/src/components/ui/NumberField/contexts/NumberFieldContext.tsx @@ -10,6 +10,7 @@ export type NumberFieldContextType = { readOnly?: boolean; required?: boolean; rootClass?: string; + locale?: string; }; const NumberFieldContext = React.createContext(null); From d5789ab53cc6326c91587992fcd05e44f8823251 Mon Sep 17 00:00:00 2001 From: GoldGroove06 <73437174+GoldGroove06@users.noreply.github.com> Date: Wed, 1 Oct 2025 19:59:32 +0530 Subject: [PATCH 5/8] fix: operations of applyStep --- .../fragments/NumberFieldInput.tsx | 18 +++++++++++-- .../NumberField/fragments/NumberFieldRoot.tsx | 25 ++++++++++--------- .../stories/NumberField.stories.tsx | 4 +-- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/components/ui/NumberField/fragments/NumberFieldInput.tsx b/src/components/ui/NumberField/fragments/NumberFieldInput.tsx index f5773edd3..9d05dccb1 100644 --- a/src/components/ui/NumberField/fragments/NumberFieldInput.tsx +++ b/src/components/ui/NumberField/fragments/NumberFieldInput.tsx @@ -49,14 +49,28 @@ const NumberFieldInput = forwardRef= "0" && event.key <= "9") return; + + // Allow one dot if not present + if (event.key === "." && !event.currentTarget.value.includes(".")) return; + + // Allow minus only at start + if (event.key === "-" && event.currentTarget.selectionStart === 0 && !event.currentTarget.value.includes("-")) return; + + // Allow navigation keys + if (allowedKeys.includes(event.key)) return; + }; return ( { const val = e.target.value; handleOnChange(val === '' ? '' : Number(val)); }} + onChange={(e) => { const val = e.target.value; handleOnChange(val) }} id={id} name={name} disabled={disabled} diff --git a/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx b/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx index 50dbf2176..813228624 100644 --- a/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx +++ b/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx @@ -51,7 +51,7 @@ const NumberFieldRoot = forwardRef const applyStep = (amount: number) => { setInputValue((prev) => { let temp: number; - let nextValue: number; + let nextValue: number ; // Handle empty input if (prev === '' || prev === null) { @@ -60,20 +60,21 @@ const NumberFieldRoot = forwardRef temp = Number(prev); } - if (temp % largeStep != 0 && snapOnStep && largeStep === Math.abs(amount)) { temp = Math.round(temp / largeStep) * largeStep; } + // Round to nearest step + if (temp % largeStep != 0 && snapOnStep && largeStep === Math.abs(amount)) { + temp = Math.round(temp / largeStep) * largeStep; + } - // Find decimal places in amount only const amountDecimals = (amount.toString().split('.')[1] || '').length; - if (amountDecimals === 0) { - nextValue = temp + amount; - } - else{ - const factor = Math.pow(10, amountDecimals); + const tempDecimals = (temp.toString().split('.')[1] || '').length; + const decimal = amountDecimals > tempDecimals ? amountDecimals : tempDecimals; - // Scale value to integer, apply step, then scale back - let scaledValue = Math.round(temp * factor) + Math.round(amount * factor); - nextValue = scaledValue / factor; - } + // multiply temp and amount with same decimal count to remove decimal places + nextValue = (temp*Math.pow(10,decimal)) + (amount*Math.pow(10,decimal)); + + // divide nextValue by same decimal count + nextValue = nextValue / Math.pow(10,decimal); + // Clamp to min/max if (max !== undefined && nextValue > max) return max; diff --git a/src/components/ui/NumberField/stories/NumberField.stories.tsx b/src/components/ui/NumberField/stories/NumberField.stories.tsx index 6097238ca..d00287f2b 100644 --- a/src/components/ui/NumberField/stories/NumberField.stories.tsx +++ b/src/components/ui/NumberField/stories/NumberField.stories.tsx @@ -9,7 +9,7 @@ export default { export const Basic = () => ( - + - + @@ -21,7 +21,7 @@ export const Controlled = () => { const [value, setValue] = React.useState(3); return ( - + - + From 9830afaa1706a9cc428e6c09930467899fa59131 Mon Sep 17 00:00:00 2001 From: GoldGroove06 <73437174+GoldGroove06@users.noreply.github.com> Date: Wed, 1 Oct 2025 20:15:34 +0530 Subject: [PATCH 6/8] fix --- .../contexts/NumberFieldContext.tsx | 4 +-- .../fragments/NumberFieldInput.tsx | 22 +++++++------ .../NumberField/fragments/NumberFieldRoot.tsx | 31 +++++++++---------- .../stories/NumberField.stories.tsx | 2 +- 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/components/ui/NumberField/contexts/NumberFieldContext.tsx b/src/components/ui/NumberField/contexts/NumberFieldContext.tsx index b71ce3f83..0bd052e08 100644 --- a/src/components/ui/NumberField/contexts/NumberFieldContext.tsx +++ b/src/components/ui/NumberField/contexts/NumberFieldContext.tsx @@ -2,8 +2,8 @@ import React from 'react'; export type NumberFieldContextType = { inputValue: number|''; - handleOnChange: (input: number|'') => void; - handleStep: (opts: { direction: 'increment' | 'decrement'; type: 'small' | 'large' }) => void; + handleOnChange: (input: number) => void; + handleStep: (opts: { direction: 'increment' | 'decrement'; type: 'small' | 'normal' | 'large' }) => void; id?: string; name?: string; disabled?: boolean; diff --git a/src/components/ui/NumberField/fragments/NumberFieldInput.tsx b/src/components/ui/NumberField/fragments/NumberFieldInput.tsx index 9d05dccb1..f23d75e2a 100644 --- a/src/components/ui/NumberField/fragments/NumberFieldInput.tsx +++ b/src/components/ui/NumberField/fragments/NumberFieldInput.tsx @@ -49,20 +49,22 @@ const NumberFieldInput = forwardRef= "0" && event.key <= "9") return; + // Allow digits + if (event.key >= '0' && event.key <= '9') return; - // Allow one dot if not present - if (event.key === "." && !event.currentTarget.value.includes(".")) return; + // Allow one dot if not present + if (event.key === '.' && !event.currentTarget.value.includes('.')) return; - // Allow minus only at start - if (event.key === "-" && event.currentTarget.selectionStart === 0 && !event.currentTarget.value.includes("-")) return; + // Allow minus only at start + if (event.key === '-' && event.currentTarget.selectionStart === 0 && !event.currentTarget.value.includes('-')) return; - // Allow navigation keys - if (allowedKeys.includes(event.key)) return; + // Allow navigation keys + if (allowedKeys.includes(event.key)) return; + // Prevent other keys + event.preventDefault(); }; return ( { const val = e.target.value; handleOnChange(val) }} + onChange={(e) => { const val = e.target.value; handleOnChange(val); }} id={id} name={name} disabled={disabled} diff --git a/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx b/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx index 813228624..6c5d55ad9 100644 --- a/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx +++ b/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx @@ -26,16 +26,12 @@ export type NumberFieldRootProps = { const NumberFieldRoot = forwardRef(({ children, name, defaultValue = '', value, onValueChange, largeStep = 10, step = 1, smallStep = 0.1, snapOnStep = false, locale, min, max, disabled, readOnly, required, id, className, ...props }, ref) => { const rootClass = customClassSwitcher(className, COMPONENT_NAME); - const [inputValue, setInputValue] = useControllableState( + const [inputValue, setInputValue] = useControllableState( value, defaultValue, onValueChange); - const handleOnChange = (input: number| '') => { - if (input === '') { - setInputValue(''); - return; - } + const handleOnChange = (input: number) => { if (max !== undefined && input > max) { setInputValue(max); return; @@ -51,30 +47,31 @@ const NumberFieldRoot = forwardRef const applyStep = (amount: number) => { setInputValue((prev) => { let temp: number; - let nextValue: number ; + let nextValue: number; // Handle empty input - if (prev === '' || prev === null) { - temp = min !== undefined ? min : 0; - } else { - temp = Number(prev); - } + // if (prev === '' || prev === null) { + // temp = min !== undefined ? min : 0; + // } else { + temp = Number(prev); + // } // Round to nearest step - if (temp % largeStep != 0 && snapOnStep && largeStep === Math.abs(amount)) { + if (temp % largeStep != 0 && snapOnStep && largeStep === Math.abs(amount)) { temp = Math.round(temp / largeStep) * largeStep; - } + } const amountDecimals = (amount.toString().split('.')[1] || '').length; const tempDecimals = (temp.toString().split('.')[1] || '').length; const decimal = amountDecimals > tempDecimals ? amountDecimals : tempDecimals; // multiply temp and amount with same decimal count to remove decimal places - nextValue = (temp*Math.pow(10,decimal)) + (amount*Math.pow(10,decimal)); + nextValue = (temp * Math.pow(10, decimal)) + (amount * Math.pow(10, decimal)); // divide nextValue by same decimal count - nextValue = nextValue / Math.pow(10,decimal); - + nextValue = nextValue / Math.pow(10, decimal); + const factor = Math.pow(10, decimal); + nextValue = (Math.round(temp * factor) + Math.round(amount * factor)) / factor; // Clamp to min/max if (max !== undefined && nextValue > max) return max; diff --git a/src/components/ui/NumberField/stories/NumberField.stories.tsx b/src/components/ui/NumberField/stories/NumberField.stories.tsx index d00287f2b..89d2827fe 100644 --- a/src/components/ui/NumberField/stories/NumberField.stories.tsx +++ b/src/components/ui/NumberField/stories/NumberField.stories.tsx @@ -9,7 +9,7 @@ export default { export const Basic = () => ( - + - + From 8fd039d92648074d5c67704bce91b96a17f3a08b Mon Sep 17 00:00:00 2001 From: GoldGroove06 <73437174+GoldGroove06@users.noreply.github.com> Date: Wed, 1 Oct 2025 22:20:43 +0530 Subject: [PATCH 7/8] fixes --- .../contexts/NumberFieldContext.tsx | 2 +- .../fragments/NumberFieldInput.tsx | 20 ++----------------- .../NumberField/fragments/NumberFieldRoot.tsx | 18 ++++++++++------- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/src/components/ui/NumberField/contexts/NumberFieldContext.tsx b/src/components/ui/NumberField/contexts/NumberFieldContext.tsx index 0bd052e08..6a45fd59a 100644 --- a/src/components/ui/NumberField/contexts/NumberFieldContext.tsx +++ b/src/components/ui/NumberField/contexts/NumberFieldContext.tsx @@ -2,7 +2,7 @@ import React from 'react'; export type NumberFieldContextType = { inputValue: number|''; - handleOnChange: (input: number) => void; + handleOnChange: (input: number | '') => void; handleStep: (opts: { direction: 'increment' | 'decrement'; type: 'small' | 'normal' | 'large' }) => void; id?: string; name?: string; diff --git a/src/components/ui/NumberField/fragments/NumberFieldInput.tsx b/src/components/ui/NumberField/fragments/NumberFieldInput.tsx index f23d75e2a..f5773edd3 100644 --- a/src/components/ui/NumberField/fragments/NumberFieldInput.tsx +++ b/src/components/ui/NumberField/fragments/NumberFieldInput.tsx @@ -49,30 +49,14 @@ const NumberFieldInput = forwardRef= '0' && event.key <= '9') return; - - // Allow one dot if not present - if (event.key === '.' && !event.currentTarget.value.includes('.')) return; - - // Allow minus only at start - if (event.key === '-' && event.currentTarget.selectionStart === 0 && !event.currentTarget.value.includes('-')) return; - - // Allow navigation keys - if (allowedKeys.includes(event.key)) return; - - // Prevent other keys - event.preventDefault(); }; return ( { const val = e.target.value; handleOnChange(val); }} + onChange={(e) => { const val = e.target.value; handleOnChange(val === '' ? '' : Number(val)); }} id={id} name={name} disabled={disabled} diff --git a/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx b/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx index 6c5d55ad9..e03f30df9 100644 --- a/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx +++ b/src/components/ui/NumberField/fragments/NumberFieldRoot.tsx @@ -26,12 +26,16 @@ export type NumberFieldRootProps = { const NumberFieldRoot = forwardRef(({ children, name, defaultValue = '', value, onValueChange, largeStep = 10, step = 1, smallStep = 0.1, snapOnStep = false, locale, min, max, disabled, readOnly, required, id, className, ...props }, ref) => { const rootClass = customClassSwitcher(className, COMPONENT_NAME); - const [inputValue, setInputValue] = useControllableState( + const [inputValue, setInputValue] = useControllableState( value, defaultValue, onValueChange); - const handleOnChange = (input: number) => { + const handleOnChange = (input: number | '') => { + if (input === '') { + setInputValue(''); + return; + } if (max !== undefined && input > max) { setInputValue(max); return; @@ -50,11 +54,11 @@ const NumberFieldRoot = forwardRef let nextValue: number; // Handle empty input - // if (prev === '' || prev === null) { - // temp = min !== undefined ? min : 0; - // } else { - temp = Number(prev); - // } + if (prev === '' || prev === null) { + temp = min !== undefined ? min : 0; + } else { + temp = Number(prev); + } // Round to nearest step if (temp % largeStep != 0 && snapOnStep && largeStep === Math.abs(amount)) { From a4ff45fdaa467311ed6fffa1a55acf7152fc577a Mon Sep 17 00:00:00 2001 From: GoldGroove06 <73437174+GoldGroove06@users.noreply.github.com> Date: Wed, 1 Oct 2025 22:23:56 +0530 Subject: [PATCH 8/8] add: changeset --- .changeset/ninety-cats-pull.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/ninety-cats-pull.md diff --git a/.changeset/ninety-cats-pull.md b/.changeset/ninety-cats-pull.md new file mode 100644 index 000000000..36cc8addf --- /dev/null +++ b/.changeset/ninety-cats-pull.md @@ -0,0 +1,5 @@ +--- +"@radui/ui": patch +--- + +AddedsnapOnStep, smallStep support for NumberField