@patternfly/react-core 4.232.13 → 4.233.0

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 (48) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/esm/components/ExpandableSection/ExpandableSection.d.ts +17 -3
  3. package/dist/esm/components/ExpandableSection/ExpandableSection.d.ts.map +1 -1
  4. package/dist/esm/components/ExpandableSection/ExpandableSection.js +39 -8
  5. package/dist/esm/components/ExpandableSection/ExpandableSection.js.map +1 -1
  6. package/dist/esm/components/ExpandableSection/ExpandableSectionToggle.d.ts +2 -0
  7. package/dist/esm/components/ExpandableSection/ExpandableSectionToggle.d.ts.map +1 -1
  8. package/dist/esm/components/ExpandableSection/ExpandableSectionToggle.js +4 -4
  9. package/dist/esm/components/ExpandableSection/ExpandableSectionToggle.js.map +1 -1
  10. package/dist/esm/components/InputGroup/InputGroup.d.ts.map +1 -1
  11. package/dist/esm/components/InputGroup/InputGroup.js +5 -3
  12. package/dist/esm/components/InputGroup/InputGroup.js.map +1 -1
  13. package/dist/esm/components/NumberInput/NumberInput.d.ts +5 -0
  14. package/dist/esm/components/NumberInput/NumberInput.d.ts.map +1 -1
  15. package/dist/esm/components/NumberInput/NumberInput.js +5 -4
  16. package/dist/esm/components/NumberInput/NumberInput.js.map +1 -1
  17. package/dist/js/components/ExpandableSection/ExpandableSection.d.ts +17 -3
  18. package/dist/js/components/ExpandableSection/ExpandableSection.d.ts.map +1 -1
  19. package/dist/js/components/ExpandableSection/ExpandableSection.js +40 -9
  20. package/dist/js/components/ExpandableSection/ExpandableSection.js.map +1 -1
  21. package/dist/js/components/ExpandableSection/ExpandableSectionToggle.d.ts +2 -0
  22. package/dist/js/components/ExpandableSection/ExpandableSectionToggle.d.ts.map +1 -1
  23. package/dist/js/components/ExpandableSection/ExpandableSectionToggle.js +4 -4
  24. package/dist/js/components/ExpandableSection/ExpandableSectionToggle.js.map +1 -1
  25. package/dist/js/components/InputGroup/InputGroup.d.ts.map +1 -1
  26. package/dist/js/components/InputGroup/InputGroup.js +5 -3
  27. package/dist/js/components/InputGroup/InputGroup.js.map +1 -1
  28. package/dist/js/components/NumberInput/NumberInput.d.ts +5 -0
  29. package/dist/js/components/NumberInput/NumberInput.d.ts.map +1 -1
  30. package/dist/js/components/NumberInput/NumberInput.js +4 -3
  31. package/dist/js/components/NumberInput/NumberInput.js.map +1 -1
  32. package/dist/umd/react-core.css +69 -69
  33. package/dist/umd/react-core.js +56 -18
  34. package/dist/umd/react-core.min.css +921 -921
  35. package/dist/umd/react-core.min.js +5 -5
  36. package/package.json +6 -6
  37. package/src/components/ExpandableSection/ExpandableSection.tsx +73 -19
  38. package/src/components/ExpandableSection/ExpandableSectionToggle.tsx +15 -9
  39. package/src/components/ExpandableSection/__tests__/ExpandableSection.test.tsx +27 -1
  40. package/src/components/ExpandableSection/examples/ExpandableSection.md +7 -0
  41. package/src/components/ExpandableSection/examples/ExpandableSectionTruncateExpansion.tsx +27 -0
  42. package/src/components/InputGroup/InputGroup.tsx +5 -3
  43. package/src/components/InputGroup/__tests__/InputGroup.test.tsx +30 -0
  44. package/src/components/NumberInput/NumberInput.tsx +14 -8
  45. package/src/components/NumberInput/__tests__/NumberInput.test.tsx +16 -0
  46. package/src/components/NumberInput/__tests__/__snapshots__/NumberInput.test.tsx.snap +292 -18
  47. package/src/components/NumberInput/examples/NumberInput.md +5 -0
  48. package/src/components/NumberInput/examples/WithStatus.tsx +59 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "4.232.13",
3
+ "version": "4.233.0",
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",
@@ -50,16 +50,16 @@
50
50
  "generate": "node scripts/copyStyles.js"
51
51
  },
52
52
  "dependencies": {
53
- "@patternfly/react-icons": "^4.83.13",
54
- "@patternfly/react-styles": "^4.82.13",
55
- "@patternfly/react-tokens": "^4.84.13",
53
+ "@patternfly/react-icons": "^4.84.0",
54
+ "@patternfly/react-styles": "^4.83.0",
55
+ "@patternfly/react-tokens": "^4.85.0",
56
56
  "focus-trap": "6.9.2",
57
57
  "react-dropzone": "9.0.0",
58
58
  "tippy.js": "5.1.2",
59
59
  "tslib": "^2.0.0"
60
60
  },
61
61
  "devDependencies": {
62
- "@patternfly/patternfly": "4.208.1",
62
+ "@patternfly/patternfly": "4.209.0",
63
63
  "@rollup/plugin-commonjs": "^22.0.2",
64
64
  "@rollup/plugin-node-resolve": "^13.3.0",
65
65
  "@rollup/plugin-replace": "^4.0.0",
@@ -76,5 +76,5 @@
76
76
  "react": "^16.8.0 || ^17.0.0",
77
77
  "react-dom": "^16.8.0 || ^17.0.0"
78
78
  },
79
- "gitHead": "0dd257e3f6ec904a5aa670c4c8364e75ced77404"
79
+ "gitHead": "816b8605d11e6374b6f6b4c5d6da80d43265fc70"
80
80
  }
@@ -1,13 +1,19 @@
1
1
  import * as React from 'react';
2
2
  import styles from '@patternfly/react-styles/css/components/ExpandableSection/expandable-section';
3
3
  import { css } from '@patternfly/react-styles';
4
+ import lineClamp from '@patternfly/react-tokens/dist/esm/c_expandable_section_m_truncate__content_LineClamp';
4
5
  import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-icon';
5
6
  import { PickOptional } from '../../helpers/typeUtils';
6
7
 
8
+ export enum ExpandableSectionVariant {
9
+ default = 'default',
10
+ truncate = 'truncate'
11
+ }
12
+
7
13
  export interface ExpandableSectionProps extends React.HTMLProps<HTMLDivElement> {
8
- /** Content rendered inside the Expandable Component */
14
+ /** Content rendered inside the expandable section. */
9
15
  children?: React.ReactNode;
10
- /** Additional classes added to the Expandable Component */
16
+ /** Additional classes added to the expandable section. */
11
17
  className?: string;
12
18
  /** Flag to indicate if the content is expanded */
13
19
  isExpanded?: boolean;
@@ -19,7 +25,7 @@ export interface ExpandableSectionProps extends React.HTMLProps<HTMLDivElement>
19
25
  toggleTextCollapsed?: string;
20
26
  /** React node that appears in the attached toggle in place of toggle text */
21
27
  toggleContent?: React.ReactNode;
22
- /** Callback function to toggle the expandable content. Detached expandable sections should use the onToggle property of ExpandableSectionToggle. */
28
+ /** Callback function to toggle the expandable section. Detached expandable sections should use the onToggle property of the expandable section toggle sub-component. */
23
29
  onToggle?: (isExpanded: boolean) => void;
24
30
  /** Forces active state */
25
31
  isActive?: boolean;
@@ -33,12 +39,27 @@ export interface ExpandableSectionProps extends React.HTMLProps<HTMLDivElement>
33
39
  isWidthLimited?: boolean;
34
40
  /** Flag to indicate if the content is indented */
35
41
  isIndented?: boolean;
42
+ /** @beta Determines the variant of the expandable section. When passing in "truncate" as the
43
+ * variant, the expandable content will be truncated after 3 lines by default.
44
+ */
45
+ variant?: 'default' | 'truncate';
46
+ /** @beta Truncates the expandable content to the specified number of lines when using the
47
+ * "truncate" variant. */
48
+ truncateMaxLines?: number;
36
49
  }
37
50
 
38
51
  interface ExpandableSectionState {
39
52
  isExpanded: boolean;
40
53
  }
41
54
 
55
+ const setLineClamp = (lines: number, element: HTMLDivElement) => {
56
+ if (!element || lines < 1) {
57
+ return;
58
+ }
59
+
60
+ element.style.setProperty(lineClamp.name, lines.toString());
61
+ };
62
+
42
63
  export class ExpandableSection extends React.Component<ExpandableSectionProps, ExpandableSectionState> {
43
64
  static displayName = 'ExpandableSection';
44
65
  constructor(props: ExpandableSectionProps) {
@@ -49,6 +70,7 @@ export class ExpandableSection extends React.Component<ExpandableSectionProps, E
49
70
  };
50
71
  }
51
72
 
73
+ expandableContentRef = React.createRef<HTMLDivElement>();
52
74
  static defaultProps: PickOptional<ExpandableSectionProps> = {
53
75
  className: '',
54
76
  toggleText: '',
@@ -61,7 +83,8 @@ export class ExpandableSection extends React.Component<ExpandableSectionProps, E
61
83
  displaySize: 'default',
62
84
  isWidthLimited: false,
63
85
  isIndented: false,
64
- contentId: ''
86
+ contentId: '',
87
+ variant: 'default'
65
88
  };
66
89
 
67
90
  private calculateToggleText(
@@ -79,6 +102,23 @@ export class ExpandableSection extends React.Component<ExpandableSectionProps, E
79
102
  return toggleText;
80
103
  }
81
104
 
105
+ componentDidMount() {
106
+ if (this.props.variant === ExpandableSectionVariant.truncate && this.props.truncateMaxLines) {
107
+ const expandableContent = this.expandableContentRef.current;
108
+ setLineClamp(this.props.truncateMaxLines, expandableContent);
109
+ }
110
+ }
111
+
112
+ componentDidUpdate(prevProps: ExpandableSectionProps) {
113
+ if (
114
+ this.props.variant === ExpandableSectionVariant.truncate &&
115
+ prevProps.truncateMaxLines !== this.props.truncateMaxLines
116
+ ) {
117
+ const expandableContent = this.expandableContentRef.current;
118
+ setLineClamp(this.props.truncateMaxLines, expandableContent);
119
+ }
120
+ }
121
+
82
122
  render() {
83
123
  const {
84
124
  onToggle: onToggleProp,
@@ -96,6 +136,9 @@ export class ExpandableSection extends React.Component<ExpandableSectionProps, E
96
136
  isWidthLimited,
97
137
  isIndented,
98
138
  contentId,
139
+ variant,
140
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
141
+ truncateMaxLines,
99
142
  ...props
100
143
  } = this.props;
101
144
  let onToggle = onToggleProp;
@@ -116,9 +159,24 @@ export class ExpandableSection extends React.Component<ExpandableSectionProps, E
116
159
  propOrStateIsExpanded
117
160
  );
118
161
 
162
+ const expandableToggle = !isDetached && (
163
+ <button
164
+ className={css(styles.expandableSectionToggle)}
165
+ type="button"
166
+ aria-expanded={propOrStateIsExpanded}
167
+ onClick={() => onToggle(!propOrStateIsExpanded)}
168
+ >
169
+ {variant !== ExpandableSectionVariant.truncate && (
170
+ <span className={css(styles.expandableSectionToggleIcon)}>
171
+ <AngleRightIcon aria-hidden />
172
+ </span>
173
+ )}
174
+ <span className={css(styles.expandableSectionToggleText)}>{toggleContent || computedToggleText}</span>
175
+ </button>
176
+ );
177
+
119
178
  return (
120
179
  <div
121
- {...props}
122
180
  className={css(
123
181
  styles.expandableSection,
124
182
  propOrStateIsExpanded && styles.modifiers.expanded,
@@ -127,25 +185,21 @@ export class ExpandableSection extends React.Component<ExpandableSectionProps, E
127
185
  displaySize === 'large' && styles.modifiers.displayLg,
128
186
  isWidthLimited && styles.modifiers.limitWidth,
129
187
  isIndented && styles.modifiers.indented,
188
+ variant === ExpandableSectionVariant.truncate && styles.modifiers.truncate,
130
189
  className
131
190
  )}
191
+ {...props}
132
192
  >
133
- {!isDetached && (
134
- <button
135
- className={css(styles.expandableSectionToggle)}
136
- type="button"
137
- aria-expanded={propOrStateIsExpanded}
138
- onClick={() => onToggle(!propOrStateIsExpanded)}
139
- >
140
- <span className={css(styles.expandableSectionToggleIcon)}>
141
- <AngleRightIcon aria-hidden />
142
- </span>
143
- <span className={css(styles.expandableSectionToggleText)}>{toggleContent || computedToggleText}</span>
144
- </button>
145
- )}
146
- <div className={css(styles.expandableSectionContent)} hidden={!propOrStateIsExpanded} id={contentId}>
193
+ {variant === ExpandableSectionVariant.default && expandableToggle}
194
+ <div
195
+ ref={this.expandableContentRef}
196
+ className={css(styles.expandableSectionContent)}
197
+ hidden={variant !== ExpandableSectionVariant.truncate && !propOrStateIsExpanded}
198
+ id={contentId}
199
+ >
147
200
  {children}
148
201
  </div>
202
+ {variant === ExpandableSectionVariant.truncate && expandableToggle}
149
203
  </div>
150
204
  );
151
205
  }
@@ -16,6 +16,8 @@ export interface ExpandableSectionToggleProps extends React.HTMLProps<HTMLDivEle
16
16
  contentId?: string;
17
17
  /** Direction the toggle arrow should point when the expandable section is expanded. */
18
18
  direction?: 'up' | 'down';
19
+ /** @beta Flag to determine toggle styling when the expandable content is truncated. */
20
+ hasTruncatedContent?: boolean;
19
21
  }
20
22
 
21
23
  export const ExpandableSectionToggle: React.FunctionComponent<ExpandableSectionToggleProps> = ({
@@ -25,16 +27,18 @@ export const ExpandableSectionToggle: React.FunctionComponent<ExpandableSectionT
25
27
  onToggle,
26
28
  contentId,
27
29
  direction = 'down',
30
+ hasTruncatedContent = false,
28
31
  ...props
29
32
  }: ExpandableSectionToggleProps) => (
30
33
  <div
31
- {...props}
32
34
  className={css(
33
35
  styles.expandableSection,
34
36
  isExpanded && styles.modifiers.expanded,
35
37
  styles.modifiers.detached,
38
+ hasTruncatedContent && styles.modifiers.truncate,
36
39
  className
37
40
  )}
41
+ {...props}
38
42
  >
39
43
  <button
40
44
  className={css(styles.expandableSectionToggle)}
@@ -43,14 +47,16 @@ export const ExpandableSectionToggle: React.FunctionComponent<ExpandableSectionT
43
47
  aria-controls={contentId}
44
48
  onClick={() => onToggle(!isExpanded)}
45
49
  >
46
- <span
47
- className={css(
48
- styles.expandableSectionToggleIcon,
49
- isExpanded && direction === 'up' && styles.modifiers.expandTop
50
- )}
51
- >
52
- <AngleRightIcon aria-hidden />
53
- </span>
50
+ {!hasTruncatedContent && (
51
+ <span
52
+ className={css(
53
+ styles.expandableSectionToggleIcon,
54
+ isExpanded && direction === 'up' && styles.modifiers.expandTop
55
+ )}
56
+ >
57
+ <AngleRightIcon aria-hidden />
58
+ </span>
59
+ )}
54
60
  <span className={css(styles.expandableSectionToggleText)}>{children}</span>
55
61
  </button>
56
62
  </div>
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { render, screen } from '@testing-library/react';
4
4
  import userEvent from '@testing-library/user-event';
5
5
 
6
- import { ExpandableSection } from '../ExpandableSection';
6
+ import { ExpandableSection, ExpandableSectionVariant } from '../ExpandableSection';
7
7
  import { ExpandableSectionToggle } from '../ExpandableSectionToggle';
8
8
 
9
9
  const props = {};
@@ -64,3 +64,29 @@ test('Renders ExpandableSection indented', () => {
64
64
  );
65
65
  expect(asFragment()).toMatchSnapshot();
66
66
  });
67
+
68
+ test('Does not render with pf-m-truncate class when variant is not passed', () => {
69
+ render(<ExpandableSection {...props}>test</ExpandableSection>);
70
+
71
+ expect(screen.getByText('test').parentElement).not.toHaveClass('pf-m-truncate');
72
+ });
73
+
74
+ test('Does not render with pf-m-truncate class when variant is not truncate', () => {
75
+ render(
76
+ <ExpandableSection variant={ExpandableSectionVariant.default} {...props}>
77
+ test
78
+ </ExpandableSection>
79
+ );
80
+
81
+ expect(screen.getByText('test').parentElement).not.toHaveClass('pf-m-truncate');
82
+ });
83
+
84
+ test('Renders with pf-m-truncate class when variant is truncate', () => {
85
+ render(
86
+ <ExpandableSection variant={ExpandableSectionVariant.truncate} {...props}>
87
+ test
88
+ </ExpandableSection>
89
+ );
90
+
91
+ expect(screen.getByText('test').parentElement).toHaveClass('pf-m-truncate');
92
+ });
@@ -45,3 +45,10 @@ By using the `toggleContent` prop, you can pass in content other than a simple s
45
45
 
46
46
  ```ts file="ExpandableSectionCustomToggle.tsx"
47
47
  ```
48
+
49
+ ### Truncate expansion
50
+
51
+ By passing in `variant="truncate"`, the expandable content will be visible up to a maximum number of lines before being truncated, with the toggle revealing or hiding the truncated content. By default the expandable content will truncate after 3 lines, and this can be customized by also passing in the `truncateMaxLines` prop.
52
+
53
+ ```ts file="ExpandableSectionTruncateExpansion.tsx" isBeta
54
+ ```
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import { ExpandableSection, ExpandableSectionVariant } from '@patternfly/react-core';
3
+
4
+ export const ExpandableSectionTruncateExpansion: React.FunctionComponent = () => {
5
+ const [isExpanded, setIsExpanded] = React.useState(false);
6
+
7
+ const onToggle = (isExpanded: boolean) => {
8
+ setIsExpanded(isExpanded);
9
+ };
10
+
11
+ return (
12
+ <ExpandableSection
13
+ variant={ExpandableSectionVariant.truncate}
14
+ toggleText={isExpanded ? 'Show less' : 'Show more'}
15
+ onToggle={onToggle}
16
+ isExpanded={isExpanded}
17
+ >
18
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque nec dignissim turpis, et tristique purus.
19
+ Phasellus efficitur ante quis dolor viverra imperdiet. Orci varius natoque penatibus et magnis dis parturient
20
+ montes, nascetur ridiculus mus. Pellentesque laoreet, sem ac elementum semper, lectus mauris vestibulum nulla,
21
+ eget volutpat massa neque vel turpis. Donec finibus enim eu leo accumsan consectetur. Praesent massa diam,
22
+ tincidunt eu dui ac, ullamcorper elementum est. Phasellus metus felis, venenatis vitae semper nec, porta a metus.
23
+ Vestibulum justo nisi, imperdiet id eleifend at, varius nec lorem. Fusce porttitor mollis nibh, ut elementum ante
24
+ commodo tincidunt. Integer tincidunt at ipsum non aliquet.
25
+ </ExpandableSection>
26
+ );
27
+ };
@@ -31,9 +31,11 @@ export const InputGroup: React.FunctionComponent<InputGroupProps> = ({
31
31
  <div ref={inputGroupRef} className={css(styles.inputGroup, className)} {...props}>
32
32
  {idItem
33
33
  ? React.Children.map(children, (child: any) =>
34
- formCtrls.includes(child.type.displayName)
35
- ? React.cloneElement(child, { 'aria-describedby': idItem.props.id })
36
- : child
34
+ !formCtrls.includes(child.type.displayName) || child.props['aria-describedby']
35
+ ? child
36
+ : React.cloneElement(child, {
37
+ 'aria-describedby': child.props['aria-describedby'] === '' ? undefined : idItem.props.id
38
+ })
37
39
  )
38
40
  : children}
39
41
  </div>
@@ -20,4 +20,34 @@ describe('InputGroup', () => {
20
20
  );
21
21
  expect(screen.getByLabelText('some text')).toHaveAttribute('aria-describedby', 'button-id');
22
22
  });
23
+
24
+ test('wont add aria-describedby to form-control if describedby is empty string', () => {
25
+ // In this test, TextInput is a form-control component and Button is not.
26
+ // If Button has an id props, this should be used in aria-describedby, but this
27
+ // example has an empty aria-describedby to prevent that from happening.
28
+ render(
29
+ <InputGroup>
30
+ <TextInput value="some data" aria-describedby="" aria-label="some text" />
31
+ <Button id="button-id">
32
+ hello
33
+ </Button>
34
+ </InputGroup>
35
+ );
36
+ expect(screen.getByLabelText('some text')).not.toHaveAttribute('aria-describedby');
37
+ });
38
+
39
+ test('wont override aria-describedby in form-control if describedby has value', () => {
40
+ // In this test, TextInput is a form-control component and Button is not.
41
+ // If Button has an id props, this should be used in aria-describedby, but this
42
+ // example has a predefined aria-describedby to prevent that from happening
43
+ render(
44
+ <InputGroup>
45
+ <TextInput value="some data" aria-describedby="myself" aria-label="some text" />
46
+ <Button id="button-id">
47
+ hello
48
+ </Button>
49
+ </InputGroup>
50
+ );
51
+ expect(screen.getByLabelText('some text')).toHaveAttribute('aria-describedby', 'myself');
52
+ });
23
53
  });
@@ -5,7 +5,8 @@ import MinusIcon from '@patternfly/react-icons/dist/esm/icons/minus-icon';
5
5
  import PlusIcon from '@patternfly/react-icons/dist/esm/icons/plus-icon';
6
6
  import { InputGroup } from '../InputGroup';
7
7
  import { Button, ButtonProps } from '../Button';
8
- import { KEY_CODES } from '../../helpers';
8
+ import { KEY_CODES, ValidatedOptions } from '../../helpers';
9
+ import { TextInput } from '../TextInput';
9
10
 
10
11
  export interface NumberInputProps extends React.HTMLProps<HTMLDivElement> {
11
12
  /** Value of the number input */
@@ -16,6 +17,10 @@ export interface NumberInputProps extends React.HTMLProps<HTMLDivElement> {
16
17
  widthChars?: number;
17
18
  /** Indicates the whole number input should be disabled */
18
19
  isDisabled?: boolean;
20
+ /** Value to indicate if the input is modified to show that validation state
21
+ * @beta
22
+ */
23
+ validated?: 'default' | 'error' | 'warning' | 'success' | ValidatedOptions;
19
24
  /** Callback for the minus button */
20
25
  onMinus?: (event: React.MouseEvent, name?: string) => void;
21
26
  /** Callback for the text input changing */
@@ -66,6 +71,7 @@ export const NumberInput: React.FunctionComponent<NumberInputProps> = ({
66
71
  className,
67
72
  widthChars,
68
73
  isDisabled = false,
74
+ validated = ValidatedOptions.default,
69
75
  onMinus = () => {},
70
76
  onChange,
71
77
  onBlur,
@@ -99,7 +105,7 @@ export const NumberInput: React.FunctionComponent<NumberInputProps> = ({
99
105
 
100
106
  return (
101
107
  <div
102
- className={css(styles.numberInput, className)}
108
+ className={css(styles.numberInput, validated !== 'default' && styles.modifiers.status, className)}
103
109
  {...(widthChars && {
104
110
  style: {
105
111
  '--pf-c-number-input--c-form-control--width-chars': widthChars,
@@ -121,18 +127,18 @@ export const NumberInput: React.FunctionComponent<NumberInputProps> = ({
121
127
  <MinusIcon aria-hidden="true" />
122
128
  </span>
123
129
  </Button>
124
- <input
125
- className={css(styles.formControl)}
130
+ <TextInput
126
131
  type="number"
127
132
  value={value}
128
133
  name={inputName}
129
134
  aria-label={inputAriaLabel}
130
- {...(isDisabled && { disabled: isDisabled })}
131
- {...(onChange && { onChange })}
135
+ {...(isDisabled && { isDisabled })}
136
+ {...(onChange && { onChange: (value, event) => onChange(event) })}
132
137
  onBlur={handleBlur}
133
- {...(!onChange && { readOnly: true })}
134
- {...inputProps}
138
+ {...(!onChange && { isReadOnly: true })}
135
139
  onKeyDown={keyDownHandler}
140
+ validated={validated}
141
+ {...inputProps}
136
142
  />
137
143
  <Button
138
144
  variant="control"
@@ -9,6 +9,21 @@ describe('numberInput', () => {
9
9
  expect(asFragment()).toMatchSnapshot();
10
10
  });
11
11
 
12
+ test('renders success validated', () => {
13
+ const { asFragment } = render(<NumberInput validated='success' />);
14
+ expect(asFragment()).toMatchSnapshot();
15
+ })
16
+
17
+ test('renders error validated', () => {
18
+ const { asFragment } = render(<NumberInput validated='error' />);
19
+ expect(asFragment()).toMatchSnapshot();
20
+ })
21
+
22
+ test('renders warning validated', () => {
23
+ const { asFragment } = render(<NumberInput validated='warning' />);
24
+ expect(asFragment()).toMatchSnapshot();
25
+ })
26
+
12
27
  test('renders value', () => {
13
28
  const { asFragment } = render(<NumberInput value={90} />);
14
29
  expect(asFragment()).toMatchSnapshot();
@@ -54,6 +69,7 @@ describe('numberInput', () => {
54
69
  <NumberInput
55
70
  value={5}
56
71
  onMinus={jest.fn()}
72
+ inputProps={{ 'aria-describedby': '' }}
57
73
  minusBtnProps={{ id: 'minus-id' }}
58
74
  onPlus={jest.fn()}
59
75
  plusBtnProps={{ id: 'plus-id' }}