@patternfly/react-docs 7.6.0-prerelease.7 → 7.6.0-prerelease.8

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 (162) hide show
  1. package/package.json +12 -13
  2. package/patternfly-docs/generated/components/about-modal/react.js +149 -0
  3. package/patternfly-docs/generated/components/accordion/react.js +262 -0
  4. package/patternfly-docs/generated/components/action-list/react.js +144 -0
  5. package/patternfly-docs/generated/components/alert/react-demos.js +56 -0
  6. package/patternfly-docs/generated/components/alert/react.js +1433 -0
  7. package/patternfly-docs/generated/components/avatar/react.js +166 -0
  8. package/patternfly-docs/generated/components/back-to-top/react-demos.js +60 -0
  9. package/patternfly-docs/generated/components/back-to-top/react.js +77 -0
  10. package/patternfly-docs/generated/components/backdrop/react.js +64 -0
  11. package/patternfly-docs/generated/components/background-image/react.js +62 -0
  12. package/patternfly-docs/generated/components/badge/react.js +97 -0
  13. package/patternfly-docs/generated/components/banner/react-demos.js +57 -0
  14. package/patternfly-docs/generated/components/banner/react.js +148 -0
  15. package/patternfly-docs/generated/components/brand/react.js +142 -0
  16. package/patternfly-docs/generated/components/breadcrumb/react.js +206 -0
  17. package/patternfly-docs/generated/components/button/react-demos.js +57 -0
  18. package/patternfly-docs/generated/components/button/react.js +826 -0
  19. package/patternfly-docs/generated/components/card/react-demos.js +201 -0
  20. package/patternfly-docs/generated/components/card/react.js +1015 -0
  21. package/patternfly-docs/generated/components/charts/area-chart/-Victory.js +1350 -0
  22. package/patternfly-docs/generated/components/charts/bar-chart/-Victory.js +1334 -0
  23. package/patternfly-docs/generated/components/charts/box-plot-chart/-Victory.js +1282 -0
  24. package/patternfly-docs/generated/components/charts/bullet-chart/-Victory.js +848 -0
  25. package/patternfly-docs/generated/components/charts/colors-for-charts/-Victory.js +192 -0
  26. package/patternfly-docs/generated/components/charts/donut-chart/-Victory.js +426 -0
  27. package/patternfly-docs/generated/components/charts/donut-utilization-chart/-Victory.js +804 -0
  28. package/patternfly-docs/generated/components/charts/legends/-Victory.js +3230 -0
  29. package/patternfly-docs/generated/components/charts/line-chart/-Victory.js +1178 -0
  30. package/patternfly-docs/generated/components/charts/line-chart/ECharts.js +525 -0
  31. package/patternfly-docs/generated/components/charts/patterns/-Victory.js +3382 -0
  32. package/patternfly-docs/generated/components/charts/pie-chart/-Victory.js +377 -0
  33. package/patternfly-docs/generated/components/charts/resize-observer/-Victory.js +2475 -0
  34. package/patternfly-docs/generated/components/charts/sankey-chart/ECharts.js +538 -0
  35. package/patternfly-docs/generated/components/charts/scatter-chart/-Victory.js +1551 -0
  36. package/patternfly-docs/generated/components/charts/skeletons/-Victory.js +4115 -0
  37. package/patternfly-docs/generated/components/charts/sparkline-chart/-Victory.js +955 -0
  38. package/patternfly-docs/generated/components/charts/stack-chart/-Victory.js +1173 -0
  39. package/patternfly-docs/generated/components/charts/threshold-chart/-Victory.js +1166 -0
  40. package/patternfly-docs/generated/components/charts/tooltips/-Victory.js +413 -0
  41. package/patternfly-docs/generated/components/chip/react-deprecated.js +323 -0
  42. package/patternfly-docs/generated/components/clipboard-copy/react.js +373 -0
  43. package/patternfly-docs/generated/components/code-block/react.js +148 -0
  44. package/patternfly-docs/generated/components/code-editor/react.js +659 -0
  45. package/patternfly-docs/generated/components/compass/react-demos.js +147 -0
  46. package/patternfly-docs/generated/components/compass/react.js +440 -0
  47. package/patternfly-docs/generated/components/content/react.js +248 -0
  48. package/patternfly-docs/generated/components/data-list/react-demos.js +90 -0
  49. package/patternfly-docs/generated/components/data-list/react.js +709 -0
  50. package/patternfly-docs/generated/components/date-and-time/calendar-month/react.js +283 -0
  51. package/patternfly-docs/generated/components/date-and-time/date-and-time-picker/react-demos.js +64 -0
  52. package/patternfly-docs/generated/components/date-and-time/date-picker/react-demos.js +83 -0
  53. package/patternfly-docs/generated/components/date-and-time/date-picker/react.js +395 -0
  54. package/patternfly-docs/generated/components/date-and-time/time-picker/react.js +241 -0
  55. package/patternfly-docs/generated/components/description-list/react-demos.js +58 -0
  56. package/patternfly-docs/generated/components/description-list/react.js +743 -0
  57. package/patternfly-docs/generated/components/divider/react.js +126 -0
  58. package/patternfly-docs/generated/components/drag-and-drop/react-demos.js +351 -0
  59. package/patternfly-docs/generated/components/drag-and-drop/react-deprecated.js +184 -0
  60. package/patternfly-docs/generated/components/drag-and-drop/react.js +137 -0
  61. package/patternfly-docs/generated/components/drawer/react.js +598 -0
  62. package/patternfly-docs/generated/components/dual-list-selector/react-deprecated.js +772 -0
  63. package/patternfly-docs/generated/components/dual-list-selector/react.js +594 -0
  64. package/patternfly-docs/generated/components/empty-state/react.js +199 -0
  65. package/patternfly-docs/generated/components/expandable-section/react-demos.js +65 -0
  66. package/patternfly-docs/generated/components/expandable-section/react.js +408 -0
  67. package/patternfly-docs/generated/components/file-upload/multiple-file-upload/react-demos.js +52 -0
  68. package/patternfly-docs/generated/components/file-upload/multiple-file-upload/react.js +398 -0
  69. package/patternfly-docs/generated/components/file-upload/simple-file-upload/react.js +749 -0
  70. package/patternfly-docs/generated/components/forms/checkbox/react.js +222 -0
  71. package/patternfly-docs/generated/components/forms/form/react.js +1106 -0
  72. package/patternfly-docs/generated/components/forms/form-select/react.js +208 -0
  73. package/patternfly-docs/generated/components/forms/radio/react.js +212 -0
  74. package/patternfly-docs/generated/components/forms/text-area/react.js +160 -0
  75. package/patternfly-docs/generated/components/forms/text-input/react.js +216 -0
  76. package/patternfly-docs/generated/components/helper-text/react-demos.js +180 -0
  77. package/patternfly-docs/generated/components/helper-text/react.js +164 -0
  78. package/patternfly-docs/generated/components/hero/react.js +88 -0
  79. package/patternfly-docs/generated/components/hint/react.js +169 -0
  80. package/patternfly-docs/generated/components/icon/react.js +215 -0
  81. package/patternfly-docs/generated/components/input-group/react.js +182 -0
  82. package/patternfly-docs/generated/components/jump-links/react-demos.js +154 -0
  83. package/patternfly-docs/generated/components/jump-links/react.js +212 -0
  84. package/patternfly-docs/generated/components/label/react-demos.js +57 -0
  85. package/patternfly-docs/generated/components/label/react.js +417 -0
  86. package/patternfly-docs/generated/components/list/react.js +175 -0
  87. package/patternfly-docs/generated/components/login-page/react.js +587 -0
  88. package/patternfly-docs/generated/components/masthead/react-demos.js +79 -0
  89. package/patternfly-docs/generated/components/masthead/react.js +291 -0
  90. package/patternfly-docs/generated/components/menus/application-launcher/react-demos.js +769 -0
  91. package/patternfly-docs/generated/components/menus/context-selector/react-demos.js +665 -0
  92. package/patternfly-docs/generated/components/menus/custom-menus/react-demos.js +187 -0
  93. package/patternfly-docs/generated/components/menus/dropdown/react-templates.js +163 -0
  94. package/patternfly-docs/generated/components/menus/dropdown/react.js +998 -0
  95. package/patternfly-docs/generated/components/menus/menu/react.js +1540 -0
  96. package/patternfly-docs/generated/components/menus/menu-toggle/react.js +747 -0
  97. package/patternfly-docs/generated/components/menus/options-menu/react-demos.js +508 -0
  98. package/patternfly-docs/generated/components/menus/select/react-templates.js +257 -0
  99. package/patternfly-docs/generated/components/menus/select/react.js +998 -0
  100. package/patternfly-docs/generated/components/modal/react-deprecated.js +554 -0
  101. package/patternfly-docs/generated/components/modal/react.js +597 -0
  102. package/patternfly-docs/generated/components/navigation/react-demos.js +356 -0
  103. package/patternfly-docs/generated/components/navigation/react.js +409 -0
  104. package/patternfly-docs/generated/components/notification-badge/react.js +196 -0
  105. package/patternfly-docs/generated/components/notification-drawer/react-demos.js +107 -0
  106. package/patternfly-docs/generated/components/notification-drawer/react.js +394 -0
  107. package/patternfly-docs/generated/components/number-input/react.js +210 -0
  108. package/patternfly-docs/generated/components/overflow-menu/react.js +274 -0
  109. package/patternfly-docs/generated/components/page/react-demos.js +149 -0
  110. package/patternfly-docs/generated/components/page/react.js +1352 -0
  111. package/patternfly-docs/generated/components/pagination/react.js +492 -0
  112. package/patternfly-docs/generated/components/panel/react.js +236 -0
  113. package/patternfly-docs/generated/components/popover/react.js +390 -0
  114. package/patternfly-docs/generated/components/progress/react-demos.js +59 -0
  115. package/patternfly-docs/generated/components/progress/react.js +283 -0
  116. package/patternfly-docs/generated/components/progress-stepper/react-demos.js +45 -0
  117. package/patternfly-docs/generated/components/progress-stepper/react.js +219 -0
  118. package/patternfly-docs/generated/components/search-input/react-demos.js +113 -0
  119. package/patternfly-docs/generated/components/search-input/react.js +263 -0
  120. package/patternfly-docs/generated/components/sidebar/react.js +236 -0
  121. package/patternfly-docs/generated/components/simple-list/react.js +200 -0
  122. package/patternfly-docs/generated/components/skeleton/react-demos.js +44 -0
  123. package/patternfly-docs/generated/components/skeleton/react.js +122 -0
  124. package/patternfly-docs/generated/components/skip-to-content/react.js +73 -0
  125. package/patternfly-docs/generated/components/slider/react.js +309 -0
  126. package/patternfly-docs/generated/components/spinner/react.js +111 -0
  127. package/patternfly-docs/generated/components/switch/react.js +163 -0
  128. package/patternfly-docs/generated/components/table/react-demos.js +355 -0
  129. package/patternfly-docs/generated/components/table/react-deprecated.js +1350 -0
  130. package/patternfly-docs/generated/components/table/react.js +3241 -0
  131. package/patternfly-docs/generated/components/tabs/react-demos.js +108 -0
  132. package/patternfly-docs/generated/components/tabs/react.js +1359 -0
  133. package/patternfly-docs/generated/components/text-input-group/react-demos.js +152 -0
  134. package/patternfly-docs/generated/components/text-input-group/react.js +278 -0
  135. package/patternfly-docs/generated/components/tile/react-deprecated.js +242 -0
  136. package/patternfly-docs/generated/components/timestamp/react.js +283 -0
  137. package/patternfly-docs/generated/components/title/react.js +94 -0
  138. package/patternfly-docs/generated/components/toggle-group/react.js +299 -0
  139. package/patternfly-docs/generated/components/toolbar/react-demos.js +66 -0
  140. package/patternfly-docs/generated/components/toolbar/react.js +932 -0
  141. package/patternfly-docs/generated/components/tooltip/react.js +241 -0
  142. package/patternfly-docs/generated/components/tree-view/react.js +429 -0
  143. package/patternfly-docs/generated/components/truncate/react.js +211 -0
  144. package/patternfly-docs/generated/components/wizard/react-demos.js +87 -0
  145. package/patternfly-docs/generated/components/wizard/react-deprecated.js +788 -0
  146. package/patternfly-docs/generated/components/wizard/react.js +986 -0
  147. package/patternfly-docs/generated/developer-guides/open-ui-automation/react.js +285 -0
  148. package/patternfly-docs/generated/foundations-and-styles/layouts/bullseye/react.js +70 -0
  149. package/patternfly-docs/generated/foundations-and-styles/layouts/flex/react.js +506 -0
  150. package/patternfly-docs/generated/foundations-and-styles/layouts/gallery/react.js +94 -0
  151. package/patternfly-docs/generated/foundations-and-styles/layouts/grid/react.js +272 -0
  152. package/patternfly-docs/generated/foundations-and-styles/layouts/level/react.js +87 -0
  153. package/patternfly-docs/generated/foundations-and-styles/layouts/split/react.js +124 -0
  154. package/patternfly-docs/generated/foundations-and-styles/layouts/stack/react.js +112 -0
  155. package/patternfly-docs/generated/index.js +1769 -0
  156. package/patternfly-docs/generated/patterns/card-view/react-demos.js +78 -0
  157. package/patternfly-docs/generated/patterns/filters/react-demos.js +141 -0
  158. package/patternfly-docs/generated/patterns/password-generator/react-demos.js +51 -0
  159. package/patternfly-docs/generated/patterns/password-strength/react-demos.js +61 -0
  160. package/patternfly-docs/generated/patterns/primary-detail/react-demos.js +124 -0
  161. package/patternfly-docs/generated/patterns/right-to-left/react-demos.js +81 -0
  162. package/LICENSE +0 -21
@@ -0,0 +1,355 @@
1
+ import React from 'react';
2
+ import { AutoLinkHeader, Example, Link as PatternflyThemeLink } from '@patternfly/documentation-framework/components';
3
+ import { Fragment, ReactNode, useEffect, useState } from 'react';
4
+ import {
5
+ Checkbox,
6
+ Content,
7
+ Label,
8
+ PageSection,
9
+ ToolbarExpandIconWrapper,
10
+ ToolbarContent,
11
+ Toolbar,
12
+ ToolbarItem,
13
+ SearchInput,
14
+ Masthead,
15
+ MastheadToggle,
16
+ MastheadBrand,
17
+ MastheadContent,
18
+ SkipToContent,
19
+ Breadcrumb,
20
+ BreadcrumbItem,
21
+ Page,
22
+ PageSectionVariants,
23
+ Divider,
24
+ Avatar,
25
+ Brand,
26
+ Button,
27
+ ButtonVariant,
28
+ Dropdown,
29
+ DropdownGroup,
30
+ DropdownItem,
31
+ DropdownList,
32
+ MastheadLogo,
33
+ MenuToggle,
34
+ ToolbarGroup,
35
+ PageToggleButton,
36
+ Nav,
37
+ NavItem,
38
+ NavList,
39
+ PageSidebar,
40
+ PageSidebarBody,
41
+ Modal,
42
+ ModalHeader,
43
+ ModalBody,
44
+ ModalFooter,
45
+ } from '@patternfly/react-core';
46
+ import { DragDropSort } from '@patternfly/react-drag-drop';
47
+ import CheckIcon from '@patternfly/react-icons/dist/esm/icons/check-icon';
48
+ import CloneIcon from '@patternfly/react-icons/dist/esm/icons/clone-icon';
49
+ import RhUiCodeIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-code-icon';
50
+ import RhUiBranchFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-branch-fill-icon';
51
+ import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';
52
+ import EditIcon from '@patternfly/react-icons/dist/esm/icons/edit-icon';
53
+ import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
54
+ import RhMicronsSortDownLargeToSmallIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-sort-down-large-to-small-icon';
55
+ import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
56
+ import SyncIcon from '@patternfly/react-icons/dist/esm/icons/sync-icon';
57
+ import RhUiErrorFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-error-fill-icon';
58
+ import RhUiSettingsFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-settings-fill-icon';
59
+ import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon';
60
+ import RhUiQuestionMarkCircleFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-question-mark-circle-fill-icon';
61
+ import RhMicronsCaretDownIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-caret-down-icon';
62
+ import RhMicronsCaretRightIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-caret-right-icon';
63
+ import RhUiBlueprintIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-blueprint-icon';
64
+ import RhUiMenuBarsIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-menu-bars-icon';
65
+ import RhUiEllipsisVerticalFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-ellipsis-vertical-fill-icon';
66
+ import { DashboardWrapper } from '@patternfly/react-table/dist/esm/demos/DashboardWrapper';
67
+ import { rows, columns } from '@patternfly/react-table/dist/esm/demos/sampleData';
68
+ import spacing from '@patternfly/react-styles/css/utilities/Spacing/spacing';
69
+ import RhUiNotificationFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-notification-fill-icon';
70
+ import srcImportautomaticpagination from './react-demos/automatic-pagination.png';
71
+ import srcImportbulkselect from './react-demos/bulk-select.png';
72
+ import srcImportcolumnmanagementwithdraggable from './react-demos/column-management-with-draggable.png';
73
+ import srcImportcolumnmanagement from './react-demos/column-management.png';
74
+ import srcImportcompact from './react-demos/compact.png';
75
+ import srcImportcompoundexpansion from './react-demos/compound-expansion.png';
76
+ import srcImportempty from './react-demos/empty.png';
77
+ import srcImporterror from './react-demos/error.png';
78
+ import srcImportexpandcollapseall from './react-demos/expandcollapse-all.png';
79
+ import srcImportfilterable from './react-demos/filterable.png';
80
+ import srcImportloading from './react-demos/loading.png';
81
+ import srcImportsortableresponsive from './react-demos/sortable---responsive.png';
82
+ import srcImportstaticbottompaginationonmobile from './react-demos/static-bottom-pagination-on-mobile.png';
83
+ import srcImportstickycolumnsandheaderwithtoolbar from './react-demos/sticky-columns-and-header-with-toolbar.png';
84
+ import srcImportstickyfirstcolumn from './react-demos/sticky-first-column.png';
85
+ import srcImportstickyheader from './react-demos/sticky-header.png';
86
+ const pageData = {
87
+ "id": "Table",
88
+ "section": "components",
89
+ "subsection": "",
90
+ "deprecated": false,
91
+ "template": false,
92
+ "beta": false,
93
+ "demo": false,
94
+ "newImplementationLink": false,
95
+ "source": "react-demos",
96
+ "tabName": null,
97
+ "slug": "/components/table/react-demos",
98
+ "sourceLink": "https://github.com/patternfly/patternfly-react/blob/main/packages/react-table/src/demos/Table.md",
99
+ "relPath": "packages/react-table/src/demos/Table.md",
100
+ "fullscreenExamples": [
101
+ "Bulk select",
102
+ "Expand/collapse all",
103
+ "Compact",
104
+ "Compound expansion",
105
+ "Column management",
106
+ "Column management with draggable",
107
+ "Filterable",
108
+ "Sortable - responsive",
109
+ "Automatic pagination",
110
+ "Static bottom pagination on mobile",
111
+ "Sticky header",
112
+ "Sticky first column",
113
+ "Sticky columns and header with toolbar",
114
+ "Empty",
115
+ "Loading",
116
+ "Error"
117
+ ]
118
+ };
119
+ pageData.liveContext = {
120
+ Fragment,
121
+ ReactNode,
122
+ useEffect,
123
+ useState,
124
+ Checkbox,
125
+ Content,
126
+ Label,
127
+ PageSection,
128
+ ToolbarExpandIconWrapper,
129
+ ToolbarContent,
130
+ Toolbar,
131
+ ToolbarItem,
132
+ SearchInput,
133
+ Masthead,
134
+ MastheadToggle,
135
+ MastheadBrand,
136
+ MastheadContent,
137
+ SkipToContent,
138
+ Breadcrumb,
139
+ BreadcrumbItem,
140
+ Page,
141
+ PageSectionVariants,
142
+ Divider,
143
+ Avatar,
144
+ Brand,
145
+ Button,
146
+ ButtonVariant,
147
+ Dropdown,
148
+ DropdownGroup,
149
+ DropdownItem,
150
+ DropdownList,
151
+ MastheadLogo,
152
+ MenuToggle,
153
+ ToolbarGroup,
154
+ PageToggleButton,
155
+ Nav,
156
+ NavItem,
157
+ NavList,
158
+ PageSidebar,
159
+ PageSidebarBody,
160
+ Modal,
161
+ ModalHeader,
162
+ ModalBody,
163
+ ModalFooter,
164
+ DragDropSort,
165
+ CheckIcon,
166
+ CloneIcon,
167
+ RhUiCodeIcon,
168
+ RhUiBranchFillIcon,
169
+ CubeIcon,
170
+ EditIcon,
171
+ FilterIcon,
172
+ RhMicronsSortDownLargeToSmallIcon,
173
+ SearchIcon,
174
+ SyncIcon,
175
+ RhUiErrorFillIcon,
176
+ RhUiSettingsFillIcon,
177
+ HelpIcon,
178
+ RhUiQuestionMarkCircleFillIcon,
179
+ RhMicronsCaretDownIcon,
180
+ RhMicronsCaretRightIcon,
181
+ RhUiBlueprintIcon,
182
+ RhUiMenuBarsIcon,
183
+ RhUiEllipsisVerticalFillIcon,
184
+ DashboardWrapper,
185
+ rows,
186
+ columns,
187
+ spacing,
188
+ RhUiNotificationFillIcon
189
+ };
190
+ pageData.examples = {
191
+ 'Bulk select': props =>
192
+ <Example {...pageData} {...props} thumbnail={srcImportbulkselect} {...{"code":"import { useState } from 'react';\nimport {\n Dropdown,\n DropdownList,\n DropdownItem,\n MenuToggle,\n MenuToggleCheckbox,\n MenuToggleElement,\n PageSection,\n Pagination,\n Toolbar,\n ToolbarContent,\n ToolbarGroup,\n ToolbarItem,\n PaginationVariant\n} from '@patternfly/react-core';\nimport { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';\nimport { rows, columns, SampleDataRow } from '@patternfly/react-table/dist/esm/demos/sampleData';\nimport { DashboardWrapper } from '@patternfly/react-table/dist/esm/demos/DashboardWrapper';\n\nexport const TableBulkSelect: React.FunctionComponent = () => {\n const [isBulkSelectDropdownOpen, setIsBulkSelectDropdownOpen] = useState(false);\n const [bulkSelection, setBulkSelection] = useState('');\n const [page, setPage] = useState(1);\n const [perPage, setPerPage] = useState(10);\n const [paginatedRows, setPaginatedRows] = useState(rows.slice(0, 10));\n const [selectedRows, setSelectedRows] = useState<string[]>([]);\n\n const handleSetPage = (\n _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent,\n newPage: number,\n _perPage: number,\n startIdx: number,\n endIdx: number\n ) => {\n setPaginatedRows(rows?.slice(startIdx, endIdx));\n setPage(newPage);\n };\n\n const handlePerPageSelect = (\n _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent,\n newPerPage: number,\n newPage: number,\n startIdx: number,\n endIdx: number\n ) => {\n setPaginatedRows(rows.slice(startIdx, endIdx));\n setPage(newPage);\n setPerPage(newPerPage);\n };\n\n const setRowSelected = (row: SampleDataRow, isSelecting: boolean) =>\n setSelectedRows((prevSelected) => {\n const otherSelectedRows = prevSelected.filter((r) => r !== row.name);\n return isSelecting ? [...otherSelectedRows, row.name] : otherSelectedRows;\n });\n\n const selectAllRows = (isSelecting: boolean) => setSelectedRows(isSelecting ? rows.map((r) => r.name) : []);\n\n const selectPageRows = (isSelecting: boolean) => setSelectedRows(isSelecting ? paginatedRows.map((r) => r.name) : []);\n\n const isRowSelected = (row: any) => selectedRows.includes(row.name);\n\n const buildPagination = (variant: 'bottom' | 'top' | PaginationVariant, isCompact: boolean) => (\n <Pagination\n isCompact={isCompact}\n itemCount={rows.length}\n page={page}\n perPage={perPage}\n onSetPage={handleSetPage}\n onPerPageSelect={handlePerPageSelect}\n variant={variant}\n titles={{\n paginationAriaLabel: `${variant} pagination`\n }}\n />\n );\n\n const buildBulkSelectDropdown = () => {\n const numSelected = selectedRows.length;\n const allSelected = numSelected === rows.length;\n const anySelected = numSelected > 0;\n const someChecked = anySelected ? null : false;\n const isChecked = allSelected ? true : someChecked;\n\n const items = (\n <>\n <DropdownItem value=\"none\">Select none (0 items)</DropdownItem>\n <DropdownItem value=\"page\">Select page ({perPage} items)</DropdownItem>\n <DropdownItem value=\"all\">Select all ({rows.length} items)</DropdownItem>\n </>\n );\n\n return (\n <Dropdown\n role=\"menu\"\n onSelect={(_event: React.MouseEvent<Element, MouseEvent>, value: string) => {\n if (value === 'all') {\n selectAllRows(bulkSelection !== 'all');\n } else if (value === 'page') {\n selectPageRows(bulkSelection !== 'page');\n } else {\n setSelectedRows([]);\n }\n setBulkSelection(value as string);\n }}\n isOpen={isBulkSelectDropdownOpen}\n onOpenChange={(isOpen: boolean) => setIsBulkSelectDropdownOpen(isOpen)}\n toggle={(toggleRef: React.Ref<MenuToggleElement>) => (\n <MenuToggle\n ref={toggleRef}\n isExpanded={isBulkSelectDropdownOpen}\n onClick={() => setIsBulkSelectDropdownOpen(!isBulkSelectDropdownOpen)}\n aria-label=\"Select cards\"\n splitButtonItems={[\n <MenuToggleCheckbox\n id=\"split-dropdown-checkbox\"\n key=\"split-dropdown-checkbox\"\n aria-label={anySelected ? 'Deselect all cards' : 'Select all cards'}\n isChecked={isChecked}\n onClick={() => {\n anySelected ? setSelectedRows([]) : selectAllRows(bulkSelection !== 'all');\n }}\n >\n {numSelected !== 0 && `${numSelected} selected`}\n </MenuToggleCheckbox>\n ]}\n ></MenuToggle>\n )}\n >\n <DropdownList>{items}</DropdownList>\n </Dropdown>\n );\n };\n\n const toolbar = (\n <Toolbar>\n <ToolbarContent>\n <ToolbarGroup>\n <ToolbarItem variant=\"bulk-select\">{buildBulkSelectDropdown()}</ToolbarItem>\n </ToolbarGroup>\n <ToolbarItem variant=\"pagination\">{buildPagination('top', false)}</ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n );\n\n return (\n <DashboardWrapper hasPageTemplateTitle>\n <PageSection isWidthLimited aria-label=\"Bulk select table data\">\n {toolbar}\n <Table aria-label=\"Selectable table\">\n <Thead>\n <Tr>\n <Th screenReaderText=\"Row select\" />\n <Th key={0}>{columns[0]}</Th>\n <Th key={1}>{columns[1]}</Th>\n <Th key={2}>{columns[2]}</Th>\n <Th key={3}>{columns[3]}</Th>\n </Tr>\n </Thead>\n <Tbody>\n {paginatedRows.map((row, rowIndex) => (\n <Tr key={row.name}>\n <Td\n select={{\n rowIndex,\n onSelect: (_event: React.FormEvent<HTMLInputElement>, isSelecting: boolean) =>\n setRowSelected(row, isSelecting),\n isSelected: isRowSelected(row)\n }}\n />\n <Td dataLabel={columns[0]}>{row.name}</Td>\n <Td dataLabel={columns[1]}>{row.threads}</Td>\n <Td dataLabel={columns[2]}>{row.applications}</Td>\n <Td dataLabel={columns[3]}>{row.workspaces}</Td>\n </Tr>\n ))}\n </Tbody>\n </Table>\n {buildPagination('bottom', true)}\n </PageSection>\n </DashboardWrapper>\n );\n};\n","title":"Bulk select","lang":"ts","isFullscreen":true,"className":""}}>
193
+
194
+ </Example>,
195
+ 'Expand/collapse all': props =>
196
+ <Example {...pageData} {...props} thumbnail={srcImportexpandcollapseall} {...{"code":"import { Fragment, ReactNode, useEffect, useState } from 'react';\nimport { Content, Label, PageSection } from '@patternfly/react-core';\nimport { Table, Thead, Tbody, Tr, Th, Td, ExpandableRowContent } from '@patternfly/react-table';\nimport { DashboardWrapper } from '@patternfly/react-table/dist/esm/demos/DashboardWrapper';\n\nconst expandableColumns = ['Servers', 'Threads', 'Applications', 'Workspaces', 'Status'];\n\ninterface Server {\n name: string;\n threads: number;\n applications: number;\n workspaces: number;\n status: { title: ReactNode };\n details: ReactNode;\n}\n\nconst serverData: Server[] = [\n {\n name: 'US-Node 1',\n threads: 18,\n applications: 42,\n workspaces: 7,\n status: { title: <Label color=\"green\">Running</Label> },\n details: (\n <Content>\n <p>\n Location<small>Boston</small>\n </p>\n <p>\n Last Modified<small>2 hours ago</small>\n </p>\n <p>\n URL<small>http://www.redhat.com/en/office-locations/US-node1</small>\n </p>\n </Content>\n )\n },\n {\n name: 'US-Node 2',\n threads: 9,\n applications: 24,\n workspaces: 17,\n status: { title: <Label color=\"red\">Down</Label> },\n details: (\n <Content>\n <p>\n Location<small>Atlanta</small>\n </p>\n <p>\n Last Modified<small>5 hours ago</small>\n </p>\n <p>\n URL<small>http://www.redhat.com/en/office-locations/US-node2</small>\n </p>\n </Content>\n )\n },\n {\n name: 'US-Node 3',\n threads: 8,\n applications: 47,\n workspaces: 3,\n status: { title: <Label color=\"green\">Running</Label> },\n details: (\n <Content>\n <p>\n Location<small>San Francisco</small>\n </p>\n <p>\n Last Modified<small>20 minutes ago</small>\n </p>\n <p>\n URL<small>http://www.redhat.com/en/office-locations/US-node3</small>\n </p>\n </Content>\n )\n },\n {\n name: 'US-Node 4',\n threads: 6,\n applications: 4,\n workspaces: 15,\n status: { title: <Label color=\"blue\">Needs Maintenance</Label> },\n details: (\n <Content>\n <p>\n Location<small>Raleigh</small>\n </p>\n <p>\n Last Modified<small>10 minutes ago</small>\n </p>\n <p>\n URL<small>http://www.redhat.com/en/office-locations/US-node4</small>\n </p>\n </Content>\n )\n },\n {\n name: 'US-Node 5',\n threads: 9,\n applications: 24,\n workspaces: 17,\n status: { title: <Label color=\"orange\">Stopped</Label> },\n details: (\n <Content>\n <p>\n Location<small>Atlanta</small>\n </p>\n <p>\n Last Modified<small>15 minutes ago</small>\n </p>\n <p>\n URL<small>http://www.redhat.com/en/office-locations/US-node5</small>\n </p>\n </Content>\n )\n }\n];\n\nconst initialExpandedServerNames = ['US-Node 2']; // Default to expanded\n\nexport const TableExpandCollapseAll: React.FunctionComponent = () => {\n const [areAllExpanded, setAreAllExpanded] = useState(false);\n const [collapseAllAriaLabel, setCollapseAllAriaLabel] = useState('Expand all');\n const [expandedServerNames, setExpandedServerNames] = useState(initialExpandedServerNames);\n\n useEffect(() => {\n const allExpanded = expandedServerNames.length === serverData.length;\n setAreAllExpanded(allExpanded);\n setCollapseAllAriaLabel(allExpanded ? 'Collapse all' : 'Expand all');\n }, [expandedServerNames]);\n\n const setServerExpanded = (server: Server, isExpanding: boolean) => {\n const otherExpandedServerNames = expandedServerNames.filter((r) => r !== server.name);\n setExpandedServerNames(isExpanding ? [...otherExpandedServerNames, server.name] : otherExpandedServerNames);\n };\n\n const isServerExpanded = (server: Server) => expandedServerNames.includes(server.name);\n\n // We want to be able to reference the original data object based on row index. But because an expanded\n // row takes up two row indexes, servers[rowIndex] will not be accurate like it would in a normal table.\n // One solution to this is to create an array of data objects indexed by the displayed row index.\n\n const onCollapseAll = (_event: any, _rowIndex: number, isOpen: boolean) => {\n setExpandedServerNames(isOpen ? [...serverData.map((server) => server.name)] : []);\n };\n\n return (\n <Fragment>\n <DashboardWrapper hasPageTemplateTitle>\n <PageSection\n padding={{\n default: 'noPadding',\n xl: 'padding'\n }}\n aria-label=\"Collapsible table data\"\n >\n <Table isExpandable hasAnimations aria-label=\"Collapsible table\">\n <Thead>\n <Tr>\n <Th\n expand={{\n areAllExpanded: !areAllExpanded,\n collapseAllAriaLabel,\n onToggle: onCollapseAll\n }}\n aria-label=\"Row expansion\"\n />\n {expandableColumns.map((column) => (\n <Th key={column}>{column}</Th>\n ))}\n </Tr>\n </Thead>\n\n {serverData.map((server, serverIndex) => (\n <Tbody key={server.name} isExpanded={isServerExpanded(server)}>\n <Tr isContentExpanded={isServerExpanded(server)}>\n <Td\n expand={\n server.details\n ? {\n rowIndex: serverIndex,\n isExpanded: isServerExpanded(server),\n onToggle: () => setServerExpanded(server, !isServerExpanded(server))\n }\n : undefined\n }\n >\n <ExpandableRowContent>{server.details}</ExpandableRowContent>\n </Td>\n <Td>{server?.name}</Td>\n <Td>{server?.threads}</Td>\n <Td>{server?.applications}</Td>\n <Td>{server?.workspaces}</Td>\n <Td>{server?.status?.title}</Td>\n </Tr>\n <Tr isExpanded={isServerExpanded(server)}>\n <Td></Td>\n <Td colSpan={expandableColumns.length}>\n <ExpandableRowContent>{server?.details}</ExpandableRowContent>\n </Td>\n </Tr>\n </Tbody>\n ))}\n </Table>\n </PageSection>\n </DashboardWrapper>\n </Fragment>\n );\n};\n","title":"Expand/collapse all","lang":"ts","isFullscreen":true,"className":""}}>
197
+
198
+ </Example>,
199
+ 'Compact': props =>
200
+ <Example {...pageData} {...props} thumbnail={srcImportcompact} {...{"code":"import { Fragment, useState } from 'react';\nimport {\n Button,\n MenuToggle,\n MenuToggleElement,\n Pagination,\n PageSection,\n Select,\n SelectOption,\n Toolbar,\n ToolbarContent,\n ToolbarGroup,\n ToolbarItem,\n Label,\n PaginationVariant\n} from '@patternfly/react-core';\nimport { Table, TableText, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';\nimport FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';\nimport { rows, columns } from '@patternfly/react-table/dist/esm/demos/sampleData';\nimport { DashboardWrapper } from '@patternfly/react-table/dist/esm/demos/DashboardWrapper';\n\nexport const TableCompact: React.FunctionComponent = () => {\n const [isSelectOpen, setIsSelectOpen] = useState<boolean>(false);\n const [page, setPage] = useState<number>(1);\n const [perPage, setPerPage] = useState<number>(10);\n const [paginatedRows, setPaginatedRows] = useState(rows.slice(0, 10));\n\n const handleSetPage = (\n _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent,\n newPage: number,\n _perPage: number,\n startIdx: number,\n endIdx: number\n ) => {\n setPaginatedRows(rows.slice(startIdx, endIdx));\n setPage(newPage);\n };\n\n const handlePerPageSelect = (\n _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent,\n newPerPage: number,\n newPage: number,\n startIdx: number,\n endIdx: number\n ) => {\n setPaginatedRows(rows.slice(startIdx, endIdx));\n setPage(newPage);\n setPerPage(newPerPage);\n };\n\n const renderPagination = (variant: string, isCompact: boolean) => (\n <Pagination\n isCompact={isCompact}\n itemCount={rows.length}\n page={page}\n perPage={perPage}\n onSetPage={handleSetPage}\n onPerPageSelect={handlePerPageSelect}\n variant={variant as PaginationVariant}\n titles={{\n paginationAriaLabel: `${variant} pagination`\n }}\n />\n );\n\n const tableToolbar = (\n <Toolbar usePageInsets id=\"compact-toolbar\">\n <ToolbarContent>\n <ToolbarItem>\n <Select\n id=\"select-example\"\n aria-label=\"Select Input\"\n toggle={(toggleRef: React.Ref<MenuToggleElement>) => (\n <MenuToggle\n icon={<FilterIcon />}\n ref={toggleRef}\n onClick={() => setIsSelectOpen(!isSelectOpen)}\n isExpanded={isSelectOpen}\n >\n Status\n </MenuToggle>\n )}\n isOpen={isSelectOpen}\n onOpenChange={(isOpen: boolean) => setIsSelectOpen(isOpen)}\n onSelect={() => setIsSelectOpen(!isSelectOpen)}\n >\n {[\n <SelectOption key={0} value=\"Debug\">\n Debug\n </SelectOption>,\n <SelectOption key={1} value=\"Info\">\n Info\n </SelectOption>,\n <SelectOption key={2} value=\"Warn\">\n Warn\n </SelectOption>,\n <SelectOption key={3} value=\"Error\">\n Error\n </SelectOption>\n ]}\n </Select>\n </ToolbarItem>\n <ToolbarGroup>\n <ToolbarItem>\n <Button variant=\"primary\">Action</Button>\n </ToolbarItem>\n </ToolbarGroup>\n <ToolbarItem variant=\"pagination\">{renderPagination('top', true)}</ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n );\n\n const renderLabel = (labelText: string) => {\n switch (labelText) {\n case 'Running':\n return <Label color=\"green\">{labelText}</Label>;\n case 'Stopped':\n return <Label color=\"orange\">{labelText}</Label>;\n case 'Needs Maintenance':\n return <Label color=\"blue\">{labelText}</Label>;\n case 'Down':\n return <Label color=\"red\">{labelText}</Label>;\n default:\n return <></>;\n }\n };\n\n return (\n <Fragment>\n <DashboardWrapper hasPageTemplateTitle>\n <PageSection isFilled aria-label=\"Compact table data\">\n {tableToolbar}\n <Table variant=\"compact\" aria-label=\"Compact Table\">\n <Thead>\n <Tr>\n <Th key={0}>{columns[0]}</Th>\n <Th key={1}>{columns[1]}</Th>\n <Th key={2}>{columns[2]}</Th>\n <Th key={3}>{columns[3]}</Th>\n <Th key={4}>{columns[4]}</Th>\n <Th key={5}>{columns[5]}</Th>\n <Th key={6}>{columns[6]}</Th>\n <Th key={7} width={10}>\n {columns[7]}\n </Th>\n </Tr>\n </Thead>\n <Tbody>\n {paginatedRows.map((row, rowIndex) => (\n <Tr key={rowIndex}>\n <>\n <Td dataLabel={columns[0]}>{row.name}</Td>\n <Td dataLabel={columns[1]}>{row.threads}</Td>\n <Td dataLabel={columns[2]}>{row.applications}</Td>\n <Td dataLabel={columns[3]}>{row.workspaces}</Td>\n <Td dataLabel={columns[4]}>{renderLabel(row.status)}</Td>\n <Td dataLabel={columns[5]}>{row.location}</Td>\n <Td dataLabel={columns[6]}>{row.lastModified}</Td>\n <Td dataLabel={columns[7]} modifier=\"truncate\">\n <TableText>\n <a href=\"#\">{row.url}</a>\n </TableText>\n </Td>\n </>\n </Tr>\n ))}\n </Tbody>\n </Table>\n </PageSection>\n </DashboardWrapper>\n </Fragment>\n );\n};\n","title":"Compact","lang":"ts","isFullscreen":true,"className":""}}>
201
+
202
+ </Example>,
203
+ 'Compound expansion': props =>
204
+ <Example {...pageData} {...props} thumbnail={srcImportcompoundexpansion} {...{"code":"import { useState } from 'react';\nimport { ActionsColumn, Table, Thead, Tr, Th, Tbody, Td, ExpandableRowContent } from '@patternfly/react-table';\nimport {\n Button,\n Flex,\n FlexItem,\n MenuToggle,\n MenuToggleElement,\n Toolbar,\n ToolbarContent,\n ToolbarGroup,\n ToolbarItem,\n Pagination,\n PageSection,\n Select,\n SelectOption,\n PaginationVariant\n} from '@patternfly/react-core';\nimport RhUiCodeIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-code-icon';\nimport RhUiBranchFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-branch-fill-icon';\nimport CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';\nimport { DashboardWrapper } from '@patternfly/react-table/dist/esm/demos/DashboardWrapper';\nimport FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';\n\nexport const TableCompoundExpansion: React.FunctionComponent = () => {\n // In real usage, this data would come from some external source like an API via props.\n const [isSelectOpen, setIsSelectOpen] = useState(false);\n\n const NestedItemsTable = () => {\n // In real usage, this data would come from some external source like an API via props.\n const items = [\n { description: 'Item 1', date: 'May 9, 2018', status: 'Active' },\n { description: 'Item 2', date: 'May 9, 2018', status: 'Warning' },\n { description: 'Item 3', date: 'May 9, 2018', status: 'Active' },\n { description: 'Item 4', date: 'May 9, 2018', status: 'Active' },\n { description: 'Item 5', date: 'May 9, 2018', status: 'Active' }\n ];\n\n const columnNames = {\n description: 'Description',\n date: 'Date',\n status: 'Status'\n };\n\n return (\n <Table borders={false} aria-label=\"Nested table\" variant=\"compact\">\n <Thead>\n <Tr>\n <Th>{columnNames.description}</Th>\n <Th>{columnNames.date}</Th>\n <Th>{columnNames.status}</Th>\n <Th screenReaderText=\"Actions\" />\n </Tr>\n </Thead>\n <Tbody>\n {items.map((item) => (\n <Tr key={item.description}>\n <Td dataLabel={columnNames.description}>{item.description}</Td>\n <Td dataLabel={columnNames.date}>{item.date}</Td>\n <Td dataLabel={columnNames.status}>{item.status}</Td>\n <Td isActionCell>\n <ActionsColumn items={defaultActions()} />\n </Td>\n </Tr>\n ))}\n </Tbody>\n </Table>\n );\n };\n\n const renderPagination = (variant: 'top' | 'bottom' | PaginationVariant, isCompact: boolean) => (\n <Pagination\n isCompact={isCompact}\n itemCount={36}\n page={1}\n perPage={10}\n variant={variant}\n titles={{\n paginationAriaLabel: `${variant} pagination`\n }}\n />\n );\n\n const tableToolbar = (\n <Toolbar id=\"compact-toolbar\">\n <ToolbarContent>\n <ToolbarItem>\n <Select\n id=\"select-example\"\n aria-label=\"Select Input\"\n toggle={(toggleRef: React.Ref<MenuToggleElement>) => (\n <MenuToggle\n ref={toggleRef}\n onClick={() => setIsSelectOpen(!isSelectOpen)}\n isExpanded={isSelectOpen}\n icon={<FilterIcon />}\n >\n Status\n </MenuToggle>\n )}\n isOpen={isSelectOpen}\n onOpenChange={(isOpen: boolean) => setIsSelectOpen(isOpen)}\n onSelect={() => setIsSelectOpen(!isSelectOpen)}\n >\n {[\n <SelectOption key={0} value=\"Debug\">\n Debug\n </SelectOption>,\n <SelectOption key={1} value=\"Info\">\n Info\n </SelectOption>,\n <SelectOption key={2} value=\"Warn\">\n Warn\n </SelectOption>,\n <SelectOption key={3} value=\"Error\">\n Error\n </SelectOption>\n ]}\n </Select>\n </ToolbarItem>\n <ToolbarGroup>\n <ToolbarItem>\n <Button variant=\"primary\">Action</Button>\n </ToolbarItem>\n </ToolbarGroup>\n <ToolbarItem variant=\"pagination\">{renderPagination('top', true)}</ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n );\n\n const defaultActions = () => [\n {\n title: 'Settings',\n // eslint-disable-next-line no-console\n onClick: () => console.log(`clicked on Settings`)\n },\n {\n title: 'Help',\n // eslint-disable-next-line no-console\n onClick: () => console.log(`clicked on Help`)\n }\n ];\n\n interface Repo {\n name: string;\n branches: number;\n prs: number;\n workspaces: number;\n lastCommit: string;\n }\n\n interface IDictionary<T> {\n [Key: string]: T;\n }\n\n const repositories: Repo[] = [\n {\n name: 'siemur/test-space',\n branches: 10,\n prs: 4,\n workspaces: 4,\n lastCommit: '20 minutes'\n },\n { name: 'siemur/test-space-2', branches: 3, prs: 4, workspaces: 4, lastCommit: '20 minutes' }\n ];\n\n const columnNames: IDictionary<string> = {\n name: 'Repositories',\n branches: 'Branches',\n prs: 'Pull requests',\n workspaces: 'Workspaces',\n lastCommit: 'Last commit'\n };\n\n // In this example, expanded cells are tracked by the repo and property names from each row. This could be any pair of unique identifiers.\n // This is to prevent state from being based on row and column order index in case we later add sorting and rearranging columns.\n // Note that this behavior is very similar to selection state.\n const [expandedCells, setExpandedCells] = useState<IDictionary<string>>({\n 'siemur/test-space': 'branches' // Default to the first cell of the first row being expanded\n });\n const setCellExpanded = (repo: Repo, columnKey: string, isExpanding = true) => {\n const newExpandedCells: IDictionary<string> = { ...expandedCells };\n if (isExpanding) {\n newExpandedCells[repo.name] = columnKey;\n } else {\n delete newExpandedCells[repo.name];\n }\n setExpandedCells(newExpandedCells);\n };\n const compoundExpandParams = (repo: Repo, columnKey: string, rowIndex: number, columnIndex: number) => ({\n isExpanded: expandedCells[repo.name] === columnKey,\n onToggle: () => setCellExpanded(repo, columnKey, expandedCells[repo.name] !== columnKey),\n expandId: 'compound-expandable-demo',\n rowIndex,\n columnIndex\n });\n\n return (\n <DashboardWrapper hasPageTemplateTitle>\n <PageSection padding={{ default: 'noPadding', xl: 'padding' }} aria-label=\"Compound expandable table data \">\n {tableToolbar}\n <Table isExpandable hasAnimations aria-label=\"Compound expandable table\">\n <Thead>\n <Tr>\n <Th>{columnNames.name}</Th>\n <Th>{columnNames.branches}</Th>\n <Th>{columnNames.prs}</Th>\n <Th>{columnNames.workspaces}</Th>\n <Th>{columnNames.lastCommit}</Th>\n <Th screenReaderText=\"URL\" />\n <Th screenReaderText=\"Actions\" />\n </Tr>\n </Thead>\n {repositories.map((repo, rowIndex) => {\n const expandedCellKey = expandedCells[repo.name];\n const isRowExpanded = !!expandedCellKey;\n return (\n <Tbody key={repo.name} isExpanded={isRowExpanded}>\n <Tr isContentExpanded={isRowExpanded} isControlRow>\n <Td dataLabel={columnNames.name} component=\"th\">\n <a href=\"#\">{repo.name}</a>\n </Td>\n <Td\n dataLabel={columnNames.branches}\n compoundExpand={compoundExpandParams(repo, 'branches', rowIndex, 1)}\n >\n <Flex spaceItems={{ default: 'spaceItemsSm' }}>\n <FlexItem>\n <RhUiBranchFillIcon key=\"icon\" />\n </FlexItem>\n <FlexItem>{repo.branches}</FlexItem>\n </Flex>\n </Td>\n <Td dataLabel={columnNames.prs} compoundExpand={compoundExpandParams(repo, 'prs', rowIndex, 2)}>\n <Flex spaceItems={{ default: 'spaceItemsSm' }}>\n <FlexItem>\n <RhUiCodeIcon key=\"icon\" />\n </FlexItem>\n <FlexItem>{repo.prs}</FlexItem>\n </Flex>{' '}\n </Td>\n <Td\n dataLabel={columnNames.workspaces}\n compoundExpand={compoundExpandParams(repo, 'workspaces', rowIndex, 3)}\n >\n <Flex spaceItems={{ default: 'spaceItemsSm' }}>\n <FlexItem>\n <CubeIcon key=\"icon\" />\n </FlexItem>\n <FlexItem>{repo.workspaces}</FlexItem>\n </Flex>\n </Td>\n <Td dataLabel={columnNames.lastCommit}>{repo.lastCommit}</Td>\n <Td>\n <a href=\"#\">Open in GitHub</a>\n </Td>\n <Td isActionCell>\n <ActionsColumn items={defaultActions()} />\n </Td>\n </Tr>\n\n <Tr isExpanded={isRowExpanded && columnNames[expandedCellKey] === columnNames.branches}>\n <Td dataLabel={columnNames[expandedCellKey]} noPadding colSpan={7}>\n <ExpandableRowContent hasNoBackground>\n <NestedItemsTable />\n </ExpandableRowContent>\n </Td>\n </Tr>\n <Tr isExpanded={isRowExpanded && columnNames[expandedCellKey] === columnNames.prs}>\n <Td dataLabel={columnNames[expandedCellKey]} colSpan={7}>\n <ExpandableRowContent>\n <div>Expanded content for {repo.name}: prs goes here!</div>\n </ExpandableRowContent>\n </Td>\n </Tr>\n <Tr isExpanded={isRowExpanded && columnNames[expandedCellKey] === columnNames.workspaces}>\n <Td dataLabel={columnNames[expandedCellKey]} colSpan={7}>\n <ExpandableRowContent>\n <div>Expanded content for {repo.name}: workspaces goes here!</div>\n </ExpandableRowContent>\n </Td>\n </Tr>\n </Tbody>\n );\n })}\n </Table>\n {renderPagination('bottom', false)}\n </PageSection>\n </DashboardWrapper>\n );\n};\n","title":"Compound expansion","lang":"ts","isFullscreen":true,"className":""}}>
205
+
206
+ </Example>,
207
+ 'Column management': props =>
208
+ <Example {...pageData} {...props} thumbnail={srcImportcolumnmanagement} {...{"code":"import { Fragment, useEffect, useState } from 'react';\n\nimport {\n Button,\n Content,\n DataList,\n DataListCheck,\n DataListItem,\n DataListItemRow,\n DataListCell,\n DataListItemCells,\n Label,\n Toolbar,\n ToolbarContent,\n ToolbarItem,\n MenuToggle,\n Modal,\n ModalHeader,\n ModalBody,\n ModalFooter,\n OverflowMenu,\n OverflowMenuGroup,\n OverflowMenuItem,\n PageSection,\n Pagination,\n PaginationVariant\n} from '@patternfly/react-core';\nimport { Table, TableText, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';\nimport FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';\nimport RhMicronsSortDownLargeToSmallIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-sort-down-large-to-small-icon';\nimport { DashboardWrapper } from '@patternfly/react-table/dist/esm/demos/DashboardWrapper';\nimport { capitalize } from '@patternfly/react-table/src/components/Table/utils/utils';\nimport { rows, columns, SampleDataRow } from '@patternfly/react-table/dist/esm/demos/sampleData';\n\nexport const TableColumnManagement: React.FunctionComponent = () => {\n const defaultColumns = columns;\n const defaultRows = rows;\n\n const [filters, setFilters] = useState<string[]>([]);\n const [filteredColumns, setFilteredColumns] = useState<string[]>([]);\n const [filteredRows, setFilteredRows] = useState<SampleDataRow[]>([]);\n const [managedColumns, setManagedColumns] = useState<string[]>(defaultColumns);\n const [managedRows, setManagedRows] = useState<SampleDataRow[]>(defaultRows);\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [checkedState, setCheckedState] = useState<boolean[]>(Array(columns.length).fill(true));\n const [page, setPage] = useState(1);\n const [perPage, setPerPage] = useState(10);\n const [paginatedRows, setPaginatedRows] = useState<any[]>(rows);\n\n const matchCheckboxNameToColumn = (name: string): string => {\n switch (name) {\n case 'check1':\n return 'Servers';\n case 'check2':\n return 'Threads';\n case 'check3':\n return 'Applications';\n case 'check4':\n return 'Workspaces';\n case 'check5':\n return 'Status';\n case 'check6':\n return 'Location';\n case 'check7':\n return 'Last Modified';\n case 'check8':\n return 'URL';\n default:\n return '';\n }\n };\n\n const matchSelectedColumnNameToAttr = (name: string): string => {\n switch (name) {\n case 'Servers':\n return 'name';\n case 'Threads':\n return 'threads';\n case 'Applications':\n return 'applications';\n case 'Workspaces':\n return 'workspaces';\n case 'Status':\n return 'status';\n case 'Location':\n return 'location';\n case 'Last Modified':\n return 'lastModified';\n case 'URL':\n return 'url';\n default:\n return '';\n }\n };\n\n // Pagination logic\n const handleSetPage = (\n _evt: MouseEvent | React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<Element>,\n newPage: number\n ) => {\n setPage(newPage);\n };\n\n const handlePerPageSelect = (\n _evt: MouseEvent | React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<Element>,\n newPerPage: number\n ) => {\n setPerPage(newPerPage);\n };\n\n const renderPagination = (variant: 'top' | 'bottom' | PaginationVariant, isCompact: boolean) => (\n <Pagination\n isCompact={isCompact}\n itemCount={rows.length}\n page={page}\n perPage={perPage}\n onSetPage={handleSetPage}\n onPerPageSelect={handlePerPageSelect}\n variant={variant}\n titles={{\n paginationAriaLabel: `${variant} pagination`\n }}\n />\n );\n\n useEffect(() => {\n setPaginatedRows(managedRows.slice((page - 1) * perPage, page * perPage - 1));\n }, [managedRows, page, perPage]);\n\n // Removes attribute from each node object in Data.jsx\n const removePropFromObject = (object: any, keys: string[]): any =>\n keys.reduce((obj, prop) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { [prop]: _, ...keep } = obj;\n return keep;\n }, object);\n\n // Filters columns out of table that are not selected in the column management modal\n const filterData = (checked: boolean, name: string) => {\n const selectedColumn = matchSelectedColumnNameToAttr(name);\n\n const filteredRows: SampleDataRow[] = [];\n if (checked) {\n const updatedFilters = filters.filter((item) => item !== selectedColumn);\n\n // Only show the names of columns that were selected in the modal\n const filteredColumns = defaultColumns.filter(\n (column) => !updatedFilters.includes(matchSelectedColumnNameToAttr(column))\n );\n\n // Remove the attributes (i.e. \"columns\") that were not selected\n defaultRows.forEach((item) => filteredRows.push(removePropFromObject(item, updatedFilters)));\n\n setFilters(updatedFilters);\n setFilteredColumns(filteredColumns);\n setFilteredRows(filteredRows);\n } else {\n const updatedFilters = filters;\n updatedFilters.push(selectedColumn);\n\n // Only show the names of columns that were selected in the modal\n const filteredColumns = managedColumns.filter(\n (column) => !filters.includes(matchSelectedColumnNameToAttr(column))\n );\n\n // Remove the attributes (i.e. \"columns\") that were not selected\n managedRows.forEach((item) => filteredRows.push(removePropFromObject(item, updatedFilters)));\n\n setFilters(updatedFilters);\n setFilteredColumns(filteredColumns);\n setFilteredRows(filteredRows);\n }\n };\n\n const unfilterAllData = () => {\n setFilters([]);\n setFilteredColumns(defaultColumns);\n setFilteredRows(defaultRows);\n };\n\n const handleChange = (event: React.FormEvent<HTMLInputElement>, checked: boolean) => {\n const target = event.currentTarget;\n const value = target.type === 'checkbox' ? target.checked : target.value;\n\n // Remove any columns from the table that aren't checked\n filterData(checked, matchCheckboxNameToColumn(target.name));\n const checkedIndex: number = columns.findIndex((element) => element === matchCheckboxNameToColumn(target.name));\n\n const updatedCheckedState: boolean[] = [...checkedState];\n updatedCheckedState[checkedIndex] = value as boolean;\n setCheckedState(updatedCheckedState);\n };\n\n const handleModalToggle = (_event: React.MouseEvent<Element, MouseEvent> | KeyboardEvent) => {\n setIsModalOpen(!isModalOpen);\n };\n\n const onSave = () => {\n setManagedColumns(filteredColumns);\n setManagedRows(filteredRows);\n setPaginatedRows(filteredRows);\n setIsModalOpen(!isModalOpen);\n };\n\n const selectAllColumns = () => {\n unfilterAllData();\n setCheckedState(Array(columns.length).fill(true));\n };\n\n const renderModal = () => (\n <Modal\n isOpen={isModalOpen}\n variant=\"small\"\n onClose={handleModalToggle}\n aria-labelledby=\"basic-modal-title\"\n aria-describedby=\"modal-box-body-basic\"\n >\n <ModalHeader\n title=\"Manage columns\"\n labelId=\"basic-modal-title\"\n description={\n <Content>\n <p>Selected categories will be displayed in the table.</p>\n <Button isInline onClick={selectAllColumns} variant=\"secondary\">\n Select all\n </Button>\n </Content>\n }\n />\n <ModalBody id=\"modal-box-body-basic\">\n <DataList aria-label=\"Table column management\" id=\"table-column-management\" isCompact>\n <DataListItem aria-labelledby=\"table-column-management-item1\">\n <DataListItemRow>\n <DataListCheck\n aria-labelledby=\"table-column-management-item1\"\n isChecked={checkedState[0]}\n name=\"check1\"\n id=\"check1\"\n onChange={handleChange}\n />\n <DataListItemCells\n dataListCells={[\n <DataListCell id=\"table-column-management-item1\" key=\"table-column-management-item1\">\n <label htmlFor=\"check1\">{columns[0]}</label>\n </DataListCell>\n ]}\n />\n </DataListItemRow>\n </DataListItem>\n <DataListItem aria-labelledby=\"table-column-management-item2\">\n <DataListItemRow>\n <DataListCheck\n aria-labelledby=\"table-column-management-item2\"\n isChecked={checkedState[1]}\n name=\"check2\"\n id=\"check2\"\n onChange={handleChange}\n />\n <DataListItemCells\n dataListCells={[\n <DataListCell id=\"table-column-management-item2\" key=\"table-column-management-item2\">\n <label htmlFor=\"check2\">{columns[1]}</label>\n </DataListCell>\n ]}\n />\n </DataListItemRow>\n </DataListItem>\n <DataListItem aria-labelledby=\"table-column-management-item3\">\n <DataListItemRow>\n <DataListCheck\n aria-labelledby=\"table-column-management-item3\"\n isChecked={checkedState[2]}\n name=\"check3\"\n id=\"check3\"\n onChange={handleChange}\n />\n <DataListItemCells\n dataListCells={[\n <DataListCell id=\"table-column-management-item3\" key=\"table-column-management-item3\">\n <label htmlFor=\"check3\">{columns[2]}</label>\n </DataListCell>\n ]}\n />\n </DataListItemRow>\n </DataListItem>\n <DataListItem aria-labelledby=\"table-column-management-item4\">\n <DataListItemRow>\n <DataListCheck\n aria-labelledby=\"table-column-management-item4\"\n isChecked={checkedState[3]}\n name=\"check4\"\n id=\"check4\"\n onChange={handleChange}\n />\n <DataListItemCells\n dataListCells={[\n <DataListCell id=\"table-column-management-item4\" key=\"table-column-management-item4\">\n <label htmlFor=\"check4\">{columns[3]}</label>\n </DataListCell>\n ]}\n />\n </DataListItemRow>\n </DataListItem>\n <DataListItem aria-labelledby=\"table-column-management-item4\">\n <DataListItemRow>\n <DataListCheck\n aria-labelledby=\"table-column-management-item4\"\n isChecked={checkedState[4]}\n name=\"check5\"\n id=\"check5\"\n onChange={handleChange}\n />\n <DataListItemCells\n dataListCells={[\n <DataListCell id=\"table-column-management-item4\" key=\"table-column-management-item4\">\n <label htmlFor=\"check5\">{columns[4]}</label>\n </DataListCell>\n ]}\n />\n </DataListItemRow>\n </DataListItem>\n <DataListItem aria-labelledby=\"table-column-management-item5\">\n <DataListItemRow>\n <DataListCheck\n aria-labelledby=\"table-column-management-item5\"\n isChecked={checkedState[5]}\n name=\"check6\"\n id=\"check6\"\n onChange={handleChange}\n />\n <DataListItemCells\n dataListCells={[\n <DataListCell id=\"table-column-management-item5\" key=\"table-column-management-item5\">\n <label htmlFor=\"check6\">{columns[5]}</label>\n </DataListCell>\n ]}\n />\n </DataListItemRow>\n </DataListItem>\n <DataListItem aria-labelledby=\"table-column-management-item6\">\n <DataListItemRow>\n <DataListCheck\n aria-labelledby=\"table-column-management-item6\"\n isChecked={checkedState[6]}\n name=\"check7\"\n id=\"check7\"\n onChange={handleChange}\n />\n <DataListItemCells\n dataListCells={[\n <DataListCell id=\"table-column-management-item6\" key=\"table-column-management-item5\">\n <label htmlFor=\"check7\">{columns[6]}</label>\n </DataListCell>\n ]}\n />\n </DataListItemRow>\n </DataListItem>\n <DataListItem aria-labelledby=\"table-column-management-item5\">\n <DataListItemRow>\n <DataListCheck\n aria-labelledby=\"table-column-management-item5\"\n isChecked={checkedState[7]}\n name=\"check8\"\n id=\"check8\"\n onChange={handleChange}\n />\n <DataListItemCells\n dataListCells={[\n <DataListCell id=\"table-column-management-item7\" key=\"table-column-management-item7\">\n <label htmlFor=\"check8\">{columns[7]}</label>\n </DataListCell>\n ]}\n />\n </DataListItemRow>\n </DataListItem>\n </DataList>\n </ModalBody>\n <ModalFooter>\n <Button key=\"save\" variant=\"primary\" onClick={onSave}>\n Save\n </Button>\n <Button key=\"cancel\" variant=\"link\" onClick={handleModalToggle}>\n Cancel\n </Button>\n </ModalFooter>\n </Modal>\n );\n\n const renderLabel = (labelText: string): React.JSX.Element => {\n switch (labelText) {\n case 'Running':\n return <Label color=\"green\">{labelText}</Label>;\n case 'Stopped':\n return <Label color=\"orange\">{labelText}</Label>;\n case 'Needs maintenance':\n return <Label color=\"blue\">{labelText}</Label>;\n case 'Down':\n return <Label color=\"red\">{labelText}</Label>;\n default:\n return <></>;\n }\n };\n\n const toolbarItems = (\n <Fragment>\n <Toolbar id=\"page-layout-table-column-management-action-toolbar-top\">\n <span id=\"page-layout-table-column-management-action-toolbar-top-select-checkbox-label\" hidden>\n Choose one\n </span>\n <ToolbarContent>\n <ToolbarItem>\n <OverflowMenu breakpoint=\"md\">\n <OverflowMenuItem>\n <MenuToggle icon={<FilterIcon />}>Name</MenuToggle>\n </OverflowMenuItem>\n <OverflowMenuItem>\n <MenuToggle variant=\"plain\" aria-label=\"Sort columns\" icon={<RhMicronsSortDownLargeToSmallIcon />} />\n </OverflowMenuItem>\n <OverflowMenuGroup groupType=\"button\" isPersistent>\n <OverflowMenuItem>\n <Button variant=\"primary\">Action</Button>\n </OverflowMenuItem>\n <OverflowMenuItem isPersistent>\n <Button variant=\"link\" onClick={handleModalToggle}>\n Manage columns\n </Button>\n </OverflowMenuItem>\n </OverflowMenuGroup>\n </OverflowMenu>\n </ToolbarItem>\n <ToolbarItem variant=\"pagination\">{renderPagination('top', false)}</ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n </Fragment>\n );\n\n return (\n <Fragment>\n <DashboardWrapper hasPageTemplateTitle>\n <PageSection isFilled aria-label=\"Column management table data\">\n {toolbarItems}\n <Table variant=\"compact\" aria-label=\"Column Management Table\">\n <Thead>\n <Tr>\n {managedColumns.map((column, columnIndex) => (\n <Th key={columnIndex}>{column}</Th>\n ))}\n </Tr>\n </Thead>\n <Tbody>\n {paginatedRows.map((row, rowIndex) => (\n <Tr key={rowIndex}>\n <>\n {Object.entries(row).map(([key, value], idx) =>\n // eslint-disable-next-line no-nested-ternary\n key === 'status' ? (\n <Td width={15} dataLabel=\"Status\" key={`${idx}-${value}`}>\n {renderLabel(value as string)}\n </Td>\n ) : key === 'url' ? (\n <Td width={10} dataLabel=\"URL\" modifier=\"truncate\" key={`${idx}-${value}`}>\n <TableText>\n <a href=\"#\">{row.url}</a>\n </TableText>\n </Td>\n ) : (\n <Td\n width={key === 'name' ? 15 : 10}\n dataLabel={key === 'lastModified' ? 'Last modified' : capitalize(key)}\n key={`${idx}-${value}`}\n >\n {value as string}\n </Td>\n )\n )}\n </>\n </Tr>\n ))}\n </Tbody>\n </Table>\n {renderPagination('bottom', false)}\n {renderModal()}\n </PageSection>\n </DashboardWrapper>\n </Fragment>\n );\n};\n","title":"Column management","lang":"ts","isFullscreen":true,"className":""}}>
209
+
210
+ </Example>,
211
+ 'Column management with draggable': props =>
212
+ <Example {...pageData} {...props} thumbnail={srcImportcolumnmanagementwithdraggable} {...{"code":"import { Fragment, useEffect, useState } from 'react';\n\nimport {\n Button,\n Content,\n DataList,\n DataListCheck,\n DataListCell,\n DataListItemCells,\n DataListControl,\n Label,\n Toolbar,\n ToolbarContent,\n ToolbarItem,\n MenuToggle,\n Modal,\n ModalHeader,\n ModalBody,\n ModalFooter,\n OverflowMenu,\n OverflowMenuGroup,\n OverflowMenuItem,\n PageSection,\n Pagination,\n PaginationVariant\n} from '@patternfly/react-core';\nimport { Table, TableText, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';\nimport { DragDropSort } from '@patternfly/react-drag-drop';\nimport FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';\nimport RhMicronsSortDownLargeToSmallIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-sort-down-large-to-small-icon';\nimport { DashboardWrapper } from '@patternfly/react-table/dist/esm/demos/DashboardWrapper';\nimport { capitalize } from '@patternfly/react-table/src/components/Table/utils/utils';\nimport { rows, columns, SampleDataRow } from '@patternfly/react-table/dist/esm/demos/sampleData';\n\nexport const TableColumnManagement: React.FunctionComponent = () => {\n const defaultColumns = columns;\n const defaultRows = rows;\n\n const [filters, setFilters] = useState<string[]>([]);\n const [filteredColumns, setFilteredColumns] = useState<string[]>(defaultColumns);\n const [filteredRows, setFilteredRows] = useState<SampleDataRow[]>(defaultRows);\n const [managedColumns, setManagedColumns] = useState<string[]>(defaultColumns);\n const [managedRows, setManagedRows] = useState<SampleDataRow[]>(defaultRows);\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [page, setPage] = useState(1);\n const [perPage, setPerPage] = useState(10);\n const [paginatedRows, setPaginatedRows] = useState<any[]>(rows);\n\n const [columnData, setColumnData] = useState(defaultColumns.map((col) => ({ name: col, checked: true })));\n const [initialColData, setInitialColData] = useState(columnData);\n\n const matchSelectedColumnNameToAttr = (name: string): string => {\n switch (name) {\n case 'Servers':\n return 'name';\n case 'Threads':\n return 'threads';\n case 'Applications':\n return 'applications';\n case 'Workspaces':\n return 'workspaces';\n case 'Status':\n return 'status';\n case 'Location':\n return 'location';\n case 'Last Modified':\n return 'lastModified';\n case 'URL':\n return 'url';\n default:\n return '';\n }\n };\n\n // Pagination logic\n const handleSetPage = (\n _evt: MouseEvent | React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<Element>,\n newPage: number\n ) => {\n setPage(newPage);\n };\n\n const handlePerPageSelect = (\n _evt: MouseEvent | React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<Element>,\n newPerPage: number\n ) => {\n setPerPage(newPerPage);\n };\n\n const renderPagination = (variant: 'top' | 'bottom' | PaginationVariant, isCompact: boolean) => (\n <Pagination\n isCompact={isCompact}\n itemCount={rows.length}\n page={page}\n perPage={perPage}\n onSetPage={handleSetPage}\n onPerPageSelect={handlePerPageSelect}\n variant={variant}\n titles={{\n paginationAriaLabel: `${variant} pagination`\n }}\n />\n );\n\n useEffect(() => {\n setPaginatedRows(managedRows.slice((page - 1) * perPage, page * perPage - 1));\n }, [managedRows, page, perPage]);\n\n // Removes attribute from each node object in Data.jsx\n const removePropFromObject = (object: any, keys: string[]): any =>\n keys.reduce((obj, prop) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { [prop]: _, ...keep } = obj;\n return keep;\n }, object);\n\n // Filters columns out of table that are not selected in the column management modal\n const filterData = (checked: boolean, name: string) => {\n const selectedColumn = matchSelectedColumnNameToAttr(name);\n\n const filteredRows: SampleDataRow[] = [];\n if (checked) {\n const updatedFilters = filters.filter((item) => item !== selectedColumn);\n\n // Only show the names of columns that were selected in the modal\n const filteredColumns = defaultColumns.filter(\n (column) => !updatedFilters.includes(matchSelectedColumnNameToAttr(column))\n );\n\n // Remove the attributes (i.e. \"columns\") that were not selected\n defaultRows.forEach((item) => filteredRows.push(removePropFromObject(item, updatedFilters)));\n\n setFilters(updatedFilters);\n setFilteredColumns(filteredColumns);\n setFilteredRows(filteredRows);\n } else {\n const updatedFilters = filters;\n updatedFilters.push(selectedColumn);\n\n // Only show the names of columns that were selected in the modal\n const filteredColumns = managedColumns.filter(\n (column) => !filters.includes(matchSelectedColumnNameToAttr(column))\n );\n\n // Remove the attributes (i.e. \"columns\") that were not selected\n managedRows.forEach((item) => filteredRows.push(removePropFromObject(item, updatedFilters)));\n\n setFilters(updatedFilters);\n setFilteredColumns(filteredColumns);\n setFilteredRows(filteredRows);\n }\n };\n\n const unfilterAllData = () => {\n setFilters([]);\n setFilteredColumns(defaultColumns);\n setFilteredRows(defaultRows);\n };\n\n const handleModalToggle = (_event: React.MouseEvent<Element, MouseEvent> | KeyboardEvent) => {\n setIsModalOpen(!isModalOpen);\n setInitialColData(columnData);\n };\n\n const onSave = () => {\n const orderedFilteredColumns: string[] = [];\n columnData.map((col) => {\n if (filteredColumns.find((filteredCol) => filteredCol === col.name)) {\n orderedFilteredColumns.push(col.name);\n }\n });\n\n const orderedFilteredRows = filteredRows.map((row) => {\n let orderedRow;\n columnData.map((col) => {\n if (filteredColumns.find((filteredCol) => filteredCol === col.name)) {\n const rowField = matchSelectedColumnNameToAttr(col.name);\n orderedRow = { ...orderedRow, [rowField]: row[rowField] };\n }\n });\n return orderedRow;\n });\n\n setManagedColumns(orderedFilteredColumns);\n setManagedRows(orderedFilteredRows);\n setPaginatedRows(filteredRows);\n setIsModalOpen(!isModalOpen);\n };\n\n const selectAllColumns = () => {\n unfilterAllData();\n setColumnData(columnData.map((col) => ({ name: col.name, checked: true })));\n };\n\n const renderModal = () => (\n <Modal\n isOpen={isModalOpen}\n variant=\"small\"\n onClose={handleModalToggle}\n aria-labelledby=\"basic-modal-title\"\n aria-describedby=\"modal-box-body-basic\"\n >\n <ModalHeader\n title=\"Manage columns\"\n labelId=\"basic-modal-title\"\n description={\n <Content>\n <p>Selected categories will be displayed in the table.</p>\n <Button isInline onClick={selectAllColumns} variant=\"secondary\">\n Select all\n </Button>\n </Content>\n }\n />\n <ModalBody id=\"modal-box-body-basic\">\n <DragDropSort\n items={columnData.map((colData) => ({\n id: colData.name,\n content: (\n <>\n <DataListControl>\n <DataListCheck\n aria-labelledby={`table-column-management-item-${colData.name}`}\n isChecked={colData.checked}\n name={`check-${colData.name}`}\n id={`check-${colData.name}`}\n onChange={(event: React.FormEvent<HTMLInputElement>, _checked: boolean) => {\n let newColumnData: { name: string; checked: boolean }[] = [];\n\n columnData.map((colData) => {\n if (event.currentTarget.name === `check-${colData.name}`) {\n newColumnData = [...newColumnData, { name: colData.name, checked: !colData.checked }];\n filterData(!colData.checked, colData.name);\n } else {\n newColumnData = [...newColumnData, colData];\n }\n });\n\n setColumnData(newColumnData);\n }}\n />\n </DataListControl>\n <DataListItemCells\n dataListCells={[\n <DataListCell\n id={`table-column-management-item-${colData.name}`}\n key={`table-column-management-item-${colData.name}`}\n >\n <label htmlFor={`check-${colData.name}`}>{colData.name}</label>\n </DataListCell>\n ]}\n />\n </>\n ),\n data: colData\n }))}\n onDrop={(_, newItems) => {\n setColumnData(newItems.map((item) => (item as any).data));\n }}\n variant=\"DataList\"\n overlayProps={{ isCompact: true }}\n >\n <DataList aria-label=\"Table column management\" id=\"table-column-management\" isCompact />\n </DragDropSort>\n </ModalBody>\n <ModalFooter>\n <Button key=\"save\" variant=\"primary\" onClick={onSave}>\n Save\n </Button>\n <Button\n key=\"cancel\"\n variant=\"link\"\n onClick={(event: React.MouseEvent<Element, MouseEvent> | KeyboardEvent) => {\n setColumnData(initialColData);\n handleModalToggle(event);\n }}\n >\n Cancel\n </Button>\n </ModalFooter>\n </Modal>\n );\n\n const renderLabel = (labelText: string): React.JSX.Element => {\n switch (labelText) {\n case 'Running':\n return <Label color=\"green\">{labelText}</Label>;\n case 'Stopped':\n return <Label color=\"orange\">{labelText}</Label>;\n case 'Needs maintenance':\n return <Label color=\"blue\">{labelText}</Label>;\n case 'Down':\n return <Label color=\"red\">{labelText}</Label>;\n default:\n return <></>;\n }\n };\n\n const toolbarItems = (\n <Fragment>\n <Toolbar id=\"page-layout-table-column-management-action-toolbar-top\">\n <span id=\"page-layout-table-column-management-action-toolbar-top-select-checkbox-label\" hidden>\n Choose one\n </span>\n <ToolbarContent>\n <ToolbarItem>\n <OverflowMenu breakpoint=\"md\">\n <OverflowMenuItem>\n <MenuToggle icon={<FilterIcon />}>Name</MenuToggle>\n </OverflowMenuItem>\n <OverflowMenuItem>\n <MenuToggle\n variant=\"plain\"\n aria-label=\"Sort columns\"\n icon={<RhMicronsSortDownLargeToSmallIcon aria-hidden=\"true\" />}\n />\n </OverflowMenuItem>\n <OverflowMenuGroup groupType=\"button\" isPersistent>\n <OverflowMenuItem>\n <Button variant=\"primary\">Action</Button>\n </OverflowMenuItem>\n <OverflowMenuItem isPersistent>\n <Button variant=\"link\" onClick={handleModalToggle}>\n Manage columns\n </Button>\n </OverflowMenuItem>\n </OverflowMenuGroup>\n </OverflowMenu>\n </ToolbarItem>\n <ToolbarItem variant=\"pagination\">{renderPagination('top', false)}</ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n </Fragment>\n );\n\n return (\n <Fragment>\n <DashboardWrapper hasPageTemplateTitle>\n <PageSection isFilled aria-label=\"Draggable Column Management table data\">\n {toolbarItems}\n <Table variant=\"compact\" aria-label=\"Column Management Table\">\n <Thead>\n <Tr>\n {managedColumns.map((column, columnIndex) => (\n <Th key={columnIndex}>{column}</Th>\n ))}\n </Tr>\n </Thead>\n <Tbody>\n {paginatedRows.map((row, rowIndex) => (\n <Tr key={rowIndex}>\n <>\n {Object.entries(row).map(([key, value], idx) =>\n // eslint-disable-next-line no-nested-ternary\n key === 'status' ? (\n <Td width={15} dataLabel=\"Status\" key={`${idx}-${value}`}>\n {renderLabel(value as string)}\n </Td>\n ) : key === 'url' ? (\n <Td width={10} dataLabel=\"URL\" modifier=\"truncate\" key={`${idx}-${value}`}>\n <TableText>\n <a href=\"#\">{row.url}</a>\n </TableText>\n </Td>\n ) : (\n <Td\n width={key === 'name' ? 15 : 10}\n dataLabel={key === 'lastModified' ? 'Last modified' : capitalize(key)}\n key={`${idx}-${value}`}\n >\n {value as string}\n </Td>\n )\n )}\n </>\n </Tr>\n ))}\n </Tbody>\n </Table>\n {renderPagination('bottom', false)}\n {renderModal()}\n </PageSection>\n </DashboardWrapper>\n </Fragment>\n );\n};\n","title":"Column management with draggable","lang":"ts","isFullscreen":true,"className":""}}>
213
+
214
+ </Example>,
215
+ 'Filterable': props =>
216
+ <Example {...pageData} {...props} thumbnail={srcImportfilterable} {...{"code":"import { Fragment, useState } from 'react';\nimport {\n Badge,\n Button,\n Bullseye,\n EmptyState,\n EmptyStateActions,\n EmptyStateBody,\n EmptyStateFooter,\n Label,\n MenuToggle,\n MenuToggleElement,\n Toolbar,\n ToolbarItem,\n ToolbarContent,\n ToolbarFilter,\n ToolbarToggleGroup,\n ToolbarGroup,\n Select,\n SelectOption,\n SearchInput,\n ToolbarLabelGroup\n} from '@patternfly/react-core';\nimport SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';\nimport FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';\nimport { Table, TableText, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';\nimport { rows, columns } from '@patternfly/react-table/dist/esm/demos/sampleData';\n\nexport const TableFilterable: React.FunctionComponent = () => {\n const [filters, setFilters] = useState<Record<string, string[]>>({ location: [], name: [], status: [] });\n const [currentCategory, setCurrentCategory] = useState('Status');\n const [isFilterDropdownOpen, setIsFilterDropdownOpen] = useState(false);\n const [isCategoryDropdownOpen, setIsCategoryDropdownOpen] = useState(false);\n const [inputValue, setInputValue] = useState('');\n\n const rowData = rows.slice(0, 10);\n\n const onDelete = (type: string | ToolbarLabelGroup, id: string) => {\n if (type === 'Location') {\n setFilters({\n ...filters,\n location: filters.location.filter((fil: string) => fil !== id)\n });\n } else if (type === 'Name') {\n setFilters({\n ...filters,\n name: filters.name.filter((fil: string) => fil !== id)\n });\n } else if (type === 'Status') {\n setFilters({\n ...filters,\n status: filters.status.filter((fil: string) => fil !== id)\n });\n } else {\n setFilters({ location: [], name: [], status: [] });\n }\n };\n\n const onCategoryToggle = () => {\n setIsCategoryDropdownOpen(!isCategoryDropdownOpen);\n };\n\n const onCategorySelect = (event: React.MouseEvent<Element, MouseEvent>, value: string) => {\n setCurrentCategory(value);\n setIsCategoryDropdownOpen(false);\n };\n\n const onFilterToggle = () => {\n setIsFilterDropdownOpen(!isFilterDropdownOpen);\n };\n\n const onFilterSelect = () => {\n setIsFilterDropdownOpen(!isFilterDropdownOpen);\n };\n\n const onInputChange = (newValue: string) => {\n setInputValue(newValue);\n };\n\n const onStatusSelect = (event: React.MouseEvent<Element, MouseEvent>, selection: string) => {\n const checked = (event.target as HTMLInputElement).checked;\n setFilters({\n ...filters,\n status: checked ? [...filters.status, selection] : filters.status.filter((value) => value !== selection)\n });\n setIsFilterDropdownOpen(false);\n };\n\n const onNameInput = (event: React.KeyboardEvent) => {\n if (event.key && event.key !== 'Enter') {\n return;\n }\n\n const prevFilters = filters.name;\n setFilters({ ...filters, name: prevFilters.includes(inputValue) ? prevFilters : [...prevFilters, inputValue] });\n };\n\n const onLocationSelect = (event: React.MouseEvent<Element, MouseEvent>, selection: string) => {\n setFilters({ ...filters, location: [selection] });\n\n setIsFilterDropdownOpen(false);\n onFilterSelect();\n };\n\n const buildCategoryDropdown = () => {\n const categoryMenuItems = [\n <SelectOption key=\"cat1\" value=\"Location\">\n Location\n </SelectOption>,\n <SelectOption key=\"cat2\" value=\"Name\">\n Name\n </SelectOption>,\n <SelectOption key=\"cat3\" value=\"Status\">\n Status\n </SelectOption>\n ];\n\n return (\n <ToolbarItem>\n <Select\n onSelect={onCategorySelect}\n selected={currentCategory}\n toggle={(toggleRef: React.Ref<MenuToggleElement>) => (\n <MenuToggle\n ref={toggleRef}\n onClick={onCategoryToggle}\n isExpanded={isCategoryDropdownOpen}\n icon={<FilterIcon />}\n style={\n {\n width: '100%',\n verticalAlign: 'text-bottom'\n } as React.CSSProperties\n }\n >\n {currentCategory}\n </MenuToggle>\n )}\n isOpen={isCategoryDropdownOpen}\n >\n {categoryMenuItems}\n </Select>\n </ToolbarItem>\n );\n };\n\n const buildFilterDropdown = () => {\n const locationMenuItems = [\n <SelectOption key=\"raleigh\" value=\"Raleigh\">\n Raleigh\n </SelectOption>,\n <SelectOption key=\"san francisco\" value=\"San Francisco\">\n San Francisco\n </SelectOption>,\n <SelectOption key=\"boston\" value=\"Boston\">\n Boston\n </SelectOption>,\n <SelectOption key=\"atlanta\" value=\"Atlanta\">\n Atlanta\n </SelectOption>\n ];\n\n const statusMenuItems = [\n <SelectOption hasCheckbox key=\"statusRunning\" value=\"Running\" isSelected={filters.status.includes('Running')}>\n Running\n </SelectOption>,\n <SelectOption hasCheckbox key=\"statusStopped\" value=\"Stopped\" isSelected={filters.status.includes('Stopped')}>\n Stopped\n </SelectOption>,\n <SelectOption hasCheckbox key=\"statusDown\" value=\"Down\" isSelected={filters.status.includes('Down')}>\n Down\n </SelectOption>,\n <SelectOption hasCheckbox key=\"statusDegraded\" value=\"Degraded\" isSelected={filters.status.includes('Degraded')}>\n Degraded\n </SelectOption>,\n <SelectOption\n hasCheckbox\n key=\"statusMaint\"\n value=\"Needs maintenance\"\n isSelected={filters.status.includes('Needs maintenance')}\n >\n Needs maintenance\n </SelectOption>\n ];\n\n return (\n <Fragment>\n <ToolbarFilter\n labels={filters.location}\n deleteLabel={(category, label) => onDelete(category, label as string)}\n categoryName=\"Location\"\n showToolbarItem={currentCategory === 'Location'}\n >\n <Select\n aria-label=\"Location\"\n onSelect={onLocationSelect}\n selected={filters.location[0]}\n isOpen={isFilterDropdownOpen}\n popperProps={{ minWidth: '100px' }}\n toggle={(toggleRef: React.Ref<MenuToggleElement>) => (\n <MenuToggle\n ref={toggleRef}\n onClick={onFilterToggle}\n isExpanded={isFilterDropdownOpen}\n style={\n {\n width: '100%',\n verticalAlign: 'text-bottom'\n } as React.CSSProperties\n }\n >\n {filters.location[0] || `Any`}\n </MenuToggle>\n )}\n >\n {locationMenuItems}\n </Select>\n </ToolbarFilter>\n <ToolbarFilter\n labels={filters.name}\n deleteLabel={(category, label) => onDelete(category, label as string)}\n categoryName=\"Name\"\n showToolbarItem={currentCategory === 'Name'}\n >\n <SearchInput\n aria-label=\"name filter\"\n placeholder=\"Filter by name...\"\n onChange={(_event, value) => onInputChange(value)}\n value={inputValue}\n onClear={() => {\n onInputChange('');\n }}\n onSearch={onNameInput}\n />\n </ToolbarFilter>\n <ToolbarFilter\n labels={filters.status}\n deleteLabel={(category, label) => onDelete(category, label as string)}\n categoryName=\"Status\"\n showToolbarItem={currentCategory === 'Status'}\n >\n <Select\n aria-label=\"Status\"\n isOpen={isFilterDropdownOpen}\n popperProps={{ minWidth: '100px' }}\n onSelect={onStatusSelect}\n selected={filters.status}\n toggle={(toggleRef: React.Ref<MenuToggleElement>) => (\n <MenuToggle\n ref={toggleRef}\n onClick={onFilterToggle}\n isExpanded={isFilterDropdownOpen}\n style={\n {\n width: '100%',\n verticalAlign: 'text-bottom'\n } as React.CSSProperties\n }\n >\n Filter by status\n {filters.status.length > 0 && <Badge isRead>{filters.status.length}</Badge>}\n </MenuToggle>\n )}\n >\n {statusMenuItems}\n </Select>\n </ToolbarFilter>\n </Fragment>\n );\n };\n\n const renderToolbar = () => (\n <Toolbar\n id=\"toolbar-with-label-groups\"\n clearAllFilters={() => setFilters({ location: [], name: [], status: [] })}\n collapseListedFiltersBreakpoint=\"xl\"\n >\n <ToolbarContent>\n <ToolbarToggleGroup toggleIcon={<FilterIcon />} breakpoint=\"xl\">\n <ToolbarGroup\n variant=\"filter-group\"\n style={\n {\n lineHeight: '22px',\n alignItems: 'center'\n } as React.CSSProperties\n }\n >\n {buildCategoryDropdown()}\n {buildFilterDropdown()}\n </ToolbarGroup>\n </ToolbarToggleGroup>\n </ToolbarContent>\n </Toolbar>\n );\n\n const filteredRows =\n filters.name.length > 0 || filters.location.length > 0 || filters.status.length > 0\n ? rowData.filter(\n (row) =>\n (filters.name.length === 0 ||\n filters.name.some((name) => row.name.toLowerCase().includes(name.toLowerCase()))) &&\n (filters.location.length === 0 || filters.location.includes(row.location)) &&\n (filters.status.length === 0 || filters.status.includes(row.status))\n )\n : rowData;\n\n const emptyState = (\n <EmptyState icon={SearchIcon} titleText=\"Clear all filters and try again.\" headingLevel=\"h5\">\n <EmptyStateBody>No results match the filter criteria. Clear all filters and try again.</EmptyStateBody>\n <EmptyStateFooter>\n <EmptyStateActions>\n <Button\n variant=\"link\"\n onClick={() => {\n setFilters({ location: [], name: [], status: [] });\n }}\n >\n Clear all filters\n </Button>\n </EmptyStateActions>\n </EmptyStateFooter>\n </EmptyState>\n );\n\n const renderLabel = (labelText: string) => {\n switch (labelText) {\n case 'Running':\n return <Label color=\"green\">{labelText}</Label>;\n case 'Stopped':\n return <Label color=\"orange\">{labelText}</Label>;\n case 'Needs maintenance':\n return <Label color=\"blue\">{labelText}</Label>;\n case 'Down':\n return <Label color=\"red\">{labelText}</Label>;\n }\n };\n\n return (\n <Fragment>\n {renderToolbar()}\n <Table aria-label=\"Filterable Table Demo\">\n <Thead>\n <Tr>\n <Th key={0}>{columns[0]}</Th>\n <Th key={1}>{columns[1]}</Th>\n <Th key={2}>{columns[2]}</Th>\n <Th key={3}>{columns[3]}</Th>\n <Th key={4}>{columns[4]}</Th>\n <Th key={5}>{columns[5]}</Th>\n <Th key={6}>{columns[6]}</Th>\n <Th key={7} width={10}>\n {columns[7]}\n </Th>\n </Tr>\n </Thead>\n <Tbody>\n {filteredRows.slice(0, 10).map((row, rowIndex) => (\n <Tr key={rowIndex}>\n <>\n <Td dataLabel={columns[0]}>{row.name}</Td>\n <Td dataLabel={columns[1]}>{row.threads}</Td>\n <Td dataLabel={columns[2]}>{row.applications}</Td>\n <Td dataLabel={columns[3]}>{row.workspaces}</Td>\n <Td dataLabel={columns[4]}>{renderLabel(row.status)}</Td>\n <Td dataLabel={columns[5]}>{row.location}</Td>\n <Td dataLabel={columns[6]}>{row.lastModified}</Td>\n <Td dataLabel={columns[7]} modifier=\"truncate\">\n <TableText>\n <a href=\"#\">{row.url}</a>\n </TableText>\n </Td>\n </>\n </Tr>\n ))}\n {filteredRows.length === 0 && (\n <Tr>\n <Td colSpan={8}>\n <Bullseye>{emptyState}</Bullseye>\n </Td>\n </Tr>\n )}\n </Tbody>\n </Table>\n </Fragment>\n );\n};\n","title":"Filterable","lang":"ts","isFullscreen":true,"className":""}}>
217
+
218
+ </Example>,
219
+ 'Sortable - responsive': props =>
220
+ <Example {...pageData} {...props} thumbnail={srcImportsortableresponsive} {...{"code":"import { Fragment, useEffect, useState } from 'react';\nimport {\n Button,\n Content,\n Dropdown,\n DropdownList,\n Flex,\n FlexItem,\n MenuToggle,\n MenuToggleElement,\n PageSection,\n Pagination,\n SelectOption,\n SelectList,\n SelectGroup,\n Toolbar,\n ToolbarContent,\n ToolbarGroup,\n ToolbarItem,\n OverflowMenuDropdownItem,\n PaginationVariant,\n Label,\n Select,\n OverflowMenu,\n OverflowMenuContent,\n OverflowMenuControl,\n OverflowMenuGroup,\n OverflowMenuItem,\n PageSectionVariants\n} from '@patternfly/react-core';\nimport { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';\nimport CloneIcon from '@patternfly/react-icons/dist/esm/icons/clone-icon';\nimport EditIcon from '@patternfly/react-icons/dist/esm/icons/edit-icon';\nimport SyncIcon from '@patternfly/react-icons/dist/esm/icons/sync-icon';\nimport RhUiCodeIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-code-icon';\nimport RhMicronsSortDownLargeToSmallIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-sort-down-large-to-small-icon';\nimport RhUiBranchFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-branch-fill-icon';\nimport CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';\nimport { DashboardWrapper } from '@patternfly/react-table/dist/esm/demos/DashboardWrapper';\nimport RhUiEllipsisVerticalFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-ellipsis-vertical-fill-icon';\nimport { rows, columns, SampleDataRow } from '@patternfly/react-table/dist/esm/demos/sampleData';\n\ntype Direction = 'asc' | 'desc' | undefined;\n\nexport const TableSortableResponsive: React.FunctionComponent = () => {\n const [isKebabDropdownOpen, setIsKebabDropdownOpen] = useState(false);\n\n const sortRows = (rows: SampleDataRow[], sortIndex: number, sortDirection: Direction) =>\n [...rows].sort((a, b) => {\n let returnValue = 0;\n if (typeof Object.values(a)[sortIndex] === 'number') {\n // numeric sort\n returnValue = Object.values(a)[sortIndex] - Object.values(b)[sortIndex];\n } else {\n // string sort using natural sort\n returnValue = Object.values(a)[sortIndex].localeCompare(Object.values(b)[sortIndex], undefined, {\n numeric: true\n });\n }\n if (sortDirection === 'desc') {\n return returnValue * -1;\n }\n return returnValue;\n });\n\n const [sortedData, setSortedData] = useState([...sortRows(rows, 0, 'asc')]);\n const [sortedRows, setSortedRows] = useState([...sortedData]);\n const [page, setPage] = useState(1);\n const [perPage, setPerPage] = useState(10);\n\n // index of the currently active column\n const [activeSortIndex, setActiveSortIndex] = useState(0);\n // sort direction of the currently active column\n const [activeSortDirection, setActiveSortDirection] = useState<Direction>('asc');\n // sort dropdown expansion\n const [isSortDropdownOpen, setIsSortDropdownOpen] = useState(false);\n\n const onSort = (_event: any, index: number, direction: Direction) => {\n setActiveSortIndex(index);\n setActiveSortDirection(direction);\n\n setSortedData(sortRows(rows, index, direction));\n };\n\n const kebabDropdownItems = [<OverflowMenuDropdownItem key=\"kebab-1\">Some action</OverflowMenuDropdownItem>];\n\n useEffect(() => {\n setSortedRows(sortedData.slice((page - 1) * perPage, page * perPage));\n }, [sortedData, page, perPage]);\n\n const handleSetPage = (_evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, newPage: number) => {\n setPage(newPage);\n };\n\n const handlePerPageSelect = (_evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, newPerPage: number) => {\n setPerPage(newPerPage);\n };\n\n const renderPagination = (variant: 'top' | 'bottom' | PaginationVariant, isCompact: boolean) => (\n <Pagination\n isCompact={isCompact}\n itemCount={rows.length}\n page={page}\n perPage={perPage}\n onSetPage={handleSetPage}\n onPerPageSelect={handlePerPageSelect}\n perPageOptions={[\n { title: '10', value: 10 },\n { title: '20', value: 20 },\n { title: '50', value: 50 },\n { title: '100', value: 100 }\n ]}\n variant={variant}\n titles={{\n paginationAriaLabel: `${variant} pagination`\n }}\n />\n );\n\n const renderLabel = (labelText: string) => {\n switch (labelText) {\n case 'Running':\n return <Label color=\"green\">{labelText}</Label>;\n case 'Stopped':\n return <Label color=\"orange\">{labelText}</Label>;\n case 'Needs Maintenance':\n return <Label color=\"blue\">{labelText}</Label>;\n case 'Down':\n return <Label color=\"red\">{labelText}</Label>;\n }\n };\n\n const tableToolbar = (\n <Toolbar id=\"sortable-toolbar\">\n <ToolbarContent>\n <ToolbarItem visibility={{ md: 'hidden' }}>\n <Select\n isOpen={isSortDropdownOpen}\n selected={[activeSortDirection, activeSortIndex]}\n onOpenChange={(isOpen: boolean) => setIsSortDropdownOpen(isOpen)}\n onSelect={(event: React.MouseEvent<Element, MouseEvent>, value: string | number) => {\n if (value === 'asc' || value === 'desc') {\n onSort(event, activeSortIndex, value);\n } else {\n onSort(event, value as number, activeSortDirection ?? 'asc');\n }\n }}\n toggle={(toggleRef: React.Ref<MenuToggleElement>) => (\n <MenuToggle\n ref={toggleRef}\n onClick={() => setIsSortDropdownOpen(!isSortDropdownOpen)}\n isExpanded={isSortDropdownOpen}\n variant=\"plain\"\n icon={<RhMicronsSortDownLargeToSmallIcon />}\n />\n )}\n >\n <SelectGroup label=\"Sort column\">\n <SelectList>\n {columns.map((column, columnIndex) => (\n <SelectOption key={column} value={columnIndex} isSelected={activeSortIndex === columnIndex}>\n {column}\n </SelectOption>\n ))}\n </SelectList>\n </SelectGroup>\n <SelectGroup label=\"Sort direction\">\n <SelectList>\n <SelectOption isSelected={activeSortDirection === 'asc'} value=\"asc\" key=\"ascending\">\n Ascending\n </SelectOption>\n <SelectOption isSelected={activeSortDirection === 'desc'} value=\"desc\" key=\"descending\">\n Descending\n </SelectOption>\n </SelectList>\n </SelectGroup>\n </Select>\n </ToolbarItem>\n <ToolbarItem>\n <OverflowMenu breakpoint=\"lg\">\n <OverflowMenuContent isPersistent>\n <OverflowMenuGroup isPersistent groupType=\"button\">\n <OverflowMenuItem>\n <Button variant=\"primary\">Create instance</Button>\n </OverflowMenuItem>\n <OverflowMenuItem>\n <Button variant=\"secondary\">Action</Button>\n </OverflowMenuItem>\n </OverflowMenuGroup>\n </OverflowMenuContent>\n <OverflowMenuControl hasAdditionalOptions>\n <Dropdown\n onSelect={() => setIsKebabDropdownOpen(!isKebabDropdownOpen)}\n onOpenChange={(isKebabDropdownOpen: boolean) => setIsKebabDropdownOpen(isKebabDropdownOpen)}\n toggle={(toggleRef: React.Ref<MenuToggleElement>) => (\n <MenuToggle\n ref={toggleRef}\n aria-label=\"overflow menu\"\n variant=\"plain\"\n onClick={() => setIsKebabDropdownOpen(!isKebabDropdownOpen)}\n isExpanded={false}\n icon={<RhUiEllipsisVerticalFillIcon />}\n />\n )}\n isOpen={isKebabDropdownOpen}\n >\n <DropdownList>{kebabDropdownItems}</DropdownList>\n </Dropdown>\n </OverflowMenuControl>\n </OverflowMenu>\n </ToolbarItem>\n <ToolbarGroup variant=\"action-group-plain\">\n <ToolbarItem>\n <Button aria-label=\"Edit\" variant=\"plain\" icon={<EditIcon />} />\n </ToolbarItem>\n <ToolbarItem>\n <Button aria-label=\"Clone\" variant=\"plain\" icon={<CloneIcon />} />\n </ToolbarItem>\n <ToolbarItem>\n <Button aria-label=\"Sync\" variant=\"plain\" icon={<SyncIcon />} />\n </ToolbarItem>\n </ToolbarGroup>\n <ToolbarItem variant=\"pagination\">{renderPagination('top', true)}</ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n );\n\n return (\n <Fragment>\n <DashboardWrapper>\n <PageSection isWidthLimited variant={PageSectionVariants.light} aria-labelledby=\"table-title\">\n <Content>\n <h1 id=\"table-title\">Table demos</h1>\n <p>\n Below is an example of a responsive sortable table. When the screen size shrinks the table into a compact\n form, the toolbar will display a dropdown menu containing sorting options.\n </p>\n </Content>\n </PageSection>\n <PageSection\n padding={{\n default: 'noPadding',\n xl: 'padding'\n }}\n aria-label=\"Sortable table data\"\n >\n {tableToolbar}\n <Table aria-label=\"Sortable Table\">\n <Thead>\n <Tr>\n {columns.map((column, columnIndex) => {\n const sortParams = {\n sort: {\n sortBy: {\n index: activeSortIndex,\n direction: activeSortDirection\n },\n onSort,\n columnIndex\n }\n };\n return (\n <Th modifier={columnIndex !== 6 ? 'wrap' : undefined} key={columnIndex} {...sortParams}>\n {column}\n </Th>\n );\n })}\n </Tr>\n </Thead>\n <Tbody>\n {sortedRows.map((row, rowIndex) => (\n <Tr key={rowIndex}>\n <>\n <Td dataLabel={columns[0]} width={15}>\n <div>{row.name}</div>\n </Td>\n <Td dataLabel={columns[1]} width={10}>\n <Flex spaceItems={{ default: 'spaceItemsSm' }}>\n <FlexItem>\n <RhUiBranchFillIcon key=\"icon\" />\n </FlexItem>\n <FlexItem>{row.threads}</FlexItem>\n </Flex>\n </Td>\n <Td dataLabel={columns[2]} width={10}>\n <Flex spaceItems={{ default: 'spaceItemsSm' }}>\n <FlexItem>\n <RhUiCodeIcon key=\"icon\" />\n </FlexItem>\n <FlexItem>{row.applications}</FlexItem>\n </Flex>\n </Td>\n <Td dataLabel={columns[3]} width={10}>\n <Flex spaceItems={{ default: 'spaceItemsSm' }}>\n <FlexItem>\n <CubeIcon key=\"icon\" />\n </FlexItem>\n <FlexItem>{row.workspaces}</FlexItem>\n </Flex>\n </Td>\n <Td dataLabel={columns[4]} width={15}>\n <Flex spaceItems={{ default: 'spaceItemsSm' }}>\n <FlexItem>{renderLabel(row.status)}</FlexItem>\n </Flex>\n </Td>\n <Td dataLabel={columns[5]} width={10}>\n <Flex spaceItems={{ default: 'spaceItemsSm' }}>\n <FlexItem>{row.location}</FlexItem>\n </Flex>\n </Td>\n <Td dataLabel={columns[6]} width={10}>\n <Flex spaceItems={{ default: 'spaceItemsSm' }}>\n <FlexItem>{row.lastModified[0]} days ago</FlexItem>\n </Flex>\n </Td>\n <Td dataLabel={columns[7]} modifier=\"truncate\">\n <a href=\"#\">{row.url}</a>\n </Td>\n </>\n </Tr>\n ))}\n </Tbody>\n </Table>\n {renderPagination('bottom', false)}\n </PageSection>\n </DashboardWrapper>\n </Fragment>\n );\n};\n","title":"Sortable - responsive","lang":"ts","isFullscreen":true,"className":""}}>
221
+
222
+ </Example>,
223
+ 'Automatic pagination': props =>
224
+ <Example {...pageData} {...props} thumbnail={srcImportautomaticpagination} {...{"code":"import { Fragment, useState } from 'react';\nimport { Pagination } from '@patternfly/react-core';\nimport { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';\n\nexport const TableAutomaticPagination: React.FunctionComponent = () => {\n const columns = {\n firstColumn: 'First column',\n secondColumn: 'Second column',\n thirdColumn: 'Third column'\n };\n\n const defaultRows = [\n { firstColumn: 'Row 1 column 1', secondColumn: 'Row 1 column 2', thirdColumn: 'Row 1 column 3' },\n { firstColumn: 'Row 2 column 1', secondColumn: 'Row 2 column 2', thirdColumn: 'Row 2 column 3' },\n { firstColumn: 'Row 3 column 1', secondColumn: 'Row 3 column 2', thirdColumn: 'Row 3 column 3' },\n { firstColumn: 'Row 4 column 1', secondColumn: 'Row 4 column 2', thirdColumn: 'Row 4 column 3' },\n { firstColumn: 'Row 5 column 1', secondColumn: 'Row 5 column 2', thirdColumn: 'Row 5 column 3' },\n { firstColumn: 'Row 6 column 1', secondColumn: 'Row 6 column 2', thirdColumn: 'Row 6 column 3' },\n { firstColumn: 'Row 7 column 1', secondColumn: 'Row 7 column 2', thirdColumn: 'Row 7 column 3' },\n { firstColumn: 'Row 8 column 1', secondColumn: 'Row 8 column 2', thirdColumn: 'Row 8 column 3' },\n { firstColumn: 'Row 9 column 1', secondColumn: 'Row 9 column 2', thirdColumn: 'Row 9 column 3' },\n { firstColumn: 'Row 10 column 1', secondColumn: 'Row 10 column 2', thirdColumn: 'Row 10 column 3' },\n { firstColumn: 'Row 11 column 1', secondColumn: 'Row 11 column 2', thirdColumn: 'Row 11 column 3' },\n { firstColumn: 'Row 12 column 1', secondColumn: 'Row 12 column 2', thirdColumn: 'Row 12 column 3' }\n ];\n const defaultPerPage = 10;\n\n const [perPage, setPerPage] = useState(defaultPerPage);\n const [page, setPage] = useState(1);\n const [rows, setRows] = useState(defaultRows.slice(0, defaultPerPage));\n\n const handleSetPage = (\n _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent,\n newPage: number,\n _perPage: number,\n startIdx: number,\n endIdx: number\n ) => {\n setPage(newPage);\n setRows(defaultRows.slice(startIdx, endIdx));\n };\n\n const handlePerPageSelect = (\n _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent,\n newPerPage: number,\n newPage: number,\n startIdx: number,\n endIdx: number\n ) => {\n setPerPage(newPerPage);\n setPage(newPage);\n setRows(defaultRows.slice(startIdx, endIdx));\n };\n\n const renderPagination = (variant = 'top') => (\n <Pagination\n isCompact\n itemCount={defaultRows.length}\n page={page}\n perPage={perPage}\n isLastFullPageShown\n onSetPage={handleSetPage}\n onPerPageSelect={handlePerPageSelect}\n perPageOptions={[\n { title: '3', value: 3 },\n { title: '5', value: 5 },\n { title: '12', value: 12 },\n { title: '20', value: 20 }\n ]}\n titles={{\n paginationAriaLabel: `${variant} pagination`\n }}\n />\n );\n\n return (\n <Fragment>\n {renderPagination()}\n <Table aria-label=\"Automated Pagination Table Demo\">\n <Thead>\n <Tr>\n <Th>{columns.firstColumn}</Th>\n <Th>{columns.secondColumn}</Th>\n <Th>{columns.thirdColumn}</Th>\n </Tr>\n </Thead>\n <Tbody>\n {rows.map((row, rowIndex) => (\n <Tr key={rowIndex}>\n <>\n <Td dataLabel={columns.firstColumn}>{row.firstColumn}</Td>\n <Td dataLabel={columns.secondColumn}>{row.secondColumn}</Td>\n <Td dataLabel={columns.thirdColumn}>{row.thirdColumn}</Td>\n </>\n </Tr>\n ))}\n </Tbody>\n </Table>\n </Fragment>\n );\n};\n","title":"Automatic pagination","lang":"js","isFullscreen":true,"className":""}}>
225
+
226
+ <p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
227
+ {`The below example illustrates the `}
228
+
229
+ <code {...{"className":"ws-code "}}>
230
+ {`isLastFullPageShown`}
231
+ </code>
232
+ {` prop, which makes the following changes when the user sets the number of items to display per page to an amount that exceeds the remaining amount of data:`}
233
+ </p>
234
+
235
+ <ul {...{"className":"pf-v6-c-content--ul pf-m-editorial ws-ul "}}>
236
+
237
+
238
+
239
+ <li {...{"className":"pf-v6-c-content--li pf-m-editorial ws-li "}}>
240
+ {`The component automatically changes the page back to the last full page of results, rather than defaulting to the final page of results.`}
241
+ </li>
242
+
243
+
244
+ </ul>
245
+
246
+ <p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
247
+ {`To demonstrate this, navigate to the last page of data below using the `}
248
+
249
+ <code {...{"className":"ws-code "}}>
250
+ {`>>`}
251
+ </code>
252
+ {` navigation arrows, then use the dropdown selector to change the view to 5 per page.`}
253
+ </p>
254
+
255
+ <ul {...{"className":"pf-v6-c-content--ul pf-m-editorial ws-ul "}}>
256
+
257
+
258
+
259
+ <li {...{"className":"pf-v6-c-content--li pf-m-editorial ws-li "}}>
260
+ {`The default behavior would show the last page of results, which would only contain the last two rows (rows 11 - 12).`}
261
+ </li>
262
+
263
+
264
+
265
+ <li {...{"className":"pf-v6-c-content--li pf-m-editorial ws-li "}}>
266
+ {`The `}
267
+
268
+ <code {...{"className":"ws-code "}}>
269
+ {`isLastFullPageShown`}
270
+ </code>
271
+ {` prop navigates you back to the previous page which does contain a full page of 5 rows (rows 6 - 10).`}
272
+ </li>
273
+
274
+
275
+ </ul>
276
+ </Example>,
277
+ 'Static bottom pagination on mobile': props =>
278
+ <Example {...pageData} {...props} thumbnail={srcImportstaticbottompaginationonmobile} {...{"code":"import { Fragment, useState } from 'react';\nimport {\n Button,\n Toolbar,\n ToolbarContent,\n ToolbarGroup,\n ToolbarItem,\n Pagination,\n PageSection,\n MenuToggle,\n MenuToggleElement,\n Label,\n Select,\n SelectOption,\n PaginationVariant\n} from '@patternfly/react-core';\nimport { Table, TableText, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';\nimport FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';\nimport { DashboardWrapper } from '@patternfly/react-table/dist/esm/demos/DashboardWrapper';\nimport { rows, columns } from '@patternfly/react-table/dist/esm/demos/sampleData';\n\nexport const TableStaticBottomPagination: React.FunctionComponent = () => {\n const [isSelectOpen, setIsSelectOpen] = useState(false);\n const [page, setPage] = useState(1);\n const [perPage, setPerPage] = useState(10);\n const [paginatedRows, setPaginatedRows] = useState(rows.slice(0, 10));\n const handleSetPage = (\n _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent,\n newPage: number,\n _perPage: number,\n startIdx: number,\n endIdx: number\n ) => {\n setPaginatedRows(rows.slice(startIdx, endIdx));\n setPage(newPage);\n };\n const handlePerPageSelect = (\n _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent,\n newPerPage: number,\n newPage: number,\n startIdx: number,\n endIdx: number\n ) => {\n setPaginatedRows(rows.slice(startIdx, endIdx));\n setPage(newPage);\n setPerPage(newPerPage);\n };\n\n const renderPagination = (variant: PaginationVariant | 'bottom' | 'top', isCompact: boolean) => (\n <Pagination\n isCompact={isCompact}\n itemCount={rows.length}\n page={page}\n perPage={perPage}\n onSetPage={handleSetPage}\n onPerPageSelect={handlePerPageSelect}\n variant={variant}\n titles={{\n paginationAriaLabel: `${variant} pagination`\n }}\n isStatic\n />\n );\n\n const renderLabel = (labelText: string) => {\n switch (labelText) {\n case 'Running':\n return (\n <span>\n <Label color=\"green\">{labelText}</Label>\n </span>\n );\n case 'Stopped':\n return (\n <span>\n <Label color=\"orange\">{labelText}</Label>\n </span>\n );\n case 'Needs Maintenance':\n return (\n <span>\n <Label color=\"blue\">{labelText}</Label>\n </span>\n );\n case 'Down':\n return (\n <span>\n <Label color=\"red\">{labelText}</Label>\n </span>\n );\n }\n };\n\n const tableToolbar = (\n <Toolbar usePageInsets id=\"pagination-toolbar\">\n <ToolbarContent>\n <ToolbarItem>\n <Select\n id=\"select-example\"\n aria-label=\"Select Input\"\n toggle={(toggleRef: React.Ref<MenuToggleElement>) => (\n <MenuToggle\n icon={<FilterIcon />}\n ref={toggleRef}\n onClick={() => setIsSelectOpen(!isSelectOpen)}\n isExpanded={isSelectOpen}\n >\n Status\n </MenuToggle>\n )}\n isOpen={isSelectOpen}\n onOpenChange={(isOpen: boolean) => setIsSelectOpen(isOpen)}\n onSelect={() => setIsSelectOpen(!isSelectOpen)}\n >\n {[\n <SelectOption key={0} value=\"Debug\">\n Debug\n </SelectOption>,\n <SelectOption key={1} value=\"Info\">\n Info\n </SelectOption>,\n <SelectOption key={2} value=\"Warn\">\n Warn\n </SelectOption>,\n <SelectOption key={3} value=\"Error\">\n Error\n </SelectOption>\n ]}\n </Select>\n </ToolbarItem>\n <ToolbarGroup>\n <ToolbarItem>\n <Button variant=\"primary\">Action</Button>\n </ToolbarItem>\n </ToolbarGroup>\n <ToolbarItem variant=\"pagination\">{renderPagination('top', true)}</ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n );\n\n return (\n <Fragment>\n <DashboardWrapper hasPageTemplateTitle>\n <PageSection isFilled aria-label=\"Paginated table data\">\n {tableToolbar}\n <Table variant=\"compact\" aria-label=\"Paginated Table\">\n <Thead>\n <Tr>\n {columns.map((column, columnIndex) => (\n <Th key={columnIndex}>{column}</Th>\n ))}\n </Tr>\n </Thead>\n <Tbody>\n {paginatedRows.map((row, rowIndex) => (\n <Tr key={rowIndex}>\n <Td dataLabel={columns[0]}>{row.name}</Td>\n <Td dataLabel={columns[1]}>{row.threads}</Td>\n <Td dataLabel={columns[2]}>{row.applications}</Td>\n <Td dataLabel={columns[3]}>{row.workspaces}</Td>\n <Td dataLabel={columns[4]}>{renderLabel(row.status)}</Td>\n <Td dataLabel={columns[5]}>{row.location}</Td>\n <Td dataLabel={columns[6]}>{row.lastModified}</Td>\n <Td dataLabel={columns[7]} modifier=\"truncate\">\n <TableText>\n <a href=\"#\">{row.url}</a>\n </TableText>\n </Td>\n </Tr>\n ))}\n </Tbody>\n </Table>\n {renderPagination('bottom', false)}\n </PageSection>\n </DashboardWrapper>\n </Fragment>\n );\n};\n","title":"Static bottom pagination on mobile","lang":"ts","isFullscreen":true,"className":""}}>
279
+
280
+ </Example>,
281
+ 'Sticky header': props =>
282
+ <Example {...pageData} {...props} thumbnail={srcImportstickyheader} {...{"code":"import { Label, PageSection } from '@patternfly/react-core';\nimport { Table, Thead, Tr, Th, Tbody, Td, TableText } from '@patternfly/react-table';\nimport { DashboardWrapper } from '@patternfly/react-table/dist/esm/demos/DashboardWrapper';\nimport { rows, columns } from '@patternfly/react-table/dist/esm/demos/sampleData';\n\nexport const TableStickyHeader: React.FunctionComponent = () => {\n const renderLabel = (labelText: string) => {\n switch (labelText) {\n case 'Running':\n return <Label color=\"green\">{labelText}</Label>;\n case 'Stopped':\n return <Label color=\"orange\">{labelText}</Label>;\n case 'Needs Maintenance':\n return <Label color=\"blue\">{labelText}</Label>;\n case 'Down':\n return <Label color=\"red\">{labelText}</Label>;\n }\n };\n\n return (\n <DashboardWrapper hasPageTemplateTitle>\n <PageSection padding={{ default: 'noPadding', xl: 'padding' }} aria-label=\"Sticky header table data\">\n <Table aria-label=\"Sticky Header Table Demo\" isStickyHeader>\n <Thead>\n <Tr>\n <Th width={15}>{columns[0]}</Th>\n <Th width={10}>{columns[1]}</Th>\n <Th width={10}>{columns[2]}</Th>\n <Th width={10}>{columns[3]}</Th>\n <Th width={10}>{columns[4]}</Th>\n <Th width={15}>{columns[5]}</Th>\n <Th width={15}>{columns[6]}</Th>\n <Th width={10}>{columns[7]}</Th>\n </Tr>\n </Thead>\n <Tbody>\n {rows.map((row) => (\n <Tr key={row.name}>\n <Td dataLabel={columns[0]}>{row.name}</Td>\n <Td dataLabel={columns[1]}>{row.threads}</Td>\n <Td dataLabel={columns[2]}>{row.applications}</Td>\n <Td dataLabel={columns[3]}>{row.workspaces}</Td>\n <Td dataLabel={columns[4]}>{renderLabel(row.status)}</Td>\n <Td dataLabel={columns[5]}>{row.location}</Td>\n <Td dataLabel={columns[6]}>{row.lastModified}</Td>\n <Td dataLabel={columns[7]}>\n <a href=\"#\">\n <TableText wrapModifier=\"truncate\">{row.url} </TableText>\n </a>\n </Td>\n </Tr>\n ))}\n </Tbody>\n </Table>\n </PageSection>\n </DashboardWrapper>\n );\n};\n","title":"Sticky header","lang":"js","isFullscreen":true,"className":""}}>
283
+
284
+ </Example>,
285
+ 'Sticky first column': props =>
286
+ <Example {...pageData} {...props} thumbnail={srcImportstickyfirstcolumn} {...{"code":"import { useState } from 'react';\nimport { Table, Thead, Tr, Th, Tbody, Td, InnerScrollContainer } from '@patternfly/react-table';\nimport { PageSection } from '@patternfly/react-core';\nimport { DashboardWrapper } from '@patternfly/react-table/dist/esm/demos/DashboardWrapper';\n\ntype Direction = 'asc' | 'desc' | undefined;\n\ninterface Fact {\n name: string;\n state: string;\n detail1: string;\n detail2: string;\n detail3: string;\n detail4: string;\n detail5: string;\n detail6: string;\n detail7: string;\n detail8: string;\n detail9: string;\n detail10: string;\n detail11: string;\n detail12: string;\n detail13: string;\n detail14: string;\n}\n\nexport const TableStickyFirstColumn = () => {\n const facts = Array.from(\n {\n length: 9\n },\n (_, index) => ({\n name: `Fact ${index + 1}`,\n state: `State ${index + 1}`,\n detail1: `Test cell ${index + 1}-3`,\n detail2: `Test cell ${index + 1}-4`,\n detail3: `Test cell ${index + 1}-5`,\n detail4: `Test cell ${index + 1}-6`,\n detail5: `Test cell ${index + 1}-7`,\n detail6: `Test cell ${index + 1}-8`,\n detail7: `Test cell ${index + 1}-9`,\n detail8: `Test cell ${index + 1}-10`,\n detail9: `Test cell ${index + 1}-11`,\n detail10: `Test cell ${index + 1}-12`,\n detail11: `Test cell ${index + 1}-13`,\n detail12: `Test cell ${index + 1}-14`,\n detail13: `Test cell ${index + 1}-15`,\n detail14: `Test cell ${index + 1}-16`\n })\n );\n const columnNames = {\n name: 'Fact',\n state: 'State',\n header3: 'Header 3',\n header4: 'Header 4',\n header5: 'Header 5',\n header6: 'Header 6',\n header7: 'Header 7',\n header8: 'Header 8',\n header9: 'Header 9',\n header10: 'Header 10',\n header11: 'Header 11',\n header12: 'Header 12',\n header13: 'Header 13',\n header14: 'Header 14',\n header15: 'Header 15',\n header16: 'Header 16'\n };\n\n const [activeSortIndex, setActiveSortIndex] = useState(-1);\n const [activeSortDirection, setActiveSortDirection] = useState<Direction>('asc');\n const getSortableRowValues = (fact: Fact) => {\n const {\n name,\n state,\n detail1,\n detail2,\n detail3,\n detail4,\n detail5,\n detail6,\n detail7,\n detail8,\n detail9,\n detail10,\n detail11,\n detail12,\n detail13,\n detail14\n } = fact;\n return [\n name,\n state,\n detail1,\n detail2,\n detail3,\n detail4,\n detail5,\n detail6,\n detail7,\n detail8,\n detail9,\n detail10,\n detail11,\n detail12,\n detail13,\n detail14\n ];\n };\n let sortedFacts = facts;\n if (activeSortIndex > -1) {\n sortedFacts = facts.sort((a, b) => {\n const aValue = getSortableRowValues(a)[activeSortIndex];\n const bValue = getSortableRowValues(b)[activeSortIndex];\n if (aValue === bValue) {\n return 0;\n }\n if (activeSortDirection === 'asc') {\n return aValue > bValue ? 1 : -1;\n } else {\n return bValue > aValue ? 1 : -1;\n }\n });\n }\n const getSortParams = (columnIndex: number) => ({\n sortBy: {\n index: activeSortIndex,\n direction: activeSortDirection\n },\n onSort: (_event: React.MouseEvent, index: number, direction: Direction) => {\n setActiveSortIndex(index);\n setActiveSortDirection(direction);\n },\n columnIndex\n });\n return (\n <DashboardWrapper hasPageTemplateTitle>\n <PageSection\n isWidthLimited\n padding={{ default: 'noPadding', xl: 'padding' }}\n aria-label=\"Sticky column table data\"\n >\n <InnerScrollContainer>\n <Table aria-label=\"Sticky column table\" gridBreakPoint=\"\">\n <Thead>\n <Tr>\n <Th isStickyColumn stickyMinWidth=\"100px\" hasRightBorder modifier=\"fitContent\" sort={getSortParams(0)}>\n {columnNames.name}\n </Th>\n <Th modifier=\"fitContent\" sort={getSortParams(1)}>\n {columnNames.state}\n </Th>\n <Th>{columnNames.header3}</Th>\n <Th>{columnNames.header4}</Th>\n <Th>{columnNames.header5}</Th>\n <Th>{columnNames.header6}</Th>\n <Th>{columnNames.header7}</Th>\n <Th>{columnNames.header8}</Th>\n <Th>{columnNames.header9}</Th>\n <Th>{columnNames.header10}</Th>\n <Th>{columnNames.header11}</Th>\n <Th>{columnNames.header12}</Th>\n <Th>{columnNames.header13}</Th>\n <Th>{columnNames.header14}</Th>\n <Th>{columnNames.header15}</Th>\n <Th>{columnNames.header16}</Th>\n </Tr>\n </Thead>\n <Tbody>\n {sortedFacts.map((fact) => (\n <Tr key={fact.name}>\n <Th isStickyColumn stickyMinWidth=\"100px\" hasRightBorder modifier=\"truncate\">\n {fact.name}\n </Th>\n <Td modifier=\"nowrap\" dataLabel={columnNames.state}>\n {fact.state}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header3}>\n {fact.detail1}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header4}>\n {fact.detail2}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header5}>\n {fact.detail3}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header6}>\n {fact.detail4}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header7}>\n {fact.detail5}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header8}>\n {fact.detail6}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header9}>\n {fact.detail7}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header10}>\n {fact.detail8}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header11}>\n {fact.detail9}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header12}>\n {fact.detail10}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header13}>\n {fact.detail11}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header14}>\n {fact.detail12}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header15}>\n {fact.detail13}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header16}>\n {fact.detail14}\n </Td>\n </Tr>\n ))}\n </Tbody>\n </Table>\n </InnerScrollContainer>\n </PageSection>\n </DashboardWrapper>\n );\n};\n","title":"Sticky first column","lang":"js","isFullscreen":true,"className":""}}>
287
+
288
+ </Example>,
289
+ 'Sticky columns and header with toolbar': props =>
290
+ <Example {...pageData} {...props} thumbnail={srcImportstickycolumnsandheaderwithtoolbar} {...{"code":"import { useState } from 'react';\nimport {\n Table,\n Thead,\n Tr,\n Th,\n Tbody,\n Td,\n InnerScrollContainer,\n OuterScrollContainer,\n ThProps,\n ISortBy\n} from '@patternfly/react-table';\nimport RhUiBlueprintIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-blueprint-icon';\n\ninterface Fact {\n name: string;\n state: string;\n detail1: string;\n detail2: string;\n detail3: string;\n detail4: string;\n detail5: string;\n detail6: string;\n detail7: string;\n}\n\nexport const TableStickyColumnsAndHeader: React.FunctionComponent = () => {\n // In real usage, this data would come from some external source like an API via props.\n const facts: Fact[] = Array.from({ length: 9 }, (_, index) => ({\n name: `Fact ${index + 1}`,\n state: `State ${index + 1}`,\n detail1: `Test cell ${index + 1}-3`,\n detail2: `Test cell ${index + 1}-4`,\n detail3: `Test cell ${index + 1}-5`,\n detail4: `Test cell ${index + 1}-6`,\n detail5: `Test cell ${index + 1}-7`,\n detail6: `Test cell ${index + 1}-8`,\n detail7: `Test cell ${index + 1}-9`\n }));\n\n const columnNames = {\n name: 'Fact',\n state: 'State',\n header3: 'Header 3',\n header4: 'Header 4',\n header5: 'Header 5',\n header6: 'Header 6',\n header7: 'Header 7',\n header8: 'Header 8',\n header9: 'Header 9'\n };\n\n // Index of the currently sorted column\n // Note: if you intend to make columns reorderable, you may instead want to use a non-numeric key\n // as the identifier of the sorted column. See the \"Compound expandable\" example.\n const [activeSortIndex, setActiveSortIndex] = useState(-1);\n\n // Sort direction of the currently sorted column\n const [activeSortDirection, setActiveSortDirection] = useState<ISortBy['direction']>();\n\n // Since OnSort specifies sorted columns by index, we need sortable values for our object by column index.\n // This example is trivial since our data objects just contain strings, but if the data was more complex\n // this would be a place to return simplified string or number versions of each column to sort by.\n const getSortableRowValues = (fact: Fact): (string | number)[] => {\n const { name, state, detail1, detail2, detail3, detail4, detail5, detail6, detail7 } = fact;\n return [name, state, detail1, detail2, detail3, detail4, detail5, detail6, detail7];\n };\n\n // Note that we perform the sort as part of the component's render logic and not in onSort.\n // We shouldn't store the list of data in state because we don't want to have to sync that with props.\n let sortedFacts = facts;\n if (activeSortIndex > -1) {\n sortedFacts = facts.sort((a, b) => {\n const aValue = getSortableRowValues(a)[activeSortIndex];\n const bValue = getSortableRowValues(b)[activeSortIndex];\n if (aValue === bValue) {\n return 0;\n }\n if (activeSortDirection === 'asc') {\n return aValue > bValue ? 1 : -1;\n } else {\n return bValue > aValue ? 1 : -1;\n }\n });\n }\n\n const getSortParams = (columnIndex: number): ThProps['sort'] => ({\n sortBy: {\n index: activeSortIndex,\n direction: activeSortDirection\n },\n onSort: (_event, index, direction) => {\n setActiveSortIndex(index);\n setActiveSortDirection(direction);\n },\n columnIndex\n });\n\n return (\n <div style={{ height: '400px' }}>\n <OuterScrollContainer>\n <InnerScrollContainer>\n <Table aria-label=\"Sticky columns and header table\" gridBreakPoint=\"\" isStickyHeader>\n <Thead>\n <Tr>\n <Th isStickyColumn modifier=\"truncate\" sort={getSortParams(0)}>\n {columnNames.name}\n </Th>\n <Th\n isStickyColumn\n stickyMinWidth=\"120px\"\n stickyLeftOffset=\"120px\"\n hasRightBorder\n modifier=\"truncate\"\n sort={getSortParams(1)}\n >\n {columnNames.state}\n </Th>\n <Th modifier=\"truncate\">{columnNames.header3}</Th>\n <Th modifier=\"truncate\">{columnNames.header4}</Th>\n <Th modifier=\"truncate\">{columnNames.header5}</Th>\n <Th modifier=\"truncate\">{columnNames.header6}</Th>\n <Th modifier=\"truncate\">{columnNames.header7}</Th>\n <Th modifier=\"truncate\">{columnNames.header8}</Th>\n <Th modifier=\"truncate\">{columnNames.header9}</Th>\n </Tr>\n </Thead>\n <Tbody>\n {sortedFacts.map((fact) => (\n <Tr key={fact.name}>\n <Th isStickyColumn modifier=\"truncate\">\n {fact.name}\n </Th>\n <Th isStickyColumn stickyMinWidth=\"120px\" stickyLeftOffset=\"120px\" modifier=\"truncate\" hasRightBorder>\n <RhUiBlueprintIcon />\n {` ${fact.state}`}\n </Th>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header3}>\n {fact.detail1}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header4}>\n {fact.detail2}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header5}>\n {fact.detail3}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header6}>\n {fact.detail4}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header7}>\n {fact.detail5}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header8}>\n {fact.detail6}\n </Td>\n <Td modifier=\"nowrap\" dataLabel={columnNames.header9}>\n {fact.detail7}\n </Td>\n </Tr>\n ))}\n </Tbody>\n </Table>\n </InnerScrollContainer>\n </OuterScrollContainer>\n </div>\n );\n};\n","title":"Sticky columns and header with toolbar","lang":"js","isFullscreen":true,"className":""}}>
291
+
292
+ <p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
293
+ {`A toolbar may be added above a sticky table either inside or outside the `}
294
+
295
+ <code {...{"className":"ws-code "}}>
296
+ {`OuterScrollContainer`}
297
+ </code>
298
+ {`.`}
299
+ </p>
300
+ </Example>,
301
+ 'Empty': props =>
302
+ <Example {...pageData} {...props} thumbnail={srcImportempty} {...{"code":"import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';\nimport {\n Bullseye,\n Button,\n EmptyState,\n EmptyStateVariant,\n EmptyStateBody,\n EmptyStateFooter,\n EmptyStateActions,\n PageSection\n} from '@patternfly/react-core';\nimport SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';\nimport { DashboardWrapper } from '@patternfly/react-table/dist/esm/demos/DashboardWrapper';\n\nexport const TableEmptyStateDefault: React.FunctionComponent = () => (\n <DashboardWrapper hasPageTemplateTitle>\n <PageSection padding={{ default: 'noPadding', xl: 'padding' }} aria-label=\"Empty state table data\">\n <Table aria-label=\"Empty state table\">\n <Thead>\n <Tr>\n <Th>Repositories</Th>\n <Th>Branches</Th>\n <Th>Pull requests</Th>\n <Th>Workspaces</Th>\n <Th>Last commit</Th>\n </Tr>\n </Thead>\n <Tbody>\n <Tr>\n <Td colSpan={8}>\n <Bullseye>\n <EmptyState\n titleText=\"No results found\"\n icon={SearchIcon}\n headingLevel=\"h2\"\n variant={EmptyStateVariant.sm}\n >\n <EmptyStateBody>\n No results match this filter criteria. Clear all filters and try again.\n </EmptyStateBody>\n <EmptyStateFooter>\n <EmptyStateActions>\n <Button variant=\"link\">Clear all filters</Button>\n </EmptyStateActions>\n </EmptyStateFooter>\n </EmptyState>\n </Bullseye>\n </Td>\n </Tr>\n </Tbody>\n </Table>\n </PageSection>\n </DashboardWrapper>\n);\n","title":"Empty","lang":"js","isFullscreen":true,"className":""}}>
303
+
304
+ </Example>,
305
+ 'Loading': props =>
306
+ <Example {...pageData} {...props} thumbnail={srcImportloading} {...{"code":"import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';\nimport { Bullseye, EmptyState, PageSection, Spinner } from '@patternfly/react-core';\nimport { DashboardWrapper } from '@patternfly/react-table/dist/esm/demos/DashboardWrapper';\n\nexport const TableEmptyStateLoading: React.FunctionComponent = () => (\n <DashboardWrapper hasPageTemplateTitle>\n <PageSection padding={{ default: 'noPadding', xl: 'padding' }} aria-label=\"Empty state table loading\">\n <Table aria-label=\"Loading table demo\">\n <Thead>\n <Tr>\n <Th>Repositories</Th>\n <Th>Branches</Th>\n <Th>Pull requests</Th>\n <Th>Workspaces</Th>\n <Th>Last commit</Th>\n </Tr>\n </Thead>\n <Tbody>\n <Tr>\n <Td colSpan={8}>\n <Bullseye>\n <EmptyState titleText=\"Loading\" icon={Spinner} headingLevel=\"h2\" />\n </Bullseye>\n </Td>\n </Tr>\n </Tbody>\n </Table>\n </PageSection>\n </DashboardWrapper>\n);\n","title":"Loading","lang":"js","isFullscreen":true,"className":""}}>
307
+
308
+ </Example>,
309
+ 'Error': props =>
310
+ <Example {...pageData} {...props} thumbnail={srcImporterror} {...{"code":"import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';\nimport { Bullseye, EmptyState, EmptyStateVariant, EmptyStateBody, PageSection } from '@patternfly/react-core';\nimport RhUiErrorFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-error-fill-icon';\nimport { DashboardWrapper } from '@patternfly/react-table/dist/esm/demos/DashboardWrapper';\n\nexport const TableEmptyStateError: React.FunctionComponent = () => (\n <DashboardWrapper hasPageTemplateTitle>\n <PageSection padding={{ default: 'noPadding', xl: 'padding' }} aria-label=\"Empty state table with error\">\n <Table aria-label=\"Loading table demo\">\n <Thead>\n <Tr>\n <Th>Repositories</Th>\n <Th>Branches</Th>\n <Th>Pull requests</Th>\n <Th>Workspaces</Th>\n <Th>Last commit</Th>\n </Tr>\n </Thead>\n <Tbody>\n <Tr>\n <Td colSpan={8}>\n <Bullseye>\n <EmptyState\n icon={RhUiErrorFillIcon}\n titleText=\"Unable to connect\"\n headingLevel=\"h2\"\n variant={EmptyStateVariant.sm}\n >\n <EmptyStateBody>\n There was an error retrieving data. Check your connection and reload the page.\n </EmptyStateBody>\n </EmptyState>\n </Bullseye>\n </Td>\n </Tr>\n </Tbody>\n </Table>\n </PageSection>\n </DashboardWrapper>\n);\n","title":"Error","lang":"js","isFullscreen":true,"className":""}}>
311
+
312
+ </Example>
313
+ };
314
+
315
+ const Component = () => (
316
+ <React.Fragment>
317
+ <AutoLinkHeader {...{"id":"demos","headingLevel":"h2","className":"ws-title ws-h2"}}>
318
+ {`Demos`}
319
+ </AutoLinkHeader>
320
+ {React.createElement(pageData.examples["Bulk select"])}
321
+ {React.createElement(pageData.examples["Expand/collapse all"])}
322
+ {React.createElement(pageData.examples["Compact"])}
323
+ {React.createElement(pageData.examples["Compound expansion"])}
324
+ {React.createElement(pageData.examples["Column management"])}
325
+ {React.createElement(pageData.examples["Column management with draggable"])}
326
+ {React.createElement(pageData.examples["Filterable"])}
327
+ {React.createElement(pageData.examples["Sortable - responsive"])}
328
+ {React.createElement(pageData.examples["Automatic pagination"])}
329
+ {React.createElement(pageData.examples["Static bottom pagination on mobile"])}
330
+ {React.createElement(pageData.examples["Sticky header"])}
331
+ {React.createElement(pageData.examples["Sticky first column"])}
332
+ {React.createElement(pageData.examples["Sticky columns and header with toolbar"])}
333
+ <AutoLinkHeader {...{"id":"empty-states","headingLevel":"h2","className":"ws-title ws-h2"}}>
334
+ {`Empty states`}
335
+ </AutoLinkHeader>
336
+ <p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
337
+ {`These examples demonstrate the use of an `}
338
+ <PatternflyThemeLink {...{"to":"/components/empty-state","className":""}}>
339
+ {`Empty State component`}
340
+ </PatternflyThemeLink>
341
+ {` inside of a `}
342
+ <PatternflyThemeLink {...{"to":"/components/table","className":""}}>
343
+ {`Table`}
344
+ </PatternflyThemeLink>
345
+ {`. Empty states are useful in a table when a filter returns no results, while data is loading, or when any type of error or exception condition occurs.`}
346
+ </p>
347
+ {React.createElement(pageData.examples["Empty"])}
348
+ {React.createElement(pageData.examples["Loading"])}
349
+ {React.createElement(pageData.examples["Error"])}
350
+ </React.Fragment>
351
+ );
352
+ Component.displayName = 'ComponentsTableReactDemosDocs';
353
+ Component.pageData = pageData;
354
+
355
+ export default Component;