@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.
@@ -0,0 +1,253 @@
1
+ import React from 'react';
2
+ import {
3
+ Button,
4
+ ButtonVariant,
5
+ KebabToggle,
6
+ Select,
7
+ SelectOption,
8
+ SelectOptionObject,
9
+ SelectVariant,
10
+ Pagination,
11
+ Dropdown,
12
+ DropdownSeparator,
13
+ DropdownToggle,
14
+ DropdownToggleCheckbox,
15
+ DropdownItem,
16
+ DropdownPosition,
17
+ Divider,
18
+ OverflowMenu,
19
+ OverflowMenuContent,
20
+ OverflowMenuControl,
21
+ OverflowMenuGroup,
22
+ OverflowMenuItem,
23
+ Toolbar,
24
+ ToolbarContent,
25
+ ToolbarToggleGroup,
26
+ ToolbarItem
27
+ } from '@patternfly/react-core';
28
+ import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
29
+
30
+ export const ToolbarStacked: React.FunctionComponent = () => {
31
+ // toggle group - three option menus with labels, two icon buttons, Kebab menu - right aligned
32
+ // pagination - right aligned
33
+ const resourceOptions = [
34
+ { value: 'All resources', disabled: false },
35
+ { value: 'Deployment', disabled: false },
36
+ { value: 'Pod', disabled: false }
37
+ ];
38
+
39
+ const statusOptions = [
40
+ { value: 'Running', disabled: false },
41
+ { value: 'New', disabled: false },
42
+ { value: 'Pending', disabled: false },
43
+ { value: 'Cancelled', disabled: false }
44
+ ];
45
+
46
+ const [kebabIsOpen, setKebabIsOpen] = React.useState(false);
47
+ const [resourceIsExpanded, setResourceIsExpanded] = React.useState(false);
48
+ const [resourceSelected, setResourceSelected] = React.useState<string | SelectOptionObject>();
49
+ const [statusIsExpanded, setStatusIsExpanded] = React.useState(false);
50
+ const [statusSelected, setStatusSelected] = React.useState<string | SelectOptionObject>();
51
+ const [splitButtonDropdownIsOpen, setSplitButtonDropdownIsOpen] = React.useState(false);
52
+ const [page, setPage] = React.useState(1);
53
+ const [perPage, setPerPage] = React.useState(20);
54
+
55
+ const onKebabToggle = (isOpen: boolean) => {
56
+ setKebabIsOpen(isOpen);
57
+ };
58
+
59
+ const onResourceToggle = (isExpanded: boolean) => {
60
+ setResourceIsExpanded(isExpanded);
61
+ };
62
+
63
+ const onResourceSelect = (_event: React.ChangeEvent | React.MouseEvent, selection: string | SelectOptionObject) => {
64
+ setResourceSelected(selection);
65
+ setResourceIsExpanded(false);
66
+ };
67
+
68
+ const onResourceSelectDropdown = (event: React.SyntheticEvent<HTMLDivElement, Event> | undefined) => {
69
+ setResourceSelected(event?.target);
70
+ setResourceIsExpanded(false);
71
+ };
72
+
73
+ const onStatusToggle = (isExpanded: boolean) => {
74
+ setStatusIsExpanded(isExpanded);
75
+ };
76
+
77
+ const onStatusSelect = (_event: React.ChangeEvent | React.MouseEvent, selection: string | SelectOptionObject) => {
78
+ setStatusSelected(selection);
79
+ setStatusIsExpanded(false);
80
+ };
81
+
82
+ const onSetPage = (_event: React.MouseEvent | React.KeyboardEvent | MouseEvent, pageNumber: number) => {
83
+ setPage(pageNumber);
84
+ };
85
+
86
+ const onPerPageSelect = (
87
+ _event: React.MouseEvent | React.KeyboardEvent | MouseEvent,
88
+ perPage: number,
89
+ page: number
90
+ ) => {
91
+ setPage(page);
92
+ setPerPage(perPage);
93
+ };
94
+
95
+ const onSplitButtonToggle = (isOpen: boolean) => {
96
+ setSplitButtonDropdownIsOpen(isOpen);
97
+ };
98
+
99
+ const onSplitButtonSelect = () => {
100
+ setSplitButtonDropdownIsOpen(!splitButtonDropdownIsOpen);
101
+ };
102
+
103
+ const dropdownItems = [
104
+ <DropdownItem key="link">Link</DropdownItem>,
105
+ <DropdownItem key="action" component="button">
106
+ Action
107
+ </DropdownItem>,
108
+ <DropdownItem key="disabled link" isDisabled>
109
+ Disabled Link
110
+ </DropdownItem>,
111
+ <DropdownItem key="disabled action" isDisabled component="button">
112
+ Disabled Action
113
+ </DropdownItem>,
114
+ <DropdownSeparator key="separator" />,
115
+ <DropdownItem key="separated link">Separated Link</DropdownItem>,
116
+ <DropdownItem key="separated action" component="button">
117
+ Separated Action
118
+ </DropdownItem>
119
+ ];
120
+
121
+ const splitButtonDropdownItems = [
122
+ <DropdownItem key="link">Link</DropdownItem>,
123
+ <DropdownItem key="action" component="button">
124
+ Action
125
+ </DropdownItem>,
126
+ <DropdownItem key="disabled link" isDisabled>
127
+ Disabled Link
128
+ </DropdownItem>,
129
+ <DropdownItem key="disabled action" isDisabled component="button">
130
+ Disabled Action
131
+ </DropdownItem>
132
+ ];
133
+
134
+ const toggleGroupItems = (
135
+ <React.Fragment>
136
+ <ToolbarItem variant="label" id="stacked-example-resource-select">
137
+ Resource
138
+ </ToolbarItem>
139
+ <ToolbarItem>
140
+ <Select
141
+ variant={SelectVariant.single}
142
+ aria-label="Select Input"
143
+ onToggle={onResourceToggle}
144
+ onSelect={onResourceSelect}
145
+ selections={resourceSelected}
146
+ isOpen={resourceIsExpanded}
147
+ aria-labelledby="stacked-example-resource-select"
148
+ >
149
+ {resourceOptions.map((option, index) => (
150
+ <SelectOption isDisabled={option.disabled} key={index} value={option.value} />
151
+ ))}
152
+ </Select>
153
+ </ToolbarItem>
154
+ <ToolbarItem variant="label" id="stacked-example-status-select">
155
+ Status
156
+ </ToolbarItem>
157
+ <ToolbarItem>
158
+ <Select
159
+ variant={SelectVariant.single}
160
+ aria-label="Select Input"
161
+ onToggle={onStatusToggle}
162
+ onSelect={onStatusSelect}
163
+ selections={statusSelected}
164
+ isOpen={statusIsExpanded}
165
+ aria-labelledby="stacked-example-status-select"
166
+ >
167
+ {statusOptions.map((option, index) => (
168
+ <SelectOption isDisabled={option.disabled} key={index} value={option.value} />
169
+ ))}
170
+ </Select>
171
+ </ToolbarItem>
172
+ </React.Fragment>
173
+ );
174
+
175
+ const firstRowItems = (
176
+ <React.Fragment>
177
+ <Toolbar>
178
+ <ToolbarContent>
179
+ <ToolbarToggleGroup toggleIcon={<FilterIcon />} breakpoint="lg">
180
+ {toggleGroupItems}
181
+ </ToolbarToggleGroup>
182
+ <ToolbarItem variant="overflow-menu">
183
+ <OverflowMenu breakpoint="2xl">
184
+ <OverflowMenuContent>
185
+ <OverflowMenuGroup groupType="button">
186
+ <OverflowMenuItem>
187
+ <Button variant={ButtonVariant.primary}>Primary</Button>
188
+ </OverflowMenuItem>
189
+ <OverflowMenuItem>
190
+ <Button variant={ButtonVariant.secondary}>Secondary</Button>
191
+ </OverflowMenuItem>
192
+ </OverflowMenuGroup>
193
+ </OverflowMenuContent>
194
+ <OverflowMenuControl hasAdditionalOptions>
195
+ <Dropdown
196
+ onSelect={onResourceSelectDropdown}
197
+ toggle={<KebabToggle onToggle={onKebabToggle} />}
198
+ isOpen={kebabIsOpen}
199
+ isPlain
200
+ dropdownItems={dropdownItems}
201
+ position={DropdownPosition.right}
202
+ />
203
+ </OverflowMenuControl>
204
+ </OverflowMenu>
205
+ </ToolbarItem>
206
+ </ToolbarContent>
207
+ </Toolbar>
208
+ </React.Fragment>
209
+ );
210
+
211
+ const secondRowItems = (
212
+ <React.Fragment>
213
+ <Toolbar>
214
+ <ToolbarContent>
215
+ <ToolbarItem variant="bulk-select">
216
+ <Dropdown
217
+ onSelect={onSplitButtonSelect}
218
+ toggle={
219
+ <DropdownToggle
220
+ id="stacked-example-toggle"
221
+ splitButtonItems={[
222
+ <DropdownToggleCheckbox id="example-checkbox-1" key="split-checkbox" aria-label="Select all" />
223
+ ]}
224
+ onToggle={onSplitButtonToggle}
225
+ />
226
+ }
227
+ isOpen={splitButtonDropdownIsOpen}
228
+ dropdownItems={splitButtonDropdownItems}
229
+ />
230
+ </ToolbarItem>
231
+ <ToolbarItem variant="pagination" alignment={{ default: 'alignRight' }}>
232
+ <Pagination
233
+ itemCount={37}
234
+ perPage={perPage}
235
+ page={page}
236
+ onSetPage={onSetPage}
237
+ widgetId="pagination-options-menu-top"
238
+ onPerPageSelect={onPerPageSelect}
239
+ />
240
+ </ToolbarItem>
241
+ </ToolbarContent>
242
+ </Toolbar>
243
+ </React.Fragment>
244
+ );
245
+
246
+ return (
247
+ <React.Fragment>
248
+ {firstRowItems}
249
+ <Divider />
250
+ {secondRowItems}
251
+ </React.Fragment>
252
+ );
253
+ };
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import { Toolbar, ToolbarItem, ToolbarContent, SearchInput, Checkbox } from '@patternfly/react-core';
3
+
4
+ export const ToolbarSticky: React.FunctionComponent = () => {
5
+ const [isSticky, setIsSticky] = React.useState(true);
6
+ const [showEvenOnly, setShowEvenOnly] = React.useState(true);
7
+ const array = Array.from(Array(30), (_, x) => x); // create array of numbers from 1-30 for demo purposes
8
+ const numbers = showEvenOnly ? array.filter(number => number % 2 === 0) : array;
9
+
10
+ return (
11
+ <React.Fragment>
12
+ <div style={{ overflowY: 'scroll', height: '200px' }}>
13
+ <Toolbar id="toolbar-sticky" inset={{ default: 'insetNone' }} isSticky={isSticky}>
14
+ <ToolbarContent>
15
+ <ToolbarItem>
16
+ <SearchInput aria-label="Sticky example search input" />
17
+ </ToolbarItem>
18
+ <ToolbarItem>
19
+ <Checkbox
20
+ label="Show only even number items"
21
+ isChecked={showEvenOnly}
22
+ onChange={setShowEvenOnly}
23
+ id="showOnlyEvenCheckbox"
24
+ />
25
+ </ToolbarItem>
26
+ </ToolbarContent>
27
+ </Toolbar>
28
+ <ul>
29
+ {numbers.map(number => (
30
+ <li key={number}>{`item ${number}`}</li>
31
+ ))}
32
+ </ul>
33
+ </div>
34
+ <Checkbox label="Is toolbar sticky" isChecked={isSticky} onChange={setIsSticky} id="isStickyCheckbox" />
35
+ </React.Fragment>
36
+ );
37
+ };
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import { Toolbar, ToolbarItem, ToolbarContent } from '@patternfly/react-core';
3
+ import { Button } from '@patternfly/react-core';
4
+
5
+ export const ToolbarWidths: React.FunctionComponent = () => {
6
+ const widths = {
7
+ default: '100px',
8
+ sm: '80px',
9
+ md: '150px',
10
+ lg: '200px',
11
+ xl: '250px',
12
+ '2xl': '300px'
13
+ };
14
+
15
+ const items = (
16
+ <React.Fragment>
17
+ <ToolbarItem widths={widths}>
18
+ <Button variant="secondary" style={{ width: '100%' }}>
19
+ Action
20
+ </Button>
21
+ </ToolbarItem>
22
+ </React.Fragment>
23
+ );
24
+
25
+ return (
26
+ <Toolbar id="toolbar-widths">
27
+ <ToolbarContent>{items}</ToolbarContent>
28
+ </Toolbar>
29
+ );
30
+ };
@@ -0,0 +1,222 @@
1
+ import React from 'react';
2
+ import {
3
+ Toolbar,
4
+ ToolbarItem,
5
+ ToolbarContent,
6
+ ToolbarFilter,
7
+ ToolbarToggleGroup,
8
+ ToolbarGroup,
9
+ SelectOptionObject
10
+ } from '@patternfly/react-core';
11
+ import {
12
+ Button,
13
+ Select,
14
+ SelectOption,
15
+ SelectVariant,
16
+ Dropdown,
17
+ DropdownItem,
18
+ DropdownSeparator,
19
+ DropdownPosition,
20
+ KebabToggle,
21
+ SearchInput
22
+ } from '@patternfly/react-core';
23
+ import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
24
+ import EditIcon from '@patternfly/react-icons/dist/esm/icons/edit-icon';
25
+ import CloneIcon from '@patternfly/react-icons/dist/esm/icons/clone-icon';
26
+ import SyncIcon from '@patternfly/react-icons/dist/esm/icons/sync-icon';
27
+
28
+ export const ToolbarWithFilters: React.FunctionComponent = () => {
29
+ const [inputValue, setInputValue] = React.useState('');
30
+ const [statusIsExpanded, setStatusIsExpanded] = React.useState(false);
31
+ const [riskIsExpanded, setRiskIsExpanded] = React.useState(false);
32
+ const [filters, setFilters] = React.useState({
33
+ risk: ['Low'],
34
+ status: ['New', 'Pending']
35
+ });
36
+ const [kebabIsOpen, setKebabIsOpen] = React.useState(false);
37
+
38
+ const onInputChange = (newValue: string) => {
39
+ setInputValue(newValue);
40
+ };
41
+
42
+ const onSelect = (
43
+ type: string,
44
+ event: React.MouseEvent | React.ChangeEvent,
45
+ selection: string | SelectOptionObject
46
+ ) => {
47
+ const checked = (event.target as HTMLInputElement).checked;
48
+ setFilters(prev => {
49
+ const prevSelections = prev[type];
50
+ return {
51
+ ...prev,
52
+ [type]: checked ? [...prevSelections, selection] : prevSelections.filter(value => value !== selection)
53
+ };
54
+ });
55
+ };
56
+
57
+ const onStatusSelect = (event: React.MouseEvent | React.ChangeEvent, selection: string | SelectOptionObject) => {
58
+ onSelect('status', event, selection);
59
+ };
60
+
61
+ const onRiskSelect = (event: React.MouseEvent | React.ChangeEvent, selection: string | SelectOptionObject) => {
62
+ onSelect('risk', event, selection);
63
+ };
64
+
65
+ const onDelete = (type: string, id: string) => {
66
+ if (type === 'Risk') {
67
+ setFilters({ risk: filters.risk.filter((fil: string) => fil !== id), status: filters.status });
68
+ } else if (type === 'Status') {
69
+ setFilters({ risk: filters.risk, status: filters.status.filter((fil: string) => fil !== id) });
70
+ } else {
71
+ setFilters({ risk: [], status: [] });
72
+ }
73
+ };
74
+
75
+ const onDeleteGroup = (type: string) => {
76
+ if (type === 'Risk') {
77
+ setFilters({ risk: [], status: filters.status });
78
+ } else if (type === 'Status') {
79
+ setFilters({ risk: filters.risk, status: [] });
80
+ }
81
+ };
82
+
83
+ const onStatusToggle = (isExpanded: boolean) => {
84
+ setStatusIsExpanded(isExpanded);
85
+ };
86
+
87
+ const onRiskToggle = (isExpanded: boolean) => {
88
+ setRiskIsExpanded(isExpanded);
89
+ };
90
+
91
+ const onKebabToggle = (isOpen: boolean) => {
92
+ setKebabIsOpen(isOpen);
93
+ };
94
+
95
+ const statusMenuItems = [
96
+ <SelectOption key="statusNew" value="New" />,
97
+ <SelectOption key="statusPending" value="Pending" />,
98
+ <SelectOption key="statusRunning" value="Running" />,
99
+ <SelectOption key="statusCancelled" value="Cancelled" />
100
+ ];
101
+
102
+ const riskMenuItems = [
103
+ <SelectOption key="riskLow" value="Low" />,
104
+ <SelectOption key="riskMedium" value="Medium" />,
105
+ <SelectOption key="riskHigh" value="High" />
106
+ ];
107
+
108
+ const toggleGroupItems = (
109
+ <React.Fragment>
110
+ <ToolbarItem variant="search-filter">
111
+ <SearchInput
112
+ aria-label="With filters example search input"
113
+ onChange={onInputChange}
114
+ value={inputValue}
115
+ onClear={() => {
116
+ onInputChange('');
117
+ }}
118
+ />
119
+ </ToolbarItem>
120
+ <ToolbarGroup variant="filter-group">
121
+ <ToolbarFilter
122
+ chips={filters.status}
123
+ deleteChip={(category, chip) => onDelete(category as string, chip as string)}
124
+ deleteChipGroup={category => onDeleteGroup(category as string)}
125
+ categoryName="Status"
126
+ >
127
+ <Select
128
+ variant={SelectVariant.checkbox}
129
+ aria-label="Status"
130
+ onToggle={onStatusToggle}
131
+ onSelect={onStatusSelect}
132
+ selections={filters.status}
133
+ isOpen={statusIsExpanded}
134
+ placeholderText="Status"
135
+ >
136
+ {statusMenuItems}
137
+ </Select>
138
+ </ToolbarFilter>
139
+ <ToolbarFilter
140
+ chips={filters.risk}
141
+ deleteChip={(category, chip) => onDelete(category as string, chip as string)}
142
+ categoryName="Risk"
143
+ >
144
+ <Select
145
+ variant={SelectVariant.checkbox}
146
+ aria-label="Risk"
147
+ onToggle={onRiskToggle}
148
+ onSelect={onRiskSelect}
149
+ selections={filters.risk}
150
+ isOpen={riskIsExpanded}
151
+ placeholderText="Risk"
152
+ >
153
+ {riskMenuItems}
154
+ </Select>
155
+ </ToolbarFilter>
156
+ </ToolbarGroup>
157
+ </React.Fragment>
158
+ );
159
+
160
+ const dropdownItems = [
161
+ <DropdownItem key="link">Link</DropdownItem>,
162
+ <DropdownItem key="action" component="button">
163
+ Action
164
+ </DropdownItem>,
165
+ <DropdownItem key="disabled link" isDisabled>
166
+ Disabled Link
167
+ </DropdownItem>,
168
+ <DropdownItem key="disabled action" isDisabled component="button">
169
+ Disabled Action
170
+ </DropdownItem>,
171
+ <DropdownSeparator key="separator" />,
172
+ <DropdownItem key="separated link">Separated Link</DropdownItem>,
173
+ <DropdownItem key="separated action" component="button">
174
+ Separated Action
175
+ </DropdownItem>
176
+ ];
177
+
178
+ const toolbarItems = (
179
+ <React.Fragment>
180
+ <ToolbarToggleGroup toggleIcon={<FilterIcon />} breakpoint="xl">
181
+ {toggleGroupItems}
182
+ </ToolbarToggleGroup>
183
+ <ToolbarGroup variant="icon-button-group">
184
+ <ToolbarItem>
185
+ <Button variant="plain" aria-label="edit">
186
+ <EditIcon />
187
+ </Button>
188
+ </ToolbarItem>
189
+ <ToolbarItem>
190
+ <Button variant="plain" aria-label="clone">
191
+ <CloneIcon />
192
+ </Button>
193
+ </ToolbarItem>
194
+ <ToolbarItem>
195
+ <Button variant="plain" aria-label="sync">
196
+ <SyncIcon />
197
+ </Button>
198
+ </ToolbarItem>
199
+ </ToolbarGroup>
200
+ <ToolbarItem>
201
+ <Dropdown
202
+ toggle={<KebabToggle onToggle={onKebabToggle} />}
203
+ isOpen={kebabIsOpen}
204
+ isPlain
205
+ dropdownItems={dropdownItems}
206
+ position={DropdownPosition.right}
207
+ />
208
+ </ToolbarItem>
209
+ </React.Fragment>
210
+ );
211
+
212
+ return (
213
+ <Toolbar
214
+ id="toolbar-with-filter"
215
+ className="pf-m-toggle-group-container"
216
+ collapseListedFiltersBreakpoint="xl"
217
+ clearAllFilters={() => onDelete('', '')}
218
+ >
219
+ <ToolbarContent>{toolbarItems}</ToolbarContent>
220
+ </Toolbar>
221
+ );
222
+ };