@patternfly/react-table 6.0.0-alpha.2 → 6.0.0-alpha.21

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 (178) hide show
  1. package/CHANGELOG.md +316 -0
  2. package/components/package.json +1 -1
  3. package/deprecated/package.json +1 -1
  4. package/dist/dynamic/components/Table/package.json +1 -1
  5. package/dist/dynamic/components/Table/utils/decorators/package.json +1 -1
  6. package/dist/dynamic/components/Table/utils/package.json +1 -1
  7. package/dist/dynamic/deprecated/components/Table/base/package.json +1 -1
  8. package/dist/dynamic/deprecated/components/Table/package.json +1 -1
  9. package/dist/dynamic/deprecated/components/package.json +1 -1
  10. package/dist/esm/components/Table/Caption.js +1 -1
  11. package/dist/esm/components/Table/Caption.js.map +1 -1
  12. package/dist/esm/components/Table/CollapseColumn.js +1 -1
  13. package/dist/esm/components/Table/CollapseColumn.js.map +1 -1
  14. package/dist/esm/components/Table/DraggableRowWrapper.js +2 -2
  15. package/dist/esm/components/Table/DraggableRowWrapper.js.map +1 -1
  16. package/dist/esm/components/Table/EditColumn.js +1 -1
  17. package/dist/esm/components/Table/EditColumn.js.map +1 -1
  18. package/dist/esm/components/Table/EditableSelectInputCell.js +3 -3
  19. package/dist/esm/components/Table/EditableSelectInputCell.js.map +1 -1
  20. package/dist/esm/components/Table/EditableTextCell.js +3 -3
  21. package/dist/esm/components/Table/EditableTextCell.js.map +1 -1
  22. package/dist/esm/components/Table/ExpandableRowContent.js +1 -1
  23. package/dist/esm/components/Table/ExpandableRowContent.js.map +1 -1
  24. package/dist/esm/components/Table/HeaderCellInfoWrapper.js +1 -1
  25. package/dist/esm/components/Table/HeaderCellInfoWrapper.js.map +1 -1
  26. package/dist/esm/components/Table/InnerScrollContainer.js +1 -1
  27. package/dist/esm/components/Table/InnerScrollContainer.js.map +1 -1
  28. package/dist/esm/components/Table/OuterScrollContainer.js +1 -1
  29. package/dist/esm/components/Table/OuterScrollContainer.js.map +1 -1
  30. package/dist/esm/components/Table/SelectColumn.d.ts +5 -0
  31. package/dist/esm/components/Table/SelectColumn.d.ts.map +1 -1
  32. package/dist/esm/components/Table/SelectColumn.js +6 -3
  33. package/dist/esm/components/Table/SelectColumn.js.map +1 -1
  34. package/dist/esm/components/Table/SortColumn.d.ts +4 -0
  35. package/dist/esm/components/Table/SortColumn.d.ts.map +1 -1
  36. package/dist/esm/components/Table/SortColumn.js +3 -3
  37. package/dist/esm/components/Table/SortColumn.js.map +1 -1
  38. package/dist/esm/components/Table/Table.js +3 -3
  39. package/dist/esm/components/Table/Table.js.map +1 -1
  40. package/dist/esm/components/Table/TableText.d.ts +3 -1
  41. package/dist/esm/components/Table/TableText.d.ts.map +1 -1
  42. package/dist/esm/components/Table/TableText.js +13 -11
  43. package/dist/esm/components/Table/TableText.js.map +1 -1
  44. package/dist/esm/components/Table/TableTypes.d.ts +3 -0
  45. package/dist/esm/components/Table/TableTypes.d.ts.map +1 -1
  46. package/dist/esm/components/Table/Tbody.js +1 -1
  47. package/dist/esm/components/Table/Tbody.js.map +1 -1
  48. package/dist/esm/components/Table/Td.js +3 -3
  49. package/dist/esm/components/Table/Td.js.map +1 -1
  50. package/dist/esm/components/Table/Th.d.ts +3 -0
  51. package/dist/esm/components/Table/Th.d.ts.map +1 -1
  52. package/dist/esm/components/Table/Th.js +16 -9
  53. package/dist/esm/components/Table/Th.js.map +1 -1
  54. package/dist/esm/components/Table/Thead.js +1 -1
  55. package/dist/esm/components/Table/Thead.js.map +1 -1
  56. package/dist/esm/components/Table/Tr.js +2 -2
  57. package/dist/esm/components/Table/Tr.js.map +1 -1
  58. package/dist/esm/components/Table/TreeRowWrapper.js +2 -2
  59. package/dist/esm/components/Table/TreeRowWrapper.js.map +1 -1
  60. package/dist/esm/components/Table/utils/decorators/cellActions.js +1 -1
  61. package/dist/esm/components/Table/utils/decorators/cellActions.js.map +1 -1
  62. package/dist/esm/components/Table/utils/decorators/cellWidth.js +1 -1
  63. package/dist/esm/components/Table/utils/decorators/cellWidth.js.map +1 -1
  64. package/dist/esm/components/Table/utils/decorators/classNames.js +1 -1
  65. package/dist/esm/components/Table/utils/decorators/classNames.js.map +1 -1
  66. package/dist/esm/components/Table/utils/decorators/collapsible.js +1 -1
  67. package/dist/esm/components/Table/utils/decorators/collapsible.js.map +1 -1
  68. package/dist/esm/components/Table/utils/decorators/compoundExpand.js +1 -1
  69. package/dist/esm/components/Table/utils/decorators/compoundExpand.js.map +1 -1
  70. package/dist/esm/components/Table/utils/decorators/editable.js +1 -1
  71. package/dist/esm/components/Table/utils/decorators/editable.js.map +1 -1
  72. package/dist/esm/components/Table/utils/decorators/favoritable.js +1 -1
  73. package/dist/esm/components/Table/utils/decorators/favoritable.js.map +1 -1
  74. package/dist/esm/components/Table/utils/decorators/info.js +1 -1
  75. package/dist/esm/components/Table/utils/decorators/info.js.map +1 -1
  76. package/dist/esm/components/Table/utils/decorators/selectable.d.ts.map +1 -1
  77. package/dist/esm/components/Table/utils/decorators/selectable.js +4 -4
  78. package/dist/esm/components/Table/utils/decorators/selectable.js.map +1 -1
  79. package/dist/esm/components/Table/utils/decorators/sortable.d.ts.map +1 -1
  80. package/dist/esm/components/Table/utils/decorators/sortable.js +7 -4
  81. package/dist/esm/components/Table/utils/decorators/sortable.js.map +1 -1
  82. package/dist/esm/components/Table/utils/decorators/treeRow.js +2 -2
  83. package/dist/esm/components/Table/utils/decorators/treeRow.js.map +1 -1
  84. package/dist/esm/components/Table/utils/decorators/wrappable.js +1 -1
  85. package/dist/esm/components/Table/utils/decorators/wrappable.js.map +1 -1
  86. package/dist/esm/demos/index.d.ts +2 -0
  87. package/dist/esm/demos/index.d.ts.map +1 -0
  88. package/dist/esm/demos/index.js +2 -0
  89. package/dist/esm/demos/index.js.map +1 -0
  90. package/dist/esm/demos/sampleData.d.ts +13 -0
  91. package/dist/esm/demos/sampleData.d.ts.map +1 -0
  92. package/dist/esm/demos/sampleData.js +764 -0
  93. package/dist/esm/demos/sampleData.js.map +1 -0
  94. package/dist/esm/deprecated/components/Table/Table.js +1 -1
  95. package/dist/esm/deprecated/components/Table/Table.js.map +1 -1
  96. package/dist/esm/index.d.ts +1 -0
  97. package/dist/esm/index.d.ts.map +1 -1
  98. package/dist/esm/index.js +1 -0
  99. package/dist/esm/index.js.map +1 -1
  100. package/dist/js/components/Table/EditableSelectInputCell.js +1 -1
  101. package/dist/js/components/Table/EditableSelectInputCell.js.map +1 -1
  102. package/dist/js/components/Table/EditableTextCell.js +1 -1
  103. package/dist/js/components/Table/EditableTextCell.js.map +1 -1
  104. package/dist/js/components/Table/SelectColumn.d.ts +5 -0
  105. package/dist/js/components/Table/SelectColumn.d.ts.map +1 -1
  106. package/dist/js/components/Table/SelectColumn.js +6 -3
  107. package/dist/js/components/Table/SelectColumn.js.map +1 -1
  108. package/dist/js/components/Table/SortColumn.d.ts +4 -0
  109. package/dist/js/components/Table/SortColumn.d.ts.map +1 -1
  110. package/dist/js/components/Table/SortColumn.js +3 -2
  111. package/dist/js/components/Table/SortColumn.js.map +1 -1
  112. package/dist/js/components/Table/TableText.d.ts +3 -1
  113. package/dist/js/components/Table/TableText.d.ts.map +1 -1
  114. package/dist/js/components/Table/TableText.js +12 -10
  115. package/dist/js/components/Table/TableText.js.map +1 -1
  116. package/dist/js/components/Table/TableTypes.d.ts +3 -0
  117. package/dist/js/components/Table/TableTypes.d.ts.map +1 -1
  118. package/dist/js/components/Table/Th.d.ts +3 -0
  119. package/dist/js/components/Table/Th.d.ts.map +1 -1
  120. package/dist/js/components/Table/Th.js +14 -7
  121. package/dist/js/components/Table/Th.js.map +1 -1
  122. package/dist/js/components/Table/utils/decorators/selectable.d.ts.map +1 -1
  123. package/dist/js/components/Table/utils/decorators/selectable.js +2 -2
  124. package/dist/js/components/Table/utils/decorators/selectable.js.map +1 -1
  125. package/dist/js/components/Table/utils/decorators/sortable.d.ts.map +1 -1
  126. package/dist/js/components/Table/utils/decorators/sortable.js +6 -3
  127. package/dist/js/components/Table/utils/decorators/sortable.js.map +1 -1
  128. package/dist/js/demos/index.d.ts +2 -0
  129. package/dist/js/demos/index.d.ts.map +1 -0
  130. package/dist/js/demos/index.js +5 -0
  131. package/dist/js/demos/index.js.map +1 -0
  132. package/dist/js/demos/sampleData.d.ts +13 -0
  133. package/dist/js/demos/sampleData.d.ts.map +1 -0
  134. package/dist/js/demos/sampleData.js +767 -0
  135. package/dist/js/demos/sampleData.js.map +1 -0
  136. package/dist/js/index.d.ts +1 -0
  137. package/dist/js/index.d.ts.map +1 -1
  138. package/dist/js/index.js +1 -0
  139. package/dist/js/index.js.map +1 -1
  140. package/dist/umd/react-table.min.js +3 -3
  141. package/package.json +6 -6
  142. package/single-packages.config.json +3 -6
  143. package/src/components/Table/EditableSelectInputCell.tsx +1 -1
  144. package/src/components/Table/EditableTextCell.tsx +1 -1
  145. package/src/components/Table/SelectColumn.tsx +27 -8
  146. package/src/components/Table/SortColumn.tsx +15 -1
  147. package/src/components/Table/TableText.tsx +19 -9
  148. package/src/components/Table/TableTypes.tsx +3 -0
  149. package/src/components/Table/Th.tsx +16 -5
  150. package/src/components/Table/examples/TableEmptyState.tsx +1 -8
  151. package/src/components/Table/examples/TableStickyColumnsAndHeader.tsx +5 -4
  152. package/src/components/Table/utils/decorators/selectable.tsx +2 -1
  153. package/src/components/Table/utils/decorators/sortable.tsx +8 -2
  154. package/src/components/Table/utils/transformers.test.tsx +1 -0
  155. package/src/demos/Table.md +159 -0
  156. package/src/demos/examples/TableAutomaticPagination.tsx +101 -0
  157. package/src/{docs/demos/table-demos/BulkSelect.jsx → demos/examples/TableBulkSelect.tsx} +42 -21
  158. package/src/demos/examples/TableColumnManagement.tsx +486 -0
  159. package/src/demos/examples/TableColumnManagementWithDraggable.tsx +641 -0
  160. package/src/{docs/demos/table-demos/Compact.jsx → demos/examples/TableCompact.tsx} +32 -16
  161. package/src/{docs/demos/table-demos/CompoundExpansion.jsx → demos/examples/TableCompoundExpansion.tsx} +25 -12
  162. package/src/demos/examples/TableEmptyStateDefault.tsx +58 -0
  163. package/src/demos/examples/TableEmptyStateError.tsx +42 -0
  164. package/src/demos/examples/TableEmptyStateLoading.tsx +33 -0
  165. package/src/{docs/demos/table-demos/ExpandCollapseAll.jsx → demos/examples/TableExpandCollapseAll.tsx} +17 -10
  166. package/src/demos/examples/TableFilterable.tsx +387 -0
  167. package/src/{docs/demos/table-demos/SortableResponsive.jsx → demos/examples/TableSortableResponsive.tsx} +31 -28
  168. package/src/{docs/demos/table-demos/StaticBottomPagination.jsx → demos/examples/TableStaticBottomPagination.tsx} +22 -9
  169. package/src/{docs/demos/table-demos/StickyFirstColumn.jsx → demos/examples/TableStickyFirstColumn.tsx} +31 -9
  170. package/src/{docs/demos/table-demos/StickyHeader.jsx → demos/examples/TableStickyHeader.tsx} +3 -3
  171. package/src/demos/index.ts +1 -0
  172. package/src/{docs/demos/table-demos/sampleData.js → demos/sampleData.tsx} +88 -77
  173. package/src/deprecated/components/Table/__tests__/Table.test.tsx +4 -9
  174. package/src/deprecated/components/Table/__tests__/__snapshots__/Table.test.tsx.snap +8 -8
  175. package/src/deprecated/components/Table/examples/LegacyTableEmptyState.tsx +6 -8
  176. package/src/index.ts +1 -0
  177. package/src/docs/demos/Table.md +0 -1620
  178. package/src/docs/demos/table-demos/ColumnManagement.jsx +0 -471
@@ -0,0 +1,387 @@
1
+ import React from 'react';
2
+ import {
3
+ Badge,
4
+ Button,
5
+ Bullseye,
6
+ EmptyState,
7
+ EmptyStateActions,
8
+ EmptyStateBody,
9
+ EmptyStateFooter,
10
+ Label,
11
+ MenuToggle,
12
+ MenuToggleElement,
13
+ Toolbar,
14
+ ToolbarItem,
15
+ ToolbarContent,
16
+ ToolbarFilter,
17
+ ToolbarToggleGroup,
18
+ ToolbarGroup,
19
+ Select,
20
+ SelectOption,
21
+ SearchInput,
22
+ ToolbarChipGroup
23
+ } from '@patternfly/react-core';
24
+ import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
25
+ import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
26
+ import { Table, TableText, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';
27
+ import { rows, columns } from '@patternfly/react-table/dist/esm/demos/sampleData';
28
+
29
+ export const TableFilterable: React.FunctionComponent = () => {
30
+ const [filters, setFilters] = React.useState<Record<string, string[]>>({ location: [], name: [], status: [] });
31
+ const [currentCategory, setCurrentCategory] = React.useState('Status');
32
+ const [isFilterDropdownOpen, setIsFilterDropdownOpen] = React.useState(false);
33
+ const [isCategoryDropdownOpen, setIsCategoryDropdownOpen] = React.useState(false);
34
+ const [inputValue, setInputValue] = React.useState('');
35
+
36
+ const rowData = rows.slice(0, 10);
37
+
38
+ const onDelete = (type: string | ToolbarChipGroup, id: string) => {
39
+ if (type === 'Location') {
40
+ setFilters({
41
+ ...filters,
42
+ location: filters.location.filter((fil: string) => fil !== id)
43
+ });
44
+ } else if (type === 'Name') {
45
+ setFilters({
46
+ ...filters,
47
+ name: filters.name.filter((fil: string) => fil !== id)
48
+ });
49
+ } else if (type === 'Status') {
50
+ setFilters({
51
+ ...filters,
52
+ status: filters.status.filter((fil: string) => fil !== id)
53
+ });
54
+ } else {
55
+ setFilters({ location: [], name: [], status: [] });
56
+ }
57
+ };
58
+
59
+ const onCategoryToggle = () => {
60
+ setIsCategoryDropdownOpen(!isCategoryDropdownOpen);
61
+ };
62
+
63
+ const onCategorySelect = (event: React.MouseEvent<Element, MouseEvent>, value: string) => {
64
+ setCurrentCategory(value);
65
+ setIsCategoryDropdownOpen(false);
66
+ };
67
+
68
+ const onFilterToggle = () => {
69
+ setIsFilterDropdownOpen(!isFilterDropdownOpen);
70
+ };
71
+
72
+ const onFilterSelect = () => {
73
+ setIsFilterDropdownOpen(!isFilterDropdownOpen);
74
+ };
75
+
76
+ const onInputChange = (newValue: string) => {
77
+ setInputValue(newValue);
78
+ };
79
+
80
+ const onStatusSelect = (event: React.MouseEvent<Element, MouseEvent>, selection: string) => {
81
+ const checked = (event.target as HTMLInputElement).checked;
82
+ setFilters({
83
+ ...filters,
84
+ status: checked ? [...filters.status, selection] : filters.status.filter((value) => value !== selection)
85
+ });
86
+ setIsFilterDropdownOpen(false);
87
+ };
88
+
89
+ const onNameInput = (event: React.KeyboardEvent) => {
90
+ if (event.key && event.key !== 'Enter') {
91
+ return;
92
+ }
93
+
94
+ const prevFilters = filters.name;
95
+ setFilters({ ...filters, name: prevFilters.includes(inputValue) ? prevFilters : [...prevFilters, inputValue] });
96
+ };
97
+
98
+ const onLocationSelect = (event: React.MouseEvent<Element, MouseEvent>, selection: string) => {
99
+ setFilters({ ...filters, location: [selection] });
100
+
101
+ setIsFilterDropdownOpen(false);
102
+ onFilterSelect();
103
+ };
104
+
105
+ const buildCategoryDropdown = () => {
106
+ const categoryMenuItems = [
107
+ <SelectOption key="cat1" value="Location">
108
+ Location
109
+ </SelectOption>,
110
+ <SelectOption key="cat2" value="Name">
111
+ Name
112
+ </SelectOption>,
113
+ <SelectOption key="cat3" value="Status">
114
+ Status
115
+ </SelectOption>
116
+ ];
117
+
118
+ return (
119
+ <ToolbarItem>
120
+ <Select
121
+ onSelect={onCategorySelect}
122
+ selected={currentCategory}
123
+ toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
124
+ <MenuToggle
125
+ ref={toggleRef}
126
+ onClick={onCategoryToggle}
127
+ isExpanded={isCategoryDropdownOpen}
128
+ icon={<FilterIcon />}
129
+ style={
130
+ {
131
+ width: '100%',
132
+ verticalAlign: 'text-bottom'
133
+ } as React.CSSProperties
134
+ }
135
+ >
136
+ {currentCategory}
137
+ </MenuToggle>
138
+ )}
139
+ isOpen={isCategoryDropdownOpen}
140
+ >
141
+ {categoryMenuItems}
142
+ </Select>
143
+ </ToolbarItem>
144
+ );
145
+ };
146
+
147
+ const buildFilterDropdown = () => {
148
+ const locationMenuItems = [
149
+ <SelectOption key="raleigh" value="Raleigh">
150
+ Raleigh
151
+ </SelectOption>,
152
+ <SelectOption key="san francisco" value="San Francisco">
153
+ San Francisco
154
+ </SelectOption>,
155
+ <SelectOption key="boston" value="Boston">
156
+ Boston
157
+ </SelectOption>,
158
+ <SelectOption key="atlanta" value="Atlanta">
159
+ Atlanta
160
+ </SelectOption>
161
+ ];
162
+
163
+ const statusMenuItems = [
164
+ <SelectOption hasCheckbox key="statusRunning" value="Running" isSelected={filters.status.includes('Running')}>
165
+ Running
166
+ </SelectOption>,
167
+ <SelectOption hasCheckbox key="statusStopped" value="Stopped" isSelected={filters.status.includes('Stopped')}>
168
+ Stopped
169
+ </SelectOption>,
170
+ <SelectOption hasCheckbox key="statusDown" value="Down" isSelected={filters.status.includes('Down')}>
171
+ Down
172
+ </SelectOption>,
173
+ <SelectOption hasCheckbox key="statusDegraded" value="Degraded" isSelected={filters.status.includes('Degraded')}>
174
+ Degraded
175
+ </SelectOption>,
176
+ <SelectOption
177
+ hasCheckbox
178
+ key="statusMaint"
179
+ value="Needs maintenance"
180
+ isSelected={filters.status.includes('Needs maintenance')}
181
+ >
182
+ Needs maintenance
183
+ </SelectOption>
184
+ ];
185
+
186
+ return (
187
+ <React.Fragment>
188
+ <ToolbarFilter
189
+ chips={filters.location}
190
+ deleteChip={(category, chip) => onDelete(category, chip as string)}
191
+ categoryName="Location"
192
+ showToolbarItem={currentCategory === 'Location'}
193
+ >
194
+ <Select
195
+ aria-label="Location"
196
+ onSelect={onLocationSelect}
197
+ selected={filters.location[0]}
198
+ isOpen={isFilterDropdownOpen}
199
+ popperProps={{ minWidth: '100px' }}
200
+ toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
201
+ <MenuToggle
202
+ ref={toggleRef}
203
+ onClick={onFilterToggle}
204
+ isExpanded={isFilterDropdownOpen}
205
+ style={
206
+ {
207
+ width: '100%',
208
+ verticalAlign: 'text-bottom'
209
+ } as React.CSSProperties
210
+ }
211
+ >
212
+ {filters.location[0] || `Any`}
213
+ </MenuToggle>
214
+ )}
215
+ >
216
+ {locationMenuItems}
217
+ </Select>
218
+ </ToolbarFilter>
219
+ <ToolbarFilter
220
+ chips={filters.name}
221
+ deleteChip={(category, chip) => onDelete(category, chip as string)}
222
+ categoryName="Name"
223
+ showToolbarItem={currentCategory === 'Name'}
224
+ >
225
+ <SearchInput
226
+ aria-label="name filter"
227
+ placeholder="Filter by name..."
228
+ onChange={(_event, value) => onInputChange(value)}
229
+ value={inputValue}
230
+ onClear={() => {
231
+ onInputChange('');
232
+ }}
233
+ onSearch={onNameInput}
234
+ />
235
+ </ToolbarFilter>
236
+ <ToolbarFilter
237
+ chips={filters.status}
238
+ deleteChip={(category, chip) => onDelete(category, chip as string)}
239
+ categoryName="Status"
240
+ showToolbarItem={currentCategory === 'Status'}
241
+ >
242
+ <Select
243
+ aria-label="Status"
244
+ isOpen={isFilterDropdownOpen}
245
+ popperProps={{ minWidth: '100px' }}
246
+ onSelect={onStatusSelect}
247
+ selected={filters.status}
248
+ toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
249
+ <MenuToggle
250
+ ref={toggleRef}
251
+ onClick={onFilterToggle}
252
+ isExpanded={isFilterDropdownOpen}
253
+ style={
254
+ {
255
+ width: '100%',
256
+ verticalAlign: 'text-bottom'
257
+ } as React.CSSProperties
258
+ }
259
+ >
260
+ Filter by status
261
+ {filters.status.length > 0 && <Badge isRead>{filters.status.length}</Badge>}
262
+ </MenuToggle>
263
+ )}
264
+ >
265
+ {statusMenuItems}
266
+ </Select>
267
+ </ToolbarFilter>
268
+ </React.Fragment>
269
+ );
270
+ };
271
+
272
+ const renderToolbar = () => (
273
+ <Toolbar
274
+ id="toolbar-with-chip-groups"
275
+ clearAllFilters={() => setFilters({ location: [], name: [], status: [] })}
276
+ collapseListedFiltersBreakpoint="xl"
277
+ >
278
+ <ToolbarContent>
279
+ <ToolbarToggleGroup toggleIcon={<FilterIcon />} breakpoint="xl">
280
+ <ToolbarGroup
281
+ variant="filter-group"
282
+ style={
283
+ {
284
+ lineHeight: '22px',
285
+ alignItems: 'center'
286
+ } as React.CSSProperties
287
+ }
288
+ >
289
+ {buildCategoryDropdown()}
290
+ {buildFilterDropdown()}
291
+ </ToolbarGroup>
292
+ </ToolbarToggleGroup>
293
+ </ToolbarContent>
294
+ </Toolbar>
295
+ );
296
+
297
+ const filteredRows =
298
+ filters.name.length > 0 || filters.location.length > 0 || filters.status.length > 0
299
+ ? rowData.filter(
300
+ (row) =>
301
+ (filters.name.length === 0 ||
302
+ filters.name.some((name) => row.name.toLowerCase().includes(name.toLowerCase()))) &&
303
+ (filters.location.length === 0 || filters.location.includes(row.location)) &&
304
+ (filters.status.length === 0 || filters.status.includes(row.status))
305
+ )
306
+ : rowData;
307
+
308
+ const emptyState = (
309
+ <EmptyState headingLevel="h5" titleText="Clear all filters and try again." icon={SearchIcon}>
310
+ <EmptyStateBody>No results match the filter criteria. Clear all filters and try again.</EmptyStateBody>
311
+ <EmptyStateFooter>
312
+ <EmptyStateActions>
313
+ <Button
314
+ variant="link"
315
+ onClick={() => {
316
+ setFilters({ location: [], name: [], status: [] });
317
+ }}
318
+ >
319
+ Clear all filters
320
+ </Button>
321
+ </EmptyStateActions>
322
+ </EmptyStateFooter>
323
+ </EmptyState>
324
+ );
325
+
326
+ const renderLabel = (labelText: string) => {
327
+ switch (labelText) {
328
+ case 'Running':
329
+ return <Label color="green">{labelText}</Label>;
330
+ case 'Stopped':
331
+ return <Label color="orange">{labelText}</Label>;
332
+ case 'Needs maintenance':
333
+ return <Label color="blue">{labelText}</Label>;
334
+ case 'Down':
335
+ return <Label color="red">{labelText}</Label>;
336
+ }
337
+ };
338
+
339
+ return (
340
+ <React.Fragment>
341
+ {renderToolbar()}
342
+ <Table aria-label="Filterable Table Demo">
343
+ <Thead>
344
+ <Tr>
345
+ <Th key={0}>{columns[0]}</Th>
346
+ <Th key={1}>{columns[1]}</Th>
347
+ <Th key={2}>{columns[2]}</Th>
348
+ <Th key={3}>{columns[3]}</Th>
349
+ <Th key={4}>{columns[4]}</Th>
350
+ <Th key={5}>{columns[5]}</Th>
351
+ <Th key={6}>{columns[6]}</Th>
352
+ <Th key={7} width={10}>
353
+ {columns[7]}
354
+ </Th>
355
+ </Tr>
356
+ </Thead>
357
+ <Tbody>
358
+ {filteredRows.slice(0, 10).map((row, rowIndex) => (
359
+ <Tr key={rowIndex}>
360
+ <>
361
+ <Td dataLabel={columns[0]}>{row.name}</Td>
362
+ <Td dataLabel={columns[1]}>{row.threads}</Td>
363
+ <Td dataLabel={columns[2]}>{row.applications}</Td>
364
+ <Td dataLabel={columns[3]}>{row.workspaces}</Td>
365
+ <Td dataLabel={columns[4]}>{renderLabel(row.status)}</Td>
366
+ <Td dataLabel={columns[5]}>{row.location}</Td>
367
+ <Td dataLabel={columns[6]}>{row.lastModified}</Td>
368
+ <Td dataLabel={columns[7]} modifier="truncate">
369
+ <TableText>
370
+ <a href="#">{row.url}</a>
371
+ </TableText>
372
+ </Td>
373
+ </>
374
+ </Tr>
375
+ ))}
376
+ {filteredRows.length === 0 && (
377
+ <Tr>
378
+ <Td colSpan={8}>
379
+ <Bullseye>{emptyState}</Bullseye>
380
+ </Td>
381
+ </Tr>
382
+ )}
383
+ </Tbody>
384
+ </Table>
385
+ </React.Fragment>
386
+ );
387
+ };
@@ -7,18 +7,10 @@ import {
7
7
  DropdownList,
8
8
  Flex,
9
9
  FlexItem,
10
- Label,
11
10
  MenuToggle,
12
11
  MenuToggleElement,
13
- OverflowMenu,
14
- OverflowMenuContent,
15
- OverflowMenuControl,
16
- OverflowMenuDropdownItem,
17
- OverflowMenuGroup,
18
- OverflowMenuItem,
19
12
  PageSection,
20
13
  Pagination,
21
- Select,
22
14
  SelectOption,
23
15
  SelectList,
24
16
  SelectGroup,
@@ -27,7 +19,17 @@ import {
27
19
  Toolbar,
28
20
  ToolbarContent,
29
21
  ToolbarGroup,
30
- ToolbarItem
22
+ ToolbarItem,
23
+ OverflowMenuDropdownItem,
24
+ PaginationVariant,
25
+ Label,
26
+ Select,
27
+ OverflowMenu,
28
+ OverflowMenuContent,
29
+ OverflowMenuControl,
30
+ OverflowMenuGroup,
31
+ OverflowMenuItem,
32
+ PageSectionVariants
31
33
  } from '@patternfly/react-core';
32
34
  import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';
33
35
  import CloneIcon from '@patternfly/react-icons/dist/esm/icons/clone-icon';
@@ -37,15 +39,17 @@ import CodeIcon from '@patternfly/react-icons/dist/esm/icons/code-icon';
37
39
  import CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-icon';
38
40
  import SortAmountDownIcon from '@patternfly/react-icons/dist/esm/icons/sort-amount-down-icon';
39
41
  import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';
40
- import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper';
42
+ import { DashboardWrapper } from '@patternfly/react-core/dist/esm/demos/DashboardWrapper';
41
43
  import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
42
- import { rows, columns } from '@patternfly/react-table/src/docs/demos/table-demos/sampleData';
44
+ import { rows, columns, SampleDataRow } from '@patternfly/react-table/dist/esm/demos/sampleData';
43
45
 
44
- export const ComposableTableSortable = () => {
46
+ type Direction = 'asc' | 'desc' | undefined;
47
+
48
+ export const TableSortableResponsive: React.FunctionComponent = () => {
45
49
  const [isKebabDropdownOpen, setIsKebabDropdownOpen] = React.useState(false);
46
50
 
47
- const sortRows = (r, sortIndex, sortDirection) => {
48
- return [...r].sort((a, b) => {
51
+ const sortRows = (rows: SampleDataRow[], sortIndex: number, sortDirection: Direction) =>
52
+ [...rows].sort((a, b) => {
49
53
  let returnValue = 0;
50
54
  if (sortIndex === 0 || sortIndex === 7) {
51
55
  returnValue = 1;
@@ -61,7 +65,6 @@ export const ComposableTableSortable = () => {
61
65
  }
62
66
  return returnValue;
63
67
  });
64
- };
65
68
 
66
69
  const [sortedData, setSortedData] = React.useState([...sortRows(rows, 0, 'asc')]);
67
70
  const [sortedRows, setSortedRows] = React.useState([...sortedData]);
@@ -71,11 +74,11 @@ export const ComposableTableSortable = () => {
71
74
  // index of the currently active column
72
75
  const [activeSortIndex, setActiveSortIndex] = React.useState(0);
73
76
  // sort direction of the currently active column
74
- const [activeSortDirection, setActiveSortDirection] = React.useState('asc');
77
+ const [activeSortDirection, setActiveSortDirection] = React.useState<Direction>('asc');
75
78
  // sort dropdown expansion
76
79
  const [isSortDropdownOpen, setIsSortDropdownOpen] = React.useState(false);
77
80
 
78
- const onSort = (event, index, direction) => {
81
+ const onSort = (_event: any, index: number, direction: Direction) => {
79
82
  setActiveSortIndex(index);
80
83
  setActiveSortDirection(direction);
81
84
 
@@ -88,17 +91,17 @@ export const ComposableTableSortable = () => {
88
91
  setSortedRows(sortedData.slice((page - 1) * perPage, page * perPage - 1));
89
92
  }, [sortedData, page, perPage]);
90
93
 
91
- const handleSetPage = (_evt, newPage) => {
94
+ const handleSetPage = (_evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, newPage: number) => {
92
95
  setPage(newPage);
93
96
  };
94
97
 
95
- const handlePerPageSelect = (_evt, newPerPage) => {
98
+ const handlePerPageSelect = (_evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, newPerPage: number) => {
96
99
  setPerPage(newPerPage);
97
100
  };
98
101
 
99
- const renderPagination = (variant) => (
102
+ const renderPagination = (variant: 'top' | 'bottom' | PaginationVariant, isCompact: boolean) => (
100
103
  <Pagination
101
- isCompact
104
+ isCompact={isCompact}
102
105
  itemCount={rows.length}
103
106
  page={page}
104
107
  perPage={perPage}
@@ -117,7 +120,7 @@ export const ComposableTableSortable = () => {
117
120
  />
118
121
  );
119
122
 
120
- const renderLabel = (labelText) => {
123
+ const renderLabel = (labelText: string) => {
121
124
  switch (labelText) {
122
125
  case 'Running':
123
126
  return <Label color="green">{labelText}</Label>;
@@ -137,12 +140,12 @@ export const ComposableTableSortable = () => {
137
140
  <Select
138
141
  isOpen={isSortDropdownOpen}
139
142
  selected={[activeSortDirection, activeSortIndex]}
140
- onOpenChange={(isOpen) => setIsSortDropdownOpen(isOpen)}
141
- onSelect={(event, value) => {
143
+ onOpenChange={(isOpen: boolean) => setIsSortDropdownOpen(isOpen)}
144
+ onSelect={(event: React.MouseEvent<Element, MouseEvent>, value: string | number) => {
142
145
  if (value === 'asc' || value === 'desc') {
143
146
  onSort(event, activeSortIndex, value);
144
147
  } else {
145
- onSort(event, value, activeSortDirection !== 'none' ? activeSortDirection : 'asc');
148
+ onSort(event, value as number, activeSortDirection ?? 'asc');
146
149
  }
147
150
  }}
148
151
  toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
@@ -192,8 +195,8 @@ export const ComposableTableSortable = () => {
192
195
  <OverflowMenuControl hasAdditionalOptions>
193
196
  <Dropdown
194
197
  onSelect={() => setIsKebabDropdownOpen(!isKebabDropdownOpen)}
195
- onOpenChange={(isKebabDropdownOpen) => setIsKebabDropdownOpen(isKebabDropdownOpen)}
196
- toggle={(toggleRef) => (
198
+ onOpenChange={(isKebabDropdownOpen: boolean) => setIsKebabDropdownOpen(isKebabDropdownOpen)}
199
+ toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
197
200
  <MenuToggle
198
201
  ref={toggleRef}
199
202
  aria-label="overflow menu"
@@ -230,7 +233,7 @@ export const ComposableTableSortable = () => {
230
233
  return (
231
234
  <React.Fragment>
232
235
  <DashboardWrapper>
233
- <PageSection isWidthLimited>
236
+ <PageSection isWidthLimited variant={PageSectionVariants.light}>
234
237
  <TextContent>
235
238
  <Text component="h1">Table demos</Text>
236
239
  <Text component="p">
@@ -13,29 +13,42 @@ import {
13
13
  MenuToggleElement,
14
14
  Label,
15
15
  Select,
16
- SelectOption
16
+ SelectOption,
17
+ PaginationVariant
17
18
  } from '@patternfly/react-core';
18
19
  import { Table, TableText, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';
19
20
  import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
20
- import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper';
21
- import { rows, columns } from '@patternfly/react-table/src/docs/demos/table-demos/sampleData';
21
+ import { DashboardWrapper } from '@patternfly/react-core/dist/esm/demos/DashboardWrapper';
22
+ import { rows, columns } from '@patternfly/react-table/dist/esm/demos/sampleData';
22
23
 
23
- export const StaticBottomPagination = () => {
24
+ export const TableStaticBottomPagination: React.FunctionComponent = () => {
24
25
  const [isSelectOpen, setIsSelectOpen] = React.useState(false);
25
26
  const [page, setPage] = React.useState(1);
26
27
  const [perPage, setPerPage] = React.useState(10);
27
28
  const [paginatedRows, setPaginatedRows] = React.useState(rows.slice(0, 10));
28
- const handleSetPage = (_evt, newPage, perPage, startIdx, endIdx) => {
29
+ const handleSetPage = (
30
+ _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent,
31
+ newPage: number,
32
+ _perPage: number,
33
+ startIdx: number,
34
+ endIdx: number
35
+ ) => {
29
36
  setPaginatedRows(rows.slice(startIdx, endIdx));
30
37
  setPage(newPage);
31
38
  };
32
- handlePerPageSelect = (_evt, newPerPage, newPage, startIdx, endIdx) => {
39
+ const handlePerPageSelect = (
40
+ _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent,
41
+ newPerPage: number,
42
+ newPage: number,
43
+ startIdx: number,
44
+ endIdx: number
45
+ ) => {
33
46
  setPaginatedRows(rows.slice(startIdx, endIdx));
34
47
  setPage(newPage);
35
48
  setPerPage(newPerPage);
36
49
  };
37
50
 
38
- const renderPagination = (variant, isCompact) => (
51
+ const renderPagination = (variant: PaginationVariant | 'bottom' | 'top', isCompact: boolean) => (
39
52
  <Pagination
40
53
  isCompact={isCompact}
41
54
  itemCount={rows.length}
@@ -51,7 +64,7 @@ export const StaticBottomPagination = () => {
51
64
  />
52
65
  );
53
66
 
54
- const renderLabel = (labelText) => {
67
+ const renderLabel = (labelText: string) => {
55
68
  switch (labelText) {
56
69
  case 'Running':
57
70
  return (
@@ -93,7 +106,7 @@ export const StaticBottomPagination = () => {
93
106
  </MenuToggle>
94
107
  )}
95
108
  isOpen={isSelectOpen}
96
- onOpenChange={(isOpen) => setIsSelectOpen(isOpen)}
109
+ onOpenChange={(isOpen: boolean) => setIsSelectOpen(isOpen)}
97
110
  onSelect={() => setIsSelectOpen(!isSelectOpen)}
98
111
  >
99
112
  {[
@@ -1,9 +1,30 @@
1
1
  import React from 'react';
2
2
  import { Table, Thead, Tr, Th, Tbody, Td, InnerScrollContainer } from '@patternfly/react-table';
3
3
  import { Card, PageSection } from '@patternfly/react-core';
4
- import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper';
4
+ import { DashboardWrapper } from '@patternfly/react-core/dist/esm/demos/DashboardWrapper';
5
5
 
6
- export const StickyFirstColumn = () => {
6
+ type Direction = 'asc' | 'desc' | undefined;
7
+
8
+ interface Fact {
9
+ name: string;
10
+ state: string;
11
+ detail1: string;
12
+ detail2: string;
13
+ detail3: string;
14
+ detail4: string;
15
+ detail5: string;
16
+ detail6: string;
17
+ detail7: string;
18
+ detail8: string;
19
+ detail9: string;
20
+ detail10: string;
21
+ detail11: string;
22
+ detail12: string;
23
+ detail13: string;
24
+ detail14: string;
25
+ }
26
+
27
+ export const TableStickyFirstColumn = () => {
7
28
  const facts = Array.from(
8
29
  {
9
30
  length: 9
@@ -45,9 +66,10 @@ export const StickyFirstColumn = () => {
45
66
  header15: 'Header 15',
46
67
  header16: 'Header 16'
47
68
  };
48
- const [activeSortIndex, setActiveSortIndex] = React.useState(null);
49
- const [activeSortDirection, setActiveSortDirection] = React.useState(null);
50
- const getSortableRowValues = fact => {
69
+
70
+ const [activeSortIndex, setActiveSortIndex] = React.useState(-1);
71
+ const [activeSortDirection, setActiveSortDirection] = React.useState<Direction>('asc');
72
+ const getSortableRowValues = (fact: Fact) => {
51
73
  const {
52
74
  name,
53
75
  state,
@@ -86,7 +108,7 @@ export const StickyFirstColumn = () => {
86
108
  ];
87
109
  };
88
110
  let sortedFacts = facts;
89
- if (activeSortIndex !== null) {
111
+ if (activeSortIndex > -1) {
90
112
  sortedFacts = facts.sort((a, b) => {
91
113
  const aValue = getSortableRowValues(a)[activeSortIndex];
92
114
  const bValue = getSortableRowValues(b)[activeSortIndex];
@@ -100,12 +122,12 @@ export const StickyFirstColumn = () => {
100
122
  }
101
123
  });
102
124
  }
103
- const getSortParams = columnIndex => ({
125
+ const getSortParams = (columnIndex: number) => ({
104
126
  sortBy: {
105
127
  index: activeSortIndex,
106
128
  direction: activeSortDirection
107
129
  },
108
- onSort: (_event, index, direction) => {
130
+ onSort: (_event: React.MouseEvent, index: number, direction: Direction) => {
109
131
  setActiveSortIndex(index);
110
132
  setActiveSortDirection(direction);
111
133
  },
@@ -148,7 +170,7 @@ export const StickyFirstColumn = () => {
148
170
  </Tr>
149
171
  </Thead>
150
172
  <Tbody>
151
- {sortedFacts.map(fact => (
173
+ {sortedFacts.map((fact) => (
152
174
  <Tr key={fact.name}>
153
175
  <Th isStickyColumn stickyMinWidth="100px" hasRightBorder modifier="truncate">
154
176
  {fact.name}