Add 'min' and 'max' attributes to number block (#40715)
* Add 'min' and 'max' attributes to number block * Rename string
This commit is contained in:
parent
c4e0113c09
commit
c3ffd5af95
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: add
|
||||||
|
|
||||||
|
Add 'min' and 'max' attributes to number block
|
|
@ -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:
|
||||||
|
|
|
@ -23,6 +23,12 @@
|
||||||
},
|
},
|
||||||
"placeholder": {
|
"placeholder": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"min": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"max": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"supports": {
|
"supports": {
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue