@patternfly/react-core 4.267.6 → 4.267.7
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.
- package/CHANGELOG.md +8 -0
- package/package.json +2 -2
- package/src/components/Toolbar/examples/Toolbar.md +10 -1272
- package/src/components/Toolbar/examples/ToolbarComponentManagedToggleGroups.tsx +137 -0
- package/src/components/Toolbar/examples/ToolbarConsumerManagedToggleGroups.tsx +147 -0
- package/src/components/Toolbar/examples/ToolbarGroups.tsx +158 -0
- package/src/components/Toolbar/examples/ToolbarInsets.tsx +52 -0
- package/src/components/Toolbar/examples/ToolbarItems.tsx +26 -0
- package/src/components/Toolbar/examples/ToolbarSpacers.tsx +51 -0
- package/src/components/Toolbar/examples/ToolbarStacked.tsx +253 -0
- package/src/components/Toolbar/examples/ToolbarSticky.tsx +37 -0
- package/src/components/Toolbar/examples/ToolbarWidths.tsx +30 -0
- package/src/components/Toolbar/examples/ToolbarWithFilters.tsx +222 -0
|
@@ -17,464 +17,34 @@ import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
|
|
|
17
17
|
|
|
18
18
|
Toolbar items are individual components that can be placed inside of a toolbar. Buttons or select lists are examples of items. (Note: This example does not demonstrate the desired responsive behavior of the toolbar. That is handled in later examples.)
|
|
19
19
|
|
|
20
|
-
```
|
|
21
|
-
import React from 'react';
|
|
22
|
-
import { Toolbar, ToolbarItem, ToolbarContent } from '@patternfly/react-core';
|
|
23
|
-
import { Button, SearchInput } from '@patternfly/react-core';
|
|
24
|
-
|
|
25
|
-
class ToolbarItems extends React.Component {
|
|
26
|
-
constructor(props) {
|
|
27
|
-
super(props);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
render() {
|
|
31
|
-
const items = (
|
|
32
|
-
<React.Fragment>
|
|
33
|
-
<ToolbarItem variant="search-filter">
|
|
34
|
-
<SearchInput aria-label="search input example" />
|
|
35
|
-
</ToolbarItem>
|
|
36
|
-
<ToolbarItem>
|
|
37
|
-
<Button variant="secondary">Action</Button>
|
|
38
|
-
</ToolbarItem>
|
|
39
|
-
<ToolbarItem variant="separator" />
|
|
40
|
-
<ToolbarItem>
|
|
41
|
-
<Button variant="primary">Action</Button>
|
|
42
|
-
</ToolbarItem>
|
|
43
|
-
</React.Fragment>
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
return (
|
|
47
|
-
<Toolbar id="toolbar-items">
|
|
48
|
-
<ToolbarContent>{items}</ToolbarContent>
|
|
49
|
-
</Toolbar>
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
20
|
+
```ts file="./ToolbarItems.tsx"
|
|
53
21
|
```
|
|
54
22
|
|
|
55
23
|
### Adjusting item spacers
|
|
56
24
|
|
|
57
|
-
```
|
|
58
|
-
import React from 'react';
|
|
59
|
-
import { Toolbar, ToolbarItem, ToolbarGroup, ToolbarContent } from '@patternfly/react-core';
|
|
60
|
-
import { Button } from '@patternfly/react-core';
|
|
61
|
-
|
|
62
|
-
class ToolbarSpacers extends React.Component {
|
|
63
|
-
constructor(props) {
|
|
64
|
-
super(props);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
render() {
|
|
68
|
-
const firstSpacers = {
|
|
69
|
-
default: 'spacerNone'
|
|
70
|
-
};
|
|
71
|
-
const secondSpacers = {
|
|
72
|
-
default: 'spacerSm'
|
|
73
|
-
};
|
|
74
|
-
const thirdSpacers = {
|
|
75
|
-
default: 'spacerMd'
|
|
76
|
-
};
|
|
77
|
-
const fourthSpacers = {
|
|
78
|
-
default: 'spacerLg'
|
|
79
|
-
};
|
|
80
|
-
const fifthSpacers = {
|
|
81
|
-
default: 'spacerNone',
|
|
82
|
-
md: 'spacerSm',
|
|
83
|
-
lg: 'spacerMd',
|
|
84
|
-
xl: 'spacerLg'
|
|
85
|
-
};
|
|
86
|
-
const spaceItems = {
|
|
87
|
-
lg: 'spaceItemsLg'
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const items = (
|
|
91
|
-
<React.Fragment>
|
|
92
|
-
<ToolbarItem spacer={firstSpacers}>
|
|
93
|
-
<Button variant="secondary">Action</Button>
|
|
94
|
-
</ToolbarItem>
|
|
95
|
-
<ToolbarItem spacer={secondSpacers}>
|
|
96
|
-
<Button variant="secondary">Action</Button>
|
|
97
|
-
</ToolbarItem>
|
|
98
|
-
<ToolbarItem spacer={thirdSpacers}>
|
|
99
|
-
<Button variant="secondary">Action</Button>
|
|
100
|
-
</ToolbarItem>
|
|
101
|
-
<ToolbarItem spacer={fourthSpacers}>
|
|
102
|
-
<Button variant="secondary">Action</Button>
|
|
103
|
-
</ToolbarItem>
|
|
104
|
-
<ToolbarItem variant="separator"></ToolbarItem>
|
|
105
|
-
<ToolbarItem spacer={fifthSpacers}>
|
|
106
|
-
<Button variant="secondary">Action</Button>
|
|
107
|
-
</ToolbarItem>
|
|
108
|
-
<ToolbarItem>
|
|
109
|
-
<Button variant="primary">Action</Button>
|
|
110
|
-
</ToolbarItem>
|
|
111
|
-
<ToolbarItem variant="separator"></ToolbarItem>
|
|
112
|
-
<ToolbarGroup spaceItems={spaceItems}>
|
|
113
|
-
<ToolbarItem>
|
|
114
|
-
<Button variant="secondary">Action</Button>
|
|
115
|
-
</ToolbarItem>
|
|
116
|
-
<ToolbarItem>
|
|
117
|
-
<Button variant="secondary">Action</Button>
|
|
118
|
-
</ToolbarItem>
|
|
119
|
-
</ToolbarGroup>
|
|
120
|
-
</React.Fragment>
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
return (
|
|
124
|
-
<Toolbar id="toolbar-spacers">
|
|
125
|
-
<ToolbarContent>{items}</ToolbarContent>
|
|
126
|
-
</Toolbar>
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
25
|
+
```ts file="./ToolbarSpacers.tsx"
|
|
130
26
|
```
|
|
131
27
|
|
|
132
28
|
### Adjusting item widths
|
|
133
29
|
|
|
134
|
-
```
|
|
135
|
-
import React from 'react';
|
|
136
|
-
import { Toolbar, ToolbarItem, ToolbarContent } from '@patternfly/react-core';
|
|
137
|
-
import { Button } from '@patternfly/react-core';
|
|
138
|
-
|
|
139
|
-
class ToolbarWidths extends React.Component {
|
|
140
|
-
constructor(props) {
|
|
141
|
-
super(props);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
render() {
|
|
145
|
-
const widths = {
|
|
146
|
-
default: '100px',
|
|
147
|
-
sm: '80px',
|
|
148
|
-
md: '150px',
|
|
149
|
-
lg: '200px',
|
|
150
|
-
xl: '250px',
|
|
151
|
-
'2xl': '300px'
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
const items = (
|
|
155
|
-
<React.Fragment>
|
|
156
|
-
<ToolbarItem widths={widths}>
|
|
157
|
-
<Button variant="secondary" style={{ width: '100%' }}>
|
|
158
|
-
Action
|
|
159
|
-
</Button>
|
|
160
|
-
</ToolbarItem>
|
|
161
|
-
</React.Fragment>
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
return (
|
|
165
|
-
<Toolbar id="toolbar-widths">
|
|
166
|
-
<ToolbarContent>{items}</ToolbarContent>
|
|
167
|
-
</Toolbar>
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
30
|
+
```ts file="./ToolbarWidths.tsx"
|
|
171
31
|
```
|
|
172
32
|
|
|
173
33
|
### Adjusting toolbar inset
|
|
174
34
|
|
|
175
|
-
```
|
|
176
|
-
import React from 'react';
|
|
177
|
-
import { Toolbar, ToolbarItem, ToolbarGroup, ToolbarContent } from '@patternfly/react-core';
|
|
178
|
-
import { Button } from '@patternfly/react-core';
|
|
179
|
-
|
|
180
|
-
class ToolbarSpacers extends React.Component {
|
|
181
|
-
constructor(props) {
|
|
182
|
-
super(props);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
render() {
|
|
186
|
-
const items = (
|
|
187
|
-
<React.Fragment>
|
|
188
|
-
<ToolbarItem>
|
|
189
|
-
<Button variant="secondary">Action</Button>
|
|
190
|
-
</ToolbarItem>
|
|
191
|
-
<ToolbarItem>
|
|
192
|
-
<Button variant="secondary">Action</Button>
|
|
193
|
-
</ToolbarItem>
|
|
194
|
-
<ToolbarItem>
|
|
195
|
-
<Button variant="secondary">Action</Button>
|
|
196
|
-
</ToolbarItem>
|
|
197
|
-
<ToolbarItem>
|
|
198
|
-
<Button variant="secondary">Action</Button>
|
|
199
|
-
</ToolbarItem>
|
|
200
|
-
<ToolbarItem variant="separator"></ToolbarItem>
|
|
201
|
-
<ToolbarItem>
|
|
202
|
-
<Button variant="secondary">Action</Button>
|
|
203
|
-
</ToolbarItem>
|
|
204
|
-
<ToolbarItem>
|
|
205
|
-
<Button variant="primary">Action</Button>
|
|
206
|
-
</ToolbarItem>
|
|
207
|
-
<ToolbarItem variant="separator"></ToolbarItem>
|
|
208
|
-
<ToolbarGroup>
|
|
209
|
-
<ToolbarItem>
|
|
210
|
-
<Button variant="secondary">Action</Button>
|
|
211
|
-
</ToolbarItem>
|
|
212
|
-
<ToolbarItem>
|
|
213
|
-
<Button variant="secondary">Action</Button>
|
|
214
|
-
</ToolbarItem>
|
|
215
|
-
</ToolbarGroup>
|
|
216
|
-
</React.Fragment>
|
|
217
|
-
);
|
|
218
|
-
|
|
219
|
-
return (
|
|
220
|
-
<Toolbar
|
|
221
|
-
id="toolbar-insets"
|
|
222
|
-
inset={{
|
|
223
|
-
default: 'insetNone',
|
|
224
|
-
md: 'insetSm',
|
|
225
|
-
xl: 'inset2xl',
|
|
226
|
-
'2xl': 'insetLg'
|
|
227
|
-
}}
|
|
228
|
-
>
|
|
229
|
-
<ToolbarContent>{items}</ToolbarContent>
|
|
230
|
-
</Toolbar>
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
35
|
+
```ts file="./ToolbarInsets.tsx"
|
|
234
36
|
```
|
|
235
37
|
|
|
236
38
|
### Sticky
|
|
237
39
|
|
|
238
|
-
```
|
|
239
|
-
import React from 'react';
|
|
240
|
-
import { Toolbar, ToolbarItem, ToolbarContent, SearchInput, Checkbox } from '@patternfly/react-core';
|
|
241
|
-
import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
|
|
242
|
-
|
|
243
|
-
const ToolbarItems = () => {
|
|
244
|
-
const [isSticky, setIsSticky] = React.useState(true);
|
|
245
|
-
const [showEvenOnly, setShowEvenOnly] = React.useState(true);
|
|
246
|
-
const array = [...Array(30).keys()];
|
|
247
|
-
const numbers = showEvenOnly ? array.filter(number => number % 2 === 0) : array;
|
|
248
|
-
|
|
249
|
-
return (
|
|
250
|
-
<React.Fragment>
|
|
251
|
-
<div style={{ overflowY: 'scroll', height: '200px' }}>
|
|
252
|
-
<Toolbar id="toolbar-sticky" inset={{ default: 'insetNone' }} isSticky={isSticky}>
|
|
253
|
-
<ToolbarContent>
|
|
254
|
-
<ToolbarItem>
|
|
255
|
-
<SearchInput aria-label="search input example" />
|
|
256
|
-
</ToolbarItem>
|
|
257
|
-
<ToolbarItem>
|
|
258
|
-
<Checkbox
|
|
259
|
-
label="Show only even number items"
|
|
260
|
-
isChecked={showEvenOnly}
|
|
261
|
-
onChange={setShowEvenOnly}
|
|
262
|
-
aria-label="checkbox for showing only even numbers"
|
|
263
|
-
id="showOnlyEvenCheckbox"
|
|
264
|
-
/>
|
|
265
|
-
</ToolbarItem>
|
|
266
|
-
</ToolbarContent>
|
|
267
|
-
</Toolbar>
|
|
268
|
-
<ul>
|
|
269
|
-
{numbers.map(number => (
|
|
270
|
-
<li key={number}>{`item ${number}`}</li>
|
|
271
|
-
))}
|
|
272
|
-
</ul>
|
|
273
|
-
</div>
|
|
274
|
-
<Checkbox
|
|
275
|
-
label="Is toolbar sticky"
|
|
276
|
-
isChecked={isSticky}
|
|
277
|
-
onChange={setIsSticky}
|
|
278
|
-
aria-label="checkbox for is sticky"
|
|
279
|
-
id="isStickyCheckbox"
|
|
280
|
-
/>
|
|
281
|
-
</React.Fragment>
|
|
282
|
-
);
|
|
283
|
-
};
|
|
40
|
+
```ts file="./ToolbarSticky.tsx"
|
|
284
41
|
```
|
|
285
42
|
|
|
286
43
|
### Groups
|
|
287
44
|
|
|
288
45
|
Often, it makes sense to group sets of like items to create desired associations and to enable items to respond together to changes in viewport width. (Note: This example does not demonstrate the desired responsive behavior of the toolbar. That is handled in later examples.)
|
|
289
46
|
|
|
290
|
-
```
|
|
291
|
-
import React from 'react';
|
|
292
|
-
import { Toolbar, ToolbarContent, ToolbarGroup, ToolbarItem } from '@patternfly/react-core';
|
|
293
|
-
import { Button, Select, SelectOption, SelectVariant } from '@patternfly/react-core';
|
|
294
|
-
import EditIcon from '@patternfly/react-icons/dist/esm/icons/edit-icon';
|
|
295
|
-
import CloneIcon from '@patternfly/react-icons/dist/esm/icons/clone-icon';
|
|
296
|
-
import SyncIcon from '@patternfly/react-icons/dist/esm/icons/sync-icon';
|
|
297
|
-
|
|
298
|
-
class ToolbarGroupTypes extends React.Component {
|
|
299
|
-
constructor(props) {
|
|
300
|
-
super(props);
|
|
301
|
-
|
|
302
|
-
this.firstOptions = [
|
|
303
|
-
{ value: 'Filter 1', disabled: false, isPlaceholder: true },
|
|
304
|
-
{ value: 'A', disabled: false },
|
|
305
|
-
{ value: 'B', disabled: false },
|
|
306
|
-
{ value: 'C', disabled: false }
|
|
307
|
-
];
|
|
308
|
-
|
|
309
|
-
this.secondOptions = [
|
|
310
|
-
{ value: 'Filter 2', disabled: false, isPlaceholder: true },
|
|
311
|
-
{ value: '1', disabled: false },
|
|
312
|
-
{ value: '2', disabled: false },
|
|
313
|
-
{ value: '3', disabled: false }
|
|
314
|
-
];
|
|
315
|
-
|
|
316
|
-
this.thirdOptions = [
|
|
317
|
-
{ value: 'Filter 3', disabled: false, isPlaceholder: true },
|
|
318
|
-
{ value: 'I', disabled: false },
|
|
319
|
-
{ value: 'II', disabled: false },
|
|
320
|
-
{ value: 'III', disabled: false }
|
|
321
|
-
];
|
|
322
|
-
|
|
323
|
-
this.state = {
|
|
324
|
-
firstIsExpanded: false,
|
|
325
|
-
firstSelected: null,
|
|
326
|
-
secondIsExpanded: false,
|
|
327
|
-
secondSelected: null,
|
|
328
|
-
thirdIsExpanded: false,
|
|
329
|
-
thirdSelected: null
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
this.onFirstToggle = isExpanded => {
|
|
333
|
-
this.setState({
|
|
334
|
-
firstIsExpanded: isExpanded
|
|
335
|
-
});
|
|
336
|
-
};
|
|
337
|
-
|
|
338
|
-
this.onFirstSelect = (event, selection) => {
|
|
339
|
-
this.setState({
|
|
340
|
-
firstSelected: selection,
|
|
341
|
-
firstIsExpanded: false
|
|
342
|
-
});
|
|
343
|
-
};
|
|
344
|
-
|
|
345
|
-
this.onSecondToggle = isExpanded => {
|
|
346
|
-
this.setState({
|
|
347
|
-
secondIsExpanded: isExpanded
|
|
348
|
-
});
|
|
349
|
-
};
|
|
350
|
-
|
|
351
|
-
this.onSecondSelect = (event, selection) => {
|
|
352
|
-
this.setState({
|
|
353
|
-
secondSelected: selection,
|
|
354
|
-
secondIsExpanded: false
|
|
355
|
-
});
|
|
356
|
-
};
|
|
357
|
-
|
|
358
|
-
this.onThirdToggle = isExpanded => {
|
|
359
|
-
this.setState({
|
|
360
|
-
thirdIsExpanded: isExpanded
|
|
361
|
-
});
|
|
362
|
-
};
|
|
363
|
-
|
|
364
|
-
this.onThirdSelect = (event, selection) => {
|
|
365
|
-
this.setState({
|
|
366
|
-
thirdSelected: selection,
|
|
367
|
-
thirdIsExpanded: false
|
|
368
|
-
});
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
render() {
|
|
373
|
-
const {
|
|
374
|
-
firstIsExpanded,
|
|
375
|
-
firstSelected,
|
|
376
|
-
secondIsExpanded,
|
|
377
|
-
secondSelected,
|
|
378
|
-
thirdIsExpanded,
|
|
379
|
-
thirdSelected
|
|
380
|
-
} = this.state;
|
|
381
|
-
|
|
382
|
-
const filterGroupItems = (
|
|
383
|
-
<React.Fragment>
|
|
384
|
-
<ToolbarItem>
|
|
385
|
-
<Select
|
|
386
|
-
variant={SelectVariant.single}
|
|
387
|
-
aria-label="Select Input"
|
|
388
|
-
onToggle={this.onFirstToggle}
|
|
389
|
-
onSelect={this.onFirstSelect}
|
|
390
|
-
selections={firstSelected}
|
|
391
|
-
isOpen={firstIsExpanded}
|
|
392
|
-
>
|
|
393
|
-
{this.firstOptions.map((option, index) => (
|
|
394
|
-
<SelectOption isDisabled={option.disabled} key={index} value={option.value} />
|
|
395
|
-
))}
|
|
396
|
-
</Select>
|
|
397
|
-
</ToolbarItem>
|
|
398
|
-
<ToolbarItem>
|
|
399
|
-
<Select
|
|
400
|
-
variant={SelectVariant.single}
|
|
401
|
-
aria-label="Select Input"
|
|
402
|
-
onToggle={this.onSecondToggle}
|
|
403
|
-
onSelect={this.onSecondSelect}
|
|
404
|
-
selections={secondSelected}
|
|
405
|
-
isOpen={secondIsExpanded}
|
|
406
|
-
>
|
|
407
|
-
{this.secondOptions.map((option, index) => (
|
|
408
|
-
<SelectOption isDisabled={option.disabled} key={index} value={option.value} />
|
|
409
|
-
))}
|
|
410
|
-
</Select>
|
|
411
|
-
</ToolbarItem>
|
|
412
|
-
<ToolbarItem>
|
|
413
|
-
<Select
|
|
414
|
-
variant={SelectVariant.single}
|
|
415
|
-
aria-label="Select Input"
|
|
416
|
-
onToggle={this.onThirdToggle}
|
|
417
|
-
onSelect={this.onThirdSelect}
|
|
418
|
-
selections={thirdSelected}
|
|
419
|
-
isOpen={thirdIsExpanded}
|
|
420
|
-
>
|
|
421
|
-
{this.thirdOptions.map((option, index) => (
|
|
422
|
-
<SelectOption isDisabled={option.disabled} key={index} value={option.value} />
|
|
423
|
-
))}
|
|
424
|
-
</Select>
|
|
425
|
-
</ToolbarItem>
|
|
426
|
-
</React.Fragment>
|
|
427
|
-
);
|
|
428
|
-
|
|
429
|
-
const iconButtonGroupItems = (
|
|
430
|
-
<React.Fragment>
|
|
431
|
-
<ToolbarItem>
|
|
432
|
-
<Button variant="plain" aria-label="edit">
|
|
433
|
-
<EditIcon />
|
|
434
|
-
</Button>
|
|
435
|
-
</ToolbarItem>
|
|
436
|
-
<ToolbarItem>
|
|
437
|
-
<Button variant="plain" aria-label="clone">
|
|
438
|
-
<CloneIcon />
|
|
439
|
-
</Button>
|
|
440
|
-
</ToolbarItem>
|
|
441
|
-
<ToolbarItem>
|
|
442
|
-
<Button variant="plain" aria-label="sync">
|
|
443
|
-
<SyncIcon />
|
|
444
|
-
</Button>
|
|
445
|
-
</ToolbarItem>
|
|
446
|
-
</React.Fragment>
|
|
447
|
-
);
|
|
448
|
-
|
|
449
|
-
const buttonGroupItems = (
|
|
450
|
-
<React.Fragment>
|
|
451
|
-
<ToolbarItem>
|
|
452
|
-
<Button variant="primary">Action</Button>
|
|
453
|
-
</ToolbarItem>
|
|
454
|
-
<ToolbarItem>
|
|
455
|
-
<Button variant="secondary">Secondary</Button>
|
|
456
|
-
</ToolbarItem>
|
|
457
|
-
<ToolbarItem>
|
|
458
|
-
<Button variant="tertiary">Tertiary</Button>
|
|
459
|
-
</ToolbarItem>
|
|
460
|
-
</React.Fragment>
|
|
461
|
-
);
|
|
462
|
-
|
|
463
|
-
const items = (
|
|
464
|
-
<React.Fragment>
|
|
465
|
-
<ToolbarGroup variant="filter-group">{filterGroupItems}</ToolbarGroup>
|
|
466
|
-
<ToolbarGroup variant="icon-button-group">{iconButtonGroupItems}</ToolbarGroup>
|
|
467
|
-
<ToolbarGroup variant="button-group">{buttonGroupItems}</ToolbarGroup>
|
|
468
|
-
</React.Fragment>
|
|
469
|
-
);
|
|
470
|
-
|
|
471
|
-
return (
|
|
472
|
-
<Toolbar id="toolbar-group-types">
|
|
473
|
-
<ToolbarContent>{items}</ToolbarContent>
|
|
474
|
-
</Toolbar>
|
|
475
|
-
);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
47
|
+
```ts file="./ToolbarGroups.tsx"
|
|
478
48
|
```
|
|
479
49
|
|
|
480
50
|
## Examples with toggle groups and filters
|
|
@@ -483,146 +53,7 @@ A toggle group can be used when you want to collapse a set of items into an over
|
|
|
483
53
|
|
|
484
54
|
### Component managed toggle groups
|
|
485
55
|
|
|
486
|
-
```
|
|
487
|
-
import React from 'react';
|
|
488
|
-
import { Toolbar, ToolbarItem, ToolbarContent, ToolbarToggleGroup, ToolbarGroup } from '@patternfly/react-core';
|
|
489
|
-
import { Select, SelectOption, SelectVariant, SearchInput } from '@patternfly/react-core';
|
|
490
|
-
import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
|
|
491
|
-
|
|
492
|
-
class ToolbarComponentMangedToggleGroup extends React.Component {
|
|
493
|
-
constructor(props) {
|
|
494
|
-
super(props);
|
|
495
|
-
this.state = {
|
|
496
|
-
inputValue: '',
|
|
497
|
-
statusIsExpanded: false,
|
|
498
|
-
statusSelected: null,
|
|
499
|
-
riskIsExpanded: false,
|
|
500
|
-
riskSelected: null
|
|
501
|
-
};
|
|
502
|
-
|
|
503
|
-
this.statusOptions = [
|
|
504
|
-
{ value: 'Status', disabled: false, isPlaceholder: true },
|
|
505
|
-
{ value: 'New', disabled: false },
|
|
506
|
-
{ value: 'Pending', disabled: false },
|
|
507
|
-
{ value: 'Running', disabled: false },
|
|
508
|
-
{ value: 'Cancelled', disabled: false }
|
|
509
|
-
];
|
|
510
|
-
|
|
511
|
-
this.riskOptions = [
|
|
512
|
-
{ value: 'Risk', disabled: false, isPlaceholder: true },
|
|
513
|
-
{ value: 'Low', disabled: false },
|
|
514
|
-
{ value: 'Medium', disabled: false },
|
|
515
|
-
{ value: 'High', disabled: false }
|
|
516
|
-
];
|
|
517
|
-
|
|
518
|
-
this.onInputChange = newValue => {
|
|
519
|
-
this.setState({ inputValue: newValue });
|
|
520
|
-
};
|
|
521
|
-
|
|
522
|
-
this.onStatusToggle = isExpanded => {
|
|
523
|
-
this.setState({
|
|
524
|
-
statusIsExpanded: isExpanded
|
|
525
|
-
});
|
|
526
|
-
};
|
|
527
|
-
|
|
528
|
-
this.onStatusSelect = (event, selection, isPlaceholder) => {
|
|
529
|
-
if (isPlaceholder) this.clearStatusSelection();
|
|
530
|
-
this.setState({
|
|
531
|
-
statusSelected: selection,
|
|
532
|
-
statusIsExpanded: false
|
|
533
|
-
});
|
|
534
|
-
};
|
|
535
|
-
|
|
536
|
-
this.clearStatusSelection = () => {
|
|
537
|
-
this.setState({
|
|
538
|
-
statusSelected: null,
|
|
539
|
-
statusIsExpanded: false
|
|
540
|
-
});
|
|
541
|
-
};
|
|
542
|
-
|
|
543
|
-
this.onRiskToggle = isExpanded => {
|
|
544
|
-
this.setState({
|
|
545
|
-
riskIsExpanded: isExpanded
|
|
546
|
-
});
|
|
547
|
-
};
|
|
548
|
-
|
|
549
|
-
this.onRiskSelect = (event, selection, isPlaceholder) => {
|
|
550
|
-
if (isPlaceholder) this.clearRiskSelection();
|
|
551
|
-
this.setState({
|
|
552
|
-
riskSelected: selection,
|
|
553
|
-
riskIsExpanded: false
|
|
554
|
-
});
|
|
555
|
-
};
|
|
556
|
-
|
|
557
|
-
this.clearRiskSelection = () => {
|
|
558
|
-
this.setState({
|
|
559
|
-
riskSelected: null,
|
|
560
|
-
riskIsExpanded: false
|
|
561
|
-
});
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
render() {
|
|
566
|
-
const { inputValue, statusIsExpanded, statusSelected, riskIsExpanded, riskSelected } = this.state;
|
|
567
|
-
|
|
568
|
-
const toggleGroupItems = (
|
|
569
|
-
<React.Fragment>
|
|
570
|
-
<ToolbarItem variant="search-filter">
|
|
571
|
-
<SearchInput
|
|
572
|
-
aria-label="search input example"
|
|
573
|
-
onChange={this.onInputChange}
|
|
574
|
-
value={inputValue}
|
|
575
|
-
onClear={() => {
|
|
576
|
-
this.onInputChange('');
|
|
577
|
-
}}
|
|
578
|
-
/>
|
|
579
|
-
</ToolbarItem>
|
|
580
|
-
<ToolbarGroup variant="filter-group">
|
|
581
|
-
<ToolbarItem>
|
|
582
|
-
<Select
|
|
583
|
-
variant={SelectVariant.single}
|
|
584
|
-
aria-label="Select Input"
|
|
585
|
-
onToggle={this.onStatusToggle}
|
|
586
|
-
onSelect={this.onStatusSelect}
|
|
587
|
-
selections={statusSelected}
|
|
588
|
-
isOpen={statusIsExpanded}
|
|
589
|
-
>
|
|
590
|
-
{this.statusOptions.map((option, index) => (
|
|
591
|
-
<SelectOption isDisabled={option.disabled} key={index} value={option.value} />
|
|
592
|
-
))}
|
|
593
|
-
</Select>
|
|
594
|
-
</ToolbarItem>
|
|
595
|
-
<ToolbarItem>
|
|
596
|
-
<Select
|
|
597
|
-
variant={SelectVariant.single}
|
|
598
|
-
aria-label="Select Input"
|
|
599
|
-
onToggle={this.onRiskToggle}
|
|
600
|
-
onSelect={this.onRiskSelect}
|
|
601
|
-
selections={riskSelected}
|
|
602
|
-
isOpen={riskIsExpanded}
|
|
603
|
-
>
|
|
604
|
-
{this.riskOptions.map((option, index) => (
|
|
605
|
-
<SelectOption isDisabled={option.disabled} key={index} value={option.value} />
|
|
606
|
-
))}
|
|
607
|
-
</Select>
|
|
608
|
-
</ToolbarItem>
|
|
609
|
-
</ToolbarGroup>
|
|
610
|
-
</React.Fragment>
|
|
611
|
-
);
|
|
612
|
-
|
|
613
|
-
const items = (
|
|
614
|
-
<ToolbarToggleGroup toggleIcon={<FilterIcon />} breakpoint="xl">
|
|
615
|
-
{toggleGroupItems}
|
|
616
|
-
</ToolbarToggleGroup>
|
|
617
|
-
);
|
|
618
|
-
|
|
619
|
-
return (
|
|
620
|
-
<Toolbar id="toolbar-component-managed-toggle-groups" className="pf-m-toggle-group-container">
|
|
621
|
-
<ToolbarContent>{items}</ToolbarContent>
|
|
622
|
-
</Toolbar>
|
|
623
|
-
);
|
|
624
|
-
}
|
|
625
|
-
}
|
|
56
|
+
```ts file="./ToolbarComponentManagedToggleGroups.tsx"
|
|
626
57
|
```
|
|
627
58
|
|
|
628
59
|
### Consumer managed toggle groups
|
|
@@ -634,158 +65,7 @@ If the consumer would prefer to manage the expanded state of the toggle group fo
|
|
|
634
65
|
|
|
635
66
|
- Note: Although the toggle group is aware of the consumer provided breakpoint, the expandable content is not. So if the expandable content is expanded and the screen width surpasses that of the breakpoint, then the expandable content will not know that and will remain open, this case should be considered and handled by the consumer as well.
|
|
636
67
|
|
|
637
|
-
```
|
|
638
|
-
import React from 'react';
|
|
639
|
-
import { Toolbar, ToolbarItem, ToolbarContent, ToolbarToggleGroup, ToolbarGroup } from '@patternfly/react-core';
|
|
640
|
-
import { Select, SelectOption, SelectVariant, SearchInput } from '@patternfly/react-core';
|
|
641
|
-
import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
|
|
642
|
-
|
|
643
|
-
class ToolbarConsumerManagedToggleGroup extends React.Component {
|
|
644
|
-
constructor(props) {
|
|
645
|
-
super(props);
|
|
646
|
-
this.state = {
|
|
647
|
-
isExpanded: false,
|
|
648
|
-
inputValue: '',
|
|
649
|
-
statusIsExpanded: false,
|
|
650
|
-
statusSelected: null,
|
|
651
|
-
riskIsExpanded: false,
|
|
652
|
-
riskSelected: null
|
|
653
|
-
};
|
|
654
|
-
|
|
655
|
-
this.toggleIsExpanded = () => {
|
|
656
|
-
this.setState(prevState => ({
|
|
657
|
-
isExpanded: !prevState.isExpanded
|
|
658
|
-
}));
|
|
659
|
-
};
|
|
660
|
-
|
|
661
|
-
this.statusOptions = [
|
|
662
|
-
{ value: 'Status', disabled: false, isPlaceholder: true },
|
|
663
|
-
{ value: 'New', disabled: false },
|
|
664
|
-
{ value: 'Pending', disabled: false },
|
|
665
|
-
{ value: 'Running', disabled: false },
|
|
666
|
-
{ value: 'Cancelled', disabled: false }
|
|
667
|
-
];
|
|
668
|
-
|
|
669
|
-
this.riskOptions = [
|
|
670
|
-
{ value: 'Risk', disabled: false, isPlaceholder: true },
|
|
671
|
-
{ value: 'Low', disabled: false },
|
|
672
|
-
{ value: 'Medium', disabled: false },
|
|
673
|
-
{ value: 'High', disabled: false }
|
|
674
|
-
];
|
|
675
|
-
|
|
676
|
-
this.onInputChange = newValue => {
|
|
677
|
-
this.setState({ inputValue: newValue });
|
|
678
|
-
};
|
|
679
|
-
|
|
680
|
-
this.onStatusToggle = isExpanded => {
|
|
681
|
-
this.setState({
|
|
682
|
-
statusIsExpanded: isExpanded
|
|
683
|
-
});
|
|
684
|
-
};
|
|
685
|
-
|
|
686
|
-
this.onStatusSelect = (event, selection, isPlaceholder) => {
|
|
687
|
-
if (isPlaceholder) this.clearStatusSelection();
|
|
688
|
-
this.setState({
|
|
689
|
-
statusSelected: selection,
|
|
690
|
-
statusIsExpanded: false
|
|
691
|
-
});
|
|
692
|
-
};
|
|
693
|
-
|
|
694
|
-
this.clearStatusSelection = () => {
|
|
695
|
-
this.setState({
|
|
696
|
-
statusSelected: null,
|
|
697
|
-
statusIsExpanded: false
|
|
698
|
-
});
|
|
699
|
-
};
|
|
700
|
-
|
|
701
|
-
this.onRiskToggle = isExpanded => {
|
|
702
|
-
this.setState({
|
|
703
|
-
riskIsExpanded: isExpanded
|
|
704
|
-
});
|
|
705
|
-
};
|
|
706
|
-
|
|
707
|
-
this.onRiskSelect = (event, selection, isPlaceholder) => {
|
|
708
|
-
if (isPlaceholder) this.clearRiskSelection();
|
|
709
|
-
this.setState({
|
|
710
|
-
riskSelected: selection,
|
|
711
|
-
riskIsExpanded: false
|
|
712
|
-
});
|
|
713
|
-
};
|
|
714
|
-
|
|
715
|
-
this.clearRiskSelection = () => {
|
|
716
|
-
this.setState({
|
|
717
|
-
riskSelected: null,
|
|
718
|
-
riskIsExpanded: false
|
|
719
|
-
});
|
|
720
|
-
};
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
render() {
|
|
724
|
-
const { isExpanded, inputValue, statusIsExpanded, statusSelected, riskIsExpanded, riskSelected } = this.state;
|
|
725
|
-
|
|
726
|
-
const toggleGroupItems = (
|
|
727
|
-
<React.Fragment>
|
|
728
|
-
<ToolbarItem variant="search-filter">
|
|
729
|
-
<SearchInput
|
|
730
|
-
aria-label="search input example"
|
|
731
|
-
onChange={this.onInputChange}
|
|
732
|
-
value={inputValue}
|
|
733
|
-
onClear={() => {
|
|
734
|
-
this.onInputChange('');
|
|
735
|
-
}}
|
|
736
|
-
/>
|
|
737
|
-
</ToolbarItem>
|
|
738
|
-
<ToolbarGroup variant="filter-group">
|
|
739
|
-
<ToolbarItem>
|
|
740
|
-
<Select
|
|
741
|
-
variant={SelectVariant.single}
|
|
742
|
-
aria-label="Select Input"
|
|
743
|
-
onToggle={this.onStatusToggle}
|
|
744
|
-
onSelect={this.onStatusSelect}
|
|
745
|
-
selections={statusSelected}
|
|
746
|
-
isOpen={statusIsExpanded}
|
|
747
|
-
>
|
|
748
|
-
{this.statusOptions.map((option, index) => (
|
|
749
|
-
<SelectOption isDisabled={option.disabled} key={index} value={option.value} />
|
|
750
|
-
))}
|
|
751
|
-
</Select>
|
|
752
|
-
</ToolbarItem>
|
|
753
|
-
<ToolbarItem>
|
|
754
|
-
<Select
|
|
755
|
-
variant={SelectVariant.single}
|
|
756
|
-
aria-label="Select Input"
|
|
757
|
-
onToggle={this.onRiskToggle}
|
|
758
|
-
onSelect={this.onRiskSelect}
|
|
759
|
-
selections={riskSelected}
|
|
760
|
-
isOpen={riskIsExpanded}
|
|
761
|
-
>
|
|
762
|
-
{this.riskOptions.map((option, index) => (
|
|
763
|
-
<SelectOption isDisabled={option.disabled} key={index} value={option.value} />
|
|
764
|
-
))}
|
|
765
|
-
</Select>
|
|
766
|
-
</ToolbarItem>
|
|
767
|
-
</ToolbarGroup>
|
|
768
|
-
</React.Fragment>
|
|
769
|
-
);
|
|
770
|
-
|
|
771
|
-
const items = (
|
|
772
|
-
<ToolbarToggleGroup toggleIcon={<FilterIcon />} breakpoint="xl">
|
|
773
|
-
{toggleGroupItems}
|
|
774
|
-
</ToolbarToggleGroup>
|
|
775
|
-
);
|
|
776
|
-
|
|
777
|
-
return (
|
|
778
|
-
<Toolbar
|
|
779
|
-
id="toolbar-consumer-managed-toggle-groups"
|
|
780
|
-
isExpanded={isExpanded}
|
|
781
|
-
className="pf-m-toggle-group-container"
|
|
782
|
-
toggleIsExpanded={this.toggleIsExpanded}
|
|
783
|
-
>
|
|
784
|
-
<ToolbarContent>{items}</ToolbarContent>
|
|
785
|
-
</Toolbar>
|
|
786
|
-
);
|
|
787
|
-
}
|
|
788
|
-
}
|
|
68
|
+
```ts file="./ToolbarConsumerManagedToggleGroups.tsx"
|
|
789
69
|
```
|
|
790
70
|
|
|
791
71
|
### With filters
|
|
@@ -793,268 +73,7 @@ class ToolbarConsumerManagedToggleGroup extends React.Component {
|
|
|
793
73
|
The ToolbarFilter component expects a consumer managed list of applied filters and a delete chip handler to be passed as props. Pass a deleteChipGroup prop to provide both a handler and visual styling to remove all chips in a group. Then the rendering of chips will be handled responsively by the Toolbar
|
|
794
74
|
When filters are applied, the toolbar will expand in height to make space for a row of filter chips. Upon clearing the applied filters, the toolbar will collapse to its default height.
|
|
795
75
|
|
|
796
|
-
```
|
|
797
|
-
import React from 'react';
|
|
798
|
-
import {
|
|
799
|
-
Toolbar,
|
|
800
|
-
ToolbarItem,
|
|
801
|
-
ToolbarContent,
|
|
802
|
-
ToolbarFilter,
|
|
803
|
-
ToolbarToggleGroup,
|
|
804
|
-
ToolbarGroup
|
|
805
|
-
} from '@patternfly/react-core';
|
|
806
|
-
import {
|
|
807
|
-
Button,
|
|
808
|
-
Select,
|
|
809
|
-
SelectOption,
|
|
810
|
-
SelectVariant,
|
|
811
|
-
Dropdown,
|
|
812
|
-
DropdownItem,
|
|
813
|
-
DropdownSeparator,
|
|
814
|
-
DropdownPosition,
|
|
815
|
-
KebabToggle,
|
|
816
|
-
SearchInput
|
|
817
|
-
} from '@patternfly/react-core';
|
|
818
|
-
import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
|
|
819
|
-
import EditIcon from '@patternfly/react-icons/dist/esm/icons/edit-icon';
|
|
820
|
-
import CloneIcon from '@patternfly/react-icons/dist/esm/icons/clone-icon';
|
|
821
|
-
import SyncIcon from '@patternfly/react-icons/dist/esm/icons/sync-icon';
|
|
822
|
-
|
|
823
|
-
class ToolbarWithFilterExample extends React.Component {
|
|
824
|
-
constructor(props) {
|
|
825
|
-
super(props);
|
|
826
|
-
this.state = {
|
|
827
|
-
isExpanded: false,
|
|
828
|
-
inputValue: '',
|
|
829
|
-
statusIsExpanded: false,
|
|
830
|
-
riskIsExpanded: false,
|
|
831
|
-
filters: {
|
|
832
|
-
risk: ['Low'],
|
|
833
|
-
status: ['New', 'Pending']
|
|
834
|
-
},
|
|
835
|
-
kebabIsOpen: false
|
|
836
|
-
};
|
|
837
|
-
|
|
838
|
-
this.toggleIsExpanded = () => {
|
|
839
|
-
this.setState(prevState => ({
|
|
840
|
-
isExpanded: !prevState.isExpanded
|
|
841
|
-
}));
|
|
842
|
-
};
|
|
843
|
-
|
|
844
|
-
this.closeExpandableContent = () => {
|
|
845
|
-
this.setState(() => ({
|
|
846
|
-
isExpanded: false
|
|
847
|
-
}));
|
|
848
|
-
};
|
|
849
|
-
|
|
850
|
-
this.onInputChange = newValue => {
|
|
851
|
-
this.setState({ inputValue: newValue });
|
|
852
|
-
};
|
|
853
|
-
|
|
854
|
-
this.onSelect = (type, event, selection) => {
|
|
855
|
-
const checked = event.target.checked;
|
|
856
|
-
this.setState(prevState => {
|
|
857
|
-
const prevSelections = prevState.filters[type];
|
|
858
|
-
return {
|
|
859
|
-
filters: {
|
|
860
|
-
...prevState.filters,
|
|
861
|
-
[type]: checked ? [...prevSelections, selection] : prevSelections.filter(value => value !== selection)
|
|
862
|
-
}
|
|
863
|
-
};
|
|
864
|
-
});
|
|
865
|
-
};
|
|
866
|
-
|
|
867
|
-
this.onStatusSelect = (event, selection) => {
|
|
868
|
-
this.onSelect('status', event, selection);
|
|
869
|
-
};
|
|
870
|
-
|
|
871
|
-
this.onRiskSelect = (event, selection) => {
|
|
872
|
-
this.onSelect('risk', event, selection);
|
|
873
|
-
};
|
|
874
|
-
|
|
875
|
-
this.onDelete = (type = '', id = '') => {
|
|
876
|
-
if (type) {
|
|
877
|
-
this.setState(prevState => {
|
|
878
|
-
const newState = Object.assign(prevState);
|
|
879
|
-
newState.filters[type.toLowerCase()] = newState.filters[type.toLowerCase()].filter(s => s !== id);
|
|
880
|
-
return {
|
|
881
|
-
filters: newState.filters
|
|
882
|
-
};
|
|
883
|
-
});
|
|
884
|
-
} else {
|
|
885
|
-
this.setState({
|
|
886
|
-
filters: {
|
|
887
|
-
risk: [],
|
|
888
|
-
status: []
|
|
889
|
-
}
|
|
890
|
-
});
|
|
891
|
-
}
|
|
892
|
-
};
|
|
893
|
-
|
|
894
|
-
this.onDeleteGroup = type => {
|
|
895
|
-
this.setState(prevState => {
|
|
896
|
-
prevState.filters[type.toLowerCase()] = [];
|
|
897
|
-
return {
|
|
898
|
-
filters: prevState.filters
|
|
899
|
-
};
|
|
900
|
-
});
|
|
901
|
-
};
|
|
902
|
-
|
|
903
|
-
this.onStatusToggle = isExpanded => {
|
|
904
|
-
this.setState({
|
|
905
|
-
statusIsExpanded: isExpanded
|
|
906
|
-
});
|
|
907
|
-
};
|
|
908
|
-
|
|
909
|
-
this.onRiskToggle = isExpanded => {
|
|
910
|
-
this.setState({
|
|
911
|
-
riskIsExpanded: isExpanded
|
|
912
|
-
});
|
|
913
|
-
};
|
|
914
|
-
|
|
915
|
-
this.onKebabToggle = isOpen => {
|
|
916
|
-
this.setState({
|
|
917
|
-
kebabIsOpen: isOpen
|
|
918
|
-
});
|
|
919
|
-
};
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
componentDidMount() {
|
|
923
|
-
window.addEventListener('resize', this.closeExpandableContent);
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
componentWillUnmount() {
|
|
927
|
-
window.removeEventListener('resize', this.closeExpandableContent);
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
render() {
|
|
931
|
-
const { inputValue, filters, statusIsExpanded, riskIsExpanded, kebabIsOpen } = this.state;
|
|
932
|
-
|
|
933
|
-
const statusMenuItems = [
|
|
934
|
-
<SelectOption key="statusNew" value="New" />,
|
|
935
|
-
<SelectOption key="statusPending" value="Pending" />,
|
|
936
|
-
<SelectOption key="statusRunning" value="Running" />,
|
|
937
|
-
<SelectOption key="statusCancelled" value="Cancelled" />
|
|
938
|
-
];
|
|
939
|
-
|
|
940
|
-
const riskMenuItems = [
|
|
941
|
-
<SelectOption key="riskLow" value="Low" />,
|
|
942
|
-
<SelectOption key="riskMedium" value="Medium" />,
|
|
943
|
-
<SelectOption key="riskHigh" value="High" />
|
|
944
|
-
];
|
|
945
|
-
|
|
946
|
-
const toggleGroupItems = (
|
|
947
|
-
<React.Fragment>
|
|
948
|
-
<ToolbarItem variant="search-filter">
|
|
949
|
-
<SearchInput
|
|
950
|
-
aria-label="search input example"
|
|
951
|
-
onChange={this.onInputChange}
|
|
952
|
-
value={inputValue}
|
|
953
|
-
onClear={() => {
|
|
954
|
-
this.onInputChange('');
|
|
955
|
-
}}
|
|
956
|
-
/>
|
|
957
|
-
</ToolbarItem>
|
|
958
|
-
<ToolbarGroup variant="filter-group">
|
|
959
|
-
<ToolbarFilter
|
|
960
|
-
chips={filters.status}
|
|
961
|
-
deleteChip={this.onDelete}
|
|
962
|
-
deleteChipGroup={this.onDeleteGroup}
|
|
963
|
-
categoryName="Status"
|
|
964
|
-
>
|
|
965
|
-
<Select
|
|
966
|
-
variant={SelectVariant.checkbox}
|
|
967
|
-
aria-label="Status"
|
|
968
|
-
onToggle={this.onStatusToggle}
|
|
969
|
-
onSelect={this.onStatusSelect}
|
|
970
|
-
selections={filters.status}
|
|
971
|
-
isOpen={statusIsExpanded}
|
|
972
|
-
placeholderText="Status"
|
|
973
|
-
>
|
|
974
|
-
{statusMenuItems}
|
|
975
|
-
</Select>
|
|
976
|
-
</ToolbarFilter>
|
|
977
|
-
<ToolbarFilter chips={filters.risk} deleteChip={this.onDelete} categoryName="Risk">
|
|
978
|
-
<Select
|
|
979
|
-
variant={SelectVariant.checkbox}
|
|
980
|
-
aria-label="Risk"
|
|
981
|
-
onToggle={this.onRiskToggle}
|
|
982
|
-
onSelect={this.onRiskSelect}
|
|
983
|
-
selections={filters.risk}
|
|
984
|
-
isOpen={riskIsExpanded}
|
|
985
|
-
placeholderText="Risk"
|
|
986
|
-
>
|
|
987
|
-
{riskMenuItems}
|
|
988
|
-
</Select>
|
|
989
|
-
</ToolbarFilter>
|
|
990
|
-
</ToolbarGroup>
|
|
991
|
-
</React.Fragment>
|
|
992
|
-
);
|
|
993
|
-
|
|
994
|
-
const dropdownItems = [
|
|
995
|
-
<DropdownItem key="link">Link</DropdownItem>,
|
|
996
|
-
<DropdownItem key="action" component="button">
|
|
997
|
-
Action
|
|
998
|
-
</DropdownItem>,
|
|
999
|
-
<DropdownItem key="disabled link" isDisabled>
|
|
1000
|
-
Disabled Link
|
|
1001
|
-
</DropdownItem>,
|
|
1002
|
-
<DropdownItem key="disabled action" isDisabled component="button">
|
|
1003
|
-
Disabled Action
|
|
1004
|
-
</DropdownItem>,
|
|
1005
|
-
<DropdownSeparator key="separator" />,
|
|
1006
|
-
<DropdownItem key="separated link">Separated Link</DropdownItem>,
|
|
1007
|
-
<DropdownItem key="separated action" component="button">
|
|
1008
|
-
Separated Action
|
|
1009
|
-
</DropdownItem>
|
|
1010
|
-
];
|
|
1011
|
-
|
|
1012
|
-
const toolbarItems = (
|
|
1013
|
-
<React.Fragment>
|
|
1014
|
-
<ToolbarToggleGroup toggleIcon={<FilterIcon />} breakpoint="xl">
|
|
1015
|
-
{toggleGroupItems}
|
|
1016
|
-
</ToolbarToggleGroup>
|
|
1017
|
-
<ToolbarGroup variant="icon-button-group">
|
|
1018
|
-
<ToolbarItem>
|
|
1019
|
-
<Button variant="plain" aria-label="edit">
|
|
1020
|
-
<EditIcon />
|
|
1021
|
-
</Button>
|
|
1022
|
-
</ToolbarItem>
|
|
1023
|
-
<ToolbarItem>
|
|
1024
|
-
<Button variant="plain" aria-label="clone">
|
|
1025
|
-
<CloneIcon />
|
|
1026
|
-
</Button>
|
|
1027
|
-
</ToolbarItem>
|
|
1028
|
-
<ToolbarItem>
|
|
1029
|
-
<Button variant="plain" aria-label="sync">
|
|
1030
|
-
<SyncIcon />
|
|
1031
|
-
</Button>
|
|
1032
|
-
</ToolbarItem>
|
|
1033
|
-
</ToolbarGroup>
|
|
1034
|
-
<ToolbarItem>
|
|
1035
|
-
<Dropdown
|
|
1036
|
-
toggle={<KebabToggle onToggle={this.onKebabToggle} />}
|
|
1037
|
-
isOpen={kebabIsOpen}
|
|
1038
|
-
isPlain
|
|
1039
|
-
dropdownItems={dropdownItems}
|
|
1040
|
-
position={DropdownPosition.right}
|
|
1041
|
-
/>
|
|
1042
|
-
</ToolbarItem>
|
|
1043
|
-
</React.Fragment>
|
|
1044
|
-
);
|
|
1045
|
-
|
|
1046
|
-
return (
|
|
1047
|
-
<Toolbar
|
|
1048
|
-
id="toolbar-with-filter"
|
|
1049
|
-
className="pf-m-toggle-group-container"
|
|
1050
|
-
collapseListedFiltersBreakpoint="xl"
|
|
1051
|
-
clearAllFilters={this.onDelete}
|
|
1052
|
-
>
|
|
1053
|
-
<ToolbarContent>{toolbarItems}</ToolbarContent>
|
|
1054
|
-
</Toolbar>
|
|
1055
|
-
);
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
76
|
+
```ts file="./ToolbarWithFilters.tsx"
|
|
1058
77
|
```
|
|
1059
78
|
|
|
1060
79
|
### With custom chip group content
|
|
@@ -1068,286 +87,5 @@ The chip groups generated by toolbar filters may be further customized through t
|
|
|
1068
87
|
|
|
1069
88
|
There may be situations where all of the required elements simply cannot fit in a single line.
|
|
1070
89
|
|
|
1071
|
-
```
|
|
1072
|
-
import React from 'react';
|
|
1073
|
-
import {
|
|
1074
|
-
Button,
|
|
1075
|
-
KebabToggle,
|
|
1076
|
-
Select,
|
|
1077
|
-
SelectOption,
|
|
1078
|
-
SelectVariant,
|
|
1079
|
-
Pagination,
|
|
1080
|
-
Dropdown,
|
|
1081
|
-
DropdownSeparator,
|
|
1082
|
-
DropdownToggle,
|
|
1083
|
-
DropdownToggleCheckbox,
|
|
1084
|
-
DropdownItem,
|
|
1085
|
-
DropdownPosition,
|
|
1086
|
-
Divider,
|
|
1087
|
-
OverflowMenu,
|
|
1088
|
-
OverflowMenuContent,
|
|
1089
|
-
OverflowMenuControl,
|
|
1090
|
-
OverflowMenuGroup,
|
|
1091
|
-
OverflowMenuItem,
|
|
1092
|
-
Toolbar,
|
|
1093
|
-
ToolbarContent,
|
|
1094
|
-
ToolbarToggleGroup,
|
|
1095
|
-
ToolbarItem
|
|
1096
|
-
} from '@patternfly/react-core';
|
|
1097
|
-
import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
|
|
1098
|
-
|
|
1099
|
-
class ToolbarStacked extends React.Component {
|
|
1100
|
-
constructor(props) {
|
|
1101
|
-
super(props);
|
|
1102
|
-
|
|
1103
|
-
// toggle group - three option menus with labels, two icon buttons, Kebab menu - right aligned
|
|
1104
|
-
// pagination - right aligned
|
|
1105
|
-
this.resourceOptions = [
|
|
1106
|
-
{ value: 'All resources', disabled: false },
|
|
1107
|
-
{ value: 'Deployment', disabled: false },
|
|
1108
|
-
{ value: 'Pod', disabled: false }
|
|
1109
|
-
];
|
|
1110
|
-
|
|
1111
|
-
this.statusOptions = [
|
|
1112
|
-
{ value: 'Running', disabled: false },
|
|
1113
|
-
{ value: 'New', disabled: false },
|
|
1114
|
-
{ value: 'Pending', disabled: false },
|
|
1115
|
-
{ value: 'Cancelled', disabled: false }
|
|
1116
|
-
];
|
|
1117
|
-
|
|
1118
|
-
this.typeOptions = [
|
|
1119
|
-
{ value: 'Any type', disabled: false, isPlaceholder: true },
|
|
1120
|
-
{ value: 'No type', disabled: false }
|
|
1121
|
-
];
|
|
1122
|
-
|
|
1123
|
-
this.state = {
|
|
1124
|
-
kebabIsOpen: false,
|
|
1125
|
-
resourceIsExpanded: false,
|
|
1126
|
-
resourceSelected: null,
|
|
1127
|
-
statusIsExpanded: false,
|
|
1128
|
-
statusSelected: null,
|
|
1129
|
-
splitButtonDropdownIsOpen: false,
|
|
1130
|
-
page: 1,
|
|
1131
|
-
perPage: 20
|
|
1132
|
-
};
|
|
1133
|
-
|
|
1134
|
-
this.onKebabToggle = isOpen => {
|
|
1135
|
-
this.setState({
|
|
1136
|
-
kebabIsOpen: isOpen
|
|
1137
|
-
});
|
|
1138
|
-
};
|
|
1139
|
-
|
|
1140
|
-
this.onResourceToggle = isExpanded => {
|
|
1141
|
-
this.setState({
|
|
1142
|
-
resourceIsExpanded: isExpanded
|
|
1143
|
-
});
|
|
1144
|
-
};
|
|
1145
|
-
|
|
1146
|
-
this.onResourceSelect = (event, selection) => {
|
|
1147
|
-
this.setState({
|
|
1148
|
-
resourceSelected: selection,
|
|
1149
|
-
resourceIsExpanded: false
|
|
1150
|
-
});
|
|
1151
|
-
};
|
|
1152
|
-
|
|
1153
|
-
this.onStatusToggle = isExpanded => {
|
|
1154
|
-
this.setState({
|
|
1155
|
-
statusIsExpanded: isExpanded
|
|
1156
|
-
});
|
|
1157
|
-
};
|
|
1158
|
-
|
|
1159
|
-
this.onStatusSelect = (event, selection) => {
|
|
1160
|
-
this.setState({
|
|
1161
|
-
statusSelected: selection,
|
|
1162
|
-
statusIsExpanded: false
|
|
1163
|
-
});
|
|
1164
|
-
};
|
|
1165
|
-
|
|
1166
|
-
this.onSetPage = (_event, pageNumber) => {
|
|
1167
|
-
this.setState({
|
|
1168
|
-
page: pageNumber
|
|
1169
|
-
});
|
|
1170
|
-
};
|
|
1171
|
-
|
|
1172
|
-
this.onPerPageSelect = (_event, perPage, page) => {
|
|
1173
|
-
this.setState({
|
|
1174
|
-
page, perPage
|
|
1175
|
-
});
|
|
1176
|
-
};
|
|
1177
|
-
|
|
1178
|
-
this.onSplitButtonToggle = isOpen => {
|
|
1179
|
-
this.setState({
|
|
1180
|
-
splitButtonDropdownIsOpen: isOpen
|
|
1181
|
-
});
|
|
1182
|
-
};
|
|
1183
|
-
|
|
1184
|
-
this.onSplitButtonSelect = event => {
|
|
1185
|
-
this.setState({
|
|
1186
|
-
splitButtonDropdownIsOpen: !this.state.splitButtonDropdownIsOpen
|
|
1187
|
-
});
|
|
1188
|
-
};
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
render() {
|
|
1192
|
-
const {
|
|
1193
|
-
kebabIsOpen,
|
|
1194
|
-
resourceIsExpanded,
|
|
1195
|
-
resourceSelected,
|
|
1196
|
-
statusIsExpanded,
|
|
1197
|
-
statusSelected,
|
|
1198
|
-
splitButtonDropdownIsOpen
|
|
1199
|
-
} = this.state;
|
|
1200
|
-
|
|
1201
|
-
const dropdownItems = [
|
|
1202
|
-
<DropdownItem key="link">Link</DropdownItem>,
|
|
1203
|
-
<DropdownItem key="action" component="button">
|
|
1204
|
-
Action
|
|
1205
|
-
</DropdownItem>,
|
|
1206
|
-
<DropdownItem key="disabled link" isDisabled>
|
|
1207
|
-
Disabled Link
|
|
1208
|
-
</DropdownItem>,
|
|
1209
|
-
<DropdownItem key="disabled action" isDisabled component="button">
|
|
1210
|
-
Disabled Action
|
|
1211
|
-
</DropdownItem>,
|
|
1212
|
-
<DropdownSeparator key="separator" />,
|
|
1213
|
-
<DropdownItem key="separated link">Separated Link</DropdownItem>,
|
|
1214
|
-
<DropdownItem key="separated action" component="button">
|
|
1215
|
-
Separated Action
|
|
1216
|
-
</DropdownItem>
|
|
1217
|
-
];
|
|
1218
|
-
|
|
1219
|
-
const splitButtonDropdownItems = [
|
|
1220
|
-
<DropdownItem key="link">Link</DropdownItem>,
|
|
1221
|
-
<DropdownItem key="action" component="button">
|
|
1222
|
-
Action
|
|
1223
|
-
</DropdownItem>,
|
|
1224
|
-
<DropdownItem key="disabled link" isDisabled>
|
|
1225
|
-
Disabled Link
|
|
1226
|
-
</DropdownItem>,
|
|
1227
|
-
<DropdownItem key="disabled action" isDisabled component="button">
|
|
1228
|
-
Disabled Action
|
|
1229
|
-
</DropdownItem>
|
|
1230
|
-
];
|
|
1231
|
-
|
|
1232
|
-
const toggleGroupItems = (
|
|
1233
|
-
<React.Fragment>
|
|
1234
|
-
<ToolbarItem variant="label" id="stacked-example-resource-select">
|
|
1235
|
-
Resource
|
|
1236
|
-
</ToolbarItem>
|
|
1237
|
-
<ToolbarItem>
|
|
1238
|
-
<Select
|
|
1239
|
-
variant={SelectVariant.single}
|
|
1240
|
-
aria-label="Select Input"
|
|
1241
|
-
onToggle={this.onResourceToggle}
|
|
1242
|
-
onSelect={this.onResourceSelect}
|
|
1243
|
-
selections={resourceSelected}
|
|
1244
|
-
isOpen={resourceIsExpanded}
|
|
1245
|
-
ariaLabelledBy="stacked-example-resource-select"
|
|
1246
|
-
>
|
|
1247
|
-
{this.resourceOptions.map((option, index) => (
|
|
1248
|
-
<SelectOption isDisabled={option.disabled} key={index} value={option.value} />
|
|
1249
|
-
))}
|
|
1250
|
-
</Select>
|
|
1251
|
-
</ToolbarItem>
|
|
1252
|
-
<ToolbarItem variant="label" id="stacked-example-status-select">
|
|
1253
|
-
Status
|
|
1254
|
-
</ToolbarItem>
|
|
1255
|
-
<ToolbarItem>
|
|
1256
|
-
<Select
|
|
1257
|
-
variant={SelectVariant.single}
|
|
1258
|
-
aria-label="Select Input"
|
|
1259
|
-
onToggle={this.onStatusToggle}
|
|
1260
|
-
onSelect={this.onStatusSelect}
|
|
1261
|
-
selections={statusSelected}
|
|
1262
|
-
isOpen={statusIsExpanded}
|
|
1263
|
-
ariaLabelledBy="stacked-example-status-select"
|
|
1264
|
-
>
|
|
1265
|
-
{this.statusOptions.map((option, index) => (
|
|
1266
|
-
<SelectOption isDisabled={option.disabled} key={index} value={option.value} />
|
|
1267
|
-
))}
|
|
1268
|
-
</Select>
|
|
1269
|
-
</ToolbarItem>
|
|
1270
|
-
</React.Fragment>
|
|
1271
|
-
);
|
|
1272
|
-
|
|
1273
|
-
const firstRowItems = (
|
|
1274
|
-
<React.Fragment>
|
|
1275
|
-
<Toolbar>
|
|
1276
|
-
<ToolbarContent>
|
|
1277
|
-
<ToolbarToggleGroup toggleIcon={<FilterIcon />} breakpoint="lg">
|
|
1278
|
-
{toggleGroupItems}
|
|
1279
|
-
</ToolbarToggleGroup>
|
|
1280
|
-
<ToolbarItem variant="overflow-menu">
|
|
1281
|
-
<OverflowMenu breakpoint="2xl">
|
|
1282
|
-
<OverflowMenuContent>
|
|
1283
|
-
<OverflowMenuGroup groupType="button">
|
|
1284
|
-
<OverflowMenuItem>
|
|
1285
|
-
<Button variant={ButtonVariant.primary}>Primary</Button>
|
|
1286
|
-
</OverflowMenuItem>
|
|
1287
|
-
<OverflowMenuItem>
|
|
1288
|
-
<Button variant={ButtonVariant.secondary}>Secondary</Button>
|
|
1289
|
-
</OverflowMenuItem>
|
|
1290
|
-
</OverflowMenuGroup>
|
|
1291
|
-
</OverflowMenuContent>
|
|
1292
|
-
<OverflowMenuControl hasAdditionalOptions>
|
|
1293
|
-
<Dropdown
|
|
1294
|
-
onSelect={this.onResourceSelect}
|
|
1295
|
-
toggle={<KebabToggle onToggle={this.onKebabToggle} />}
|
|
1296
|
-
isOpen={kebabIsOpen}
|
|
1297
|
-
isPlain
|
|
1298
|
-
dropdownItems={dropdownItems}
|
|
1299
|
-
position={DropdownPosition.right}
|
|
1300
|
-
/>
|
|
1301
|
-
</OverflowMenuControl>
|
|
1302
|
-
</OverflowMenu>
|
|
1303
|
-
</ToolbarItem>
|
|
1304
|
-
</ToolbarContent>
|
|
1305
|
-
</Toolbar>
|
|
1306
|
-
</React.Fragment>
|
|
1307
|
-
);
|
|
1308
|
-
|
|
1309
|
-
const secondRowItems = (
|
|
1310
|
-
<React.Fragment>
|
|
1311
|
-
<Toolbar>
|
|
1312
|
-
<ToolbarContent>
|
|
1313
|
-
<ToolbarItem variant="bulk-select">
|
|
1314
|
-
<Dropdown
|
|
1315
|
-
onSelect={this.onSplitButtonSelect}
|
|
1316
|
-
toggle={
|
|
1317
|
-
<DropdownToggle
|
|
1318
|
-
id="stacked-example-toggle"
|
|
1319
|
-
splitButtonItems={[
|
|
1320
|
-
<DropdownToggleCheckbox id="example-checkbox-1" key="split-checkbox" aria-label="Select all" />
|
|
1321
|
-
]}
|
|
1322
|
-
onToggle={this.onSplitButtonToggle}
|
|
1323
|
-
/>
|
|
1324
|
-
}
|
|
1325
|
-
isOpen={splitButtonDropdownIsOpen}
|
|
1326
|
-
dropdownItems={splitButtonDropdownItems}
|
|
1327
|
-
/>
|
|
1328
|
-
</ToolbarItem>
|
|
1329
|
-
<ToolbarItem variant="pagination" align={{ default: 'alignRight' }}>
|
|
1330
|
-
<Pagination
|
|
1331
|
-
itemCount={37}
|
|
1332
|
-
perPage={this.state.perPage}
|
|
1333
|
-
page={this.state.page}
|
|
1334
|
-
onSetPage={this.onSetPage}
|
|
1335
|
-
widgetId="pagination-options-menu-top"
|
|
1336
|
-
onPerPageSelect={this.onPerPageSelect}
|
|
1337
|
-
/>
|
|
1338
|
-
</ToolbarItem>
|
|
1339
|
-
</ToolbarContent>
|
|
1340
|
-
</Toolbar>
|
|
1341
|
-
</React.Fragment>
|
|
1342
|
-
);
|
|
1343
|
-
|
|
1344
|
-
return (
|
|
1345
|
-
<React.Fragment>
|
|
1346
|
-
{firstRowItems}
|
|
1347
|
-
<Divider />
|
|
1348
|
-
{secondRowItems}
|
|
1349
|
-
</React.Fragment>
|
|
1350
|
-
);
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
90
|
+
```ts file="./ToolbarStacked.tsx"
|
|
1353
91
|
```
|