@patternfly/react-core 4.227.2 → 4.227.5
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 +24 -0
- package/dist/esm/components/DataList/DataList.d.ts +0 -2
- package/dist/esm/components/DataList/DataList.d.ts.map +1 -1
- package/dist/esm/components/DataList/DataList.js.map +1 -1
- package/dist/esm/components/DataList/DataListItem.d.ts.map +1 -1
- package/dist/esm/components/DataList/DataListItem.js +1 -2
- package/dist/esm/components/DataList/DataListItem.js.map +1 -1
- package/dist/js/components/DataList/DataList.d.ts +0 -2
- package/dist/js/components/DataList/DataList.d.ts.map +1 -1
- package/dist/js/components/DataList/DataList.js.map +1 -1
- package/dist/js/components/DataList/DataListItem.d.ts.map +1 -1
- package/dist/js/components/DataList/DataListItem.js +1 -2
- package/dist/js/components/DataList/DataListItem.js.map +1 -1
- package/dist/umd/react-core.js +1 -2
- package/dist/umd/react-core.min.css +3339 -3339
- package/dist/umd/react-core.min.js +1 -1
- package/package.json +5 -5
- package/src/components/DataList/DataList.tsx +0 -2
- package/src/components/DataList/DataListItem.tsx +1 -3
- package/src/components/DataList/__tests__/DataList.test.tsx +14 -32
- package/src/components/DataList/examples/DataListSelectableRows.tsx +1 -1
- package/src/components/Menu/examples/Menu.md +19 -1290
- package/src/components/Menu/examples/MenuBasic.tsx +51 -0
- package/src/components/Menu/examples/MenuFilteringWithTextInput.tsx +52 -0
- package/src/components/Menu/examples/MenuOptionMultiSelect.tsx +30 -0
- package/src/components/Menu/examples/MenuOptionSingleSelect.tsx +27 -0
- package/src/components/Menu/examples/MenuScrollable.tsx +48 -0
- package/src/components/Menu/examples/MenuScrollableCustomMenuHeight.tsx +48 -0
- package/src/components/Menu/examples/MenuWithActions.tsx +75 -0
- package/src/components/Menu/examples/MenuWithCheckbox.tsx +2 -2
- package/src/components/Menu/examples/MenuWithDescription.tsx +35 -0
- package/src/components/Menu/examples/{MenuDrilldown.tsx → MenuWithDrilldown.tsx} +1 -1
- package/src/components/Menu/examples/MenuWithDrilldownBreadcrumbs.tsx +331 -0
- package/src/components/Menu/examples/{MenuDrilldownInitialState.tsx → MenuWithDrilldownInitialState.tsx} +0 -0
- package/src/components/Menu/examples/{MenuDrilldownSubmenuFunctions.tsx → MenuWithDrilldownSubmenuFunctions.tsx} +1 -1
- package/src/components/Menu/examples/MenuWithFavorites.tsx +104 -0
- package/src/components/Menu/examples/MenuWithFooter.tsx +40 -0
- package/src/components/Menu/examples/MenuWithIcons.tsx +33 -0
- package/src/components/Menu/examples/MenuWithLinks.tsx +30 -0
- package/src/components/Menu/examples/MenuWithSeparators.tsx +26 -0
- package/src/components/Menu/examples/MenuWithTitledGroups.tsx +46 -0
- package/src/components/Menu/examples/MenuWithViewMore.tsx +118 -0
- package/src/components/Radio/examples/Radio.md +12 -68
- package/src/components/Radio/examples/RadioControlled.tsx +21 -0
- package/src/components/Radio/examples/RadioDisabled.tsx +15 -0
- package/src/components/Radio/examples/RadioLabelWraps.tsx +6 -0
- package/src/components/Radio/examples/RadioReversed.tsx +6 -0
- package/src/components/Radio/examples/RadioStandaloneInput.tsx +6 -0
- package/src/components/Radio/examples/RadioUncontrolled.tsx +6 -0
- package/src/components/Radio/examples/RadioWithBody.tsx +6 -0
- package/src/components/Radio/examples/RadioWithDescription.tsx +11 -0
- package/src/components/Radio/examples/RadioWithDescriptionAndBody.tsx +12 -0
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Menu,
|
|
4
|
+
MenuContent,
|
|
5
|
+
MenuList,
|
|
6
|
+
MenuItem,
|
|
7
|
+
Divider,
|
|
8
|
+
DrilldownMenu,
|
|
9
|
+
Breadcrumb,
|
|
10
|
+
BreadcrumbItem,
|
|
11
|
+
BreadcrumbHeading,
|
|
12
|
+
MenuBreadcrumb,
|
|
13
|
+
Dropdown,
|
|
14
|
+
DropdownItem,
|
|
15
|
+
BadgeToggle,
|
|
16
|
+
Checkbox
|
|
17
|
+
} from '@patternfly/react-core';
|
|
18
|
+
import StorageDomainIcon from '@patternfly/react-icons/dist/esm/icons/storage-domain-icon';
|
|
19
|
+
import CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-icon';
|
|
20
|
+
import LayerGroupIcon from '@patternfly/react-icons/dist/esm/icons/layer-group-icon';
|
|
21
|
+
import AngleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-left-icon';
|
|
22
|
+
import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';
|
|
23
|
+
|
|
24
|
+
export const MenuWithDrilldownBreadcrumbs: React.FunctionComponent = () => {
|
|
25
|
+
const [menuDrilledIn, setMenuDrilledIn] = React.useState<string[]>([]);
|
|
26
|
+
const [drilldownPath, setDrilldownPath] = React.useState<string[]>([]);
|
|
27
|
+
const [menuHeights, setMenuHeights] = React.useState<any>({});
|
|
28
|
+
const [activeMenu, setActiveMenu] = React.useState<string>('breadcrumbs-rootMenu');
|
|
29
|
+
const [breadcrumb, setBreadcrumb] = React.useState<JSX.Element>();
|
|
30
|
+
const [withMaxMenuHeight, setWithMaxMenuHeight] = React.useState(false);
|
|
31
|
+
|
|
32
|
+
const onToggle = (isOpen: boolean, key: string) => {
|
|
33
|
+
switch (key) {
|
|
34
|
+
case 'app':
|
|
35
|
+
setBreadcrumb(appGroupingBreadcrumb(isOpen));
|
|
36
|
+
break;
|
|
37
|
+
case 'label':
|
|
38
|
+
setBreadcrumb(labelsBreadcrumb(isOpen));
|
|
39
|
+
break;
|
|
40
|
+
default:
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const onToggleMaxMenuHeight = (checked: boolean) => {
|
|
46
|
+
setWithMaxMenuHeight(checked);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const drillOut = (toMenuId: string, fromPathId: string, _breadcrumb: JSX.Element | null) => {
|
|
50
|
+
const indexOfMenuId = menuDrilledIn.indexOf(toMenuId);
|
|
51
|
+
const menuDrilledInSansLast = menuDrilledIn.slice(0, indexOfMenuId);
|
|
52
|
+
const indexOfMenuIdPath = drilldownPath.indexOf(fromPathId);
|
|
53
|
+
const pathSansLast = drilldownPath.slice(0, indexOfMenuIdPath);
|
|
54
|
+
setMenuDrilledIn(menuDrilledInSansLast);
|
|
55
|
+
setDrilldownPath(pathSansLast);
|
|
56
|
+
setActiveMenu(toMenuId);
|
|
57
|
+
};
|
|
58
|
+
const setHeight = (menuId: string, height: number) => {
|
|
59
|
+
if (!menuHeights[menuId]) {
|
|
60
|
+
setMenuHeights({ ...menuHeights, [menuId]: height });
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const drillIn = (fromMenuId: string, toMenuId: string, pathId: string) => {
|
|
64
|
+
setMenuDrilledIn([...menuDrilledIn, fromMenuId]);
|
|
65
|
+
setDrilldownPath([...drilldownPath, pathId]);
|
|
66
|
+
setActiveMenu(toMenuId);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const startRolloutBreadcrumb = (
|
|
70
|
+
<Breadcrumb>
|
|
71
|
+
<BreadcrumbItem component="button" onClick={() => drillOut('breadcrumbs-rootMenu', 'group:start_rollout', null)}>
|
|
72
|
+
Root
|
|
73
|
+
</BreadcrumbItem>
|
|
74
|
+
<BreadcrumbHeading component="button">Start rollout</BreadcrumbHeading>
|
|
75
|
+
</Breadcrumb>
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const appGroupingBreadcrumb = (isOpen: boolean) => (
|
|
79
|
+
<Breadcrumb>
|
|
80
|
+
<BreadcrumbItem component="button" onClick={() => drillOut('breadcrumbs-rootMenu', 'group:start_rollout', null)}>
|
|
81
|
+
Root
|
|
82
|
+
</BreadcrumbItem>
|
|
83
|
+
<BreadcrumbItem isDropdown>
|
|
84
|
+
<Dropdown
|
|
85
|
+
toggle={
|
|
86
|
+
<BadgeToggle id="toggle-id" onToggle={open => onToggle(open, 'app')}>
|
|
87
|
+
1
|
|
88
|
+
</BadgeToggle>
|
|
89
|
+
}
|
|
90
|
+
isOpen={isOpen}
|
|
91
|
+
dropdownItems={[
|
|
92
|
+
<DropdownItem
|
|
93
|
+
key="dropdown-start"
|
|
94
|
+
component="button"
|
|
95
|
+
icon={<AngleLeftIcon />}
|
|
96
|
+
onClick={() =>
|
|
97
|
+
drillOut('breadcrumbs-drilldownMenuStart', 'group:app_grouping_start', startRolloutBreadcrumb)
|
|
98
|
+
}
|
|
99
|
+
>
|
|
100
|
+
Start rollout
|
|
101
|
+
</DropdownItem>
|
|
102
|
+
]}
|
|
103
|
+
/>
|
|
104
|
+
</BreadcrumbItem>
|
|
105
|
+
<BreadcrumbHeading component="button">Application Grouping</BreadcrumbHeading>
|
|
106
|
+
</Breadcrumb>
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const labelsBreadcrumb = (isOpen: boolean) => (
|
|
110
|
+
<Breadcrumb>
|
|
111
|
+
<BreadcrumbItem component="button" onClick={() => drillOut('breadcrumbs-rootMenu', 'group:start_rollout', null)}>
|
|
112
|
+
Root
|
|
113
|
+
</BreadcrumbItem>
|
|
114
|
+
<BreadcrumbItem isDropdown>
|
|
115
|
+
<Dropdown
|
|
116
|
+
toggle={
|
|
117
|
+
<BadgeToggle id="toggle-id" onToggle={open => onToggle(open, 'label')}>
|
|
118
|
+
1
|
|
119
|
+
</BadgeToggle>
|
|
120
|
+
}
|
|
121
|
+
isOpen={isOpen}
|
|
122
|
+
dropdownItems={[
|
|
123
|
+
<DropdownItem
|
|
124
|
+
key="dropdown-start"
|
|
125
|
+
component="button"
|
|
126
|
+
icon={<AngleLeftIcon />}
|
|
127
|
+
onClick={() => drillOut('breadcrumbs-drilldownMenuStart', 'group:labels_start', startRolloutBreadcrumb)}
|
|
128
|
+
>
|
|
129
|
+
Start rollout
|
|
130
|
+
</DropdownItem>
|
|
131
|
+
]}
|
|
132
|
+
/>
|
|
133
|
+
</BreadcrumbItem>
|
|
134
|
+
<BreadcrumbHeading component="button">Labels</BreadcrumbHeading>
|
|
135
|
+
</Breadcrumb>
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
const pauseRolloutsBreadcrumb = (
|
|
139
|
+
<Breadcrumb>
|
|
140
|
+
<BreadcrumbItem component="button" onClick={() => drillOut('breadcrumbs-rootMenu', 'group:pause_rollout', null)}>
|
|
141
|
+
Root
|
|
142
|
+
</BreadcrumbItem>
|
|
143
|
+
<BreadcrumbHeading component="button">Pause rollouts</BreadcrumbHeading>
|
|
144
|
+
</Breadcrumb>
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
const pauseRolloutsAppGrpBreadcrumb = (
|
|
148
|
+
<Breadcrumb>
|
|
149
|
+
<BreadcrumbItem component="button" onClick={() => drillOut('breadcrumbs-rootMenu', 'group:pause_rollout', null)}>
|
|
150
|
+
Root
|
|
151
|
+
</BreadcrumbItem>
|
|
152
|
+
<BreadcrumbItem
|
|
153
|
+
component="button"
|
|
154
|
+
onClick={() => drillOut('breadcrumbs-drilldownMenuPause', 'group:app_grouping', pauseRolloutsBreadcrumb)}
|
|
155
|
+
>
|
|
156
|
+
Pause rollouts
|
|
157
|
+
</BreadcrumbItem>
|
|
158
|
+
<BreadcrumbHeading component="button">Application Grouping</BreadcrumbHeading>
|
|
159
|
+
</Breadcrumb>
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
const pauseRolloutsLabelsBreadcrumb = (
|
|
163
|
+
<Breadcrumb>
|
|
164
|
+
<BreadcrumbItem component="button" onClick={() => drillOut('breadcrumbs-rootMenu', 'group:pause_rollout', null)}>
|
|
165
|
+
Root
|
|
166
|
+
</BreadcrumbItem>
|
|
167
|
+
<BreadcrumbItem
|
|
168
|
+
component="button"
|
|
169
|
+
onClick={() => drillOut('breadcrumbs-drilldownMenuPause', 'group:labels', pauseRolloutsBreadcrumb)}
|
|
170
|
+
>
|
|
171
|
+
Pause rollouts
|
|
172
|
+
</BreadcrumbItem>
|
|
173
|
+
<BreadcrumbHeading component="button">Labels</BreadcrumbHeading>
|
|
174
|
+
</Breadcrumb>
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
const addStorageBreadcrumb = (
|
|
178
|
+
<Breadcrumb>
|
|
179
|
+
<BreadcrumbItem component="button" onClick={() => drillOut('breadcrumbs-rootMenu', 'group:storage', null)}>
|
|
180
|
+
Root
|
|
181
|
+
</BreadcrumbItem>
|
|
182
|
+
<BreadcrumbHeading component="button">Add storage</BreadcrumbHeading>
|
|
183
|
+
</Breadcrumb>
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
return (
|
|
187
|
+
<>
|
|
188
|
+
<Checkbox
|
|
189
|
+
label="Set max menu height"
|
|
190
|
+
isChecked={withMaxMenuHeight}
|
|
191
|
+
onChange={onToggleMaxMenuHeight}
|
|
192
|
+
aria-label="Set max menu height checkbox"
|
|
193
|
+
id="toggle-max-menu-height"
|
|
194
|
+
name="toggle-max-menu-height"
|
|
195
|
+
/>
|
|
196
|
+
<br />
|
|
197
|
+
<Menu
|
|
198
|
+
id="breadcrumbs-rootMenu"
|
|
199
|
+
containsDrilldown
|
|
200
|
+
drilldownItemPath={drilldownPath}
|
|
201
|
+
drilledInMenus={menuDrilledIn}
|
|
202
|
+
activeMenu={activeMenu}
|
|
203
|
+
onDrillIn={drillIn}
|
|
204
|
+
onDrillOut={() => drillOut}
|
|
205
|
+
onGetMenuHeight={setHeight}
|
|
206
|
+
>
|
|
207
|
+
{breadcrumb && (
|
|
208
|
+
<>
|
|
209
|
+
<MenuBreadcrumb>{breadcrumb}</MenuBreadcrumb>
|
|
210
|
+
<Divider component="li" />
|
|
211
|
+
</>
|
|
212
|
+
)}
|
|
213
|
+
<MenuContent menuHeight={`${menuHeights[activeMenu]}px`} maxMenuHeight={withMaxMenuHeight ? '100px' : 'auto'}>
|
|
214
|
+
<MenuList>
|
|
215
|
+
<MenuItem
|
|
216
|
+
itemId="group:start_rollout"
|
|
217
|
+
direction="down"
|
|
218
|
+
onClick={() => setBreadcrumb(startRolloutBreadcrumb)}
|
|
219
|
+
drilldownMenu={
|
|
220
|
+
<DrilldownMenu id="breadcrumbs-drilldownMenuStart">
|
|
221
|
+
<MenuItem
|
|
222
|
+
itemId="group:app_grouping_start"
|
|
223
|
+
description="Groups A-G"
|
|
224
|
+
direction="down"
|
|
225
|
+
onClick={() => setBreadcrumb(appGroupingBreadcrumb(false))}
|
|
226
|
+
drilldownMenu={
|
|
227
|
+
<DrilldownMenu id="breadcrumbs-drilldownMenuStartGrouping">
|
|
228
|
+
<MenuItem itemId="group_a">Group A</MenuItem>
|
|
229
|
+
<MenuItem itemId="group_b">Group B</MenuItem>
|
|
230
|
+
<MenuItem itemId="group_c">Group C</MenuItem>
|
|
231
|
+
<MenuItem itemId="group_d">Group D</MenuItem>
|
|
232
|
+
<MenuItem itemId="group_e">Group E</MenuItem>
|
|
233
|
+
<MenuItem itemId="group_f">Group F</MenuItem>
|
|
234
|
+
<MenuItem itemId="group_g">Group G</MenuItem>
|
|
235
|
+
</DrilldownMenu>
|
|
236
|
+
}
|
|
237
|
+
>
|
|
238
|
+
Application grouping
|
|
239
|
+
</MenuItem>
|
|
240
|
+
<MenuItem itemId="count">Count</MenuItem>
|
|
241
|
+
<MenuItem
|
|
242
|
+
itemId="group:labels_start"
|
|
243
|
+
direction="down"
|
|
244
|
+
onClick={() => setBreadcrumb(labelsBreadcrumb(false))}
|
|
245
|
+
drilldownMenu={
|
|
246
|
+
<DrilldownMenu id="breadcrumbs-drilldownMenuStartLabels">
|
|
247
|
+
<MenuItem itemId="label_1">Label 1</MenuItem>
|
|
248
|
+
<MenuItem itemId="label_2">Label 2</MenuItem>
|
|
249
|
+
<MenuItem itemId="label_3">Label 3</MenuItem>
|
|
250
|
+
</DrilldownMenu>
|
|
251
|
+
}
|
|
252
|
+
>
|
|
253
|
+
Labels
|
|
254
|
+
</MenuItem>
|
|
255
|
+
<MenuItem itemId="annotations">Annotations</MenuItem>
|
|
256
|
+
</DrilldownMenu>
|
|
257
|
+
}
|
|
258
|
+
>
|
|
259
|
+
Start rollout
|
|
260
|
+
</MenuItem>
|
|
261
|
+
<MenuItem
|
|
262
|
+
itemId="group:pause_rollout"
|
|
263
|
+
direction="down"
|
|
264
|
+
onClick={() => setBreadcrumb(pauseRolloutsBreadcrumb)}
|
|
265
|
+
drilldownMenu={
|
|
266
|
+
<DrilldownMenu id="breadcrumbs-drilldownMenuPause">
|
|
267
|
+
<MenuItem
|
|
268
|
+
itemId="group:app_grouping"
|
|
269
|
+
description="Groups A-C"
|
|
270
|
+
direction="down"
|
|
271
|
+
onClick={() => setBreadcrumb(pauseRolloutsAppGrpBreadcrumb)}
|
|
272
|
+
drilldownMenu={
|
|
273
|
+
<DrilldownMenu id="breadcrumbs-drilldownMenuGrouping">
|
|
274
|
+
<MenuItem itemId="group_a">Group A</MenuItem>
|
|
275
|
+
<MenuItem itemId="group_b">Group B</MenuItem>
|
|
276
|
+
<MenuItem itemId="group_c">Group C</MenuItem>
|
|
277
|
+
</DrilldownMenu>
|
|
278
|
+
}
|
|
279
|
+
>
|
|
280
|
+
Application grouping
|
|
281
|
+
</MenuItem>
|
|
282
|
+
<MenuItem itemId="count">Count</MenuItem>
|
|
283
|
+
<MenuItem
|
|
284
|
+
itemId="group:labels"
|
|
285
|
+
direction="down"
|
|
286
|
+
onClick={() => setBreadcrumb(pauseRolloutsLabelsBreadcrumb)}
|
|
287
|
+
drilldownMenu={
|
|
288
|
+
<DrilldownMenu id="breadcrumbs-drilldownMenuLabels">
|
|
289
|
+
<MenuItem itemId="label_1">Label 1</MenuItem>
|
|
290
|
+
<MenuItem itemId="label_2">Label 2</MenuItem>
|
|
291
|
+
<MenuItem itemId="label_3">Label 3</MenuItem>
|
|
292
|
+
</DrilldownMenu>
|
|
293
|
+
}
|
|
294
|
+
>
|
|
295
|
+
Labels
|
|
296
|
+
</MenuItem>
|
|
297
|
+
<MenuItem itemId="annotations">Annotations</MenuItem>
|
|
298
|
+
</DrilldownMenu>
|
|
299
|
+
}
|
|
300
|
+
>
|
|
301
|
+
Pause rollouts
|
|
302
|
+
</MenuItem>
|
|
303
|
+
<MenuItem
|
|
304
|
+
itemId="group:storage"
|
|
305
|
+
icon={<StorageDomainIcon aria-hidden />}
|
|
306
|
+
direction="down"
|
|
307
|
+
onClick={() => setBreadcrumb(addStorageBreadcrumb)}
|
|
308
|
+
drilldownMenu={
|
|
309
|
+
<DrilldownMenu id="breadcrumbs-drilldownMenuStorage">
|
|
310
|
+
<MenuItem icon={<CodeBranchIcon aria-hidden />} itemId="git">
|
|
311
|
+
From git
|
|
312
|
+
</MenuItem>
|
|
313
|
+
<MenuItem icon={<LayerGroupIcon aria-hidden />} itemId="container">
|
|
314
|
+
Container image
|
|
315
|
+
</MenuItem>
|
|
316
|
+
<MenuItem icon={<CubeIcon aria-hidden />} itemId="docker">
|
|
317
|
+
Docker file
|
|
318
|
+
</MenuItem>
|
|
319
|
+
</DrilldownMenu>
|
|
320
|
+
}
|
|
321
|
+
>
|
|
322
|
+
Add storage
|
|
323
|
+
</MenuItem>
|
|
324
|
+
<MenuItem itemId="edit">Edit</MenuItem>
|
|
325
|
+
<MenuItem itemId="delete_deployment">Delete deployment config</MenuItem>
|
|
326
|
+
</MenuList>
|
|
327
|
+
</MenuContent>
|
|
328
|
+
</Menu>
|
|
329
|
+
</>
|
|
330
|
+
);
|
|
331
|
+
};
|
|
File without changes
|
|
@@ -5,7 +5,7 @@ import CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-i
|
|
|
5
5
|
import LayerGroupIcon from '@patternfly/react-icons/dist/esm/icons/layer-group-icon';
|
|
6
6
|
import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';
|
|
7
7
|
|
|
8
|
-
export const
|
|
8
|
+
export const MenuWithDrilldownSubmenuFunctions: React.FunctionComponent = () => {
|
|
9
9
|
const [menuDrilledIn, setMenuDrilledIn] = React.useState<string[]>([]);
|
|
10
10
|
const [drilldownPath, setDrilldownPath] = React.useState<string[]>([]);
|
|
11
11
|
const [menuHeights, setMenuHeights] = React.useState<any>({});
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Menu, MenuContent, MenuItem, MenuItemAction, MenuGroup, MenuList, Divider } from '@patternfly/react-core';
|
|
3
|
+
import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';
|
|
4
|
+
import ClipboardIcon from '@patternfly/react-icons/dist/esm/icons/clipboard-icon';
|
|
5
|
+
import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';
|
|
6
|
+
|
|
7
|
+
export const MenuWithFavorites: React.FunctionComponent = () => {
|
|
8
|
+
const [activeItem, setActiveItem] = React.useState(0);
|
|
9
|
+
const [favorites, setFavorites] = React.useState<string[]>([]);
|
|
10
|
+
|
|
11
|
+
const onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, itemId: number | string | undefined) => {
|
|
12
|
+
const item = itemId as number; // eslint-disable-next-line no-console
|
|
13
|
+
console.log(`clicked ${item}`);
|
|
14
|
+
setActiveItem(item);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const onFavorite = (event, itemId: string, actionId: string) => {
|
|
18
|
+
// eslint-disable-next-line no-console
|
|
19
|
+
console.log(`clicked ${itemId} - ${actionId}`);
|
|
20
|
+
if (actionId === 'fav') {
|
|
21
|
+
const isFavorite = favorites.includes(itemId);
|
|
22
|
+
if (isFavorite) {
|
|
23
|
+
setFavorites(favorites.filter(fav => fav !== itemId));
|
|
24
|
+
} else {
|
|
25
|
+
setFavorites([...favorites, itemId]);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const items = [
|
|
31
|
+
{
|
|
32
|
+
text: 'Item 1',
|
|
33
|
+
description: 'Description 1',
|
|
34
|
+
itemId: 'item-1',
|
|
35
|
+
action: <BarsIcon aria-hidden />,
|
|
36
|
+
actionId: 'bars'
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
text: 'Item 2',
|
|
40
|
+
description: 'Description 2',
|
|
41
|
+
itemId: 'item-2',
|
|
42
|
+
action: <ClipboardIcon aria-hidden />,
|
|
43
|
+
actionId: 'clipboard'
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
text: 'Item 3',
|
|
47
|
+
description: 'Description 3',
|
|
48
|
+
itemId: 'item-3',
|
|
49
|
+
action: <BellIcon aria-hidden />,
|
|
50
|
+
actionId: 'bell'
|
|
51
|
+
}
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<Menu onSelect={onSelect} onActionClick={onFavorite} activeItemId={activeItem}>
|
|
56
|
+
<MenuContent>
|
|
57
|
+
{favorites.length > 0 && (
|
|
58
|
+
<React.Fragment>
|
|
59
|
+
<MenuGroup label="Favorites" labelHeadingLevel="h3">
|
|
60
|
+
<MenuList>
|
|
61
|
+
{items
|
|
62
|
+
.filter(item => favorites.includes(item.itemId))
|
|
63
|
+
.map(item => {
|
|
64
|
+
const { text, description, itemId, action, actionId } = item;
|
|
65
|
+
return (
|
|
66
|
+
<MenuItem
|
|
67
|
+
key={`fav-${itemId}`}
|
|
68
|
+
isFavorited
|
|
69
|
+
description={description}
|
|
70
|
+
itemId={itemId}
|
|
71
|
+
actions={<MenuItemAction actionId={actionId} icon={action} aria-label={actionId} />}
|
|
72
|
+
>
|
|
73
|
+
{text}
|
|
74
|
+
</MenuItem>
|
|
75
|
+
);
|
|
76
|
+
})}
|
|
77
|
+
</MenuList>
|
|
78
|
+
</MenuGroup>
|
|
79
|
+
<Divider />
|
|
80
|
+
</React.Fragment>
|
|
81
|
+
)}
|
|
82
|
+
<MenuGroup label="All actions" labelHeadingLevel="h3">
|
|
83
|
+
<MenuList>
|
|
84
|
+
{items.map(item => {
|
|
85
|
+
const { text, description, itemId, action, actionId } = item;
|
|
86
|
+
const isFavorited = favorites.includes(item.itemId);
|
|
87
|
+
return (
|
|
88
|
+
<MenuItem
|
|
89
|
+
key={itemId}
|
|
90
|
+
isFavorited={isFavorited}
|
|
91
|
+
description={description}
|
|
92
|
+
itemId={itemId}
|
|
93
|
+
actions={<MenuItemAction actionId={actionId} icon={action} aria-label={actionId} />}
|
|
94
|
+
>
|
|
95
|
+
{text}
|
|
96
|
+
</MenuItem>
|
|
97
|
+
);
|
|
98
|
+
})}
|
|
99
|
+
</MenuList>
|
|
100
|
+
</MenuGroup>
|
|
101
|
+
</MenuContent>
|
|
102
|
+
</Menu>
|
|
103
|
+
);
|
|
104
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Menu, MenuList, MenuItem, MenuContent, MenuFooter, Button } from '@patternfly/react-core';
|
|
3
|
+
|
|
4
|
+
export const MenuWithFooter: React.FunctionComponent = () => {
|
|
5
|
+
const [activeItem, setActiveItem] = React.useState(0);
|
|
6
|
+
|
|
7
|
+
const onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, itemId: number | string | undefined) => {
|
|
8
|
+
const item = itemId as number;
|
|
9
|
+
// eslint-disable-next-line no-console
|
|
10
|
+
console.log(`clicked ${item}`);
|
|
11
|
+
setActiveItem(item);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<Menu activeItemId={activeItem} onSelect={onSelect}>
|
|
16
|
+
<MenuContent>
|
|
17
|
+
<MenuList>
|
|
18
|
+
<MenuItem itemId={0}>Action</MenuItem>
|
|
19
|
+
<MenuItem
|
|
20
|
+
itemId={1}
|
|
21
|
+
to="#default-link2"
|
|
22
|
+
// just for demo so that navigation is not triggered
|
|
23
|
+
onClick={event => event.preventDefault()}
|
|
24
|
+
>
|
|
25
|
+
Link
|
|
26
|
+
</MenuItem>
|
|
27
|
+
<MenuItem isDisabled>Disabled action</MenuItem>
|
|
28
|
+
<MenuItem isDisabled to="#default-link4">
|
|
29
|
+
Disabled link
|
|
30
|
+
</MenuItem>
|
|
31
|
+
</MenuList>
|
|
32
|
+
</MenuContent>
|
|
33
|
+
<MenuFooter>
|
|
34
|
+
<Button variant="link" isInline>
|
|
35
|
+
Action
|
|
36
|
+
</Button>
|
|
37
|
+
</MenuFooter>
|
|
38
|
+
</Menu>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Menu, MenuContent, MenuList, MenuItem } from '@patternfly/react-core';
|
|
3
|
+
import CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-icon';
|
|
4
|
+
import LayerGroupIcon from '@patternfly/react-icons/dist/esm/icons/layer-group-icon';
|
|
5
|
+
import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';
|
|
6
|
+
|
|
7
|
+
export const MenuWithIcons: React.FunctionComponent = () => {
|
|
8
|
+
const [activeItem, setActiveItem] = React.useState(0);
|
|
9
|
+
|
|
10
|
+
const onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, itemId: number | string | undefined) => {
|
|
11
|
+
const item = itemId as number; // eslint-disable-next-line no-console
|
|
12
|
+
console.log(`clicked ${item}`);
|
|
13
|
+
setActiveItem(item);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<Menu onSelect={onSelect} activeItemId={activeItem}>
|
|
18
|
+
<MenuContent>
|
|
19
|
+
<MenuList>
|
|
20
|
+
<MenuItem icon={<CodeBranchIcon aria-hidden />} itemId={0}>
|
|
21
|
+
From git
|
|
22
|
+
</MenuItem>
|
|
23
|
+
<MenuItem icon={<LayerGroupIcon aria-hidden />} itemId={1}>
|
|
24
|
+
Container image
|
|
25
|
+
</MenuItem>
|
|
26
|
+
<MenuItem icon={<CubeIcon aria-hidden />} itemId={2}>
|
|
27
|
+
Docker file
|
|
28
|
+
</MenuItem>
|
|
29
|
+
</MenuList>
|
|
30
|
+
</MenuContent>
|
|
31
|
+
</Menu>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Menu, MenuContent, MenuList, MenuItem } from '@patternfly/react-core';
|
|
3
|
+
|
|
4
|
+
export const MenuWithLinks: React.FunctionComponent = () => {
|
|
5
|
+
const [activeItem, setActiveItem] = React.useState(0);
|
|
6
|
+
|
|
7
|
+
const onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, itemId: number | string | undefined) => {
|
|
8
|
+
const item = itemId as number; // eslint-disable-next-line no-console
|
|
9
|
+
console.log(`clicked ${item}`);
|
|
10
|
+
setActiveItem(item);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<Menu onSelect={onSelect} activeItemId={activeItem}>
|
|
15
|
+
<MenuContent>
|
|
16
|
+
<MenuList>
|
|
17
|
+
<MenuItem isExternalLink to="#default-link1" itemId={0}>
|
|
18
|
+
Link 1
|
|
19
|
+
</MenuItem>
|
|
20
|
+
<MenuItem isExternalLink to="#default-link2" itemId={1}>
|
|
21
|
+
Link 2
|
|
22
|
+
</MenuItem>
|
|
23
|
+
<MenuItem to="#default-link3" itemId={2}>
|
|
24
|
+
Link 3
|
|
25
|
+
</MenuItem>
|
|
26
|
+
</MenuList>
|
|
27
|
+
</MenuContent>
|
|
28
|
+
</Menu>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Divider, Menu, MenuContent, MenuList, MenuItem } from '@patternfly/react-core';
|
|
3
|
+
|
|
4
|
+
export const MenuWithSeparators: React.FunctionComponent = () => {
|
|
5
|
+
const [activeItem, setActiveItem] = React.useState(0);
|
|
6
|
+
|
|
7
|
+
const onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, itemId: number | string | undefined) => {
|
|
8
|
+
const item = itemId as number;
|
|
9
|
+
// eslint-disable-next-line no-console
|
|
10
|
+
console.log(`clicked ${item}`);
|
|
11
|
+
setActiveItem(item);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<Menu onSelect={onSelect} activeItemId={activeItem}>
|
|
16
|
+
<MenuContent>
|
|
17
|
+
<MenuList>
|
|
18
|
+
<MenuItem itemId={0}>Action 1</MenuItem>
|
|
19
|
+
<MenuItem itemId={1}>Action 2</MenuItem>
|
|
20
|
+
<Divider component="li" />
|
|
21
|
+
<MenuItem itemId={2}>Action 3</MenuItem>
|
|
22
|
+
</MenuList>
|
|
23
|
+
</MenuContent>
|
|
24
|
+
</Menu>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Menu, MenuContent, MenuGroup, MenuList, MenuItem, Divider } from '@patternfly/react-core';
|
|
3
|
+
|
|
4
|
+
export const MenuWithTitledGroups: React.FunctionComponent = () => {
|
|
5
|
+
const [activeItem, setActiveItem] = React.useState(0);
|
|
6
|
+
|
|
7
|
+
const onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, itemId: number | string | undefined) => {
|
|
8
|
+
const item = itemId as number; // eslint-disable-next-line no-console
|
|
9
|
+
console.log(`clicked ${item}`);
|
|
10
|
+
setActiveItem(item);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<Menu onSelect={onSelect} activeItemId={activeItem}>
|
|
15
|
+
<MenuContent>
|
|
16
|
+
<MenuGroup>
|
|
17
|
+
<MenuList>
|
|
18
|
+
<MenuItem to="#" itemId={0}>
|
|
19
|
+
Link not in group
|
|
20
|
+
</MenuItem>
|
|
21
|
+
</MenuList>
|
|
22
|
+
</MenuGroup>
|
|
23
|
+
<Divider />
|
|
24
|
+
<MenuGroup label="Group 1" labelHeadingLevel="h3">
|
|
25
|
+
<MenuList>
|
|
26
|
+
<MenuItem to="#" itemId={1}>
|
|
27
|
+
Link 1
|
|
28
|
+
</MenuItem>
|
|
29
|
+
<MenuItem itemId={2}>Link 2</MenuItem>
|
|
30
|
+
</MenuList>
|
|
31
|
+
</MenuGroup>
|
|
32
|
+
<Divider />
|
|
33
|
+
<MenuGroup label="Group 2" labelHeadingLevel="h3">
|
|
34
|
+
<MenuList>
|
|
35
|
+
<MenuItem to="#" itemId={3}>
|
|
36
|
+
Link 1
|
|
37
|
+
</MenuItem>
|
|
38
|
+
<MenuItem to="#" itemId={4}>
|
|
39
|
+
Link 2
|
|
40
|
+
</MenuItem>
|
|
41
|
+
</MenuList>
|
|
42
|
+
</MenuGroup>
|
|
43
|
+
</MenuContent>
|
|
44
|
+
</Menu>
|
|
45
|
+
);
|
|
46
|
+
};
|