@patternfly/react-core 4.232.9 → 4.232.12

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 (27) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/esm/components/Label/Label.d.ts.map +1 -1
  3. package/dist/esm/components/Label/Label.js +3 -0
  4. package/dist/esm/components/Label/Label.js.map +1 -1
  5. package/dist/esm/components/LabelGroup/LabelGroup.d.ts +4 -4
  6. package/dist/esm/components/LabelGroup/LabelGroup.d.ts.map +1 -1
  7. package/dist/js/components/Label/Label.d.ts.map +1 -1
  8. package/dist/js/components/Label/Label.js +3 -0
  9. package/dist/js/components/Label/Label.js.map +1 -1
  10. package/dist/js/components/LabelGroup/LabelGroup.d.ts +4 -4
  11. package/dist/js/components/LabelGroup/LabelGroup.d.ts.map +1 -1
  12. package/dist/umd/react-core.js +415 -507
  13. package/dist/umd/react-core.min.js +5 -5
  14. package/package.json +10 -10
  15. package/src/components/Label/Label.tsx +3 -1
  16. package/src/components/LabelGroup/LabelGroup.tsx +4 -4
  17. package/src/components/LabelGroup/examples/LabelGroup.md +1 -1
  18. package/src/components/LabelGroup/examples/LabelGroupEditableAdd.tsx +1 -1
  19. package/src/components/LabelGroup/examples/LabelGroupEditableAddDropdown.tsx +1 -1
  20. package/src/components/LabelGroup/examples/LabelGroupEditableAddModal.tsx +23 -21
  21. package/src/components/SearchInput/examples/SearchInput.md +6 -223
  22. package/src/components/SearchInput/examples/SearchInputAdvanced.tsx +56 -0
  23. package/src/components/SearchInput/examples/SearchInputBasic.tsx +12 -0
  24. package/src/components/SearchInput/examples/SearchInputFocusSearch.tsx +14 -0
  25. package/src/components/SearchInput/examples/SearchInputWithNavigableOptions.tsx +43 -0
  26. package/src/components/SearchInput/examples/SearchInputWithResultCount.tsx +27 -0
  27. package/src/components/SearchInput/examples/SearchInputWithSubmitButton.tsx +16 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "4.232.9",
3
+ "version": "4.232.12",
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,9 +50,9 @@
50
50
  "generate": "node scripts/copyStyles.js"
51
51
  },
52
52
  "dependencies": {
53
- "@patternfly/react-icons": "^4.83.9",
54
- "@patternfly/react-styles": "^4.82.9",
55
- "@patternfly/react-tokens": "^4.84.9",
53
+ "@patternfly/react-icons": "^4.83.12",
54
+ "@patternfly/react-styles": "^4.82.12",
55
+ "@patternfly/react-tokens": "^4.84.12",
56
56
  "focus-trap": "6.9.2",
57
57
  "react-dropzone": "9.0.0",
58
58
  "tippy.js": "5.1.2",
@@ -60,21 +60,21 @@
60
60
  },
61
61
  "devDependencies": {
62
62
  "@patternfly/patternfly": "4.208.1",
63
- "@rollup/plugin-commonjs": "^21.0.0",
64
- "@rollup/plugin-node-resolve": "^13.0.0",
65
- "@rollup/plugin-replace": "^3.0.0",
63
+ "@rollup/plugin-commonjs": "^22.0.2",
64
+ "@rollup/plugin-node-resolve": "^13.3.0",
65
+ "@rollup/plugin-replace": "^4.0.0",
66
66
  "css": "^2.2.3",
67
67
  "fs-extra": "^6.0.1",
68
68
  "glob": "^7.1.2",
69
69
  "rimraf": "^3.0.2",
70
- "rollup": "^2.58.0",
70
+ "rollup": "^2.78.0",
71
71
  "rollup-plugin-scss": "^3.0.0",
72
- "rollup-plugin-terser": "^7.0.0",
72
+ "rollup-plugin-terser": "^7.0.2",
73
73
  "typescript": "^4.7.4"
74
74
  },
75
75
  "peerDependencies": {
76
76
  "react": "^16.8.0 || ^17.0.0",
77
77
  "react-dom": "^16.8.0 || ^17.0.0"
78
78
  },
79
- "gitHead": "5dcbfc431138fdca38af2734e31d759b3719dc32"
79
+ "gitHead": "f78c7a0fe58401bb6a9e3b380067a98af76cf523"
80
80
  }
@@ -104,7 +104,7 @@ export const Label: React.FunctionComponent<LabelProps> = ({
104
104
  render,
105
105
  ...props
106
106
  }: LabelProps) => {
107
- const [isEditableActive, setIsEditableActive] = useState(false);
107
+ const [isEditableActive, setIsEditableActive] = useState<boolean>(false);
108
108
  const [currValue, setCurrValue] = useState(children);
109
109
  const editableButtonRef = React.useRef<HTMLButtonElement>();
110
110
  const editableInputRef = React.useRef<HTMLInputElement>();
@@ -151,6 +151,7 @@ export const Label: React.FunctionComponent<LabelProps> = ({
151
151
  onEditComplete && onEditComplete(editableInputRef.current.value);
152
152
  }
153
153
  setIsEditableActive(false);
154
+ editableButtonRef?.current?.focus();
154
155
  }
155
156
  if (isEditableActive && key === 'Escape') {
156
157
  event.preventDefault();
@@ -161,6 +162,7 @@ export const Label: React.FunctionComponent<LabelProps> = ({
161
162
  onEditCancel && onEditCancel(children as string);
162
163
  }
163
164
  setIsEditableActive(false);
165
+ editableButtonRef?.current?.focus();
164
166
  }
165
167
  if (!isEditableActive && key === 'Enter') {
166
168
  event.preventDefault();
@@ -52,13 +52,13 @@ export interface LabelGroupProps extends React.HTMLProps<HTMLUListElement> {
52
52
  | 'right-end';
53
53
  /** Flag to implement a vertical layout */
54
54
  isVertical?: boolean;
55
- /** @beta Flag indicating contained labels are editable. Allows spacing for a text input after the labels. */
55
+ /** Flag indicating contained labels are editable. Allows spacing for a text input after the labels. */
56
56
  isEditable?: boolean;
57
- /** @beta Flag indicating the editable label group should be appended with a textarea. */
57
+ /** Flag indicating the editable label group should be appended with a textarea. */
58
58
  hasEditableTextArea?: boolean;
59
- /** @beta Additional props passed to the editable textarea. */
59
+ /** Additional props passed to the editable textarea. */
60
60
  editableTextAreaProps?: any;
61
- /** @beta Control for adding new labels */
61
+ /** Control for adding new labels */
62
62
  addLabelControl?: React.ReactNode;
63
63
  }
64
64
 
@@ -38,7 +38,7 @@ import InfoCircleIcon from '@patternfly/react-icons/dist/esm/icons/info-circle-i
38
38
 
39
39
  ### Editable labels
40
40
 
41
- ```ts file="LabelGroupEditableLabels.tsx" isBeta
41
+ ```ts file="LabelGroupEditableLabels.tsx"
42
42
  ```
43
43
 
44
44
  ### Editable labels with add button
@@ -58,7 +58,7 @@ export const LabelGroupEditableAdd: React.FunctionComponent = () => {
58
58
  >
59
59
  {labels.map((label, index) => (
60
60
  <Label
61
- key={`${label.name}-${index}`}
61
+ key={label.id}
62
62
  id={`${label.name}-${index}`}
63
63
  color="blue"
64
64
  onClose={() => onClose(label.id)}
@@ -121,7 +121,7 @@ export const LabelGroupEditableAddDropdown: React.FunctionComponent = () => {
121
121
  >
122
122
  {labels.map((label, index) => (
123
123
  <Label
124
- key={`${label.name}-${index}`}
124
+ key={label.id}
125
125
  id={`${label.name}-${index}`}
126
126
  color="blue"
127
127
  onClose={() => onClose(label.id)}
@@ -27,17 +27,17 @@ export const LabelGroupEditableAddModal: React.FunctionComponent = () => {
27
27
  const [labelType, setLabelType] = React.useState<string>('filled');
28
28
  const [isClosable, setIsCloseable] = React.useState<boolean>(false);
29
29
  const [isEditable, setIsEditable] = React.useState<boolean>(false);
30
- const labelInputRef = React.useRef();
30
+ const labelInputRef = React.useRef(null);
31
31
 
32
32
  const [isColorOpen, setIsColorOpen] = React.useState<boolean>(false);
33
- const colorMenuRef = React.useRef<HTMLDivElement>();
34
- const colorContainerRef = React.useRef<HTMLDivElement>();
35
- const colorToggleRef = React.useRef<HTMLButtonElement>();
33
+ const colorMenuRef = React.useRef<HTMLDivElement>(null);
34
+ const colorContainerRef = React.useRef<HTMLDivElement>(null);
35
+ const colorToggleRef = React.useRef<HTMLButtonElement>(null);
36
36
 
37
37
  const [isIconOpen, setIsIconOpen] = React.useState<boolean>(false);
38
- const iconMenuRef = React.useRef<HTMLDivElement>();
39
- const iconContainerRef = React.useRef<HTMLDivElement>();
40
- const iconToggleRef = React.useRef<HTMLButtonElement>();
38
+ const iconMenuRef = React.useRef<HTMLDivElement>(null);
39
+ const iconContainerRef = React.useRef<HTMLDivElement>(null);
40
+ const iconToggleRef = React.useRef<HTMLButtonElement>(null);
41
41
 
42
42
  const [labels, setLabels] = React.useState<any>([
43
43
  { name: 'Label 1', id: 0 },
@@ -65,7 +65,7 @@ export const LabelGroupEditableAddModal: React.FunctionComponent = () => {
65
65
  };
66
66
 
67
67
  const onAdd = () => {
68
- let labelIcon = null;
68
+ let labelIcon: any;
69
69
  if (icon === 'Info circle icon') {
70
70
  labelIcon = <InfoCircleIcon />;
71
71
  }
@@ -92,7 +92,7 @@ export const LabelGroupEditableAddModal: React.FunctionComponent = () => {
92
92
  setModalOpen(!isModalOpen);
93
93
  setIdIndex(idIndex + 1);
94
94
  setLabelText('');
95
- setColor(null);
95
+ setColor('');
96
96
  setIcon(null);
97
97
  setLabelType('filled');
98
98
  setIsCloseable(false);
@@ -110,25 +110,25 @@ export const LabelGroupEditableAddModal: React.FunctionComponent = () => {
110
110
  }, [isModalOpen]);
111
111
 
112
112
  const handleMenuKeys = (event: KeyboardEvent) => {
113
- if (isColorOpen && colorMenuRef.current.contains(event.target as Node)) {
113
+ if (isColorOpen && colorMenuRef?.current?.contains(event.target as Node)) {
114
114
  if (event.key === 'Escape' || event.key === 'Tab') {
115
115
  setIsColorOpen(!isColorOpen);
116
- colorToggleRef.current.focus();
116
+ colorToggleRef?.current?.focus();
117
117
  }
118
118
  }
119
- if (isIconOpen && iconMenuRef.current.contains(event.target as Node)) {
119
+ if (isIconOpen && iconMenuRef?.current?.contains(event.target as Node)) {
120
120
  if (event.key === 'Escape' || event.key === 'Tab') {
121
121
  setIsIconOpen(!isIconOpen);
122
- iconToggleRef.current.focus();
122
+ iconToggleRef?.current?.focus();
123
123
  }
124
124
  }
125
125
  };
126
126
 
127
127
  const handleClickOutside = (event: MouseEvent) => {
128
- if (isColorOpen && !colorMenuRef.current.contains(event.target as Node)) {
128
+ if (isColorOpen && !colorMenuRef?.current?.contains(event.target as Node)) {
129
129
  setIsColorOpen(false);
130
130
  }
131
- if (isIconOpen && !iconMenuRef.current.contains(event.target as Node)) {
131
+ if (isIconOpen && !iconMenuRef?.current?.contains(event.target as Node)) {
132
132
  setIsIconOpen(false);
133
133
  }
134
134
  };
@@ -164,7 +164,8 @@ export const LabelGroupEditableAddModal: React.FunctionComponent = () => {
164
164
  ref={colorMenuRef}
165
165
  activeItemId={color}
166
166
  onSelect={(_ev, itemId) => {
167
- setColor(itemId.toString());
167
+ setColor(itemId?.toString());
168
+ colorToggleRef?.current?.focus();
168
169
  setIsColorOpen(false);
169
170
  }}
170
171
  selected={color}
@@ -205,7 +206,8 @@ export const LabelGroupEditableAddModal: React.FunctionComponent = () => {
205
206
  ref={iconMenuRef}
206
207
  activeItemId={icon}
207
208
  onSelect={(_ev, itemId) => {
208
- setIcon(itemId.toString());
209
+ setIcon(itemId?.toString());
210
+ iconToggleRef?.current?.focus();
209
211
  setIsIconOpen(false);
210
212
  }}
211
213
  selected={icon}
@@ -234,9 +236,9 @@ export const LabelGroupEditableAddModal: React.FunctionComponent = () => {
234
236
  </Label>
235
237
  }
236
238
  >
237
- {labels.map((label, index) => (
239
+ {labels.map((label: { name: string; id: string; props: any }, index: number) => (
238
240
  <Label
239
- key={`${label.name}-${index}`}
241
+ key={label.id}
240
242
  id={`${label.name}-${index}`}
241
243
  color="blue"
242
244
  onClose={() => onClose(label.id)}
@@ -278,7 +280,7 @@ export const LabelGroupEditableAddModal: React.FunctionComponent = () => {
278
280
  <Popper
279
281
  trigger={colorToggle}
280
282
  popper={colorMenu}
281
- appendTo={colorContainerRef.current}
283
+ appendTo={colorContainerRef.current as HTMLElement}
282
284
  isVisible={isColorOpen}
283
285
  popperMatchesTriggerWidth={false}
284
286
  />
@@ -289,7 +291,7 @@ export const LabelGroupEditableAddModal: React.FunctionComponent = () => {
289
291
  <Popper
290
292
  trigger={iconToggle}
291
293
  popper={iconMenu}
292
- appendTo={iconContainerRef.current}
294
+ appendTo={iconContainerRef.current as HTMLElement}
293
295
  isVisible={isIconOpen}
294
296
  popperMatchesTriggerWidth={false}
295
297
  />
@@ -6,193 +6,33 @@ propComponents: ['SearchInput', 'SearchAttribute']
6
6
  beta: true
7
7
  ---
8
8
 
9
- import { SearchInput } from '@patternfly/react-core';
10
9
  import { ExternalLinkSquareAltIcon } from '@patternfly/react-icons';
11
10
 
12
11
  ## Examples
13
12
 
14
13
  ### Basic
15
14
 
16
- ```js
17
- import React from 'react';
18
- import { SearchInput } from '@patternfly/react-core';
19
-
20
- class BasicSearchInput extends React.Component {
21
- constructor(props) {
22
- super(props);
23
- this.state = {
24
- value: ''
25
- };
26
-
27
- this.onChange = (value, event) => {
28
- this.setState({
29
- value: value
30
- });
31
- };
32
- }
33
-
34
- render() {
35
- return (
36
- <SearchInput
37
- placeholder="Find by name"
38
- value={this.state.value}
39
- onChange={this.onChange}
40
- onClear={evt => this.onChange('', evt)}
41
- />
42
- );
43
- }
44
- }
15
+ ```ts file='./SearchInputBasic.tsx'
45
16
  ```
46
17
 
47
18
  ### Match with result count
48
19
 
49
- ```js
50
- import React from 'react';
51
- import { SearchInput } from '@patternfly/react-core';
52
-
53
- class SearchInputWithResultCount extends React.Component {
54
- constructor(props) {
55
- super(props);
56
- this.state = {
57
- value: '',
58
- resultsCount: 0
59
- };
60
-
61
- this.onChange = (value, event) => {
62
- this.setState({
63
- value: value,
64
- resultsCount: 3
65
- });
66
- };
67
-
68
- this.onClear = event => {
69
- this.setState({
70
- value: '',
71
- resultsCount: 0
72
- });
73
- };
74
- }
75
-
76
- render() {
77
- return (
78
- <SearchInput
79
- placeholder="Find by name"
80
- value={this.state.value}
81
- onChange={this.onChange}
82
- onClear={this.onClear}
83
- resultsCount={this.state.resultsCount}
84
- />
85
- );
86
- }
87
- }
20
+ ```ts file='./SearchInputWithResultCount.tsx'
88
21
  ```
89
22
 
90
23
  ### Match with navigable options
91
24
 
92
- ```js
93
- import React from 'react';
94
- import { SearchInput } from '@patternfly/react-core';
95
-
96
- class SearchInputWithNavigableOptions extends React.Component {
97
- constructor(props) {
98
- super(props);
99
- this.state = {
100
- value: '',
101
- resultsCount: 0,
102
- currentResult: 1,
103
- isPreviousNavigationButtonDisabled: false,
104
- isNextNavigationButtonDisabled: false
105
- };
106
-
107
- this.onChange = (value, event) => {
108
- this.setState({
109
- value: value,
110
- resultsCount: 3
111
- });
112
- };
113
-
114
- this.onClear = event => {
115
- this.setState({
116
- value: '',
117
- resultsCount: 0,
118
- currentResult: 1
119
- });
120
- };
121
-
122
- this.onNext = event => {
123
- this.setState(prevState => {
124
- const newCurrentResult = prevState.currentResult + 1;
125
- return {
126
- currentResult: newCurrentResult <= prevState.resultsCount ? newCurrentResult : prevState.resultsCount
127
- };
128
- });
129
- };
130
-
131
- this.onPrevious = event => {
132
- this.setState(prevState => {
133
- const newCurrentResult = prevState.currentResult - 1;
134
- return {
135
- currentResult: newCurrentResult > 0 ? newCurrentResult : 1
136
- };
137
- });
138
- };
139
- }
140
- render() {
141
- return (
142
- <SearchInput
143
- placeholder="Find by name"
144
- value={this.state.value}
145
- onChange={this.onChange}
146
- onClear={this.onClear}
147
- isNextNavigationButtonDisabled={this.state.currentResult === 3}
148
- isPreviousNavigationButtonDisabled={this.state.currentResult === 1}
149
- resultsCount={`${this.state.currentResult} / ${this.state.resultsCount}`}
150
- onNextClick={this.onNext}
151
- onPreviousClick={this.onPrevious}
152
- />
153
- );
154
- }
155
- }
25
+ ```ts file='./SearchInputWithNavigableOptions.tsx'
156
26
  ```
157
27
 
158
28
  ### With submit button
159
29
 
160
- ```js
161
- import React from 'react';
162
- import { SearchInput } from '@patternfly/react-core';
163
-
164
- SubmitButtonSearchInput = () => {
165
- const [value, setValue] = React.useState('');
166
-
167
- return (
168
- <SearchInput
169
- placeholder='Find by name'
170
- value={value}
171
- onChange={setValue}
172
- onSearch={setValue}
173
- onClear={() => setValue('')}
174
- />
175
- );
176
- }
177
-
30
+ ```ts file='./SearchInputWithSubmitButton.tsx'
178
31
  ```
179
32
 
180
33
  ### Focus search input using ref
181
34
 
182
- ```js
183
- import React from 'react';
184
- import { SearchInput, Button } from '@patternfly/react-core';
185
-
186
- TextInputSelectAll = () => {
187
- const [value, setValue] = React.useState('');
188
- const ref = React.useRef(null);
189
- return (
190
- <React.Fragment>
191
- <SearchInput ref={ref} value={value} onChange={setValue} onClear={() => setValue('')} />
192
- <Button onClick={() => ref.current && ref.current.focus()}>Focus on the search input</Button>
193
- </React.Fragment>
194
- );
195
- };
35
+ ```ts file='./SearchInputFocusSearch.tsx'
196
36
  ```
197
37
 
198
38
  ### Advanced
@@ -203,62 +43,5 @@ the following example. The search input component can also be used as a composab
203
43
  or other elements to build a completely custom advanced search form. This feature is demonstrated
204
44
  in the search input's <a href="/components/search-input/react-demos">react demos</a>.
205
45
 
206
- ```js
207
- import React from 'react';
208
- import { Button, Checkbox, FormGroup, SearchInput } from '@patternfly/react-core';
209
- import ExternalLinkSquareAltIcon from '@patternfly/react-icons/dist/esm/icons/external-link-square-alt-icon';
210
-
211
- AdvancedSearchInput = () => {
212
- const [value, setValue] = React.useState('username:player firstname:john');
213
- const [useEqualsAsDelimiter, setUseEqualsAsDelimiter] = React.useState(false);
214
- const [useCustomFooter, setUseCustomFooter] = React.useState(false);
215
-
216
- const toggleDelimiter = checked => {
217
- const newValue = value.replace(/:|=/g, checked ? '=' : ':');
218
- setUseEqualsAsDelimiter(checked);
219
- setValue(newValue);
220
- };
221
-
222
- return (
223
- <>
224
- <Checkbox
225
- label="Use equal sign as search attribute delimiter"
226
- isChecked={useEqualsAsDelimiter}
227
- onChange={toggleDelimiter}
228
- aria-label="change delimiter checkbox"
229
- id="toggle-delimiter"
230
- name="toggle-delimiter"
231
- />
232
- <Checkbox
233
- label="Add custom footer element after the attributes in the menu"
234
- isChecked={useCustomFooter}
235
- onChange={value => setUseCustomFooter(value)}
236
- aria-label="change use custom footer checkbox"
237
- id="toggle-custom-footer"
238
- name="toggle-custom-footer"
239
- />
240
- <br />
241
- <SearchInput
242
- attributes={[
243
- { attr: 'username', display: 'Username' },
244
- { attr: 'firstname', display: 'First name' }
245
- ]}
246
- advancedSearchDelimiter={useEqualsAsDelimiter ? '=' : ':'}
247
- value={value}
248
- onChange={setValue}
249
- onSearch={setValue}
250
- onClear={() => setValue('')}
251
- formAdditionalItems={
252
- useCustomFooter ? (
253
- <FormGroup>
254
- <Button variant="link" isInline icon={<ExternalLinkSquareAltIcon />} iconPosition="right">
255
- Link
256
- </Button>
257
- </FormGroup>
258
- ) : null
259
- }
260
- />
261
- </>
262
- );
263
- };
46
+ ```ts file='./SearchInputAdvanced.tsx'
264
47
  ```
@@ -0,0 +1,56 @@
1
+ import React from 'react';
2
+ import { Button, Checkbox, FormGroup, SearchInput } from '@patternfly/react-core';
3
+ import ExternalLinkSquareAltIcon from '@patternfly/react-icons/dist/esm/icons/external-link-square-alt-icon';
4
+
5
+ export const SearchInputAdvanced: React.FunctionComponent = () => {
6
+ const [value, setValue] = React.useState('username:player firstname:john');
7
+ const [useEqualsAsDelimiter, setUseEqualsAsDelimiter] = React.useState(false);
8
+ const [useCustomFooter, setUseCustomFooter] = React.useState(false);
9
+
10
+ const toggleDelimiter = (checked: boolean) => {
11
+ setValue(value.replace(/:|=/g, checked ? '=' : ':'));
12
+ setUseEqualsAsDelimiter(checked);
13
+ };
14
+
15
+ return (
16
+ <>
17
+ <Checkbox
18
+ label="Use equal sign as search attribute delimiter"
19
+ isChecked={useEqualsAsDelimiter}
20
+ onChange={toggleDelimiter}
21
+ aria-label="change delimiter checkbox"
22
+ id="toggle-delimiter"
23
+ name="toggle-delimiter"
24
+ />
25
+ <Checkbox
26
+ label="Add custom footer element after the attributes in the menu"
27
+ isChecked={useCustomFooter}
28
+ onChange={value => setUseCustomFooter(value)}
29
+ aria-label="change use custom footer checkbox"
30
+ id="toggle-custom-footer"
31
+ name="toggle-custom-footer"
32
+ />
33
+ <br />
34
+ <SearchInput
35
+ attributes={[
36
+ { attr: 'username', display: 'Username' },
37
+ { attr: 'firstname', display: 'First name' }
38
+ ]}
39
+ advancedSearchDelimiter={useEqualsAsDelimiter ? '=' : ':'}
40
+ value={value}
41
+ onChange={setValue}
42
+ onSearch={setValue}
43
+ onClear={() => setValue('')}
44
+ formAdditionalItems={
45
+ useCustomFooter ? (
46
+ <FormGroup>
47
+ <Button variant="link" isInline icon={<ExternalLinkSquareAltIcon />} iconPosition="right">
48
+ Link
49
+ </Button>
50
+ </FormGroup>
51
+ ) : null
52
+ }
53
+ />
54
+ </>
55
+ );
56
+ };
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { SearchInput } from '@patternfly/react-core';
3
+
4
+ export const SearchInputBasic: React.FunctionComponent = () => {
5
+ const [value, setValue] = React.useState('');
6
+
7
+ const onChange = (value: string) => {
8
+ setValue(value);
9
+ };
10
+
11
+ return <SearchInput placeholder="Find by name" value={value} onChange={onChange} onClear={() => onChange('')} />;
12
+ };
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { SearchInput, Button } from '@patternfly/react-core';
3
+
4
+ export const SearchInputFocusSearch: React.FunctionComponent = () => {
5
+ const [value, setValue] = React.useState('');
6
+ const ref: React.MutableRefObject<HTMLInputElement | null> = React.useRef(null);
7
+
8
+ return (
9
+ <>
10
+ <SearchInput ref={ref} value={value} onChange={setValue} onClear={() => setValue('')} />
11
+ <Button onClick={() => ref.current && ref.current.focus()}>Focus on the search input</Button>
12
+ </>
13
+ );
14
+ };
@@ -0,0 +1,43 @@
1
+ import React from 'react';
2
+ import { SearchInput } from '@patternfly/react-core';
3
+
4
+ export const SearchInputWithNavigableOptions: React.FunctionComponent = () => {
5
+ const [value, setValue] = React.useState('');
6
+ const [resultsCount, setResultsCount] = React.useState(0);
7
+ const [currentResult, setCurrentResult] = React.useState(1);
8
+
9
+ const onChange = (value: string) => {
10
+ setValue(value);
11
+ setResultsCount(3);
12
+ };
13
+
14
+ const onClear = () => {
15
+ setValue('');
16
+ setResultsCount(0);
17
+ setCurrentResult(1);
18
+ };
19
+
20
+ const onNext = () => {
21
+ const newCurrentResult = currentResult + 1;
22
+ setCurrentResult(newCurrentResult > resultsCount ? resultsCount : newCurrentResult);
23
+ };
24
+
25
+ const onPrevious = () => {
26
+ const newCurrentResult = currentResult - 1;
27
+ setCurrentResult(newCurrentResult > 0 ? newCurrentResult : 1);
28
+ };
29
+
30
+ return (
31
+ <SearchInput
32
+ placeholder="Find by name"
33
+ value={value}
34
+ onChange={onChange}
35
+ onClear={onClear}
36
+ isNextNavigationButtonDisabled={currentResult === 3}
37
+ isPreviousNavigationButtonDisabled={currentResult === 1}
38
+ resultsCount={`${currentResult} / ${resultsCount}`}
39
+ onNextClick={onNext}
40
+ onPreviousClick={onPrevious}
41
+ />
42
+ );
43
+ };
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import { SearchInput } from '@patternfly/react-core';
3
+
4
+ export const SearchInputWithResultCount: React.FunctionComponent = () => {
5
+ const [value, setValue] = React.useState('');
6
+ const [resultsCount, setResultsCount] = React.useState(0);
7
+
8
+ const onChange = (value: string) => {
9
+ setValue(value);
10
+ setResultsCount(3);
11
+ };
12
+
13
+ const onClear = () => {
14
+ setValue('');
15
+ setResultsCount(0);
16
+ };
17
+
18
+ return (
19
+ <SearchInput
20
+ placeholder="Find by name"
21
+ value={value}
22
+ onChange={onChange}
23
+ onClear={onClear}
24
+ resultsCount={resultsCount}
25
+ />
26
+ );
27
+ };
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { SearchInput } from '@patternfly/react-core';
3
+
4
+ export const SearchInputWithSubmitButton: React.FunctionComponent = () => {
5
+ const [value, setValue] = React.useState('');
6
+
7
+ return (
8
+ <SearchInput
9
+ placeholder="Find by name"
10
+ value={value}
11
+ onChange={setValue}
12
+ onSearch={setValue}
13
+ onClear={() => setValue('')}
14
+ />
15
+ );
16
+ };