diff --git a/packages/js/product-editor/changelog/update-number-control-improvements b/packages/js/product-editor/changelog/update-number-control-improvements new file mode 100644 index 00000000000..feb0626ac77 --- /dev/null +++ b/packages/js/product-editor/changelog/update-number-control-improvements @@ -0,0 +1,4 @@ +Significance: minor +Type: update + +Update number control to not allow invalid values through arrow keys or buttons diff --git a/packages/js/product-editor/src/blocks/generic/number/edit.tsx b/packages/js/product-editor/src/blocks/generic/number/edit.tsx index 891b38c5d5a..7063a2e4378 100644 --- a/packages/js/product-editor/src/blocks/generic/number/edit.tsx +++ b/packages/js/product-editor/src/blocks/generic/number/edit.tsx @@ -95,6 +95,8 @@ export function Edit( { tooltip={ tooltip } disabled={ disabled } step={ step } + min={ min } + max={ max } /> ); diff --git a/packages/js/product-editor/src/components/number-control/number-control.tsx b/packages/js/product-editor/src/components/number-control/number-control.tsx index 4c66ecee9c0..bf2603ffbbf 100644 --- a/packages/js/product-editor/src/components/number-control/number-control.tsx +++ b/packages/js/product-editor/src/components/number-control/number-control.tsx @@ -38,6 +38,8 @@ export type NumberProps = { tooltip?: string; disabled?: boolean; step?: number; + min?: number; + max?: number; }; const MEDIUM_DELAY = 500; @@ -57,6 +59,8 @@ export const NumberControl: React.FC< NumberProps > = ( { placeholder, disabled, step = 1, + min = -Infinity, + max = +Infinity, }: NumberProps ) => { const id = useInstanceId( BaseControl, 'product_number_field' ) as string; const [ isFocused, setIsFocused ] = useState( false ); @@ -74,6 +78,8 @@ export const NumberControl: React.FC< NumberProps > = ( { value: value || '', onChange, onFocus: () => setIsFocused( true ), + min, + max, } ); const [ increment, setIncrement ] = useState( 0 ); @@ -82,8 +88,11 @@ export const NumberControl: React.FC< NumberProps > = ( { const isInitialClick = useRef< boolean >( false ); - const incrementValue = () => - onChange( String( parseFloat( value || '0' ) + increment ) ); + const incrementValue = () => { + const newValue = parseFloat( value || '0' ) + increment; + if ( newValue >= min && newValue <= max ) + onChange( String( newValue ) ); + }; useEffect( () => { if ( increment !== 0 ) { @@ -104,6 +113,15 @@ export const NumberControl: React.FC< NumberProps > = ( { const resetIncrement = () => setIncrement( 0 ); + const handleIncrement = ( thisStep: number ) => { + const newValue = parseFloat( value || '0' ) + thisStep; + if ( newValue >= min && newValue <= max ) { + onChange( String( parseFloat( value || '0' ) + thisStep ) ); + setIncrement( thisStep ); + isInitialClick.current = true; + } + }; + return ( = ( {