diff --git a/.changeset/thirty-bikes-kneel.md b/.changeset/thirty-bikes-kneel.md new file mode 100644 index 0000000000..b041169ab2 --- /dev/null +++ b/.changeset/thirty-bikes-kneel.md @@ -0,0 +1,6 @@ +--- +'@commercetools-uikit/number-field': minor +'@commercetools-uikit/i18n': minor +--- + +Add `belowMin` and `aboveMax` error keys to `NumberField` diff --git a/packages/components/fields/number-field/README.md b/packages/components/fields/number-field/README.md index 9165a1e47a..bc8937bb36 100644 --- a/packages/components/fields/number-field/README.md +++ b/packages/components/fields/number-field/README.md @@ -116,6 +116,8 @@ When the `key` is known, and when the value is truthy, and when `renderError` re Known error keys are: - `missing`: tells the user that this field is required +- `belowMin`: tells the user that the value is below the minimum +- `aboveMax`: tells the user that the value is above the maximum ## Static methods diff --git a/packages/components/fields/number-field/docs/additional-info.md b/packages/components/fields/number-field/docs/additional-info.md index e9fd413577..203246af9c 100644 --- a/packages/components/fields/number-field/docs/additional-info.md +++ b/packages/components/fields/number-field/docs/additional-info.md @@ -17,6 +17,8 @@ When the `key` is known, and when the value is truthy, and when `renderError` re Known error keys are: - `missing`: tells the user that this field is required +- `belowMin`: tells the user that the value is below the minimum +- `aboveMax`: tells the user that the value is above the maximum ## Static methods diff --git a/packages/components/fields/number-field/src/messages.ts b/packages/components/fields/number-field/src/messages.ts new file mode 100644 index 0000000000..0da1992c47 --- /dev/null +++ b/packages/components/fields/number-field/src/messages.ts @@ -0,0 +1,14 @@ +import { defineMessages } from 'react-intl'; + +export default defineMessages({ + belowMinError: { + id: 'UIKit.NumberField.belowMinError', + description: 'An error message to show when the value is below the minimum', + defaultMessage: 'Value must be greater than or equal to {min}.', + }, + aboveMaxError: { + id: 'UIKit.NumberField.aboveMaxError', + description: 'An error message to show when the value is above the maximum', + defaultMessage: 'Value must be less than or equal to {max}.', + }, +}); diff --git a/packages/components/fields/number-field/src/number-field.spec.js b/packages/components/fields/number-field/src/number-field.spec.js index 5e7a7ddd41..cbea4a43e4 100644 --- a/packages/components/fields/number-field/src/number-field.spec.js +++ b/packages/components/fields/number-field/src/number-field.spec.js @@ -212,6 +212,34 @@ describe('when field is touched and has errors', () => { expect(getByText(/field is required/i)).toBeInTheDocument(); }); }); + describe('when value is below min', () => { + it('should render a default error', () => { + const min = 2; + const { getByText } = renderNumberField({ + value: 1, + min, + touched: true, + errors: { belowMin: true }, + }); + expect( + getByText(`Value must be greater than or equal to {min}.`) + ).toBeInTheDocument(); + }); + }); + describe('when value is above max', () => { + it('should render a default error', () => { + const max = 2; + const { getByText } = renderNumberField({ + value: 3, + max, + touched: true, + errors: { aboveMax: true }, + }); + expect( + getByText(`Value must be less than or equal to ${max}.`) + ).toBeInTheDocument(); + }); + }); describe('when there is a custom error', () => { it('should render the custom error message', () => { const { getByText } = renderNumberField({ diff --git a/packages/components/fields/number-field/src/number-field.story.js b/packages/components/fields/number-field/src/number-field.story.js index 0903cd2e2f..876f05f1b1 100644 --- a/packages/components/fields/number-field/src/number-field.story.js +++ b/packages/components/fields/number-field/src/number-field.story.js @@ -53,7 +53,12 @@ storiesOf('Components|Fields', module) warnings={object('warnings', { customWarning: true, })} - errors={object('errors', { missing: true, customError: true })} + errors={object('errors', { + missing: true, + belowMin: true, + aboveMax: true, + customError: true, + })} renderError={(key) => { switch (key) { case 'customError': diff --git a/packages/components/fields/number-field/src/number-field.tsx b/packages/components/fields/number-field/src/number-field.tsx index 433977b902..7da6299c80 100644 --- a/packages/components/fields/number-field/src/number-field.tsx +++ b/packages/components/fields/number-field/src/number-field.tsx @@ -20,6 +20,8 @@ import FieldLabel from '@commercetools-uikit/field-label'; import FieldErrors from '@commercetools-uikit/field-errors'; import FieldWarnings from '@commercetools-uikit/field-warnings'; import NumberInput from '@commercetools-uikit/number-input'; +import messages from './messages'; +import { FormattedMessage } from 'react-intl'; const sequentialId = createSequentialId('number-field-'); const sequentialErrorsId = createSequentialId('number-field-error-')(); @@ -278,7 +280,36 @@ class NumberField extends Component { id={sequentialErrorsId} errors={this.props.errors} isVisible={hasError} - renderError={this.props.renderError} + renderError={(key: string, error?: boolean) => { + const element = this.props.renderError?.(key, error); + if (element) { + return element; + } else { + switch (key) { + case 'belowMin': + if (typeof this.props.min === 'number') { + return ( + + ); + } + break; + case 'aboveMax': + if (typeof this.props.max === 'number') { + return ( + + ); + } + break; + } + return null; + } + }} />