@patternfly/react-data-view 7.0.0-prerelease.3 → 7.0.0-prerelease.5

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 (124) hide show
  1. package/dist/cjs/DataView/DataView.d.ts +3 -1
  2. package/dist/cjs/DataViewCheckboxFilter/DataViewCheckboxFilter.d.ts +29 -0
  3. package/dist/cjs/DataViewCheckboxFilter/DataViewCheckboxFilter.js +70 -0
  4. package/dist/cjs/DataViewCheckboxFilter/DataViewCheckboxFilter.test.d.ts +1 -0
  5. package/dist/cjs/DataViewCheckboxFilter/DataViewCheckboxFilter.test.js +25 -0
  6. package/dist/cjs/DataViewCheckboxFilter/index.d.ts +2 -0
  7. package/dist/cjs/DataViewCheckboxFilter/index.js +23 -0
  8. package/dist/cjs/DataViewFilters/DataViewFilters.d.ts +25 -0
  9. package/dist/cjs/DataViewFilters/DataViewFilters.js +85 -0
  10. package/dist/cjs/DataViewFilters/DataViewFilters.test.d.ts +1 -0
  11. package/dist/cjs/DataViewFilters/DataViewFilters.test.js +19 -0
  12. package/dist/cjs/DataViewFilters/index.d.ts +2 -0
  13. package/dist/cjs/DataViewFilters/index.js +23 -0
  14. package/dist/cjs/DataViewTable/DataViewTable.d.ts +8 -0
  15. package/dist/cjs/DataViewTableBasic/DataViewTableBasic.d.ts +1 -0
  16. package/dist/cjs/DataViewTableHead/DataViewTableHead.d.ts +1 -0
  17. package/dist/cjs/DataViewTableTree/DataViewTableTree.d.ts +1 -0
  18. package/dist/cjs/DataViewTableTree/DataViewTableTree.js +26 -14
  19. package/dist/cjs/DataViewTextFilter/DataViewTextFilter.d.ts +21 -0
  20. package/dist/cjs/DataViewTextFilter/DataViewTextFilter.js +26 -0
  21. package/dist/cjs/DataViewTextFilter/DataViewTextFilter.test.d.ts +1 -0
  22. package/dist/cjs/DataViewTextFilter/DataViewTextFilter.test.js +22 -0
  23. package/dist/cjs/DataViewTextFilter/index.d.ts +2 -0
  24. package/dist/cjs/DataViewTextFilter/index.js +23 -0
  25. package/dist/cjs/DataViewToolbar/DataViewToolbar.d.ts +10 -4
  26. package/dist/cjs/DataViewToolbar/DataViewToolbar.js +29 -6
  27. package/dist/cjs/Hooks/filters.d.ts +14 -0
  28. package/dist/cjs/Hooks/filters.js +69 -0
  29. package/dist/cjs/Hooks/filters.test.d.ts +1 -0
  30. package/dist/cjs/Hooks/filters.test.js +50 -0
  31. package/dist/cjs/Hooks/index.d.ts +2 -0
  32. package/dist/cjs/Hooks/index.js +2 -0
  33. package/dist/cjs/Hooks/pagination.d.ts +1 -0
  34. package/dist/cjs/Hooks/selection.d.ts +1 -1
  35. package/dist/cjs/Hooks/selection.js +4 -2
  36. package/dist/cjs/Hooks/sort.d.ts +32 -0
  37. package/dist/cjs/Hooks/sort.js +47 -0
  38. package/dist/cjs/Hooks/sort.test.d.ts +1 -0
  39. package/dist/cjs/Hooks/sort.test.js +68 -0
  40. package/dist/cjs/InternalContext/InternalContext.d.ts +1 -0
  41. package/dist/cjs/index.d.ts +4 -0
  42. package/dist/cjs/index.js +7 -1
  43. package/dist/dynamic/DataViewCheckboxFilter/package.json +1 -0
  44. package/dist/dynamic/DataViewFilters/package.json +1 -0
  45. package/dist/dynamic/DataViewTextFilter/package.json +1 -0
  46. package/dist/esm/DataView/DataView.d.ts +3 -1
  47. package/dist/esm/DataViewCheckboxFilter/DataViewCheckboxFilter.d.ts +29 -0
  48. package/dist/esm/DataViewCheckboxFilter/DataViewCheckboxFilter.js +62 -0
  49. package/dist/esm/DataViewCheckboxFilter/DataViewCheckboxFilter.test.d.ts +1 -0
  50. package/dist/esm/DataViewCheckboxFilter/DataViewCheckboxFilter.test.js +20 -0
  51. package/dist/esm/DataViewCheckboxFilter/index.d.ts +2 -0
  52. package/dist/esm/DataViewCheckboxFilter/index.js +2 -0
  53. package/dist/esm/DataViewFilters/DataViewFilters.d.ts +25 -0
  54. package/dist/esm/DataViewFilters/DataViewFilters.js +58 -0
  55. package/dist/esm/DataViewFilters/DataViewFilters.test.d.ts +1 -0
  56. package/dist/esm/DataViewFilters/DataViewFilters.test.js +14 -0
  57. package/dist/esm/DataViewFilters/index.d.ts +2 -0
  58. package/dist/esm/DataViewFilters/index.js +2 -0
  59. package/dist/esm/DataViewTable/DataViewTable.d.ts +8 -0
  60. package/dist/esm/DataViewTableBasic/DataViewTableBasic.d.ts +1 -0
  61. package/dist/esm/DataViewTableHead/DataViewTableHead.d.ts +1 -0
  62. package/dist/esm/DataViewTableTree/DataViewTableTree.d.ts +1 -0
  63. package/dist/esm/DataViewTableTree/DataViewTableTree.js +26 -14
  64. package/dist/esm/DataViewTextFilter/DataViewTextFilter.d.ts +21 -0
  65. package/dist/esm/DataViewTextFilter/DataViewTextFilter.js +19 -0
  66. package/dist/esm/DataViewTextFilter/DataViewTextFilter.test.d.ts +1 -0
  67. package/dist/esm/DataViewTextFilter/DataViewTextFilter.test.js +17 -0
  68. package/dist/esm/DataViewTextFilter/index.d.ts +2 -0
  69. package/dist/esm/DataViewTextFilter/index.js +2 -0
  70. package/dist/esm/DataViewToolbar/DataViewToolbar.d.ts +10 -4
  71. package/dist/esm/DataViewToolbar/DataViewToolbar.js +7 -4
  72. package/dist/esm/Hooks/filters.d.ts +14 -0
  73. package/dist/esm/Hooks/filters.js +65 -0
  74. package/dist/esm/Hooks/filters.test.d.ts +1 -0
  75. package/dist/esm/Hooks/filters.test.js +48 -0
  76. package/dist/esm/Hooks/index.d.ts +2 -0
  77. package/dist/esm/Hooks/index.js +2 -0
  78. package/dist/esm/Hooks/pagination.d.ts +1 -0
  79. package/dist/esm/Hooks/selection.d.ts +1 -1
  80. package/dist/esm/Hooks/selection.js +4 -2
  81. package/dist/esm/Hooks/sort.d.ts +32 -0
  82. package/dist/esm/Hooks/sort.js +43 -0
  83. package/dist/esm/Hooks/sort.test.d.ts +1 -0
  84. package/dist/esm/Hooks/sort.test.js +66 -0
  85. package/dist/esm/InternalContext/InternalContext.d.ts +1 -0
  86. package/dist/esm/index.d.ts +4 -0
  87. package/dist/esm/index.js +4 -0
  88. package/dist/tsconfig.tsbuildinfo +1 -1
  89. package/package.json +10 -9
  90. package/patternfly-docs/content/extensions/data-view/examples/Components/Components.md +5 -3
  91. package/patternfly-docs/content/extensions/data-view/examples/Components/DataViewTableExample.tsx +1 -1
  92. package/patternfly-docs/content/extensions/data-view/examples/EventsContext/EventsContext.md +1 -0
  93. package/patternfly-docs/content/extensions/data-view/examples/EventsContext/EventsExample.tsx +28 -6
  94. package/patternfly-docs/content/extensions/data-view/examples/Functionality/FiltersExample.tsx +107 -0
  95. package/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md +67 -2
  96. package/patternfly-docs/content/extensions/data-view/examples/Functionality/SortingExample.tsx +87 -0
  97. package/src/DataView/DataView.tsx +3 -2
  98. package/src/DataViewCheckboxFilter/DataViewCheckboxFilter.test.tsx +24 -0
  99. package/src/DataViewCheckboxFilter/DataViewCheckboxFilter.tsx +175 -0
  100. package/src/DataViewCheckboxFilter/__snapshots__/DataViewCheckboxFilter.test.tsx.snap +197 -0
  101. package/src/DataViewCheckboxFilter/index.ts +2 -0
  102. package/src/DataViewFilters/DataViewFilters.test.tsx +21 -0
  103. package/src/DataViewFilters/DataViewFilters.tsx +144 -0
  104. package/src/DataViewFilters/__snapshots__/DataViewFilters.test.tsx.snap +194 -0
  105. package/src/DataViewFilters/index.tsx +2 -0
  106. package/src/DataViewTable/DataViewTable.tsx +23 -3
  107. package/src/DataViewTableBasic/DataViewTableBasic.tsx +1 -0
  108. package/src/DataViewTableHead/DataViewTableHead.tsx +1 -0
  109. package/src/DataViewTableTree/DataViewTableTree.tsx +40 -18
  110. package/src/DataViewTextFilter/DataViewTextFilter.test.tsx +24 -0
  111. package/src/DataViewTextFilter/DataViewTextFilter.tsx +54 -0
  112. package/src/DataViewTextFilter/__snapshots__/DataViewTextFilter.test.tsx.snap +203 -0
  113. package/src/DataViewTextFilter/index.ts +2 -0
  114. package/src/DataViewToolbar/DataViewToolbar.tsx +47 -28
  115. package/src/DataViewToolbar/__snapshots__/DataViewToolbar.test.tsx.snap +44 -0
  116. package/src/Hooks/filters.test.tsx +62 -0
  117. package/src/Hooks/filters.ts +97 -0
  118. package/src/Hooks/index.ts +2 -0
  119. package/src/Hooks/pagination.ts +1 -0
  120. package/src/Hooks/selection.ts +3 -2
  121. package/src/Hooks/sort.test.tsx +84 -0
  122. package/src/Hooks/sort.ts +87 -0
  123. package/src/InternalContext/InternalContext.tsx +1 -0
  124. package/src/index.ts +6 -0
@@ -0,0 +1,66 @@
1
+ import '@testing-library/jest-dom';
2
+ import { renderHook, act } from '@testing-library/react';
3
+ import { useDataViewSort, DataViewSortParams } from './sort';
4
+ describe('useDataViewSort', () => {
5
+ const initialSort = { sortBy: 'name', direction: 'asc' };
6
+ it('should initialize with provided initial sort config', () => {
7
+ const { result } = renderHook(() => useDataViewSort({ initialSort }));
8
+ expect(result.current).toEqual(expect.objectContaining(initialSort));
9
+ });
10
+ it('should initialize with empty sort config if no initialSort is provided', () => {
11
+ const { result } = renderHook(() => useDataViewSort());
12
+ expect(result.current).toEqual(expect.objectContaining({ sortBy: undefined, direction: 'asc' }));
13
+ });
14
+ it('should update sort state when onSort is called', () => {
15
+ const { result } = renderHook(() => useDataViewSort({ initialSort }));
16
+ act(() => {
17
+ result.current.onSort(undefined, 'age', 'desc');
18
+ });
19
+ expect(result.current).toEqual(expect.objectContaining({ sortBy: 'age', direction: 'desc' }));
20
+ });
21
+ it('should sync with URL search params if isUrlSyncEnabled', () => {
22
+ const searchParams = new URLSearchParams();
23
+ const setSearchParams = jest.fn();
24
+ const props = {
25
+ initialSort,
26
+ searchParams,
27
+ setSearchParams,
28
+ };
29
+ const { result } = renderHook(() => useDataViewSort(props));
30
+ expect(setSearchParams).toHaveBeenCalledTimes(1);
31
+ expect(result.current).toEqual(expect.objectContaining(initialSort));
32
+ });
33
+ it('should validate direction and fallback to default direction if invalid direction is provided', () => {
34
+ const searchParams = new URLSearchParams();
35
+ searchParams.set(DataViewSortParams.SORT_BY, 'name');
36
+ searchParams.set(DataViewSortParams.DIRECTION, 'invalid-direction');
37
+ const { result } = renderHook(() => useDataViewSort({ searchParams, defaultDirection: 'desc' }));
38
+ expect(result.current).toEqual(expect.objectContaining({ sortBy: 'name', direction: 'desc' }));
39
+ });
40
+ it('should update search params when URL sync is enabled and sort changes', () => {
41
+ const searchParams = new URLSearchParams();
42
+ const setSearchParams = jest.fn();
43
+ const props = {
44
+ initialSort,
45
+ searchParams,
46
+ setSearchParams,
47
+ };
48
+ const { result } = renderHook(() => useDataViewSort(props));
49
+ act(() => {
50
+ expect(setSearchParams).toHaveBeenCalledTimes(1);
51
+ result.current.onSort(undefined, 'priority', 'desc');
52
+ });
53
+ expect(setSearchParams).toHaveBeenCalledTimes(2);
54
+ expect(result.current).toEqual(expect.objectContaining({ sortBy: 'priority', direction: 'desc' }));
55
+ });
56
+ it('should prioritize searchParams values', () => {
57
+ const searchParams = new URLSearchParams();
58
+ searchParams.set(DataViewSortParams.SORT_BY, 'category');
59
+ searchParams.set(DataViewSortParams.DIRECTION, 'desc');
60
+ const { result } = renderHook((props) => useDataViewSort(props), { initialProps: { initialSort, searchParams } });
61
+ expect(result.current).toEqual(expect.objectContaining({
62
+ sortBy: 'category',
63
+ direction: 'desc',
64
+ }));
65
+ });
66
+ });
@@ -14,6 +14,7 @@ export interface InternalContextProps {
14
14
  /** Currently active state */
15
15
  activeState?: DataViewState | string;
16
16
  }
17
+ /** extends InternalContextProps */
17
18
  export interface InternalContextValue extends InternalContextProps {
18
19
  /** Flag indicating if data view is selectable (auto-calculated) */
19
20
  isSelectable: boolean;
@@ -3,6 +3,8 @@ export * from './InternalContext';
3
3
  export * from './Hooks';
4
4
  export { default as DataViewToolbar } from './DataViewToolbar';
5
5
  export * from './DataViewToolbar';
6
+ export { default as DataViewTextFilter } from './DataViewTextFilter';
7
+ export * from './DataViewTextFilter';
6
8
  export { default as DataViewTableTree } from './DataViewTableTree';
7
9
  export * from './DataViewTableTree';
8
10
  export { default as DataViewTableHead } from './DataViewTableHead';
@@ -13,5 +15,7 @@ export { default as DataViewTable } from './DataViewTable';
13
15
  export * from './DataViewTable';
14
16
  export { default as DataViewEventsContext } from './DataViewEventsContext';
15
17
  export * from './DataViewEventsContext';
18
+ export { default as DataViewCheckboxFilter } from './DataViewCheckboxFilter';
19
+ export * from './DataViewCheckboxFilter';
16
20
  export { default as DataView } from './DataView';
17
21
  export * from './DataView';
package/dist/esm/index.js CHANGED
@@ -4,6 +4,8 @@ export * from './InternalContext';
4
4
  export * from './Hooks';
5
5
  export { default as DataViewToolbar } from './DataViewToolbar';
6
6
  export * from './DataViewToolbar';
7
+ export { default as DataViewTextFilter } from './DataViewTextFilter';
8
+ export * from './DataViewTextFilter';
7
9
  export { default as DataViewTableTree } from './DataViewTableTree';
8
10
  export * from './DataViewTableTree';
9
11
  export { default as DataViewTableHead } from './DataViewTableHead';
@@ -14,5 +16,7 @@ export { default as DataViewTable } from './DataViewTable';
14
16
  export * from './DataViewTable';
15
17
  export { default as DataViewEventsContext } from './DataViewEventsContext';
16
18
  export * from './DataViewEventsContext';
19
+ export { default as DataViewCheckboxFilter } from './DataViewCheckboxFilter';
20
+ export * from './DataViewCheckboxFilter';
17
21
  export { default as DataView } from './DataView';
18
22
  export * from './DataView';
@@ -1 +1 @@
1
- {"root":["../src/index.ts","../src/DataView/DataView.test.tsx","../src/DataView/DataView.tsx","../src/DataView/index.ts","../src/DataViewEventsContext/DataViewEventsContext.test.tsx","../src/DataViewEventsContext/DataViewEventsContext.tsx","../src/DataViewEventsContext/index.ts","../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/DataViewToolbar/DataViewToolbar.test.tsx","../src/DataViewToolbar/DataViewToolbar.tsx","../src/DataViewToolbar/index.ts","../src/Hooks/index.ts","../src/Hooks/pagination.test.tsx","../src/Hooks/pagination.ts","../src/Hooks/selection.test.tsx","../src/Hooks/selection.ts","../src/InternalContext/InternalContext.test.tsx","../src/InternalContext/InternalContext.tsx","../src/InternalContext/index.ts"],"version":"5.6.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/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.6.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-data-view",
3
- "version": "7.0.0-prerelease.3",
3
+ "version": "7.0.0-prerelease.5",
4
4
  "description": "Data view used for Red Hat projects.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -31,10 +31,10 @@
31
31
  "tag": "prerelease"
32
32
  },
33
33
  "dependencies": {
34
- "@patternfly/react-component-groups": "6.0.0-prerelease.7",
35
- "@patternfly/react-core": "6.0.0-prerelease.23",
36
- "@patternfly/react-icons": "6.0.0-prerelease.7",
37
- "@patternfly/react-table": "6.0.0-prerelease.24",
34
+ "@patternfly/react-component-groups": "^6.0.0",
35
+ "@patternfly/react-core": "^6.0.0",
36
+ "@patternfly/react-icons": "^6.0.0",
37
+ "@patternfly/react-table": "^6.0.0",
38
38
  "clsx": "^2.1.1",
39
39
  "react-jss": "^10.10.0"
40
40
  },
@@ -43,16 +43,17 @@
43
43
  "react-dom": "^17 || ^18"
44
44
  },
45
45
  "devDependencies": {
46
- "@patternfly/documentation-framework": "6.0.0-alpha.117",
47
- "@patternfly/patternfly": "6.0.0-prerelease.15",
48
- "@patternfly/patternfly-a11y": "^4.3.1",
46
+ "@patternfly/documentation-framework": "^6.5.0",
47
+ "@patternfly/patternfly": "^6.0.0",
48
+ "@patternfly/react-code-editor": "^6.0.0",
49
+ "@patternfly/patternfly-a11y": "^5.0.0",
49
50
  "@types/react": "^18.3.1",
50
51
  "@types/react-dom": "^18.3.0",
51
52
  "@types/react-router-dom": "^5.3.3",
52
53
  "react": "^18.3.1",
53
54
  "react-dom": "^18.3.1",
54
55
  "react-router": "^6.23.0",
55
- "react-router-dom": "^6.23.0",
56
+ "react-router-dom": "^6.28.0",
56
57
  "rimraf": "^5.0.5",
57
58
  "typescript": "^5.4.5"
58
59
  }
@@ -11,7 +11,7 @@ source: react
11
11
  # If you use typescript, the name of the interface to display props for
12
12
  # These are found through the sourceProps function provided in patternfly-docs.source.js
13
13
  sortValue: 4
14
- propComponents: ['DataViewToolbar', 'DataViewTableBasic', 'DataViewTableTree']
14
+ propComponents: ['DataViewToolbar', 'DataViewTableBasic', 'DataViewTableTree', 'DataViewTrTree', 'DataViewTrObject']
15
15
  sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/Components.md
16
16
  ---
17
17
  import { Button, EmptyState, EmptyStateActions, EmptyStateBody, EmptyStateFooter } from '@patternfly/react-core';
@@ -26,7 +26,7 @@ import { DataView, DataViewState } from '@patternfly/react-data-view/dist/dynami
26
26
 
27
27
  The **data view toolbar** component renders a default opinionated data view toolbar above or below the data section.
28
28
 
29
- Data view toolbar can contain a `pagination`, `bulkSelect`, `actions` or other children content passed. The preffered way of passing children toolbar items is using the [toolbar item](/components/toolbar#toolbar-items) component.
29
+ Data view toolbar can contain a `pagination`, `bulkSelect`, `filters`, `actions` or other children content passed. The preffered way of passing children toolbar items is using the [toolbar item](/components/toolbar#toolbar-items) component.
30
30
 
31
31
  ### Basic toolbar example
32
32
 
@@ -72,13 +72,15 @@ The `DataViewTable` component accepts the following props:
72
72
 
73
73
  - optional `props` (`TableProps`) that are passed down to the `<Table>` component, except for `onSelect`, which is managed internally.
74
74
 
75
+ It is also possible to disable row selection using the `isSelectDisabled` function passed to the wrapping data view component through `selection`.
76
+
75
77
  ### Tree table example
76
78
  This example shows the tree table variant with expandable rows, custom icons for leaf and parent nodes. Tree table is turned on by passing `isTreeTable` flag to the `DataViewTable` component. You can pass `collapsedIcon`, `expandedIcon` or `leafIcon` to be displayen rows with given status. The tree table rows have to be defined in a format of object with following keys:
77
79
  - `row` (`DataViewTd[]`) defining the content for each cell in the row.
78
80
  - `id` (`string`) for the row (used to match items in selection end expand the rows).
79
81
  - optional `children` (`DataViewTrTree[]`) defining the children rows.
80
82
 
81
- It is also possible to disable row selection using the `isSelectDisabled` function passed to the wrapping data view component.
83
+ It is also possible to disable row selection using the `isSelectDisabled` function passed to the wrapping data view component through `selection`.
82
84
 
83
85
  ```js file="./DataViewTableTreeExample.tsx"
84
86
 
@@ -54,7 +54,7 @@ const rows: DataViewTr[] = repositories.map(({ id, name, branches, prs, workspac
54
54
  const columns: DataViewTh[] = [
55
55
  null,
56
56
  'Repositories',
57
- { cell: <>Branches<ExclamationCircleIcon className='pf-v5-u-ml-sm' color="var(--pf-t--temp--dev--tbd)"/* CODEMODS: original v5 color was --pf-v5-global--danger-color--100 *//></> },
57
+ { cell: <>Branches<ExclamationCircleIcon className='pf-v6-u-ml-sm' color="var(--pf-t--global--color--status--danger--default)"/></> },
58
58
  'Pull requests',
59
59
  { cell: 'Workspaces', props: { info: { tooltip: 'More information' } } },
60
60
  { cell: 'Last commit', props: { sort: { sortBy: {}, columnIndex: 4 } } },
@@ -18,6 +18,7 @@ import { Table, Tbody, Th, Thead, Tr, Td } from '@patternfly/react-table';
18
18
  import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
19
19
  import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
20
20
  import { useDataViewEventsContext, DataViewEventsContext, DataViewEventsProvider, EventTypes } from '@patternfly/react-data-view/dist/dynamic/DataViewEventsContext';
21
+ import { useDataViewSelection } from '@patternfly/react-data-view/dist/dynamic/Hooks';
21
22
  import { Drawer, DrawerContent, DrawerContentBody } from '@patternfly/react-core';
22
23
 
23
24
  The **data view events context** provides a way of listening to the data view events from the outside of the component.
@@ -3,6 +3,8 @@ import { Drawer, DrawerActions, DrawerCloseButton, DrawerContent, DrawerContentB
3
3
  import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
4
4
  import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
5
5
  import { DataViewEventsProvider, EventTypes, useDataViewEventsContext } from '@patternfly/react-data-view/dist/dynamic/DataViewEventsContext';
6
+ import { useDataViewSelection } from '@patternfly/react-data-view/dist/dynamic/Hooks';
7
+ import { ActionsColumn } from '@patternfly/react-table';
6
8
 
7
9
  interface Repository {
8
10
  name: string;
@@ -45,7 +47,7 @@ const RepositoryDetail: React.FunctionComponent<RepositoryDetailProps> = ({ sele
45
47
  return (
46
48
  <DrawerPanelContent>
47
49
  <DrawerHead>
48
- <Title className="pf-v5-u-mb-md" headingLevel="h2" ouiaId="detail-drawer-title">
50
+ <Title className="pf-v6-u-mb-md" headingLevel="h2" ouiaId="detail-drawer-title">
49
51
  Detail of {selectedRepo?.name}
50
52
  </Title>
51
53
  <Content component="p">Branches: {selectedRepo?.branches}</Content>
@@ -64,25 +66,45 @@ interface RepositoriesTableProps {
64
66
  selectedRepo?: Repository;
65
67
  }
66
68
 
69
+ const rowActions = [
70
+ {
71
+ title: 'Some action',
72
+ onClick: () => console.log('clicked on Some action') // eslint-disable-line no-console
73
+ },
74
+ {
75
+ title: <div>Another action</div>,
76
+ onClick: () => console.log('clicked on Another action') // eslint-disable-line no-console
77
+ },
78
+ {
79
+ isSeparator: true
80
+ },
81
+ {
82
+ title: 'Third action',
83
+ onClick: () => console.log('clicked on Third action') // eslint-disable-line no-console
84
+ }
85
+ ];
86
+
67
87
  const RepositoriesTable: React.FunctionComponent<RepositoriesTableProps> = ({ selectedRepo = undefined }) => {
88
+ const selection = useDataViewSelection({ matchOption: (a, b) => a.row[0] === b.row[0] });
68
89
  const { trigger } = useDataViewEventsContext();
69
90
  const rows = useMemo(() => {
70
- const handleRowClick = (repo: Repository | undefined) => {
71
- trigger(EventTypes.rowClick, repo);
91
+ const handleRowClick = (event, repo: Repository | undefined) => {
92
+ // prevents drawer toggle on actions or checkbox click
93
+ (event.target.matches('td') || event.target.matches('tr')) && trigger(EventTypes.rowClick, repo);
72
94
  };
73
95
 
74
96
  return repositories.map(repo => ({
75
- row: Object.values(repo),
97
+ row: [ ...Object.values(repo), { cell: <ActionsColumn items={rowActions}/>, props: { isActionCell: true } } ],
76
98
  props: {
77
99
  isClickable: true,
78
- onRowClick: () => handleRowClick(selectedRepo?.name === repo.name ? undefined : repo),
100
+ onRowClick: (event) => handleRowClick(event, selectedRepo?.name === repo.name ? undefined : repo),
79
101
  isRowSelected: selectedRepo?.name === repo.name
80
102
  }
81
103
  }));
82
104
  }, [ selectedRepo?.name, trigger ]);
83
105
 
84
106
  return (
85
- <DataView>
107
+ <DataView selection={selection}>
86
108
  <DataViewTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={rows} />
87
109
  </DataView>
88
110
  );
@@ -0,0 +1,107 @@
1
+ import React, { useMemo } from 'react';
2
+ import { Pagination } from '@patternfly/react-core';
3
+ import { BrowserRouter, useSearchParams } from 'react-router-dom';
4
+ import { useDataViewFilters, useDataViewPagination } from '@patternfly/react-data-view/dist/dynamic/Hooks';
5
+ import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
6
+ import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
7
+ import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
8
+ import { DataViewFilterOption, DataViewFilters } from '@patternfly/react-data-view/dist/dynamic/DataViewFilters';
9
+ import { DataViewTextFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewTextFilter';
10
+ import { DataViewCheckboxFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewCheckboxFilter';
11
+
12
+ const perPageOptions = [
13
+ { title: '5', value: 5 },
14
+ { title: '10', value: 10 }
15
+ ];
16
+
17
+ interface Repository {
18
+ name: string;
19
+ branch: string | null;
20
+ prs: string | null;
21
+ workspace: string;
22
+ lastCommit: string;
23
+ }
24
+
25
+ interface RepositoryFilters {
26
+ name: string,
27
+ branch: string,
28
+ workspace: string[]
29
+ }
30
+
31
+ const repositories: Repository[] = [
32
+ { name: 'Repository one', branch: 'Branch one', prs: 'Pull request one', workspace: 'Workspace one', lastCommit: 'Timestamp one' },
33
+ { name: 'Repository two', branch: 'Branch two', prs: 'Pull request two', workspace: 'Workspace two', lastCommit: 'Timestamp two' },
34
+ { name: 'Repository three', branch: 'Branch three', prs: 'Pull request three', workspace: 'Workspace one', lastCommit: 'Timestamp three' },
35
+ { name: 'Repository four', branch: 'Branch four', prs: 'Pull request four', workspace: 'Workspace one', lastCommit: 'Timestamp four' },
36
+ { name: 'Repository five', branch: 'Branch five', prs: 'Pull request five', workspace: 'Workspace two', lastCommit: 'Timestamp five' },
37
+ { name: 'Repository six', branch: 'Branch six', prs: 'Pull request six', workspace: 'Workspace three', lastCommit: 'Timestamp six' }
38
+ ];
39
+
40
+ const filterOptions: DataViewFilterOption[] = [
41
+ { label: 'Workspace one', value: 'workspace-one' },
42
+ { label: 'Workspace two', value: 'workspace-two' },
43
+ { label: 'Workspace three', value: 'workspace-three' }
44
+ ];
45
+
46
+ const columns = [ 'Name', 'Branch', 'Pull requests', 'Workspace', 'Last commit' ];
47
+
48
+ const ouiaId = 'LayoutExample';
49
+
50
+ const MyTable: React.FunctionComponent = () => {
51
+ const [ searchParams, setSearchParams ] = useSearchParams();
52
+ const { filters, onSetFilters, clearAllFilters } = useDataViewFilters<RepositoryFilters>({ initialFilters: { name: '', branch: '', workspace: [] }, searchParams, setSearchParams });
53
+ const pagination = useDataViewPagination({ perPage: 5 });
54
+ const { page, perPage } = pagination;
55
+
56
+ const filteredData = useMemo(() => repositories.filter(item =>
57
+ (!filters.name || item.name?.toLocaleLowerCase().includes(filters.name?.toLocaleLowerCase())) &&
58
+ (!filters.branch || item.branch?.toLocaleLowerCase().includes(filters.branch?.toLocaleLowerCase())) &&
59
+ (!filters.workspace || filters.workspace.length === 0 || filters.workspace.includes(String(filterOptions.find(option => option.label === item.workspace)?.value)))
60
+ ), [ filters ]);
61
+
62
+ const pageRows = useMemo(() => filteredData
63
+ .slice((page - 1) * perPage, ((page - 1) * perPage) + perPage)
64
+ .map(item => Object.values(item)),
65
+ [ page, perPage, filteredData ]);
66
+
67
+ return (
68
+ <DataView>
69
+ <DataViewToolbar
70
+ ouiaId='LayoutExampleHeader'
71
+ clearAllFilters = {clearAllFilters}
72
+ pagination={
73
+ <Pagination
74
+ perPageOptions={perPageOptions}
75
+ itemCount={filteredData.length}
76
+ {...pagination}
77
+ />
78
+ }
79
+ filters={
80
+ <DataViewFilters onChange={(_e, values) => onSetFilters(values)} values={filters}>
81
+ <DataViewTextFilter filterId="name" title='Name' placeholder='Filter by name' />
82
+ <DataViewTextFilter filterId="branch" title='Branch' placeholder='Filter by branch' />
83
+ <DataViewCheckboxFilter filterId="workspace" title='Workspace' placeholder='Filter by workspace' options={filterOptions} />
84
+ </DataViewFilters>
85
+ }
86
+ />
87
+ <DataViewTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={pageRows} />
88
+ <DataViewToolbar
89
+ ouiaId='LayoutExampleFooter'
90
+ pagination={
91
+ <Pagination
92
+ isCompact
93
+ perPageOptions={perPageOptions}
94
+ itemCount={filteredData.length}
95
+ {...pagination}
96
+ />
97
+ }
98
+ />
99
+ </DataView>
100
+ );
101
+ }
102
+
103
+ export const BasicExample: React.FunctionComponent = () => (
104
+ <BrowserRouter>
105
+ <MyTable/>
106
+ </BrowserRouter>
107
+ )
@@ -11,16 +11,19 @@ source: react
11
11
  # If you use typescript, the name of the interface to display props for
12
12
  # These are found through the sourceProps function provided in patternfly-docs.source.js
13
13
  sortValue: 3
14
+ propComponents: ['DataViewFilters', 'DataViewTextFilter', 'DataViewCheckboxFilter']
14
15
  sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md
15
16
  ---
16
17
  import { useMemo } from 'react';
17
18
  import { BrowserRouter, useSearchParams } from 'react-router-dom';
18
- import { useDataViewPagination, useDataViewSelection } from '@patternfly/react-data-view/dist/dynamic/Hooks';
19
+ import { useDataViewPagination, useDataViewSelection, useDataViewFilters, useDataViewSort } from '@patternfly/react-data-view/dist/dynamic/Hooks';
19
20
  import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
20
21
  import { BulkSelect, BulkSelectValue } from '@patternfly/react-component-groups/dist/dynamic/BulkSelect';
21
22
  import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
22
23
  import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
23
-
24
+ import { DataViewFilters } from '@patternfly/react-data-view/dist/dynamic/DataViewFilters';
25
+ import { DataViewTextFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewTextFilter';
26
+ import { DataViewCheckboxFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewCheckboxFilter';
24
27
 
25
28
  This is a list of functionality you can use to manage data displayed in the **data view**.
26
29
 
@@ -83,3 +86,65 @@ The `useDataViewSelection` hook manages the selection state of the data view.
83
86
  ```js file="./SelectionExample.tsx"
84
87
 
85
88
  ```
89
+
90
+ # Filters
91
+ Enables filtering of data records in the data view and displays the applied filter labels.
92
+
93
+ ### Toolbar usage
94
+ The data view toolbar can include a set of filters by passing a React node to the `filters` property. You can use predefined components `DataViewFilters`, `DataViewTextFilter` and `DataViewCheckboxFilter` to customize and handle filtering directly in the toolbar. The `DataViewFilters` is a wrapper allowing conditional filtering using multiple attributes. If you need just a single filter, you can use `DataViewTextFilter`, `DataViewCheckboxFilter` or a different filter component alone. Props of these filter components are listed at the bottom of this page.
95
+
96
+ You can decide between passing `value` and `onChange` event to every filter separately or pass `values` and `onChange` to the `DataViewFilters` wrapper which make them available to its children. Props directly passed to child filters have a higher priority than the "inherited" ones.
97
+
98
+ ### Filters state
99
+
100
+ The `useDataViewFilters` hook manages the filter state of the data view. It allows you to define default filter values, synchronize filter state with URL parameters, and handle filter changes efficiently.
101
+
102
+ **Initial values:**
103
+ - `initialFilters` object with default filter values (if the filter param allows multiple values, pass an array)
104
+ - optional `searchParams` object for managing URL-based filter state
105
+ - optional `setSearchParams` function to update the URL when filters are modified
106
+
107
+ The `useDataViewFilters` hook works well with the React Router library to support URL-based filtering. Alternatively, you can manage filter state in the URL using `URLSearchParams` and `window.history.pushState` APIs, or other routing libraries. If no URL parameters are provided, the filter state is managed internally.
108
+
109
+ **Return values:**
110
+ - `filters` object representing the current filter values
111
+ - `onSetFilters` function to update the filter state
112
+ - `clearAllFilters` function to reset all filters to their initial values
113
+
114
+ ### Filtering example
115
+ This example demonstrates the setup and usage of filters within the data view. It includes text filters for different attributes, the ability to clear all filters, and persistence of filter state in the URL.
116
+
117
+ ```js file="./FiltersExample.tsx"
118
+
119
+ ```
120
+
121
+ ### Sort state
122
+
123
+ The `useDataViewSort` hook manages the sorting state of a data view. It provides an easy way to handle sorting logic, including synchronization with URL parameters and defining default sorting behavior.
124
+
125
+ **Initial values:**
126
+ - `initialSort` object to set default `sortBy` and `direction` values:
127
+ - `sortBy`: key of the initial column to sort.
128
+ - `direction`: default sorting direction (`asc` or `desc`).
129
+ - Optional `searchParams` object to manage URL-based synchronization of sort state.
130
+ - Optional `setSearchParams` function to update the URL parameters when sorting changes.
131
+ - `defaultDirection` to set the default direction when no direction is specified.
132
+ - Customizable parameter names for the URL:
133
+ - `sortByParam`: name of the URL parameter for the column key.
134
+ - `directionParam`: name of the URL parameter for the sorting direction.
135
+
136
+ The `useDataViewSort` hook integrates seamlessly with React Router to manage sort state via URL parameters. Alternatively, you can use `URLSearchParams` and `window.history.pushState` APIs, or other routing libraries. If URL synchronization is not configured, the sort state is managed internally within the component.
137
+
138
+ **Return values:**
139
+ - `sortBy`: key of the column currently being sorted.
140
+ - `direction`: current sorting direction (`asc` or `desc`).
141
+ - `onSort`: function to handle sorting changes programmatically or via user interaction.
142
+
143
+ ### Sorting example
144
+
145
+ This example demonstrates how to set up and use sorting functionality within a data view. The implementation includes dynamic sorting by column with persistence of sort state in the URL using React Router.
146
+
147
+
148
+ ```js file="./SortingExample.tsx"
149
+
150
+ ```
@@ -0,0 +1,87 @@
1
+ /* eslint-disable no-nested-ternary */
2
+ import React, { useMemo } from 'react';
3
+ import { useDataViewSort } from '@patternfly/react-data-view/dist/dynamic/Hooks';
4
+ import { DataViewTable, DataViewTr, DataViewTh } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
5
+ import { ThProps } from '@patternfly/react-table';
6
+ import { BrowserRouter, useSearchParams } from 'react-router-dom';
7
+
8
+ interface Repository {
9
+ name: string;
10
+ branches: string;
11
+ prs: string;
12
+ workspaces: string;
13
+ lastCommit: string;
14
+ };
15
+
16
+ const COLUMNS = [
17
+ { label: 'Repository', key: 'name', index: 0 },
18
+ { label: 'Branch', key: 'branches', index: 1 },
19
+ { label: 'Pull request', key: 'prs', index: 2 },
20
+ { label: 'Workspace', key: 'workspaces', index: 3 },
21
+ { label: 'Last commit', key: 'lastCommit', index: 4 }
22
+ ];
23
+
24
+ const repositories: Repository[] = [
25
+ { name: 'Repository one', branches: 'Branch one', prs: 'Pull request one', workspaces: 'Workspace one', lastCommit: 'Timestamp one' },
26
+ { name: 'Repository two', branches: 'Branch two', prs: 'Pull request two', workspaces: 'Workspace two', lastCommit: 'Timestamp two' },
27
+ { name: 'Repository three', branches: 'Branch three', prs: 'Pull request three', workspaces: 'Workspace three', lastCommit: 'Timestamp three' },
28
+ { name: 'Repository four', branches: 'Branch four', prs: 'Pull request four', workspaces: 'Workspace four', lastCommit: 'Timestamp four' },
29
+ { name: 'Repository five', branches: 'Branch five', prs: 'Pull request five', workspaces: 'Workspace five', lastCommit: 'Timestamp five' },
30
+ { name: 'Repository six', branches: 'Branch six', prs: 'Pull request six', workspaces: 'Workspace six', lastCommit: 'Timestamp six' }
31
+ ];
32
+
33
+ const sortData = (data: Repository[], sortBy: string | undefined, direction: 'asc' | 'desc' | undefined) =>
34
+ sortBy && direction
35
+ ? [ ...data ].sort((a, b) =>
36
+ direction === 'asc'
37
+ ? a[sortBy] < b[sortBy] ? -1 : a[sortBy] > b[sortBy] ? 1 : 0
38
+ : a[sortBy] > b[sortBy] ? -1 : a[sortBy] < b[sortBy] ? 1 : 0
39
+ )
40
+ : data;
41
+
42
+ const ouiaId = 'TableExample';
43
+
44
+ export const MyTable: React.FunctionComponent = () => {
45
+ const [ searchParams, setSearchParams ] = useSearchParams();
46
+ const { sortBy, direction, onSort } = useDataViewSort({ searchParams, setSearchParams });
47
+ const sortByIndex = useMemo(() => COLUMNS.findIndex(item => item.key === sortBy), [ sortBy ]);
48
+
49
+ const getSortParams = (columnIndex: number): ThProps['sort'] => ({
50
+ sortBy: {
51
+ index: sortByIndex,
52
+ direction,
53
+ defaultDirection: 'asc'
54
+ },
55
+ onSort: (_event, index, direction) => onSort(_event, COLUMNS[index].key, direction),
56
+ columnIndex
57
+ });
58
+
59
+ const columns: DataViewTh[] = COLUMNS.map((column, index) => ({
60
+ cell: column.label,
61
+ props: { sort: getSortParams(index) }
62
+ }));
63
+
64
+ const rows: DataViewTr[] = useMemo(() => sortData(repositories, sortBy, direction).map(({ name, branches, prs, workspaces, lastCommit }) => [
65
+ name,
66
+ branches,
67
+ prs,
68
+ workspaces,
69
+ lastCommit,
70
+ ]), [ sortBy, direction ]);
71
+
72
+ return (
73
+ <DataViewTable
74
+ aria-label="Repositories table"
75
+ ouiaId={ouiaId}
76
+ columns={columns}
77
+ rows={rows}
78
+ />
79
+ );
80
+ };
81
+
82
+ export const BasicExample: React.FunctionComponent = () => (
83
+ <BrowserRouter>
84
+ <MyTable/>
85
+ </BrowserRouter>
86
+ )
87
+
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { Stack, StackItem } from '@patternfly/react-core';
2
+ import { Stack, StackItem, StackProps } from '@patternfly/react-core';
3
3
  import { DataViewSelection, InternalContextProvider } from '../InternalContext';
4
4
 
5
5
  export const DataViewState = {
@@ -10,7 +10,8 @@ export const DataViewState = {
10
10
 
11
11
  export type DataViewState = typeof DataViewState[keyof typeof DataViewState];
12
12
 
13
- export interface DataViewProps {
13
+ /** extends StackProps */
14
+ export interface DataViewProps extends StackProps {
14
15
  /** Content rendered inside the data view */
15
16
  children: React.ReactNode;
16
17
  /** Custom OUIA ID */
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { render } from '@testing-library/react';
3
+ import DataViewCheckboxFilter, { DataViewCheckboxFilterProps } from './DataViewCheckboxFilter';
4
+ import DataViewToolbar from '../DataViewToolbar';
5
+
6
+ describe('DataViewCheckboxFilter component', () => {
7
+ const defaultProps: DataViewCheckboxFilterProps = {
8
+ filterId: 'test-checkbox-filter',
9
+ title: 'Test Checkbox Filter',
10
+ value: [ 'workspace-one' ],
11
+ options: [
12
+ { label: 'Workspace one', value: 'workspace-one' },
13
+ { label: 'Workspace two', value: 'workspace-two' },
14
+ { label: 'Workspace three', value: 'workspace-three' },
15
+ ],
16
+ };
17
+
18
+ it('should render correctly', () => {
19
+ const { container } = render(
20
+ <DataViewToolbar filters={<DataViewCheckboxFilter {...defaultProps} />} />
21
+ );
22
+ expect(container).toMatchSnapshot();
23
+ });
24
+ });