@patternfly/react-data-view 6.3.0 → 6.4.0-prerelease.10

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 (95) hide show
  1. package/dist/cjs/DataViewTable/DataViewTable.d.ts +6 -1
  2. package/dist/cjs/DataViewTable/DataViewTable.js +21 -1
  3. package/dist/cjs/DataViewTableBasic/DataViewTableBasic.d.ts +13 -0
  4. package/dist/cjs/DataViewTableBasic/DataViewTableBasic.js +46 -6
  5. package/dist/cjs/DataViewTableBasic/DataViewTableBasic.test.js +47 -9
  6. package/dist/cjs/DataViewTableHead/DataViewTableHead.d.ts +2 -0
  7. package/dist/cjs/DataViewTableHead/DataViewTableHead.js +5 -4
  8. package/dist/cjs/DataViewTableTree/DataViewTableTree.d.ts +2 -0
  9. package/dist/cjs/DataViewTableTree/DataViewTableTree.js +28 -1
  10. package/dist/cjs/DataViewTableTree/DataViewTableTree.test.js +4 -0
  11. package/dist/cjs/DataViewTh/DataViewTh.d.ts +32 -0
  12. package/dist/cjs/DataViewTh/DataViewTh.js +222 -0
  13. package/dist/cjs/DataViewTh/index.d.ts +2 -0
  14. package/dist/cjs/DataViewTh/index.js +23 -0
  15. package/dist/cjs/DataViewTreeFilter/DataViewTreeFilter.d.ts +26 -0
  16. package/dist/cjs/DataViewTreeFilter/DataViewTreeFilter.js +229 -0
  17. package/dist/cjs/DataViewTreeFilter/DataViewTreeFilter.test.d.ts +1 -0
  18. package/dist/cjs/DataViewTreeFilter/DataViewTreeFilter.test.js +171 -0
  19. package/dist/cjs/DataViewTreeFilter/index.d.ts +2 -0
  20. package/dist/cjs/DataViewTreeFilter/index.js +23 -0
  21. package/dist/cjs/Hooks/selection.d.ts +1 -0
  22. package/dist/cjs/Hooks/selection.js +5 -1
  23. package/dist/cjs/Hooks/selection.test.js +48 -0
  24. package/dist/cjs/InternalContext/InternalContext.d.ts +2 -0
  25. package/dist/cjs/index.d.ts +6 -0
  26. package/dist/cjs/index.js +10 -1
  27. package/dist/dynamic/DataViewTh/package.json +1 -0
  28. package/dist/dynamic/DataViewTreeFilter/package.json +1 -0
  29. package/dist/dynamic-modules.json +62 -0
  30. package/dist/esm/DataViewTable/DataViewTable.d.ts +6 -1
  31. package/dist/esm/DataViewTable/DataViewTable.js +21 -1
  32. package/dist/esm/DataViewTableBasic/DataViewTableBasic.d.ts +13 -0
  33. package/dist/esm/DataViewTableBasic/DataViewTableBasic.js +48 -8
  34. package/dist/esm/DataViewTableBasic/DataViewTableBasic.test.js +45 -10
  35. package/dist/esm/DataViewTableHead/DataViewTableHead.d.ts +2 -0
  36. package/dist/esm/DataViewTableHead/DataViewTableHead.js +5 -4
  37. package/dist/esm/DataViewTableTree/DataViewTableTree.d.ts +2 -0
  38. package/dist/esm/DataViewTableTree/DataViewTableTree.js +29 -2
  39. package/dist/esm/DataViewTableTree/DataViewTableTree.test.js +4 -0
  40. package/dist/esm/DataViewTh/DataViewTh.d.ts +32 -0
  41. package/dist/esm/DataViewTh/DataViewTh.js +215 -0
  42. package/dist/esm/DataViewTh/index.d.ts +2 -0
  43. package/dist/esm/DataViewTh/index.js +2 -0
  44. package/dist/esm/DataViewTreeFilter/DataViewTreeFilter.d.ts +26 -0
  45. package/dist/esm/DataViewTreeFilter/DataViewTreeFilter.js +225 -0
  46. package/dist/esm/DataViewTreeFilter/DataViewTreeFilter.test.d.ts +1 -0
  47. package/dist/esm/DataViewTreeFilter/DataViewTreeFilter.test.js +166 -0
  48. package/dist/esm/DataViewTreeFilter/index.d.ts +2 -0
  49. package/dist/esm/DataViewTreeFilter/index.js +2 -0
  50. package/dist/esm/Hooks/selection.d.ts +1 -0
  51. package/dist/esm/Hooks/selection.js +5 -1
  52. package/dist/esm/Hooks/selection.test.js +48 -0
  53. package/dist/esm/InternalContext/InternalContext.d.ts +2 -0
  54. package/dist/esm/index.d.ts +6 -0
  55. package/dist/esm/index.js +6 -0
  56. package/dist/tsconfig.tsbuildinfo +1 -1
  57. package/generate-fed-package-json.js +18 -0
  58. package/generate-index.js +2 -2
  59. package/package.json +12 -12
  60. package/patternfly-docs/content/extensions/data-view/examples/DataView/DataView.md +10 -4
  61. package/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableExpandableExample.tsx +108 -0
  62. package/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableInteractiveExample.tsx +148 -0
  63. package/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableResizableColumnsExample.tsx +155 -0
  64. package/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableStickyExample.tsx +90 -0
  65. package/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableTreeExample.tsx +1 -0
  66. package/patternfly-docs/content/extensions/data-view/examples/Table/Table.md +113 -14
  67. package/patternfly-docs/content/extensions/data-view/examples/Toolbar/SelectionExample.tsx +14 -3
  68. package/patternfly-docs/content/extensions/data-view/examples/Toolbar/Toolbar.md +10 -2
  69. package/patternfly-docs/content/extensions/data-view/examples/Toolbar/TreeFilterExample.tsx +248 -0
  70. package/patternfly-docs/patternfly-docs.config.js +4 -1
  71. package/release.config.js +1 -1
  72. package/src/DataViewCheckboxFilter/__snapshots__/DataViewCheckboxFilter.test.tsx.snap +0 -2
  73. package/src/DataViewFilters/__snapshots__/DataViewFilters.test.tsx.snap +0 -2
  74. package/src/DataViewTable/DataViewTable.tsx +51 -28
  75. package/src/DataViewTable/__snapshots__/DataViewTable.test.tsx.snap +17 -25
  76. package/src/DataViewTableBasic/DataViewTableBasic.test.tsx +54 -12
  77. package/src/DataViewTableBasic/DataViewTableBasic.tsx +104 -10
  78. package/src/DataViewTableBasic/__snapshots__/DataViewTableBasic.test.tsx.snap +30 -30
  79. package/src/DataViewTableHead/DataViewTableHead.tsx +24 -23
  80. package/src/DataViewTableHead/__snapshots__/DataViewTableHead.test.tsx.snap +15 -15
  81. package/src/DataViewTableTree/DataViewTableTree.test.tsx +9 -0
  82. package/src/DataViewTableTree/DataViewTableTree.tsx +35 -1
  83. package/src/DataViewTableTree/__snapshots__/DataViewTableTree.test.tsx.snap +977 -28
  84. package/src/DataViewTextFilter/__snapshots__/DataViewTextFilter.test.tsx.snap +0 -3
  85. package/src/DataViewTh/DataViewTh.tsx +342 -0
  86. package/src/DataViewTh/index.ts +2 -0
  87. package/src/DataViewToolbar/__snapshots__/DataViewToolbar.test.tsx.snap +0 -10
  88. package/src/DataViewTreeFilter/DataViewTreeFilter.test.tsx +222 -0
  89. package/src/DataViewTreeFilter/DataViewTreeFilter.tsx +361 -0
  90. package/src/DataViewTreeFilter/__snapshots__/DataViewTreeFilter.test.tsx.snap +199 -0
  91. package/src/DataViewTreeFilter/index.ts +2 -0
  92. package/src/Hooks/selection.test.tsx +65 -1
  93. package/src/Hooks/selection.ts +6 -1
  94. package/src/InternalContext/InternalContext.tsx +2 -0
  95. package/src/index.ts +9 -0
@@ -14,9 +14,13 @@ export const useDataViewSelection = (props) => {
14
14
  : setSelected(items ? prev => prev.filter(prevSelected => !(Array.isArray(items) ? items : [items]).some(item => matchOption(item, prevSelected))) : []);
15
15
  };
16
16
  const isSelected = (item) => Boolean(selected.find(selected => matchOption(selected, item)));
17
+ const setSelectedItems = (items) => {
18
+ setSelected(items);
19
+ };
17
20
  return {
18
21
  selected,
19
22
  onSelect,
20
- isSelected
23
+ isSelected,
24
+ setSelected: setSelectedItems
21
25
  };
22
26
  };
@@ -17,6 +17,7 @@ describe('useDataViewSelection', () => {
17
17
  selected: [],
18
18
  onSelect: expect.any(Function),
19
19
  isSelected: expect.any(Function),
20
+ setSelected: expect.any(Function),
20
21
  });
21
22
  });
22
23
  it('should get initial state correctly - with initialSelected', () => {
@@ -26,6 +27,7 @@ describe('useDataViewSelection', () => {
26
27
  selected: initialSelected,
27
28
  onSelect: expect.any(Function),
28
29
  isSelected: expect.any(Function),
30
+ setSelected: expect.any(Function),
29
31
  });
30
32
  });
31
33
  it('should select items correctly - objects', () => __awaiter(void 0, void 0, void 0, function* () {
@@ -50,4 +52,50 @@ describe('useDataViewSelection', () => {
50
52
  expect(result.current.isSelected({ id: 1, name: 'test1' })).toBe(true);
51
53
  expect(result.current.isSelected({ id: 3, name: 'test2' })).toBe(false);
52
54
  });
55
+ it('should have setSelected function in return object', () => {
56
+ const { result } = renderHook(() => useDataViewSelection({ matchOption: (a, b) => a.id === b.id }));
57
+ expect(result.current).toEqual({
58
+ selected: [],
59
+ onSelect: expect.any(Function),
60
+ isSelected: expect.any(Function),
61
+ setSelected: expect.any(Function),
62
+ });
63
+ });
64
+ it('should set selected items directly using setSelected - objects', () => __awaiter(void 0, void 0, void 0, function* () {
65
+ const initialSelected = [{ id: 1, name: 'test1' }];
66
+ const { result } = renderHook(() => useDataViewSelection({ initialSelected, matchOption: (a, b) => a.id === b.id }));
67
+ const newSelected = [{ id: 2, name: 'test2' }, { id: 3, name: 'test3' }];
68
+ yield act(() => __awaiter(void 0, void 0, void 0, function* () {
69
+ result.current.setSelected(newSelected);
70
+ }));
71
+ expect(result.current.selected).toEqual(newSelected);
72
+ }));
73
+ it('should set selected items directly using setSelected - strings', () => __awaiter(void 0, void 0, void 0, function* () {
74
+ const initialSelected = ['test1', 'test2'];
75
+ const { result } = renderHook(() => useDataViewSelection({ initialSelected, matchOption: (a, b) => a === b }));
76
+ const newSelected = ['test3', 'test4', 'test5'];
77
+ yield act(() => __awaiter(void 0, void 0, void 0, function* () {
78
+ result.current.setSelected(newSelected);
79
+ }));
80
+ expect(result.current.selected).toEqual(newSelected);
81
+ }));
82
+ it('should clear all selections using setSelected with empty array', () => __awaiter(void 0, void 0, void 0, function* () {
83
+ const initialSelected = [{ id: 1, name: 'test1' }, { id: 2, name: 'test2' }];
84
+ const { result } = renderHook(() => useDataViewSelection({ initialSelected, matchOption: (a, b) => a.id === b.id }));
85
+ yield act(() => __awaiter(void 0, void 0, void 0, function* () {
86
+ result.current.setSelected([]);
87
+ }));
88
+ expect(result.current.selected).toEqual([]);
89
+ }));
90
+ it('should update isSelected correctly after using setSelected', () => __awaiter(void 0, void 0, void 0, function* () {
91
+ const initialSelected = [{ id: 1, name: 'test1' }];
92
+ const { result } = renderHook(() => useDataViewSelection({ initialSelected, matchOption: (a, b) => a.id === b.id }));
93
+ const newSelected = [{ id: 2, name: 'test2' }, { id: 3, name: 'test3' }];
94
+ yield act(() => __awaiter(void 0, void 0, void 0, function* () {
95
+ result.current.setSelected(newSelected);
96
+ }));
97
+ expect(result.current.isSelected({ id: 1, name: 'test1' })).toBe(false);
98
+ expect(result.current.isSelected({ id: 2, name: 'test2' })).toBe(true);
99
+ expect(result.current.isSelected({ id: 3, name: 'test3' })).toBe(true);
100
+ }));
53
101
  });
@@ -5,6 +5,8 @@ export interface DataViewSelection {
5
5
  onSelect: (isSelecting: boolean, items?: any[] | any) => void;
6
6
  /** Checks if a specific item is currently selected */
7
7
  isSelected: (item: any) => boolean;
8
+ /** Directly sets the selected items */
9
+ setSelected?: (items: any[]) => void;
8
10
  /** Determines if selection is disabled for a given item */
9
11
  isSelectDisabled?: (item: any) => boolean;
10
12
  }
@@ -1,8 +1,12 @@
1
1
  export { default as InternalContext } from './InternalContext';
2
2
  export * from './InternalContext';
3
3
  export * from './Hooks';
4
+ export { default as DataViewTreeFilter } from './DataViewTreeFilter';
5
+ export * from './DataViewTreeFilter';
4
6
  export { default as DataViewToolbar } from './DataViewToolbar';
5
7
  export * from './DataViewToolbar';
8
+ export { default as DataViewTh } from './DataViewTh';
9
+ export * from './DataViewTh';
6
10
  export { default as DataViewTextFilter } from './DataViewTextFilter';
7
11
  export * from './DataViewTextFilter';
8
12
  export { default as DataViewTableTree } from './DataViewTableTree';
@@ -13,6 +17,8 @@ export { default as DataViewTableBasic } from './DataViewTableBasic';
13
17
  export * from './DataViewTableBasic';
14
18
  export { default as DataViewTable } from './DataViewTable';
15
19
  export * from './DataViewTable';
20
+ export { default as DataViewFilters } from './DataViewFilters';
21
+ export * from './DataViewFilters';
16
22
  export { default as DataViewEventsContext } from './DataViewEventsContext';
17
23
  export * from './DataViewEventsContext';
18
24
  export { default as DataViewCheckboxFilter } from './DataViewCheckboxFilter';
package/dist/esm/index.js CHANGED
@@ -2,8 +2,12 @@
2
2
  export { default as InternalContext } from './InternalContext';
3
3
  export * from './InternalContext';
4
4
  export * from './Hooks';
5
+ export { default as DataViewTreeFilter } from './DataViewTreeFilter';
6
+ export * from './DataViewTreeFilter';
5
7
  export { default as DataViewToolbar } from './DataViewToolbar';
6
8
  export * from './DataViewToolbar';
9
+ export { default as DataViewTh } from './DataViewTh';
10
+ export * from './DataViewTh';
7
11
  export { default as DataViewTextFilter } from './DataViewTextFilter';
8
12
  export * from './DataViewTextFilter';
9
13
  export { default as DataViewTableTree } from './DataViewTableTree';
@@ -14,6 +18,8 @@ export { default as DataViewTableBasic } from './DataViewTableBasic';
14
18
  export * from './DataViewTableBasic';
15
19
  export { default as DataViewTable } from './DataViewTable';
16
20
  export * from './DataViewTable';
21
+ export { default as DataViewFilters } from './DataViewFilters';
22
+ export * from './DataViewFilters';
17
23
  export { default as DataViewEventsContext } from './DataViewEventsContext';
18
24
  export * from './DataViewEventsContext';
19
25
  export { default as DataViewCheckboxFilter } from './DataViewCheckboxFilter';
@@ -1 +1 @@
1
- {"root":["../src/index.ts","../src/dataview/dataview.test.tsx","../src/dataview/dataview.tsx","../src/dataview/index.ts","../src/dataviewcheckboxfilter/dataviewcheckboxfilter.test.tsx","../src/dataviewcheckboxfilter/dataviewcheckboxfilter.tsx","../src/dataviewcheckboxfilter/index.ts","../src/datavieweventscontext/datavieweventscontext.test.tsx","../src/datavieweventscontext/datavieweventscontext.tsx","../src/datavieweventscontext/index.ts","../src/dataviewfilters/dataviewfilters.test.tsx","../src/dataviewfilters/dataviewfilters.tsx","../src/dataviewfilters/index.tsx","../src/dataviewtable/dataviewtable.test.tsx","../src/dataviewtable/dataviewtable.tsx","../src/dataviewtable/index.ts","../src/dataviewtablebasic/dataviewtablebasic.test.tsx","../src/dataviewtablebasic/dataviewtablebasic.tsx","../src/dataviewtablebasic/index.ts","../src/dataviewtablehead/dataviewtablehead.test.tsx","../src/dataviewtablehead/dataviewtablehead.tsx","../src/dataviewtablehead/index.ts","../src/dataviewtabletree/dataviewtabletree.test.tsx","../src/dataviewtabletree/dataviewtabletree.tsx","../src/dataviewtabletree/index.ts","../src/dataviewtextfilter/dataviewtextfilter.test.tsx","../src/dataviewtextfilter/dataviewtextfilter.tsx","../src/dataviewtextfilter/index.ts","../src/dataviewtoolbar/dataviewtoolbar.test.tsx","../src/dataviewtoolbar/dataviewtoolbar.tsx","../src/dataviewtoolbar/index.ts","../src/hooks/filters.test.tsx","../src/hooks/filters.ts","../src/hooks/index.ts","../src/hooks/pagination.test.tsx","../src/hooks/pagination.ts","../src/hooks/selection.test.tsx","../src/hooks/selection.ts","../src/hooks/sort.test.tsx","../src/hooks/sort.ts","../src/internalcontext/internalcontext.test.tsx","../src/internalcontext/internalcontext.tsx","../src/internalcontext/index.ts"],"version":"5.8.3"}
1
+ {"root":["../src/index.ts","../src/DataView/DataView.test.tsx","../src/DataView/DataView.tsx","../src/DataView/index.ts","../src/DataViewCheckboxFilter/DataViewCheckboxFilter.test.tsx","../src/DataViewCheckboxFilter/DataViewCheckboxFilter.tsx","../src/DataViewCheckboxFilter/index.ts","../src/DataViewEventsContext/DataViewEventsContext.test.tsx","../src/DataViewEventsContext/DataViewEventsContext.tsx","../src/DataViewEventsContext/index.ts","../src/DataViewFilters/DataViewFilters.test.tsx","../src/DataViewFilters/DataViewFilters.tsx","../src/DataViewFilters/index.tsx","../src/DataViewTable/DataViewTable.test.tsx","../src/DataViewTable/DataViewTable.tsx","../src/DataViewTable/index.ts","../src/DataViewTableBasic/DataViewTableBasic.test.tsx","../src/DataViewTableBasic/DataViewTableBasic.tsx","../src/DataViewTableBasic/index.ts","../src/DataViewTableHead/DataViewTableHead.test.tsx","../src/DataViewTableHead/DataViewTableHead.tsx","../src/DataViewTableHead/index.ts","../src/DataViewTableTree/DataViewTableTree.test.tsx","../src/DataViewTableTree/DataViewTableTree.tsx","../src/DataViewTableTree/index.ts","../src/DataViewTextFilter/DataViewTextFilter.test.tsx","../src/DataViewTextFilter/DataViewTextFilter.tsx","../src/DataViewTextFilter/index.ts","../src/DataViewTh/DataViewTh.tsx","../src/DataViewTh/index.ts","../src/DataViewToolbar/DataViewToolbar.test.tsx","../src/DataViewToolbar/DataViewToolbar.tsx","../src/DataViewToolbar/index.ts","../src/DataViewTreeFilter/DataViewTreeFilter.test.tsx","../src/DataViewTreeFilter/DataViewTreeFilter.tsx","../src/DataViewTreeFilter/index.ts","../src/Hooks/filters.test.tsx","../src/Hooks/filters.ts","../src/Hooks/index.ts","../src/Hooks/pagination.test.tsx","../src/Hooks/pagination.ts","../src/Hooks/selection.test.tsx","../src/Hooks/selection.ts","../src/Hooks/sort.test.tsx","../src/Hooks/sort.ts","../src/InternalContext/InternalContext.test.tsx","../src/InternalContext/InternalContext.tsx","../src/InternalContext/index.ts"],"version":"5.9.3"}
@@ -1,6 +1,7 @@
1
1
  const fse = require('fs-extra');
2
2
  const { globSync } = require('glob');
3
3
  const path = require('path');
4
+ const { default: getDynamicModuleMap } = require('../../scripts/parse-dynamic-modules.mjs');
4
5
 
5
6
  const root = process.cwd();
6
7
 
@@ -60,12 +61,29 @@ async function generatePackages(files) {
60
61
  return Promise.all(cmds);
61
62
  }
62
63
 
64
+ async function generateDynamicModuleMap() {
65
+ const moduleMap = getDynamicModuleMap(root);
66
+ // eslint-disable-next-line no-console
67
+ console.log('Generating dynamic module map for', Object.keys(moduleMap).length, 'modules');
68
+
69
+ if (Object.keys(moduleMap).length === 0) {
70
+ return Promise.resolve();
71
+ }
72
+
73
+ const moduleMapSorted = Object.keys(moduleMap)
74
+ .sort()
75
+ .reduce((acc, key) => ({ ...acc, [key]: moduleMap[key] }), {});
76
+
77
+ return fse.writeJSON(path.resolve(root, 'dist/dynamic-modules.json'), moduleMapSorted, { spaces: 2 });
78
+ }
79
+
63
80
  async function run(files) {
64
81
  try {
65
82
  await generatePackages(files);
66
83
  if (indexTypings.length === 1) {
67
84
  copyTypings(indexTypings, root);
68
85
  }
86
+ await generateDynamicModuleMap();
69
87
  } catch (error) {
70
88
  // eslint-disable-next-line no-console
71
89
  console.error(error);
package/generate-index.js CHANGED
@@ -6,7 +6,7 @@ const root = process.cwd();
6
6
 
7
7
  const ENV_AGNOSTIC_ROOT = `${root}/src`
8
8
 
9
- const sourceFiles = globSync(path.resolve(__dirname, './src/*/index.ts'))
9
+ const sourceFiles = globSync(path.resolve(__dirname, './src/*/index.{ts,tsx}'))
10
10
 
11
11
  async function generateIndex(files) {
12
12
  // ensure the dynamic root exists
@@ -19,7 +19,7 @@ async function generateIndex(files) {
19
19
  stream.write('// this file is autogenerated by generate-index.js, modifying it manually will have no effect\n');
20
20
 
21
21
  files.forEach(file => {
22
- const name = file.replace('/index.ts', '').split('/').pop();
22
+ const name = file.replace(/\/index\.(ts|tsx)$/, '').split('/').pop();
23
23
  // do not generate default exports for Hooks/
24
24
  name !== 'Hooks' && stream.write(`\nexport { default as ${name} } from './${name}';\n`);
25
25
  stream.write(`export * from './${name}';\n`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-data-view",
3
- "version": "6.3.0",
3
+ "version": "6.4.0-prerelease.10",
4
4
  "description": "Data view used for Red Hat projects.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -32,9 +32,9 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "@patternfly/react-component-groups": "^6.1.0",
35
- "@patternfly/react-core": "^6.0.0",
36
- "@patternfly/react-icons": "^6.0.0",
37
- "@patternfly/react-table": "^6.0.0",
35
+ "@patternfly/react-core": "^6.4.0",
36
+ "@patternfly/react-icons": "^6.4.0",
37
+ "@patternfly/react-table": "^6.4.0",
38
38
  "clsx": "^2.1.1",
39
39
  "react-jss": "^10.10.0"
40
40
  },
@@ -43,18 +43,18 @@
43
43
  "react-dom": "^17 || ^18 || ^19"
44
44
  },
45
45
  "devDependencies": {
46
- "@patternfly/documentation-framework": "^6.5.20",
47
- "@patternfly/patternfly": "^6.0.0",
48
- "@patternfly/react-code-editor": "^6.0.0",
46
+ "@patternfly/documentation-framework": "^6.24.2",
47
+ "@patternfly/patternfly": "^6.4.0",
48
+ "@patternfly/react-code-editor": "^6.4.0",
49
49
  "@patternfly/patternfly-a11y": "^5.1.0",
50
- "@types/react": "^18.3.23",
50
+ "@types/react": "^18.3.27",
51
51
  "@types/react-dom": "^18.3.7",
52
52
  "@types/react-router-dom": "^5.3.3",
53
53
  "react": "^18.3.1",
54
54
  "react-dom": "^18.3.1",
55
- "react-router": "^6.30.1",
56
- "react-router-dom": "^6.30.1",
57
- "rimraf": "^6.0.1",
58
- "typescript": "^5.8.3"
55
+ "react-router": "^6.30.2",
56
+ "react-router-dom": "^6.30.2",
57
+ "rimraf": "^6.1.2",
58
+ "typescript": "^5.9.3"
59
59
  }
60
60
  }
@@ -22,15 +22,17 @@ import { DataViewCheckboxFilter } from '@patternfly/react-data-view/dist/dynamic
22
22
 
23
23
  **Note:** Data view lives in its own package [`@patternfly/react-data-view`](https://www.npmjs.com/package/@patternfly/react-data-view)
24
24
 
25
- If you notice a bug, or if you have a suggestion for improving the data view extension or its documentation, please file an issue in the [react-data-view](https://github.com/patternfly/react-data-view/issues) repository. Before doing so, please make sure there is not already a pre-existing issue.
25
+ The **data view** extension enables you to display datasets in organized layouts, with data representations and interactive toolbars for actions like selection and pagination.
26
26
 
27
- ---
27
+ ---
28
28
 
29
- The **data view** extension enables you to display datasets in organized layouts, with data representations and interactive toolbars for actions like selection and pagination.
29
+ ## How to structure and implement the data view
30
+
31
+ The **data view** extension provides a modular architecture that lets you efficiently create consistent data views, either by using predefined sub-components and hooks or by defining your own custom implementations.
30
32
 
31
33
  ### Layout
32
34
 
33
- A data view should contain a header, the data representation, and a footer. These parts are organized in a [stack layout](/layouts/stack).
35
+ A data view should contain a header, the data representation, and a footer. These parts are organized in a [stack layout](/foundations-and-styles/layouts/stack).
34
36
 
35
37
  The data view toolbars and sub-components that display the data (like a card view or table) are always passed as `children` to the `<DataView>` component.
36
38
 
@@ -61,3 +63,7 @@ This example uses the `<DataViewEventsProvider>` to display details about a sele
61
63
  ```js file="./EventsExample.tsx"
62
64
 
63
65
  ```
66
+
67
+ ---
68
+
69
+ If you notice a bug, or if you have a suggestion for improving the data view extension or its documentation, please file an issue in the [react-data-view](https://github.com/patternfly/react-data-view/issues) repository. Before doing so, please make sure there is not already a pre-existing issue.
@@ -0,0 +1,108 @@
1
+ import { FunctionComponent } from 'react';
2
+ import { DataViewTable, DataViewTr, DataViewTh, ExpandableContent } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
3
+ import { ExclamationCircleIcon } from '@patternfly/react-icons';
4
+ import { Button } from '@patternfly/react-core';
5
+ import { ActionsColumn } from '@patternfly/react-table';
6
+
7
+ interface Repository {
8
+ id: number;
9
+ name: string;
10
+ branches: string | null;
11
+ prs: string | null;
12
+ workspaces: string;
13
+ lastCommit: string;
14
+ }
15
+
16
+ const expandableContents: ExpandableContent[] = [
17
+ // Row 1 - Repository one
18
+ { rowId: 1, columnId: 3, content: <div><strong>PR Details:</strong> 3 open PRs, 45 merged this month, avg review time: 2 days</div> },
19
+ { rowId: 1, columnId: 5, content: <div><strong>Commit Info:</strong> Author: John Doe, Message: "Fix critical authentication bug", SHA: a1b2c3d</div> },
20
+
21
+ // Row 2 - Repository two
22
+ { rowId: 2, columnId: 2, content: <div><strong>Branch Details:</strong> 8 active branches, main, staging, feature/api-v2, feature/dashboard</div> },
23
+ { rowId: 2, columnId: 3, content: <div><strong>PR Details:</strong> 5 open PRs, 120 merged this month, avg review time: 1.5 days</div> },
24
+ { rowId: 2, columnId: 4, content: <div><strong>Workspace Info:</strong> Development env, 3 active deployments, last updated 30 mins ago</div> },
25
+ { rowId: 2, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Jane Smith, Message: "Add new API endpoints", SHA: x9y8z7w</div> },
26
+
27
+ // Row 3 - Repository three
28
+ { rowId: 3, columnId: 2, content: <div><strong>Branch Details:</strong> 12 active branches including main, develop, multiple feature branches</div> },
29
+ { rowId: 3, columnId: 3, content: <div><strong>PR Details:</strong> 8 open PRs, 200 merged this month, avg review time: 3 days</div> },
30
+ { rowId: 3, columnId: 4, content: <div><strong>Workspace Info:</strong> Staging env, 10 active deployments, last updated 1 day ago</div> },
31
+ { rowId: 3, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Bob Johnson, Message: "Refactor core modules", SHA: p0o9i8u</div> },
32
+
33
+ // Row 4 - Repository four
34
+ { rowId: 4, columnId: 2, content: <div><strong>Branch Details:</strong> 6 active branches, focusing on microservices architecture</div> },
35
+ { rowId: 4, columnId: 3, content: <div><strong>PR Details:</strong> 2 open PRs, 90 merged this month, avg review time: 2.5 days</div> },
36
+ { rowId: 4, columnId: 4, content: <div><strong>Workspace Info:</strong> QA env, 7 active deployments, automated testing enabled</div> },
37
+ { rowId: 4, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Alice Williams, Message: "Update dependencies", SHA: m5n4b3v</div> },
38
+
39
+ // Row 5 - Repository five
40
+ { rowId: 5, columnId: 2, content: <div><strong>Branch Details:</strong> 4 active branches, clean branch strategy</div> },
41
+ { rowId: 5, columnId: 3, content: <div><strong>PR Details:</strong> 6 open PRs, 75 merged this month, avg review time: 1 day</div> },
42
+ { rowId: 5, columnId: 4, content: <div><strong>Workspace Info:</strong> Pre-production env, CI/CD pipeline configured</div> },
43
+ { rowId: 5, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Charlie Brown, Message: "Implement dark mode", SHA: q2w3e4r</div> },
44
+
45
+ // Row 6 - Repository six
46
+ { rowId: 6, columnId: 2, content: <div><strong>Branch Details:</strong> 15 active branches, complex branching model</div> },
47
+ { rowId: 6, columnId: 3, content: <div><strong>PR Details:</strong> 10 open PRs, 250 merged this month, avg review time: 4 days</div> },
48
+ { rowId: 6, columnId: 4, content: <div><strong>Workspace Info:</strong> Multi-region deployment, high availability setup</div> },
49
+ { rowId: 6, columnId: 5, content: <div><strong>Commit Info:</strong> Author: David Lee, Message: "Security patches applied", SHA: t6y7u8i</div> },
50
+ ];
51
+
52
+ const repositories: Repository[] = [
53
+ { id: 1, name: 'Repository one', branches: 'Branch one', prs: 'Pull request one', workspaces: 'Workspace one', lastCommit: 'Timestamp one' },
54
+ { id: 2, name: 'Repository two', branches: 'Branch two', prs: 'Pull request two', workspaces: 'Workspace two', lastCommit: 'Timestamp two' },
55
+ { id: 3, name: 'Repository three', branches: 'Branch three', prs: 'Pull request three', workspaces: 'Workspace three', lastCommit: 'Timestamp three' },
56
+ { id: 4, name: 'Repository four', branches: 'Branch four', prs: 'Pull request four', workspaces: 'Workspace four', lastCommit: 'Timestamp four' },
57
+ { id: 5, name: 'Repository five', branches: 'Branch five', prs: 'Pull request five', workspaces: 'Workspace five', lastCommit: 'Timestamp five' },
58
+ { id: 6, name: 'Repository six', branches: 'Branch six', prs: 'Pull request six', workspaces: 'Workspace six', lastCommit: 'Timestamp six' }
59
+ ];
60
+
61
+ const rowActions = [
62
+ {
63
+ title: 'Some action',
64
+ onClick: () => console.log('clicked on Some action') // eslint-disable-line no-console
65
+ },
66
+ {
67
+ title: <div>Another action</div>,
68
+ onClick: () => console.log('clicked on Another action') // eslint-disable-line no-console
69
+ },
70
+ {
71
+ isSeparator: true
72
+ },
73
+ {
74
+ title: 'Third action',
75
+ onClick: () => console.log('clicked on Third action') // eslint-disable-line no-console
76
+ }
77
+ ];
78
+
79
+ const rows: DataViewTr[] = repositories.map(({ id, name, branches, prs, workspaces, lastCommit }) => [
80
+ {
81
+ id,
82
+ cell: workspaces,
83
+ props: {
84
+ favorites: { isFavorited: true }
85
+ }
86
+ },
87
+ { cell: <Button href='#' variant='link' isInline>{name}</Button> },
88
+ branches,
89
+ prs,
90
+ workspaces,
91
+ lastCommit,
92
+ { cell: <ActionsColumn items={rowActions}/>, props: { isActionCell: true } },
93
+ ]);
94
+
95
+ const columns: DataViewTh[] = [
96
+ null,
97
+ 'Repositories',
98
+ { cell: <>Branches<ExclamationCircleIcon className='pf-v6-u-ml-sm' color="var(--pf-t--global--color--status--danger--default)"/></> },
99
+ 'Pull requests',
100
+ { cell: 'Workspaces', props: { info: { tooltip: 'More information' }, isStickyColumn: true } },
101
+ { cell: 'Last commit', props: { sort: { sortBy: {}, columnIndex: 4 } } },
102
+ ];
103
+
104
+ const ouiaId = 'TableExample';
105
+
106
+ export const ExpandableExample: FunctionComponent = () => (
107
+ <DataViewTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={rows} expandedRows={expandableContents} isExpandable={true}/>
108
+ );
@@ -0,0 +1,148 @@
1
+ import { FunctionComponent, useState } from 'react';
2
+ import { DataViewTable, DataViewTr, DataViewTh } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
3
+ import { ExpandableContent } from '@patternfly/react-data-view/dist/dynamic/DataViewTableBasic';
4
+ import { ExclamationCircleIcon } from '@patternfly/react-icons';
5
+ import { Button, Toolbar, ToolbarContent, ToolbarItem, Switch } from '@patternfly/react-core';
6
+
7
+ interface Repository {
8
+ id: number;
9
+ name: string;
10
+ branches: string | null;
11
+ prs: string | null;
12
+ workspaces: string;
13
+ lastCommit: string;
14
+ contributors: string;
15
+ stars: string;
16
+ forks: string;
17
+ }
18
+
19
+ const expandableContents: ExpandableContent[] = [
20
+ // Row 1 - Repository one
21
+ { rowId: 1, columnId: 2, content: <div><strong>Branch Details:</strong> 5 active branches, main, develop, feature/new-ui, hotfix/bug-123, release/v2.0</div> },
22
+ { rowId: 1, columnId: 3, content: <div><strong>PR Details:</strong> 3 open PRs, 45 merged this month, avg review time: 2 days</div> },
23
+ { rowId: 1, columnId: 5, content: <div><strong>Commit Info:</strong> Author: John Doe, Message: "Fix critical authentication bug", SHA: a1b2c3d</div> },
24
+
25
+ // Row 2 - Repository two
26
+ { rowId: 2, columnId: 2, content: <div><strong>Branch Details:</strong> 8 active branches, main, staging, feature/api-v2, feature/dashboard</div> },
27
+ { rowId: 2, columnId: 3, content: <div><strong>PR Details:</strong> 5 open PRs, 120 merged this month, avg review time: 1.5 days</div> },
28
+ { rowId: 2, columnId: 4, content: <div><strong>Workspace Info:</strong> Development env, 3 active deployments, last updated 30 mins ago</div> },
29
+ { rowId: 2, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Jane Smith, Message: "Add new API endpoints", SHA: x9y8z7w</div> },
30
+
31
+ // Row 3 - Repository three
32
+ { rowId: 3, columnId: 2, content: <div><strong>Branch Details:</strong> 12 active branches including main, develop, multiple feature branches</div> },
33
+ { rowId: 3, columnId: 3, content: <div><strong>PR Details:</strong> 8 open PRs, 200 merged this month, avg review time: 3 days</div> },
34
+ { rowId: 3, columnId: 4, content: <div><strong>Workspace Info:</strong> Staging env, 10 active deployments, last updated 1 day ago</div> },
35
+ { rowId: 3, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Bob Johnson, Message: "Refactor core modules", SHA: p0o9i8u</div> },
36
+
37
+ // Row 4 - Repository four
38
+ { rowId: 4, columnId: 2, content: <div><strong>Branch Details:</strong> 6 active branches, focusing on microservices architecture</div> },
39
+ { rowId: 4, columnId: 3, content: <div><strong>PR Details:</strong> 2 open PRs, 90 merged this month, avg review time: 2.5 days</div> },
40
+ { rowId: 4, columnId: 4, content: <div><strong>Workspace Info:</strong> QA env, 7 active deployments, automated testing enabled</div> },
41
+ { rowId: 4, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Alice Williams, Message: "Update dependencies", SHA: m5n4b3v</div> },
42
+
43
+ // Row 5 - Repository five
44
+ { rowId: 5, columnId: 2, content: <div><strong>Branch Details:</strong> 4 active branches, clean branch strategy</div> },
45
+ { rowId: 5, columnId: 3, content: <div><strong>PR Details:</strong> 6 open PRs, 75 merged this month, avg review time: 1 day</div> },
46
+ { rowId: 5, columnId: 4, content: <div><strong>Workspace Info:</strong> Pre-production env, CI/CD pipeline configured</div> },
47
+ { rowId: 5, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Charlie Brown, Message: "Implement dark mode", SHA: q2w3e4r</div> },
48
+
49
+ // Row 6 - Repository six
50
+ { rowId: 6, columnId: 2, content: <div><strong>Branch Details:</strong> 15 active branches, complex branching model</div> },
51
+ { rowId: 6, columnId: 3, content: <div><strong>PR Details:</strong> 10 open PRs, 250 merged this month, avg review time: 4 days</div> },
52
+ { rowId: 6, columnId: 4, content: <div><strong>Workspace Info:</strong> Multi-region deployment, high availability setup</div> },
53
+ { rowId: 6, columnId: 5, content: <div><strong>Commit Info:</strong> Author: David Lee, Message: "Security patches applied", SHA: t6y7u8i</div> },
54
+ ];
55
+
56
+ const repositories: Repository[] = [
57
+ { id: 1, name: 'Repository one', branches: 'Branch one', prs: 'Pull request one', workspaces: 'Workspace one', lastCommit: 'Timestamp one', contributors: '25 contributors', stars: '1.2k stars', forks: '340 forks' },
58
+ { id: 2, name: 'Repository two', branches: 'Branch two', prs: 'Pull request two', workspaces: 'Workspace two', lastCommit: 'Timestamp two', contributors: '45 contributors', stars: '3.5k stars', forks: '890 forks' },
59
+ { id: 3, name: 'Repository three', branches: 'Branch three', prs: 'Pull request three', workspaces: 'Workspace three', lastCommit: 'Timestamp three', contributors: '200 contributors', stars: '15k stars', forks: '2.1k forks' },
60
+ { id: 4, name: 'Repository four', branches: 'Branch four', prs: 'Pull request four', workspaces: 'Workspace four', lastCommit: 'Timestamp four', contributors: '80 contributors', stars: '5.7k stars', forks: '1.2k forks' },
61
+ { id: 5, name: 'Repository five', branches: 'Branch five', prs: 'Pull request five', workspaces: 'Workspace five', lastCommit: 'Timestamp five', contributors: '60 contributors', stars: '4.3k stars', forks: '780 forks' },
62
+ { id: 6, name: 'Repository six', branches: 'Branch six', prs: 'Pull request six', workspaces: 'Workspace six', lastCommit: 'Timestamp six', contributors: '300 contributors', stars: '22k stars', forks: '4.5k forks' },
63
+ { id: 7, name: 'Repository seven', branches: 'Branch seven', prs: 'Pull request seven', workspaces: 'Workspace seven', lastCommit: 'Timestamp seven', contributors: '12 contributors', stars: '567 stars', forks: '120 forks' },
64
+ { id: 8, name: 'Repository eight', branches: 'Branch eight', prs: 'Pull request eight', workspaces: 'Workspace eight', lastCommit: 'Timestamp eight', contributors: '98 contributors', stars: '7.8k stars', forks: '1.5k forks' },
65
+ { id: 9, name: 'Repository nine', branches: 'Branch nine', prs: 'Pull request nine', workspaces: 'Workspace nine', lastCommit: 'Timestamp nine', contributors: '33 contributors', stars: '2.1k stars', forks: '456 forks' },
66
+ { id: 10, name: 'Repository ten', branches: 'Branch ten', prs: 'Pull request ten', workspaces: 'Workspace ten', lastCommit: 'Timestamp ten', contributors: '150 contributors', stars: '11k stars', forks: '2.8k forks' },
67
+ { id: 11, name: 'Repository eleven', branches: 'Branch eleven', prs: 'Pull request eleven', workspaces: 'Workspace eleven', lastCommit: 'Timestamp eleven', contributors: '67 contributors', stars: '5.2k stars', forks: '980 forks' },
68
+ { id: 12, name: 'Repository twelve', branches: 'Branch twelve', prs: 'Pull request twelve', workspaces: 'Workspace twelve', lastCommit: 'Timestamp twelve', contributors: '41 contributors', stars: '3.1k stars', forks: '670 forks' },
69
+ { id: 13, name: 'Repository thirteen', branches: 'Branch thirteen', prs: 'Pull request thirteen', workspaces: 'Workspace thirteen', lastCommit: 'Timestamp thirteen', contributors: '89 contributors', stars: '6.4k stars', forks: '1.3k forks' },
70
+ { id: 14, name: 'Repository fourteen', branches: 'Branch fourteen', prs: 'Pull request fourteen', workspaces: 'Workspace fourteen', lastCommit: 'Timestamp fourteen', contributors: '120 contributors', stars: '9.2k stars', forks: '1.9k forks' },
71
+ { id: 15, name: 'Repository fifteen', branches: 'Branch fifteen', prs: 'Pull request fifteen', workspaces: 'Workspace fifteen', lastCommit: 'Timestamp fifteen', contributors: '78 contributors', stars: '5.9k stars', forks: '1.1k forks' }
72
+ ];
73
+
74
+ const ouiaId = 'TableInteractiveExample';
75
+
76
+ export const InteractiveExample: FunctionComponent = () => {
77
+ const [isExpandable, setIsExpandable] = useState(true);
78
+ const [isSticky, setIsSticky] = useState(true);
79
+
80
+ // Generate rows based on current settings
81
+ const rows: DataViewTr[] = repositories.map(({ id, name, branches, prs, workspaces, lastCommit, contributors, stars, forks }) => [
82
+ {
83
+ id,
84
+ cell: workspaces,
85
+ props: {
86
+ favorites: { isFavorited: true }
87
+ }
88
+ },
89
+ { cell: <Button href='#' variant='link' isInline>{name}</Button>, props: { isStickyColumn: isSticky, hasRightBorder: true, hasLeftBorder: true, modifier: "nowrap" } },
90
+ { cell: branches, props: { modifier: "nowrap" } },
91
+ { cell: prs, props: { modifier: "nowrap" } },
92
+ { cell: workspaces, props: { modifier: "nowrap" } },
93
+ { cell: lastCommit, props: { modifier: "nowrap" } },
94
+ { cell: contributors, props: { modifier: "nowrap" } },
95
+ { cell: stars, props: { modifier: "nowrap" } },
96
+ { cell: forks, props: { modifier: "nowrap" } }
97
+ ]);
98
+
99
+ const columns: DataViewTh[] = [
100
+ null,
101
+ { cell: 'Repositories', props: { isStickyColumn: isSticky, modifier: 'fitContent', hasRightBorder: true, hasLeftBorder: true } },
102
+ { cell: <>Branches<ExclamationCircleIcon className='pf-v6-u-ml-sm' color="var(--pf-t--global--color--status--danger--default)"/></>, props: { width: 20 } },
103
+ { cell: 'Pull requests', props: { width: 20 } },
104
+ { cell: 'Workspaces', props: { info: { tooltip: 'More information' }, width: 20 } },
105
+ { cell: 'Last commit', props: { sort: { sortBy: {}, columnIndex: 4 }, width: 20 } },
106
+ { cell: 'Contributors', props: { width: 20 } },
107
+ { cell: 'Stars', props: { width: 20 } },
108
+ { cell: 'Forks', props: { width: 20 } },
109
+ ];
110
+
111
+ return (
112
+ <>
113
+ <Toolbar>
114
+ <ToolbarContent>
115
+ <ToolbarItem>
116
+ <Switch
117
+ id="expandable-switch"
118
+ label="Expandable"
119
+ isChecked={isExpandable}
120
+ onChange={(_event, checked) => setIsExpandable(checked)}
121
+ aria-label="Toggle expandable rows"
122
+ />
123
+ </ToolbarItem>
124
+ <ToolbarItem>
125
+ <Switch
126
+ id="sticky-switch"
127
+ label="Sticky header & column"
128
+ isChecked={isSticky}
129
+ onChange={(_event, checked) => setIsSticky(checked)}
130
+ aria-label="Toggle sticky header and columns"
131
+ />
132
+ </ToolbarItem>
133
+ </ToolbarContent>
134
+ </Toolbar>
135
+ <div style={{ height: '400px', overflow: 'auto' }}>
136
+ <DataViewTable
137
+ aria-label='Interactive repositories table'
138
+ ouiaId={ouiaId}
139
+ columns={columns}
140
+ rows={rows}
141
+ expandedRows={isExpandable ? expandableContents : undefined}
142
+ isExpandable={isExpandable}
143
+ isSticky={isSticky}
144
+ />
145
+ </div>
146
+ </>
147
+ );
148
+ };