@patternfly/react-core 4.198.17 → 4.198.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/esm/components/AlertGroup/AlertGroup.d.ts +4 -0
  3. package/dist/esm/components/AlertGroup/AlertGroup.d.ts.map +1 -1
  4. package/dist/esm/components/AlertGroup/AlertGroup.js +2 -2
  5. package/dist/esm/components/AlertGroup/AlertGroup.js.map +1 -1
  6. package/dist/esm/components/AlertGroup/AlertGroupInline.d.ts.map +1 -1
  7. package/dist/esm/components/AlertGroup/AlertGroupInline.js +5 -2
  8. package/dist/esm/components/AlertGroup/AlertGroupInline.js.map +1 -1
  9. package/dist/esm/components/NumberInput/NumberInput.d.ts.map +1 -1
  10. package/dist/esm/components/NumberInput/NumberInput.js +2 -2
  11. package/dist/esm/components/NumberInput/NumberInput.js.map +1 -1
  12. package/dist/js/components/AlertGroup/AlertGroup.d.ts +4 -0
  13. package/dist/js/components/AlertGroup/AlertGroup.d.ts.map +1 -1
  14. package/dist/js/components/AlertGroup/AlertGroup.js +2 -2
  15. package/dist/js/components/AlertGroup/AlertGroup.js.map +1 -1
  16. package/dist/js/components/AlertGroup/AlertGroupInline.d.ts.map +1 -1
  17. package/dist/js/components/AlertGroup/AlertGroupInline.js +5 -2
  18. package/dist/js/components/AlertGroup/AlertGroupInline.js.map +1 -1
  19. package/dist/js/components/NumberInput/NumberInput.d.ts.map +1 -1
  20. package/dist/js/components/NumberInput/NumberInput.js +2 -2
  21. package/dist/js/components/NumberInput/NumberInput.js.map +1 -1
  22. package/dist/styles/assets/images/img_pie-chart-with-legend.png +0 -0
  23. package/dist/styles/assets/images/status-icon-sprite.svg +38 -0
  24. package/dist/umd/react-core.css +234 -37
  25. package/dist/umd/react-core.js +18 -7
  26. package/dist/umd/react-core.min.css +234 -37
  27. package/dist/umd/react-core.min.js +2 -2
  28. package/package.json +6 -6
  29. package/src/components/AlertGroup/AlertGroup.tsx +13 -2
  30. package/src/components/AlertGroup/AlertGroupInline.tsx +9 -0
  31. package/src/components/AlertGroup/__tests__/AlertGroup.test.tsx +15 -0
  32. package/src/components/AlertGroup/__tests__/__snapshots__/AlertGroup.test.tsx.snap +93 -1
  33. package/src/components/AlertGroup/examples/AlertGroup.md +147 -0
  34. package/src/components/NumberInput/NumberInput.tsx +3 -2
  35. package/src/components/NumberInput/examples/NumberInput.md +78 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "4.198.17",
3
+ "version": "4.198.20",
4
4
  "description": "This library provides a set of common React components for use with the PatternFly reference implementation.",
5
5
  "main": "dist/js/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -34,16 +34,16 @@
34
34
  "generate": "node scripts/copyStyles.js"
35
35
  },
36
36
  "dependencies": {
37
- "@patternfly/react-icons": "^4.49.17",
38
- "@patternfly/react-styles": "^4.48.17",
39
- "@patternfly/react-tokens": "^4.50.17",
37
+ "@patternfly/react-icons": "^4.49.20",
38
+ "@patternfly/react-styles": "^4.48.20",
39
+ "@patternfly/react-tokens": "^4.50.20",
40
40
  "focus-trap": "6.2.2",
41
41
  "react-dropzone": "9.0.0",
42
42
  "tippy.js": "5.1.2",
43
43
  "tslib": "^2.0.0"
44
44
  },
45
45
  "devDependencies": {
46
- "@patternfly/patternfly": "4.179.3",
46
+ "@patternfly/patternfly": "4.183.1",
47
47
  "@rollup/plugin-commonjs": "^21.0.0",
48
48
  "@rollup/plugin-node-resolve": "^13.0.0",
49
49
  "@rollup/plugin-replace": "^3.0.0",
@@ -60,5 +60,5 @@
60
60
  "react": "^16.8.0 || ^17.0.0",
61
61
  "react-dom": "^16.8.0 || ^17.0.0"
62
62
  },
63
- "gitHead": "0a5989506d02f2a0eef3f0a714dbcee41c556494"
63
+ "gitHead": "bc50956d075edd59c346cfbc2b9635a850f057bb"
64
64
  }
@@ -14,6 +14,10 @@ export interface AlertGroupProps extends Omit<React.HTMLProps<HTMLUListElement>,
14
14
  isLiveRegion?: boolean;
15
15
  /** Determine where the alert is appended to */
16
16
  appendTo?: HTMLElement | (() => HTMLElement);
17
+ /** Function to call if user clicks on overflow message */
18
+ onOverflowClick?: () => void;
19
+ /** Custom text to show for the overflow message */
20
+ overflowMessage?: string;
17
21
  }
18
22
 
19
23
  interface AlertGroupState {
@@ -49,9 +53,16 @@ export class AlertGroup extends React.Component<AlertGroupProps, AlertGroupState
49
53
  }
50
54
 
51
55
  render() {
52
- const { className, children, isToast, isLiveRegion, ...props } = this.props;
56
+ const { className, children, isToast, isLiveRegion, onOverflowClick, overflowMessage, ...props } = this.props;
53
57
  const alertGroup = (
54
- <AlertGroupInline className={className} isToast={isToast} isLiveRegion={isLiveRegion} {...props}>
58
+ <AlertGroupInline
59
+ onOverflowClick={onOverflowClick}
60
+ className={className}
61
+ isToast={isToast}
62
+ isLiveRegion={isLiveRegion}
63
+ overflowMessage={overflowMessage}
64
+ {...props}
65
+ >
55
66
  {children}
56
67
  </AlertGroupInline>
57
68
  );
@@ -8,6 +8,8 @@ export const AlertGroupInline: React.FunctionComponent<AlertGroupProps> = ({
8
8
  children,
9
9
  isToast,
10
10
  isLiveRegion,
11
+ onOverflowClick,
12
+ overflowMessage,
11
13
  ...rest
12
14
  }: AlertGroupProps) => (
13
15
  <ul
@@ -19,6 +21,13 @@ export const AlertGroupInline: React.FunctionComponent<AlertGroupProps> = ({
19
21
  {React.Children.toArray(children).map((Alert: React.ReactNode, index: number) => (
20
22
  <li key={index}>{Alert}</li>
21
23
  ))}
24
+ {overflowMessage && (
25
+ <li>
26
+ <button onClick={onOverflowClick} className={css(styles.alertGroupOverflowButton)}>
27
+ {overflowMessage}
28
+ </button>
29
+ </li>
30
+ )}
22
31
  </ul>
23
32
  );
24
33
  AlertGroupInline.displayName = 'AlertGroupInline';
@@ -28,6 +28,21 @@ test('Alert Group works with n children', () => {
28
28
  expect(view).toBeTruthy();
29
29
  });
30
30
 
31
+ test('Alert group overflow shows up', () => {
32
+ const overflowMessage = "View 2 more alerts";
33
+ const onOverflowClick = jest.fn();
34
+ const wrapper = mount(
35
+ <AlertGroup overflowMessage={overflowMessage} onOverflowClick={onOverflowClick}>
36
+ <Alert variant="danger" title="alert title" />
37
+ </AlertGroup>
38
+ )
39
+ expect(wrapper.find('.pf-c-alert-group > li')).toHaveLength(2);
40
+ expect(wrapper.find('.pf-c-alert-group__overflow-button').text()).toContain(overflowMessage);
41
+ expect(wrapper).toMatchSnapshot();
42
+ wrapper.find('.pf-c-alert-group__overflow-button').simulate('click');
43
+ expect(onOverflowClick).toBeCalled();
44
+ });
45
+
31
46
  test('Standard Alert Group is not a toast alert group', () => {
32
47
  const wrapper = mount(
33
48
  <AlertGroup>
@@ -8,6 +8,95 @@ exports[`Alert Group should match snapshot 1`] = `
8
8
  </div>
9
9
  `;
10
10
 
11
+ exports[`Alert group overflow shows up 1`] = `
12
+ <AlertGroup
13
+ onOverflowClick={[MockFunction]}
14
+ overflowMessage="View 2 more alerts"
15
+ >
16
+ <AlertGroupInline
17
+ onOverflowClick={[MockFunction]}
18
+ overflowMessage="View 2 more alerts"
19
+ >
20
+ <ul
21
+ aria-atomic={null}
22
+ aria-live={null}
23
+ className="pf-c-alert-group"
24
+ >
25
+ <li
26
+ key="0"
27
+ >
28
+ <Alert
29
+ key=".0"
30
+ title="alert title"
31
+ variant="danger"
32
+ >
33
+ <div
34
+ aria-label="Danger Alert"
35
+ className="pf-c-alert pf-m-danger"
36
+ data-ouia-component-id="OUIA-Generated-Alert-danger-1"
37
+ data-ouia-component-type="PF4/Alert"
38
+ data-ouia-safe={true}
39
+ onMouseEnter={[Function]}
40
+ onMouseLeave={[Function]}
41
+ >
42
+ <AlertIcon
43
+ variant="danger"
44
+ >
45
+ <div
46
+ className="pf-c-alert__icon"
47
+ >
48
+ <ExclamationCircleIcon
49
+ color="currentColor"
50
+ noVerticalAlign={false}
51
+ size="sm"
52
+ >
53
+ <svg
54
+ aria-hidden={true}
55
+ aria-labelledby={null}
56
+ fill="currentColor"
57
+ height="1em"
58
+ role="img"
59
+ style={
60
+ Object {
61
+ "verticalAlign": "-0.125em",
62
+ }
63
+ }
64
+ viewBox="0 0 512 512"
65
+ width="1em"
66
+ >
67
+ <path
68
+ d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"
69
+ />
70
+ </svg>
71
+ </ExclamationCircleIcon>
72
+ </div>
73
+ </AlertIcon>
74
+ <h4
75
+ className="pf-c-alert__title"
76
+ >
77
+ <span
78
+ className="pf-u-screen-reader"
79
+ >
80
+ Danger alert:
81
+ </span>
82
+ alert title
83
+ </h4>
84
+ </div>
85
+ </Alert>
86
+ </li>
87
+ <li>
88
+ <button
89
+ className="pf-c-alert-group__overflow-button"
90
+ onClick={[MockFunction]}
91
+ >
92
+ View 2 more alerts
93
+ </button>
94
+ </li>
95
+ </ul>
96
+ </AlertGroupInline>
97
+ </AlertGroup>
98
+ `;
99
+
11
100
  exports[`Standard Alert Group is not a toast alert group 1`] = `
12
101
  <AlertGroup>
13
102
  <AlertGroupInline>
@@ -27,7 +116,7 @@ exports[`Standard Alert Group is not a toast alert group 1`] = `
27
116
  <div
28
117
  aria-label="Danger Alert"
29
118
  className="pf-c-alert pf-m-danger"
30
- data-ouia-component-id="OUIA-Generated-Alert-danger-1"
119
+ data-ouia-component-id="OUIA-Generated-Alert-danger-2"
31
120
  data-ouia-component-type="PF4/Alert"
32
121
  data-ouia-safe={true}
33
122
  onMouseEnter={[Function]}
@@ -215,6 +304,7 @@ exports[`alertgroup closes when alerts are closed 1`] = `
215
304
  <AlertGroup
216
305
  appendTo={
217
306
  <body>
307
+ <div />
218
308
  <div />
219
309
  <div>
220
310
  <ul
@@ -420,6 +510,7 @@ exports[`alertgroup closes when alerts are closed 1`] = `
420
510
  <AlertGroupInline
421
511
  appendTo={
422
512
  <body>
513
+ <div />
423
514
  <div />
424
515
  <div>
425
516
  <ul
@@ -547,6 +638,7 @@ exports[`alertgroup closes when alerts are closed 1`] = `
547
638
  <ul
548
639
  appendTo={
549
640
  <body>
641
+ <div />
550
642
  <div />
551
643
  <div>
552
644
  <ul
@@ -78,6 +78,79 @@ class ToastAlertGroup extends React.Component {
78
78
  }
79
79
  ```
80
80
 
81
+ ### Toast alert group with overflow capture
82
+ After a specified number of alerts displayed is reached, we will see an overflow message instead of new alerts. Alerts asynchronously appended into dynamic AlertGroups with `isLiveRegion` will be announced to assistive technology at the moment the change happens. When the overflow message appears or is updated in AlertGroups with `isLiveRegion`, the `View 1 more alert` text will be read, but the alert message will not be read. screen reader user or keyboard user will need a way to navigate to and reveal the hidden alerts before they disappear. Alternatively, there should be a place that notifications or alerts are collected to be viewed or read later. In this example we are showing a max of 4 alerts.
83
+ ```js isBeta
84
+ import React from 'react';
85
+ import { Alert, AlertGroup, AlertActionCloseButton, AlertVariant, InputGroup } from '@patternfly/react-core';
86
+ class ToastAlertGroup extends React.Component {
87
+ constructor() {
88
+ super();
89
+ this.state = {
90
+ alerts: [],
91
+ maxDisplayed: "4",
92
+ overflowMessage: ''
93
+ };
94
+ this.getOverflowMessage = (alertsNumber) => {
95
+ const overflow = alertsNumber - this.state.maxDisplayed;
96
+ if (overflow > 0) {
97
+ return "View " + (overflow) + " more alerts";
98
+ }
99
+ return '';
100
+ };
101
+ this.addAlert = (title, variant, key) => {
102
+ this.setState({
103
+ ...this.state,
104
+ alerts: [ ...this.state.alerts, { title: title, variant: variant, key }],
105
+ overflowMessage: this.getOverflowMessage(this.state.alerts.length + 1)
106
+ });
107
+ };
108
+ this.removeAlert = key => {
109
+ const newAlerts = [...this.state.alerts.filter(el => el.key !== key)];
110
+ this.setState({
111
+ ...this.state,
112
+ alerts: newAlerts,
113
+ overflowMessage: this.getOverflowMessage(newAlerts.length)
114
+ });
115
+ };
116
+ }
117
+ render() {
118
+ const btnClasses = ['pf-c-button', 'pf-m-secondary'].join(' ');
119
+ const getUniqueId = () => (new Date().getTime());
120
+ const addSuccessAlert = () => { this.addAlert('Toast success alert', 'success', getUniqueId()) };
121
+ const addDangerAlert = () => { this.addAlert('Toast danger alert', 'danger', getUniqueId()) };
122
+ const addInfoAlert = () => { this.addAlert('Toast info alert', 'info', getUniqueId()) };
123
+ const onOverflowClick = () => {
124
+ console.log('Overflow message clicked');
125
+ };
126
+ return (
127
+ <React.Fragment>
128
+ <InputGroup style={{ marginBottom: '16px' }}>
129
+ <button onClick={addSuccessAlert} type="button" className={btnClasses}>Add toast success alert</button>
130
+ <button onClick={addDangerAlert} type="button" className={btnClasses}>Add toast danger alert</button>
131
+ <button onClick={addInfoAlert} type="button" className={btnClasses}>Add toast info alert</button>
132
+ </InputGroup>
133
+ <AlertGroup isToast isLiveRegion onOverflowClick={onOverflowClick} overflowMessage={this.state.overflowMessage}>
134
+ {this.state.alerts.slice(0, this.state.maxDisplayed).map(({key, variant, title}) => (
135
+ <Alert
136
+ variant={AlertVariant[variant]}
137
+ title={title}
138
+ actionClose={
139
+ <AlertActionCloseButton
140
+ title={title}
141
+ variantLabel={`${variant} alert`}
142
+ onClose={() => this.removeAlert(key)}
143
+ />
144
+ }
145
+ key={key} />
146
+ ))}
147
+ </AlertGroup>
148
+ </React.Fragment>
149
+ );
150
+ }
151
+ }
152
+ ```
153
+
81
154
  ### Singular dynamic alert group
82
155
  This alert will appear in the page, most likely in response to a user action.
83
156
  ```js
@@ -131,6 +204,80 @@ class SingularAdditiveAlertGroup extends React.Component {
131
204
  }
132
205
  ```
133
206
 
207
+ ### Singular dynamic alert group with overflow message
208
+ This alert will appear in the page, most likely in response to a user action. In this example we are showing a max of 4 alerts.
209
+ ```js isBeta
210
+ import React from 'react';
211
+ import { Alert, AlertGroup, AlertVariant, AlertActionCloseButton, InputGroup } from '@patternfly/react-core';
212
+ class SingularAdditiveAlertGroup extends React.Component {
213
+ constructor() {
214
+ super();
215
+ this.state = {
216
+ alerts: [],
217
+ maxDisplayed: "4",
218
+ overflowMessage: ''
219
+ };
220
+ this.getOverflowMessage = (alertsNumber) => {
221
+ const overflow = alertsNumber - this.state.maxDisplayed;
222
+ if (overflow > 0) {
223
+ return "View " + (overflow) + " more alerts";
224
+ }
225
+ return '';
226
+ };
227
+ this.addAlert = (title, variant, key) => {
228
+ this.setState({
229
+ ...this.state,
230
+ alerts: [ ...this.state.alerts, { title: title, variant: variant, key }],
231
+ overflowMessage: this.getOverflowMessage(this.state.alerts.length + 1)
232
+ });
233
+ };
234
+ this.removeAlert = key => {
235
+ const newAlerts = [...this.state.alerts.filter(el => el.key !== key)];
236
+ this.setState({
237
+ ...this.state,
238
+ alerts: newAlerts,
239
+ overflowMessage: this.getOverflowMessage(newAlerts.length)
240
+ });
241
+ };
242
+ }
243
+ render() {
244
+ const btnClasses = ['pf-c-button', 'pf-m-secondary'].join(' ');
245
+ const getUniqueId = () => (new Date().getTime());
246
+ const addSuccessAlert = () => { this.addAlert('Single success alert', 'success', getUniqueId()) };
247
+ const addDangerAlert = () => { this.addAlert('Single danger alert', 'danger', getUniqueId()) };
248
+ const addInfoAlert = () => { this.addAlert('Single info alert', 'info', getUniqueId()) };
249
+ const onOverflowClick = () => {
250
+ console.log('Overflow message clicked');
251
+ };
252
+ return (
253
+ <React.Fragment>
254
+ <InputGroup style={{ marginBottom: '16px' }}>
255
+ <button onClick={addSuccessAlert} type="button" className={btnClasses}>Add single success alert</button>
256
+ <button onClick={addDangerAlert} type="button" className={btnClasses}>Add single danger alert</button>
257
+ <button onClick={addInfoAlert} type="button" className={btnClasses}>Add single info alert</button>
258
+ </InputGroup>
259
+ <AlertGroup isLiveRegion overflowMessage={this.state.overflowMessage} onOverflowClick={onOverflowClick}>
260
+ {this.state.alerts.slice(0, this.state.maxDisplayed).map(({ title, variant, key }) => (
261
+ <Alert
262
+ isInline
263
+ variant={AlertVariant[variant]}
264
+ title={title}
265
+ key={key}
266
+ actionClose={
267
+ <AlertActionCloseButton
268
+ title={title}
269
+ variantLabel={`${variant} alert`}
270
+ onClose={() => this.removeAlert(key)}
271
+ />
272
+ }/>
273
+ ))}
274
+ </AlertGroup>
275
+ </React.Fragment>
276
+ );
277
+ }
278
+ }
279
+ ```
280
+
134
281
  ### Multiple dynamic alert group
135
282
  These alerts will appear in the page, most likely in response to a user action.
136
283
  ```js
@@ -83,6 +83,7 @@ export const NumberInput: React.FunctionComponent<NumberInputProps> = ({
83
83
  const numberInputUnit = <div className={css(styles.numberInputUnit)}>{unit}</div>;
84
84
  const keyDownHandler =
85
85
  inputProps && inputProps.onKeyDown ? inputProps.onKeyDown : defaultKeyDownHandler({ inputName, onMinus, onPlus });
86
+
86
87
  return (
87
88
  <div
88
89
  className={css(styles.numberInput, className)}
@@ -99,7 +100,7 @@ export const NumberInput: React.FunctionComponent<NumberInputProps> = ({
99
100
  <Button
100
101
  variant="control"
101
102
  aria-label={minusBtnAriaLabel}
102
- isDisabled={isDisabled || value === min}
103
+ isDisabled={isDisabled || value <= min}
103
104
  onClick={evt => onMinus(evt, inputName)}
104
105
  {...minusBtnProps}
105
106
  >
@@ -122,7 +123,7 @@ export const NumberInput: React.FunctionComponent<NumberInputProps> = ({
122
123
  <Button
123
124
  variant="control"
124
125
  aria-label={plusBtnAriaLabel}
125
- isDisabled={isDisabled || value === max}
126
+ isDisabled={isDisabled || value >= max}
126
127
  onClick={evt => onPlus(evt, inputName)}
127
128
  {...plusBtnProps}
128
129
  >
@@ -159,9 +159,20 @@ class UnitThresholdNumberInput extends React.Component {
159
159
  this.minValue = 0;
160
160
  this.maxValue = 10;
161
161
 
162
+ this.normalizeBetween = (value, min, max) => {
163
+ if (min !== undefined && max !== undefined) {
164
+ return Math.max(Math.min(value, max), min);
165
+ } else if (value <= min) {
166
+ return min;
167
+ } else if (value >= max) {
168
+ return max;
169
+ }
170
+ return value;
171
+ };
172
+
162
173
  this.onMinus = () => {
163
174
  this.setState({
164
- value: this.state.value - 1
175
+ value: this.normalizeBetween(this.state.value - 1, this.minValue, this.maxValue)
165
176
  });
166
177
  };
167
178
 
@@ -174,7 +185,7 @@ class UnitThresholdNumberInput extends React.Component {
174
185
 
175
186
  this.onPlus = () => {
176
187
  this.setState({
177
- value: this.state.value + 1
188
+ value: this.normalizeBetween(this.state.value + 1, this.minValue, this.maxValue)
178
189
  });
179
190
  };
180
191
  }
@@ -369,12 +380,12 @@ class CustomStepNumberInput extends React.Component {
369
380
  super(props);
370
381
  this.state = {
371
382
  value: 90,
372
- step: 3,
383
+ step: 3
373
384
  };
374
385
 
375
386
  this.stepper = step => () => {
376
- this.setState(prev => ({...prev, value: prev.value + step }))
377
- }
387
+ this.setState(prev => ({ ...prev, value: prev.value + step }));
388
+ };
378
389
 
379
390
  this.onChange = event => {
380
391
  this.setState({
@@ -400,3 +411,65 @@ class CustomStepNumberInput extends React.Component {
400
411
  }
401
412
  }
402
413
  ```
414
+
415
+ ### Custom increment/decrement and thresholds
416
+
417
+ ```js
418
+ import React from 'react';
419
+ import { NumberInput } from '@patternfly/react-core';
420
+
421
+ class CustomStepNumberInput extends React.Component {
422
+ constructor(props) {
423
+ super(props);
424
+ this.state = {
425
+ value: 90,
426
+ step: 3
427
+ };
428
+ this.minValue = 90;
429
+ this.maxValue = 100;
430
+
431
+ this.normalizeBetween = (value, min, max) => {
432
+ if (min !== undefined && max !== undefined) {
433
+ return Math.max(Math.min(value, max), min);
434
+ } else if (value <= min) {
435
+ return min;
436
+ } else if (value >= max) {
437
+ return max;
438
+ }
439
+ return value;
440
+ };
441
+
442
+ this.stepper = step => () => {
443
+ this.setState(prev => ({
444
+ ...prev,
445
+ value: this.normalizeBetween(prev.value + step, this.minValue, this.maxValue)
446
+ }));
447
+ };
448
+
449
+ this.onChange = event => {
450
+ const newValue = isNaN(event.target.value) ? 0 : Number(event.target.value);
451
+ this.setState({
452
+ value: newValue > this.maxValue ? this.maxValue : newValue < this.minValue ? this.minValue : newValue
453
+ });
454
+ };
455
+ }
456
+
457
+ render() {
458
+ const { value } = this.state;
459
+ return (
460
+ <NumberInput
461
+ value={value}
462
+ min={this.minValue}
463
+ max={this.maxValue}
464
+ onMinus={this.stepper(-3)}
465
+ onChange={this.onChange}
466
+ onPlus={this.stepper(3)}
467
+ inputName="input"
468
+ inputAriaLabel="number input"
469
+ minusBtnAriaLabel="minus"
470
+ plusBtnAriaLabel="plus"
471
+ />
472
+ );
473
+ }
474
+ }
475
+ ```