diff --git a/packages/js/product-editor/changelog/add-min-max-number-block b/packages/js/product-editor/changelog/add-min-max-number-block new file mode 100644 index 00000000000..3a7232b0d19 --- /dev/null +++ b/packages/js/product-editor/changelog/add-min-max-number-block @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Add 'min' and 'max' attributes to number block diff --git a/packages/js/product-editor/src/blocks/generic/number/README.md b/packages/js/product-editor/src/blocks/generic/number/README.md index c80f311f1b9..9825627d7fa 100644 --- a/packages/js/product-editor/src/blocks/generic/number/README.md +++ b/packages/js/product-editor/src/blocks/generic/number/README.md @@ -43,6 +43,20 @@ Suffix that can be used for a unit of measure, as an example. Placeholder text that appears in the field when it's empty. +### min + +- **Type:** `Number` +- **Required:** `No` + +The minimum numeric value that can be entered in the field. + +### max + +- **Type:** `Number` +- **Required:** `No` + +The maximum numeric value that can be entered in the field. + ## Usage Here's a snippet that adds a field similar to the previous screenshot: diff --git a/packages/js/product-editor/src/blocks/generic/number/block.json b/packages/js/product-editor/src/blocks/generic/number/block.json index 0c67f1c5771..93a7162259a 100644 --- a/packages/js/product-editor/src/blocks/generic/number/block.json +++ b/packages/js/product-editor/src/blocks/generic/number/block.json @@ -23,6 +23,12 @@ }, "placeholder": { "type": "string" + }, + "min": { + "type": "number" + }, + "max": { + "type": "number" } }, "supports": { 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 94686da66f1..5ad30e210f0 100644 --- a/packages/js/product-editor/src/blocks/generic/number/edit.tsx +++ b/packages/js/product-editor/src/blocks/generic/number/edit.tsx @@ -3,7 +3,12 @@ */ import { createElement } from '@wordpress/element'; import { useWooBlockProps } from '@woocommerce/block-templates'; +import { Product } from '@woocommerce/data'; +import { __, sprintf } from '@wordpress/i18n'; +import classNames from 'classnames'; +import { useInstanceId } from '@wordpress/compose'; import { + BaseControl, // @ts-expect-error `__experimentalInputControl` does exist. __experimentalInputControl as InputControl, } from '@wordpress/components'; @@ -14,13 +19,14 @@ import { ProductEditorBlockEditProps } from '../../../types'; import useProductEntityProp from '../../../hooks/use-product-entity-prop'; import { useNumberInputProps } from '../../../hooks/use-number-input-props'; import { NumberBlockAttributes } from './types'; +import { useValidation } from '../../../contexts/validation-context'; export function Edit( { attributes, context: { postType }, }: ProductEditorBlockEditProps< NumberBlockAttributes > ) { const blockProps = useWooBlockProps( attributes ); - const { label, property, suffix, placeholder, help } = attributes; + const { label, property, suffix, placeholder, help, min, max } = attributes; const [ value, setValue ] = useProductEntityProp( property, { postType, fallbackValue: '', @@ -31,16 +37,61 @@ export function Edit( { onChange: setValue, } ); + const id = useInstanceId( BaseControl, 'product_number_field' ) as string; + + const { error, validate } = useValidation< Product >( + property, + async function validator() { + if ( + typeof min === 'number' && + value && + parseFloat( value ) < min + ) { + return sprintf( + __( + // translators: %d is the minimum value of the number input. + 'Value must be greater than or equal to %d', + 'woocommerce' + ), + min + ); + } + if ( + typeof max === 'number' && + value && + parseFloat( value ) > max + ) { + return sprintf( + __( + // translators: %d is the maximum value of the number input. + 'Value must be less than or equal to %d', + 'woocommerce' + ), + max + ); + } + }, + [ value ] + ); + return (
- + help={ error || help } + > + +
); } diff --git a/packages/js/product-editor/src/blocks/generic/number/types.ts b/packages/js/product-editor/src/blocks/generic/number/types.ts index d4e80ac53c4..714c9e5fe85 100644 --- a/packages/js/product-editor/src/blocks/generic/number/types.ts +++ b/packages/js/product-editor/src/blocks/generic/number/types.ts @@ -9,4 +9,6 @@ export interface NumberBlockAttributes extends BlockAttributes { help?: string; suffix?: string; placeholder?: string; + min?: number; + max?: number; }