@patternfly/react-core 5.2.0-prerelease.25 → 5.2.0-prerelease.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/components/package.json +1 -1
  3. package/deprecated/package.json +1 -1
  4. package/dist/dynamic/components/AboutModal/package.json +1 -1
  5. package/dist/dynamic/components/Accordion/package.json +1 -1
  6. package/dist/dynamic/components/ActionList/package.json +1 -1
  7. package/dist/dynamic/components/Alert/package.json +1 -1
  8. package/dist/dynamic/components/Avatar/package.json +1 -1
  9. package/dist/dynamic/components/BackToTop/package.json +1 -1
  10. package/dist/dynamic/components/Backdrop/package.json +1 -1
  11. package/dist/dynamic/components/BackgroundImage/package.json +1 -1
  12. package/dist/dynamic/components/Badge/package.json +1 -1
  13. package/dist/dynamic/components/Banner/package.json +1 -1
  14. package/dist/dynamic/components/Brand/package.json +1 -1
  15. package/dist/dynamic/components/Breadcrumb/package.json +1 -1
  16. package/dist/dynamic/components/Button/package.json +1 -1
  17. package/dist/dynamic/components/CalendarMonth/package.json +1 -1
  18. package/dist/dynamic/components/Card/package.json +1 -1
  19. package/dist/dynamic/components/Checkbox/package.json +1 -1
  20. package/dist/dynamic/components/Chip/package.json +1 -1
  21. package/dist/dynamic/components/ClipboardCopy/package.json +1 -1
  22. package/dist/dynamic/components/CodeBlock/package.json +1 -1
  23. package/dist/dynamic/components/DataList/package.json +1 -1
  24. package/dist/dynamic/components/DatePicker/package.json +1 -1
  25. package/dist/dynamic/components/DescriptionList/package.json +1 -1
  26. package/dist/dynamic/components/Divider/package.json +1 -1
  27. package/dist/dynamic/components/DragDrop/package.json +1 -1
  28. package/dist/dynamic/components/Drawer/package.json +1 -1
  29. package/dist/dynamic/components/Dropdown/package.json +1 -1
  30. package/dist/dynamic/components/DualListSelector/package.json +1 -1
  31. package/dist/dynamic/components/EmptyState/package.json +1 -1
  32. package/dist/dynamic/components/ExpandableSection/package.json +1 -1
  33. package/dist/dynamic/components/FileUpload/package.json +1 -1
  34. package/dist/dynamic/components/Form/package.json +1 -1
  35. package/dist/dynamic/components/FormSelect/package.json +1 -1
  36. package/dist/dynamic/components/HelperText/package.json +1 -1
  37. package/dist/dynamic/components/Hint/package.json +1 -1
  38. package/dist/dynamic/components/Icon/package.json +1 -1
  39. package/dist/dynamic/components/InputGroup/package.json +1 -1
  40. package/dist/dynamic/components/JumpLinks/package.json +1 -1
  41. package/dist/dynamic/components/Label/package.json +1 -1
  42. package/dist/dynamic/components/List/package.json +1 -1
  43. package/dist/dynamic/components/LoginPage/package.json +1 -1
  44. package/dist/dynamic/components/Masthead/package.json +1 -1
  45. package/dist/dynamic/components/Menu/package.json +1 -1
  46. package/dist/dynamic/components/MenuToggle/package.json +1 -1
  47. package/dist/dynamic/components/Modal/package.json +1 -1
  48. package/dist/dynamic/components/MultipleFileUpload/package.json +1 -1
  49. package/dist/dynamic/components/Nav/package.json +1 -1
  50. package/dist/dynamic/components/NotificationBadge/package.json +1 -1
  51. package/dist/dynamic/components/NotificationDrawer/package.json +1 -1
  52. package/dist/dynamic/components/NumberInput/package.json +1 -1
  53. package/dist/dynamic/components/OverflowMenu/package.json +1 -1
  54. package/dist/dynamic/components/Page/package.json +1 -1
  55. package/dist/dynamic/components/Pagination/package.json +1 -1
  56. package/dist/dynamic/components/Panel/package.json +1 -1
  57. package/dist/dynamic/components/Popover/package.json +1 -1
  58. package/dist/dynamic/components/Progress/package.json +1 -1
  59. package/dist/dynamic/components/ProgressStepper/package.json +1 -1
  60. package/dist/dynamic/components/Radio/package.json +1 -1
  61. package/dist/dynamic/components/SearchInput/package.json +1 -1
  62. package/dist/dynamic/components/Select/package.json +1 -1
  63. package/dist/dynamic/components/Sidebar/package.json +1 -1
  64. package/dist/dynamic/components/SimpleList/package.json +1 -1
  65. package/dist/dynamic/components/Skeleton/package.json +1 -1
  66. package/dist/dynamic/components/SkipToContent/package.json +1 -1
  67. package/dist/dynamic/components/Slider/package.json +1 -1
  68. package/dist/dynamic/components/Spinner/package.json +1 -1
  69. package/dist/dynamic/components/Switch/package.json +1 -1
  70. package/dist/dynamic/components/Tabs/package.json +1 -1
  71. package/dist/dynamic/components/Text/package.json +1 -1
  72. package/dist/dynamic/components/TextArea/package.json +1 -1
  73. package/dist/dynamic/components/TextInput/package.json +1 -1
  74. package/dist/dynamic/components/TextInputGroup/package.json +1 -1
  75. package/dist/dynamic/components/Tile/package.json +1 -1
  76. package/dist/dynamic/components/TimePicker/package.json +1 -1
  77. package/dist/dynamic/components/Timestamp/package.json +1 -1
  78. package/dist/dynamic/components/Title/package.json +1 -1
  79. package/dist/dynamic/components/ToggleGroup/package.json +1 -1
  80. package/dist/dynamic/components/Toolbar/package.json +1 -1
  81. package/dist/dynamic/components/Tooltip/package.json +1 -1
  82. package/dist/dynamic/components/TreeView/package.json +1 -1
  83. package/dist/dynamic/components/Truncate/package.json +1 -1
  84. package/dist/dynamic/components/Wizard/hooks/package.json +1 -1
  85. package/dist/dynamic/components/Wizard/package.json +1 -1
  86. package/dist/dynamic/deprecated/components/ApplicationLauncher/package.json +1 -1
  87. package/dist/dynamic/deprecated/components/ContextSelector/package.json +1 -1
  88. package/dist/dynamic/deprecated/components/Dropdown/package.json +1 -1
  89. package/dist/dynamic/deprecated/components/OptionsMenu/package.json +1 -1
  90. package/dist/dynamic/deprecated/components/PageHeader/package.json +1 -1
  91. package/dist/dynamic/deprecated/components/Select/package.json +1 -1
  92. package/dist/dynamic/deprecated/components/Wizard/package.json +1 -1
  93. package/dist/dynamic/deprecated/components/package.json +1 -1
  94. package/dist/dynamic/helpers/FocusTrap/FocusTrap/package.json +1 -1
  95. package/dist/dynamic/helpers/GenerateId/GenerateId/package.json +1 -1
  96. package/dist/dynamic/helpers/KeyboardHandler/package.json +1 -1
  97. package/dist/dynamic/helpers/OUIA/ouia/package.json +1 -1
  98. package/dist/dynamic/helpers/Popper/Popper/package.json +1 -1
  99. package/dist/dynamic/helpers/constants/package.json +1 -1
  100. package/dist/dynamic/helpers/datetimeUtils/package.json +1 -1
  101. package/dist/dynamic/helpers/favorites/package.json +1 -1
  102. package/dist/dynamic/helpers/fileUtils/package.json +1 -1
  103. package/dist/dynamic/helpers/htmlConstants/package.json +1 -1
  104. package/dist/dynamic/helpers/package.json +1 -1
  105. package/dist/dynamic/helpers/resizeObserver/package.json +1 -1
  106. package/dist/dynamic/helpers/typeUtils/package.json +1 -1
  107. package/dist/dynamic/helpers/useInterval/package.json +1 -1
  108. package/dist/dynamic/helpers/useIsomorphicLayout/package.json +1 -1
  109. package/dist/dynamic/helpers/useUnmountEffect/package.json +1 -1
  110. package/dist/dynamic/helpers/util/package.json +1 -1
  111. package/dist/dynamic/layouts/Bullseye/package.json +1 -1
  112. package/dist/dynamic/layouts/Flex/package.json +1 -1
  113. package/dist/dynamic/layouts/Gallery/package.json +1 -1
  114. package/dist/dynamic/layouts/Grid/package.json +1 -1
  115. package/dist/dynamic/layouts/Level/package.json +1 -1
  116. package/dist/dynamic/layouts/Split/package.json +1 -1
  117. package/dist/dynamic/layouts/Stack/package.json +1 -1
  118. package/dist/dynamic/next/components/package.json +1 -1
  119. package/dist/esm/components/DatePicker/DatePicker.js +2 -2
  120. package/dist/esm/components/DatePicker/DatePicker.js.map +1 -1
  121. package/dist/js/components/DatePicker/DatePicker.js +2 -2
  122. package/dist/js/components/DatePicker/DatePicker.js.map +1 -1
  123. package/dist/umd/react-core.min.js +1 -1
  124. package/helpers/package.json +1 -1
  125. package/layouts/package.json +1 -1
  126. package/next/package.json +1 -1
  127. package/package.json +2 -2
  128. package/src/components/DatePicker/DatePicker.tsx +2 -2
  129. package/src/demos/PrimaryDetail.md +3 -975
  130. package/src/demos/examples/PrimaryDetail/PrimaryDetailCardView.tsx +659 -0
  131. package/src/demos/examples/PrimaryDetail/PrimaryDetailDataListInCard.tsx +207 -0
  132. package/src/demos/examples/PrimaryDetail/PrimaryDetailSimpleListInCard.tsx +116 -0
@@ -0,0 +1,659 @@
1
+ import React from 'react';
2
+ import {
3
+ Badge,
4
+ Button,
5
+ Card,
6
+ CardHeader,
7
+ CardBody,
8
+ CardTitle,
9
+ Divider,
10
+ Drawer,
11
+ DrawerActions,
12
+ DrawerPanelBody,
13
+ DrawerCloseButton,
14
+ DrawerContent,
15
+ DrawerContentBody,
16
+ DrawerHead,
17
+ DrawerPanelContent,
18
+ Dropdown,
19
+ DropdownItem,
20
+ DropdownList,
21
+ Flex,
22
+ FlexItem,
23
+ Gallery,
24
+ MenuToggle,
25
+ MenuToggleCheckbox,
26
+ PageSection,
27
+ PageSectionVariants,
28
+ Pagination,
29
+ Progress,
30
+ Select,
31
+ SelectList,
32
+ SelectOption,
33
+ TextContent,
34
+ Text,
35
+ Title,
36
+ Toolbar,
37
+ ToolbarFilter,
38
+ ToolbarItem,
39
+ ToolbarContent,
40
+ MenuToggleElement
41
+ } from '@patternfly/react-core';
42
+ import TrashIcon from '@patternfly/react-icons/dist/esm/icons/trash-icon';
43
+ import pfIcon from './assets/pf-logo-small.svg';
44
+ import activeMQIcon from './assets/activemq-core_200x150.png';
45
+ import avroIcon from './assets/camel-avro_200x150.png';
46
+ import dropBoxIcon from './assets/camel-dropbox_200x150.png';
47
+ import infinispanIcon from './assets/camel-infinispan_200x150.png';
48
+ import saxonIcon from './assets/camel-saxon_200x150.png';
49
+ import sparkIcon from './assets/camel-spark_200x150.png';
50
+ import swaggerIcon from './assets/camel-swagger-java_200x150.png';
51
+ import azureIcon from './assets/FuseConnector_Icons_AzureServices.png';
52
+ import restIcon from './assets/FuseConnector_Icons_REST.png';
53
+ import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
54
+ import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper';
55
+ import { data } from '@patternfly/react-core/src/demos/CardView/examples/CardViewData.jsx';
56
+
57
+ export const PrimaryDetailCardView: React.FunctionComponent = () => {
58
+ const [totalItemCount, setTotalItemCount] = React.useState(10);
59
+ const [cardData, setCardData] = React.useState(data);
60
+ const [isChecked, setIsChecked] = React.useState(false);
61
+ const [isDrawerExpanded, setIsDrawerExpanded] = React.useState(false);
62
+ const [selectedItems, setSelectedItems] = React.useState<number[]>([]);
63
+ const [areAllSelected, setAreAllSelected] = React.useState<boolean>(false);
64
+ const [splitButtonDropdownIsOpen, setSplitButtonDropdownIsOpen] = React.useState(false);
65
+ const [isLowerToolbarDropdownOpen, setIsLowerToolbarDropdownOpen] = React.useState(false);
66
+ const [isLowerToolbarKebabDropdownOpen, setIsLowerToolbarKebabDropdownOpen] = React.useState(false);
67
+ const [page, setPage] = React.useState(1);
68
+ const [perPage, setPerPage] = React.useState(10);
69
+ const [filters, setFilters] = React.useState<Record<string, string[]>>({ products: [] });
70
+ const [state, setState] = React.useState({});
71
+ const [activeCard, setActiveCard] = React.useState(-1);
72
+
73
+ interface ProductType {
74
+ id: number;
75
+ name: string;
76
+ icon: string;
77
+ description: string;
78
+ }
79
+
80
+ const onToolbarDropdownToggle = () => {
81
+ setIsLowerToolbarDropdownOpen(!isLowerToolbarDropdownOpen);
82
+ };
83
+
84
+ const onToolbarKebabDropdownToggle = () => {
85
+ setIsLowerToolbarKebabDropdownOpen(!isLowerToolbarKebabDropdownOpen);
86
+ };
87
+
88
+ const onToolbarKebabDropdownSelect = () => {
89
+ setIsLowerToolbarKebabDropdownOpen(!isLowerToolbarKebabDropdownOpen);
90
+ };
91
+
92
+ const onCardKebabDropdownToggle = (
93
+ event: React.MouseEvent<HTMLButtonElement, MouseEvent> | React.MouseEvent<HTMLDivElement, MouseEvent>,
94
+ key: string
95
+ ) => {
96
+ setState({
97
+ [key]: !state[key as keyof Object]
98
+ });
99
+ };
100
+
101
+ const checkAllSelected = (selected: number, total: number) => {
102
+ if (selected && selected < total) {
103
+ return null;
104
+ }
105
+ return selected === total;
106
+ };
107
+
108
+ const onNameSelect = (event: any, selection = '') => {
109
+ const checked = event.target.checked;
110
+ const prevSelections = filters.products;
111
+
112
+ setFilters({
113
+ ...filters,
114
+ products: checked ? [...prevSelections, selection] : prevSelections.filter((value) => value !== selection)
115
+ });
116
+ };
117
+
118
+ const onDelete = (type = '', _id = '') => {
119
+ if (type) {
120
+ setFilters(filters);
121
+ } else {
122
+ setFilters({ products: [] });
123
+ }
124
+ };
125
+
126
+ const deleteItem = (item: ProductType) => {
127
+ const filter = (getter) => (val) => getter(val) !== item.id;
128
+
129
+ setCardData(cardData.filter(filter(({ id }) => id)));
130
+
131
+ setSelectedItems(selectedItems.filter(filter((id) => id)));
132
+
133
+ setTotalItemCount(totalItemCount - 1);
134
+ setIsDrawerExpanded(false);
135
+ setActiveCard(-1);
136
+ };
137
+
138
+ const onSetPage = (_event: any, pageNumber: number) => {
139
+ setPage(pageNumber);
140
+ };
141
+
142
+ const onPerPageSelect = (_event: any, perPage: number) => {
143
+ setPerPage(perPage);
144
+ setPage(1);
145
+ };
146
+
147
+ const onSplitButtonToggle = () => {
148
+ setSplitButtonDropdownIsOpen(!splitButtonDropdownIsOpen);
149
+ };
150
+
151
+ const onSplitButtonSelect = () => {
152
+ setSplitButtonDropdownIsOpen(false);
153
+ setIsDrawerExpanded(false);
154
+ setActiveCard(-1);
155
+ };
156
+
157
+ const onCloseDrawerClick = () => {
158
+ setActiveCard(-1);
159
+ setIsDrawerExpanded(false);
160
+ };
161
+
162
+ const onChange = (event: React.FormEvent<HTMLInputElement>) => {
163
+ const name = event.currentTarget.name;
164
+ const productId = Number(name.charAt(name.length - 1));
165
+
166
+ if (selectedItems.includes(productId * 1)) {
167
+ setSelectedItems(selectedItems.filter((id) => productId * 1 !== id));
168
+
169
+ const checkAll = checkAllSelected(selectedItems.length - 1, totalItemCount);
170
+ setAreAllSelected(!!checkAll);
171
+ } else {
172
+ setSelectedItems([...selectedItems, productId * 1]);
173
+ const checkAll = checkAllSelected(selectedItems.length + 1, totalItemCount);
174
+ setAreAllSelected(!!checkAll);
175
+ }
176
+ };
177
+
178
+ const onCardClick = (productId) => {
179
+ if (productId === activeCard) {
180
+ setIsDrawerExpanded(!isDrawerExpanded);
181
+ setActiveCard(-1);
182
+ } else {
183
+ setActiveCard(productId);
184
+ setIsDrawerExpanded(true);
185
+ }
186
+ };
187
+
188
+ const selectPage = (e: { target: { checked: any } }) => {
189
+ const { checked } = e.target;
190
+ let collection: number[] = [];
191
+
192
+ collection = getAllItems();
193
+
194
+ setSelectedItems(collection);
195
+ setIsChecked(checked);
196
+ setAreAllSelected(totalItemCount === perPage ? true : false);
197
+
198
+ updateSelected();
199
+ };
200
+
201
+ const selectAll = () => {
202
+ let collection: number[] = [];
203
+ for (let i = 0; i <= 9; i++) {
204
+ collection = [...collection, i];
205
+ }
206
+
207
+ setSelectedItems(collection);
208
+ setIsChecked(true);
209
+ setAreAllSelected(true);
210
+
211
+ updateSelected();
212
+ };
213
+
214
+ const selectNone = () => {
215
+ setSelectedItems([]);
216
+ setIsChecked(false);
217
+ setAreAllSelected(false);
218
+ setIsDrawerExpanded(false);
219
+ setActiveCard(-1);
220
+
221
+ updateSelected();
222
+ };
223
+
224
+ const updateSelected = () => {
225
+ const rows = cardData.map((post) => {
226
+ post.selected = selectedItems.includes(post.id);
227
+ return post;
228
+ });
229
+
230
+ setCardData(rows);
231
+ };
232
+
233
+ const getAllItems = () => {
234
+ const collection: number[] = [];
235
+ for (const items of cardData) {
236
+ collection.push(items.id);
237
+ }
238
+
239
+ return collection;
240
+ };
241
+
242
+ const splitCheckboxSelectAll = (e: any) => {
243
+ let collection: number[] = [];
244
+
245
+ if (e.target.checked) {
246
+ for (let i = 0; i <= 9; i++) {
247
+ collection = [...collection, i];
248
+ }
249
+ }
250
+
251
+ setSelectedItems(collection);
252
+ setIsChecked(isChecked);
253
+ setAreAllSelected(e.target.checked);
254
+ setIsDrawerExpanded(false);
255
+ setActiveCard(-1);
256
+
257
+ updateSelected();
258
+ };
259
+
260
+ const renderPagination = () => {
261
+ const defaultPerPageOptions = [
262
+ {
263
+ title: '1',
264
+ value: 1
265
+ },
266
+ {
267
+ title: '5',
268
+ value: 5
269
+ },
270
+ {
271
+ title: '10',
272
+ value: 10
273
+ }
274
+ ];
275
+
276
+ return (
277
+ <Pagination
278
+ itemCount={totalItemCount}
279
+ page={page}
280
+ perPage={perPage}
281
+ perPageOptions={defaultPerPageOptions}
282
+ onSetPage={onSetPage}
283
+ onPerPageSelect={onPerPageSelect}
284
+ variant="top"
285
+ isCompact
286
+ />
287
+ );
288
+ };
289
+
290
+ const buildSelectDropdown = () => {
291
+ const numSelected = selectedItems.length;
292
+ const anySelected = numSelected > 0;
293
+ const splitButtonDropdownItems = (
294
+ <>
295
+ <DropdownItem key="item-1" onClick={selectNone}>
296
+ Select none (0 items)
297
+ </DropdownItem>
298
+ <DropdownItem key="item-2" onClick={selectPage}>
299
+ Select page ({perPage} items)
300
+ </DropdownItem>
301
+ <DropdownItem key="item-3" onClick={selectAll}>
302
+ Select all ({totalItemCount} items)
303
+ </DropdownItem>
304
+ </>
305
+ );
306
+
307
+ return (
308
+ <Dropdown
309
+ onSelect={onSplitButtonSelect}
310
+ isOpen={splitButtonDropdownIsOpen}
311
+ onOpenChange={(isOpen) => setSplitButtonDropdownIsOpen(isOpen)}
312
+ toggle={(toggleRef) => (
313
+ <MenuToggle
314
+ ref={toggleRef}
315
+ isExpanded={splitButtonDropdownIsOpen}
316
+ onClick={onSplitButtonToggle}
317
+ aria-label="Select cards"
318
+ splitButtonOptions={{
319
+ items: [
320
+ <MenuToggleCheckbox
321
+ id="split-dropdown-checkbox"
322
+ key="split-dropdown-checkbox"
323
+ aria-label={anySelected ? 'Deselect all cards' : 'Select all cards'}
324
+ isChecked={areAllSelected}
325
+ onClick={splitCheckboxSelectAll.bind(this)}
326
+ >
327
+ {numSelected !== 0 && `${numSelected} selected`}
328
+ </MenuToggleCheckbox>
329
+ ]
330
+ }}
331
+ ></MenuToggle>
332
+ )}
333
+ >
334
+ <DropdownList>{splitButtonDropdownItems}</DropdownList>
335
+ </Dropdown>
336
+ );
337
+ };
338
+
339
+ const buildFilterDropdown = () => {
340
+ const filterDropdownItems = (
341
+ <SelectList>
342
+ <SelectOption
343
+ hasCheckbox
344
+ key="patternfly"
345
+ value="PatternFly"
346
+ isSelected={filters.products.includes('PatternFly')}
347
+ >
348
+ PatternFly
349
+ </SelectOption>
350
+ <SelectOption hasCheckbox key="activemq" value="ActiveMQ" isSelected={filters.products.includes('ActiveMQ')}>
351
+ ActiveMQ
352
+ </SelectOption>
353
+ <SelectOption
354
+ hasCheckbox
355
+ key="apachespark"
356
+ value="Apache Spark"
357
+ isSelected={filters.products.includes('Apache Spark')}
358
+ >
359
+ Apache Spark
360
+ </SelectOption>
361
+ <SelectOption hasCheckbox key="avro" value="Avro" isSelected={filters.products.includes('Avro')}>
362
+ Avro
363
+ </SelectOption>
364
+ <SelectOption
365
+ hasCheckbox
366
+ key="azureservices"
367
+ value="Azure Services"
368
+ isSelected={filters.products.includes('Azure Services')}
369
+ >
370
+ Azure Services
371
+ </SelectOption>
372
+ <SelectOption hasCheckbox key="crypto" value="Crypto" isSelected={filters.products.includes('Crypto')}>
373
+ Crypto
374
+ </SelectOption>
375
+ <SelectOption hasCheckbox key="dropbox" value="DropBox" isSelected={filters.products.includes('DropBox')}>
376
+ DropBox
377
+ </SelectOption>
378
+ <SelectOption
379
+ hasCheckbox
380
+ key="jbossdatagrid"
381
+ value="JBoss Data Grid"
382
+ isSelected={filters.products.includes('JBoss Data Grid')}
383
+ >
384
+ JBoss Data Grid
385
+ </SelectOption>
386
+ <SelectOption hasCheckbox key="rest" value="REST" isSelected={filters.products.includes('REST')}>
387
+ REST
388
+ </SelectOption>
389
+ <SelectOption hasCheckbox key="swagger" value="SWAGGER" isSelected={filters.products.includes('SWAGGER')}>
390
+ SWAGGER
391
+ </SelectOption>
392
+ </SelectList>
393
+ );
394
+
395
+ return (
396
+ <ToolbarFilter
397
+ categoryName="Products"
398
+ chips={filters.products}
399
+ deleteChip={(type, id) => onDelete(type as string, id as string)}
400
+ >
401
+ <Select
402
+ aria-label="Products"
403
+ role="menu"
404
+ toggle={(toggleRef) => (
405
+ <MenuToggle ref={toggleRef} onClick={onToolbarDropdownToggle} isExpanded={isLowerToolbarDropdownOpen}>
406
+ Filter by creator name
407
+ {filters.products.length > 0 && <Badge isRead>{filters.products.length}</Badge>}
408
+ </MenuToggle>
409
+ )}
410
+ onSelect={(event, selection) => onNameSelect(event, selection?.toString())}
411
+ onOpenChange={(isOpen) => {
412
+ setIsLowerToolbarDropdownOpen(isOpen);
413
+ }}
414
+ selected={filters.products}
415
+ isOpen={isLowerToolbarDropdownOpen}
416
+ >
417
+ {filterDropdownItems}
418
+ </Select>
419
+ </ToolbarFilter>
420
+ );
421
+ };
422
+
423
+ const toolbarKebabDropdownItems = (
424
+ <>
425
+ <DropdownItem value={0} key="action">
426
+ Action
427
+ </DropdownItem>
428
+ <DropdownItem
429
+ value={1}
430
+ key="link"
431
+ to="#default-link2"
432
+ // Prevent the default onClick functionality for example purposes
433
+ onClick={(ev) => ev.preventDefault()}
434
+ >
435
+ Link
436
+ </DropdownItem>
437
+ <DropdownItem value={2} isDisabled key="disabled action">
438
+ Disabled Action
439
+ </DropdownItem>
440
+ <DropdownItem value={3} isDisabled key="disabled link" to="#default-link4">
441
+ Disabled Link
442
+ </DropdownItem>
443
+ <Divider component="li" key="separator" />
444
+ <DropdownItem value={4} key="separated action">
445
+ Separated Action
446
+ </DropdownItem>
447
+ <DropdownItem value={5} key="separated link" to="#default-link6" onClick={(ev) => ev.preventDefault()}>
448
+ Separated Link
449
+ </DropdownItem>
450
+ </>
451
+ );
452
+ const toolbarItems = (
453
+ <React.Fragment>
454
+ <ToolbarItem>{buildSelectDropdown()}</ToolbarItem>
455
+ <ToolbarItem>{buildFilterDropdown()}</ToolbarItem>
456
+ <ToolbarItem>
457
+ <Button variant="primary">Create instance</Button>
458
+ </ToolbarItem>
459
+ <ToolbarItem>
460
+ <Button variant="secondary">Action</Button>
461
+ </ToolbarItem>
462
+ <ToolbarItem>
463
+ <Dropdown
464
+ onSelect={onToolbarKebabDropdownSelect}
465
+ isOpen={isLowerToolbarKebabDropdownOpen}
466
+ onOpenChange={(isOpen) => setIsLowerToolbarKebabDropdownOpen(isOpen)}
467
+ toggle={(toggleRef) => (
468
+ <MenuToggle
469
+ ref={toggleRef}
470
+ isExpanded={isLowerToolbarKebabDropdownOpen}
471
+ variant="plain"
472
+ onClick={onToolbarKebabDropdownToggle}
473
+ aria-label="Toolbar actions"
474
+ >
475
+ <EllipsisVIcon aria-hidden="true" />
476
+ </MenuToggle>
477
+ )}
478
+ >
479
+ <DropdownList>{toolbarKebabDropdownItems}</DropdownList>
480
+ </Dropdown>
481
+ </ToolbarItem>
482
+ <ToolbarItem variant="pagination" align={{ default: 'alignRight' }}>
483
+ {renderPagination()}
484
+ </ToolbarItem>
485
+ </React.Fragment>
486
+ );
487
+
488
+ const filtered =
489
+ filters.products.length > 0
490
+ ? data.filter((card: { name: string }) => filters.products.length === 0 || filters.products.includes(card.name))
491
+ : cardData.slice((page - 1) * perPage, perPage === 1 ? page * perPage : page * perPage - 1);
492
+
493
+ const icons = {
494
+ pfIcon,
495
+ activeMQIcon,
496
+ sparkIcon,
497
+ avroIcon,
498
+ azureIcon,
499
+ saxonIcon,
500
+ dropBoxIcon,
501
+ infinispanIcon,
502
+ restIcon,
503
+ swaggerIcon
504
+ };
505
+
506
+ const drawerContent = (
507
+ <Gallery hasGutter role="region" aria-label="Selectable card container">
508
+ {filtered.map((product, key) => (
509
+ <Card
510
+ key={product.name}
511
+ id={'card-view-' + key}
512
+ isClickable
513
+ isSelectable
514
+ isSelected={activeCard === product.id}
515
+ >
516
+ <CardHeader
517
+ actions={{
518
+ actions: (
519
+ <>
520
+ <Dropdown
521
+ isOpen={!!state[key] ?? false}
522
+ onOpenChange={(isOpen) => setState({ [key]: isOpen })}
523
+ popperProps={{ position: 'right' }}
524
+ toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
525
+ <MenuToggle
526
+ ref={toggleRef}
527
+ aria-label={`${product.name} actions`}
528
+ variant="plain"
529
+ onClick={(e) => {
530
+ onCardKebabDropdownToggle(e, key.toString());
531
+ }}
532
+ isExpanded={!!state[key]}
533
+ >
534
+ <EllipsisVIcon />
535
+ </MenuToggle>
536
+ )}
537
+ >
538
+ <DropdownList>
539
+ <DropdownItem
540
+ key="trash"
541
+ onClick={() => {
542
+ deleteItem(product);
543
+ }}
544
+ >
545
+ <TrashIcon />
546
+ Delete
547
+ </DropdownItem>
548
+ </DropdownList>
549
+ </Dropdown>
550
+ </>
551
+ )
552
+ }}
553
+ selectableActions={{
554
+ isChecked: selectedItems.includes(product.id),
555
+ selectableActionId: `selectable-actions-item-${product.id}`,
556
+ selectableActionAriaLabelledby: `${'card-view-' + key}`,
557
+ name: `check-${product.id}`,
558
+ onChange
559
+ }}
560
+ >
561
+ <img src={icons[product.icon]} alt={`${product.name} icon`} style={{ height: '50px' }} />
562
+ </CardHeader>
563
+ <CardTitle>
564
+ <Flex direction={{ default: 'column' }} spaceItems={{ default: 'spaceItemsNone' }}>
565
+ <FlexItem>
566
+ <Button
567
+ variant="link"
568
+ isInline
569
+ onClick={() => onCardClick(product.id)}
570
+ aria-expanded={activeCard === product.id}
571
+ >
572
+ {product.name}
573
+ </Button>
574
+ </FlexItem>
575
+ <FlexItem>
576
+ <TextContent>
577
+ <Text component="small" className="pf-v5-u-color-200 pf-v5-u-font-family-text">
578
+ Provided by Red Hat
579
+ </Text>
580
+ </TextContent>
581
+ </FlexItem>
582
+ </Flex>
583
+ </CardTitle>
584
+
585
+ <CardBody>{product.description}</CardBody>
586
+ </Card>
587
+ ))}
588
+ </Gallery>
589
+ );
590
+
591
+ const panelContent = (
592
+ <DrawerPanelContent>
593
+ <DrawerHead>
594
+ <Title headingLevel="h2" size="xl">
595
+ node-{activeCard}
596
+ </Title>
597
+ <DrawerActions>
598
+ <DrawerCloseButton onClick={onCloseDrawerClick} />
599
+ </DrawerActions>
600
+ </DrawerHead>
601
+ <DrawerPanelBody>
602
+ <Flex spaceItems={{ default: 'spaceItemsLg' }} direction={{ default: 'column' }}>
603
+ <FlexItem>
604
+ <p>
605
+ The content of the drawer really is up to you. It could have form fields, definition lists, text lists,
606
+ labels, charts, progress bars, etc. Spacing recommendation is 24px margins. You can put tabs in here, and
607
+ can also make the drawer scrollable.
608
+ </p>
609
+ </FlexItem>
610
+ <FlexItem>
611
+ <Progress value={activeCard * 10} title="Title" />
612
+ </FlexItem>
613
+ <FlexItem>
614
+ <Progress value={activeCard * 5} title="Title" />
615
+ </FlexItem>
616
+ </Flex>
617
+ </DrawerPanelBody>
618
+ </DrawerPanelContent>
619
+ );
620
+
621
+ return (
622
+ <DashboardWrapper mainContainerId="main-content-card-view-default-nav" breadcrumb={null}>
623
+ <PageSection variant={PageSectionVariants.light}>
624
+ <TextContent>
625
+ <Text component="h1">Projects</Text>
626
+ <Text component="p">This is a demo that showcases Patternfly Cards.</Text>
627
+ </TextContent>
628
+ </PageSection>
629
+ <PageSection isFilled padding={{ default: 'noPadding' }}>
630
+ <Toolbar id="card-view-data-toolbar-group-types" usePageInsets clearAllFilters={onDelete}>
631
+ <ToolbarContent>{toolbarItems}</ToolbarContent>
632
+ </Toolbar>
633
+ <Divider component="div" />
634
+ </PageSection>
635
+ <PageSection isFilled padding={{ default: 'noPadding' }}>
636
+ <Drawer isExpanded={isDrawerExpanded} className={'pf-m-inline-on-2xl'}>
637
+ <DrawerContent panelContent={panelContent} colorVariant="no-background">
638
+ <DrawerContentBody hasPadding>{drawerContent}</DrawerContentBody>
639
+ </DrawerContent>
640
+ </Drawer>
641
+ </PageSection>
642
+ <PageSection
643
+ isFilled={false}
644
+ stickyOnBreakpoint={{ default: 'bottom' }}
645
+ padding={{ default: 'noPadding' }}
646
+ variant="light"
647
+ >
648
+ <Pagination
649
+ itemCount={filtered.length}
650
+ page={page}
651
+ perPage={perPage}
652
+ onPerPageSelect={onPerPageSelect}
653
+ onSetPage={onSetPage}
654
+ variant="bottom"
655
+ />
656
+ </PageSection>
657
+ </DashboardWrapper>
658
+ );
659
+ };