Add 'min' and 'max' attributes to number block (#40715)

* Add 'min' and 'max' attributes to number block

* Rename string
This commit is contained in:
Nathan Silveira 2023-10-16 09:07:17 -03:00 committed by GitHub
parent c4e0113c09
commit c3ffd5af95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 85 additions and 8 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add 'min' and 'max' attributes to number block

View File

@ -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. 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 ## Usage
Here's a snippet that adds a field similar to the previous screenshot: Here's a snippet that adds a field similar to the previous screenshot:

View File

@ -23,6 +23,12 @@
}, },
"placeholder": { "placeholder": {
"type": "string" "type": "string"
},
"min": {
"type": "number"
},
"max": {
"type": "number"
} }
}, },
"supports": { "supports": {

View File

@ -3,7 +3,12 @@
*/ */
import { createElement } from '@wordpress/element'; import { createElement } from '@wordpress/element';
import { useWooBlockProps } from '@woocommerce/block-templates'; 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 { import {
BaseControl,
// @ts-expect-error `__experimentalInputControl` does exist. // @ts-expect-error `__experimentalInputControl` does exist.
__experimentalInputControl as InputControl, __experimentalInputControl as InputControl,
} from '@wordpress/components'; } from '@wordpress/components';
@ -14,13 +19,14 @@ import { ProductEditorBlockEditProps } from '../../../types';
import useProductEntityProp from '../../../hooks/use-product-entity-prop'; import useProductEntityProp from '../../../hooks/use-product-entity-prop';
import { useNumberInputProps } from '../../../hooks/use-number-input-props'; import { useNumberInputProps } from '../../../hooks/use-number-input-props';
import { NumberBlockAttributes } from './types'; import { NumberBlockAttributes } from './types';
import { useValidation } from '../../../contexts/validation-context';
export function Edit( { export function Edit( {
attributes, attributes,
context: { postType }, context: { postType },
}: ProductEditorBlockEditProps< NumberBlockAttributes > ) { }: ProductEditorBlockEditProps< NumberBlockAttributes > ) {
const blockProps = useWooBlockProps( attributes ); 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, { const [ value, setValue ] = useProductEntityProp( property, {
postType, postType,
fallbackValue: '', fallbackValue: '',
@ -31,16 +37,61 @@ export function Edit( {
onChange: setValue, 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 ( return (
<div { ...blockProps }> <div { ...blockProps }>
<InputControl <BaseControl
{ ...inputProps } className={ classNames( {
__next36pxDefaultSize 'has-error': error,
} ) }
id={ id }
label={ label } label={ label }
suffix={ suffix } help={ error || help }
help={ help } >
placeholder={ placeholder } <InputControl
/> { ...inputProps }
id={ id }
suffix={ suffix }
placeholder={ placeholder }
onBlur={ validate }
/>
</BaseControl>
</div> </div>
); );
} }

View File

@ -9,4 +9,6 @@ export interface NumberBlockAttributes extends BlockAttributes {
help?: string; help?: string;
suffix?: string; suffix?: string;
placeholder?: string; placeholder?: string;
min?: number;
max?: number;
} }