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

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