@navikt/ds-react 8.10.1 → 8.10.3

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 (114) hide show
  1. package/cjs/data/table/column-header/DataTableColumnHeader.d.ts +1 -1
  2. package/cjs/data/table/column-header/DataTableColumnHeader.js +16 -11
  3. package/cjs/data/table/column-header/DataTableColumnHeader.js.map +1 -1
  4. package/cjs/data/table/column-header/useTableColumnResize.d.ts +28 -4
  5. package/cjs/data/table/column-header/useTableColumnResize.js +144 -53
  6. package/cjs/data/table/column-header/useTableColumnResize.js.map +1 -1
  7. package/cjs/data/table/helpers/collectTableRowEntries.d.ts +24 -0
  8. package/cjs/data/table/helpers/collectTableRowEntries.js +35 -0
  9. package/cjs/data/table/helpers/collectTableRowEntries.js.map +1 -0
  10. package/cjs/data/table/helpers/selection/SelectionSubtreeHelper.d.ts +46 -0
  11. package/cjs/data/table/helpers/selection/SelectionSubtreeHelper.js +112 -0
  12. package/cjs/data/table/helpers/selection/SelectionSubtreeHelper.js.map +1 -0
  13. package/cjs/data/table/helpers/selection/getMultipleSelectProps.d.ts +3 -2
  14. package/cjs/data/table/helpers/selection/getMultipleSelectProps.js +43 -19
  15. package/cjs/data/table/helpers/selection/getMultipleSelectProps.js.map +1 -1
  16. package/cjs/data/table/helpers/selection/selection.types.d.ts +1 -0
  17. package/cjs/data/table/helpers/table-keyboard.d.ts +1 -2
  18. package/cjs/data/table/helpers/table-keyboard.js +1 -5
  19. package/cjs/data/table/helpers/table-keyboard.js.map +1 -1
  20. package/cjs/data/table/hooks/useTableExpansion.d.ts +7 -6
  21. package/cjs/data/table/hooks/useTableExpansion.js +42 -15
  22. package/cjs/data/table/hooks/useTableExpansion.js.map +1 -1
  23. package/cjs/data/table/hooks/useTableItems.d.ts +33 -0
  24. package/cjs/data/table/hooks/useTableItems.js +74 -0
  25. package/cjs/data/table/hooks/useTableItems.js.map +1 -0
  26. package/cjs/data/table/hooks/useTableKeyboardNav.js +3 -3
  27. package/cjs/data/table/hooks/useTableKeyboardNav.js.map +1 -1
  28. package/cjs/data/table/hooks/useTableSelection.d.ts +3 -2
  29. package/cjs/data/table/hooks/useTableSelection.js +5 -4
  30. package/cjs/data/table/hooks/useTableSelection.js.map +1 -1
  31. package/cjs/data/table/root/DataTable.types.d.ts +5 -4
  32. package/cjs/data/table/root/DataTableAuto.d.ts +27 -1
  33. package/cjs/data/table/root/DataTableAuto.js +92 -50
  34. package/cjs/data/table/root/DataTableAuto.js.map +1 -1
  35. package/cjs/data/table/root/DataTableRoot.context.d.ts +5 -3
  36. package/cjs/data/table/root/DataTableRoot.context.js.map +1 -1
  37. package/cjs/data/table/root/DataTableRoot.js +6 -4
  38. package/cjs/data/table/root/DataTableRoot.js.map +1 -1
  39. package/cjs/data/table/tr/DataTableTr.js +30 -32
  40. package/cjs/data/table/tr/DataTableTr.js.map +1 -1
  41. package/cjs/form/checkbox/Checkbox.js +1 -0
  42. package/cjs/form/checkbox/Checkbox.js.map +1 -1
  43. package/cjs/form/radio/Radio.js +7 -1
  44. package/cjs/form/radio/Radio.js.map +1 -1
  45. package/cjs/modal/types.d.ts +8 -4
  46. package/esm/data/table/column-header/DataTableColumnHeader.d.ts +1 -1
  47. package/esm/data/table/column-header/DataTableColumnHeader.js +17 -12
  48. package/esm/data/table/column-header/DataTableColumnHeader.js.map +1 -1
  49. package/esm/data/table/column-header/useTableColumnResize.d.ts +28 -4
  50. package/esm/data/table/column-header/useTableColumnResize.js +145 -54
  51. package/esm/data/table/column-header/useTableColumnResize.js.map +1 -1
  52. package/esm/data/table/helpers/collectTableRowEntries.d.ts +24 -0
  53. package/esm/data/table/helpers/collectTableRowEntries.js +33 -0
  54. package/esm/data/table/helpers/collectTableRowEntries.js.map +1 -0
  55. package/esm/data/table/helpers/selection/SelectionSubtreeHelper.d.ts +46 -0
  56. package/esm/data/table/helpers/selection/SelectionSubtreeHelper.js +109 -0
  57. package/esm/data/table/helpers/selection/SelectionSubtreeHelper.js.map +1 -0
  58. package/esm/data/table/helpers/selection/getMultipleSelectProps.d.ts +3 -2
  59. package/esm/data/table/helpers/selection/getMultipleSelectProps.js +43 -19
  60. package/esm/data/table/helpers/selection/getMultipleSelectProps.js.map +1 -1
  61. package/esm/data/table/helpers/selection/selection.types.d.ts +1 -0
  62. package/esm/data/table/helpers/table-keyboard.d.ts +1 -2
  63. package/esm/data/table/helpers/table-keyboard.js +1 -5
  64. package/esm/data/table/helpers/table-keyboard.js.map +1 -1
  65. package/esm/data/table/hooks/useTableExpansion.d.ts +7 -6
  66. package/esm/data/table/hooks/useTableExpansion.js +42 -16
  67. package/esm/data/table/hooks/useTableExpansion.js.map +1 -1
  68. package/esm/data/table/hooks/useTableItems.d.ts +33 -0
  69. package/esm/data/table/hooks/useTableItems.js +69 -0
  70. package/esm/data/table/hooks/useTableItems.js.map +1 -0
  71. package/esm/data/table/hooks/useTableKeyboardNav.js +3 -3
  72. package/esm/data/table/hooks/useTableKeyboardNav.js.map +1 -1
  73. package/esm/data/table/hooks/useTableSelection.d.ts +3 -2
  74. package/esm/data/table/hooks/useTableSelection.js +5 -4
  75. package/esm/data/table/hooks/useTableSelection.js.map +1 -1
  76. package/esm/data/table/root/DataTable.types.d.ts +5 -4
  77. package/esm/data/table/root/DataTableAuto.d.ts +27 -1
  78. package/esm/data/table/root/DataTableAuto.js +94 -52
  79. package/esm/data/table/root/DataTableAuto.js.map +1 -1
  80. package/esm/data/table/root/DataTableRoot.context.d.ts +5 -3
  81. package/esm/data/table/root/DataTableRoot.context.js.map +1 -1
  82. package/esm/data/table/root/DataTableRoot.js +7 -5
  83. package/esm/data/table/root/DataTableRoot.js.map +1 -1
  84. package/esm/data/table/tr/DataTableTr.js +32 -34
  85. package/esm/data/table/tr/DataTableTr.js.map +1 -1
  86. package/esm/form/checkbox/Checkbox.js +1 -0
  87. package/esm/form/checkbox/Checkbox.js.map +1 -1
  88. package/esm/form/radio/Radio.js +7 -1
  89. package/esm/form/radio/Radio.js.map +1 -1
  90. package/esm/modal/types.d.ts +8 -4
  91. package/package.json +7 -7
  92. package/src/data/table/column-header/DataTableColumnHeader.tsx +26 -14
  93. package/src/data/table/column-header/useTableColumnResize.ts +209 -80
  94. package/src/data/table/helpers/collectTableRowEntries.ts +90 -0
  95. package/src/data/table/helpers/selection/SelectionSubtreeHelper.test.ts +66 -0
  96. package/src/data/table/helpers/selection/SelectionSubtreeHelper.ts +162 -0
  97. package/src/data/table/helpers/selection/getMultipleSelectProps.ts +57 -20
  98. package/src/data/table/helpers/selection/selection.types.ts +1 -0
  99. package/src/data/table/helpers/table-keyboard.ts +1 -6
  100. package/src/data/table/hooks/__tests__/useTableItems.test.ts +145 -0
  101. package/src/data/table/hooks/__tests__/useTableSelection.test.ts +132 -21
  102. package/src/data/table/hooks/useTableExpansion.tsx +68 -22
  103. package/src/data/table/hooks/useTableItems.ts +146 -0
  104. package/src/data/table/hooks/useTableKeyboardNav.ts +3 -3
  105. package/src/data/table/hooks/useTableSelection.ts +10 -6
  106. package/src/data/table/root/DataTable.types.ts +5 -4
  107. package/src/data/table/root/DataTableAuto.test.tsx +244 -0
  108. package/src/data/table/root/DataTableAuto.tsx +260 -141
  109. package/src/data/table/root/DataTableRoot.context.ts +4 -2
  110. package/src/data/table/root/DataTableRoot.tsx +22 -16
  111. package/src/data/table/tr/DataTableTr.tsx +48 -47
  112. package/src/form/checkbox/Checkbox.tsx +1 -0
  113. package/src/form/radio/Radio.tsx +7 -1
  114. package/src/modal/types.ts +8 -4
@@ -0,0 +1,244 @@
1
+ import { fireEvent, render, screen } from "@testing-library/react";
2
+ import React from "react";
3
+ import { describe, expect, test } from "vitest";
4
+ import { DataTableColumnHeader } from "../column-header/DataTableColumnHeader";
5
+ import type { ColumnDefinitions } from "./DataTable.types";
6
+ import { DataTableAuto } from "./DataTableAuto";
7
+ import { DataTable } from "./DataTableRoot";
8
+
9
+ type TestRow = {
10
+ id: string;
11
+ name: string;
12
+ subRows?: TestRow[];
13
+ };
14
+
15
+ const data: TestRow[] = [
16
+ {
17
+ id: "root",
18
+ name: "Root",
19
+ subRows: [{ id: "child", name: "Child" }],
20
+ },
21
+ ];
22
+
23
+ const deepNestedData: TestRow[] = [
24
+ {
25
+ id: "root",
26
+ name: "Root",
27
+ subRows: [
28
+ {
29
+ id: "child",
30
+ name: "Child",
31
+ subRows: [{ id: "grandchild", name: "Grandchild" }],
32
+ },
33
+ ],
34
+ },
35
+ ];
36
+
37
+ const fallbackIdData: TestRow[] = [
38
+ {
39
+ id: "unused-root-1",
40
+ name: "Root",
41
+ subRows: [{ id: "unused-child", name: "Child" }],
42
+ },
43
+ {
44
+ id: "unused-root-2",
45
+ name: "Sibling",
46
+ },
47
+ ];
48
+
49
+ const columns: ColumnDefinitions<TestRow> = [
50
+ {
51
+ id: "name",
52
+ label: "Name",
53
+ header: "Name",
54
+ cell: (row) => row.name,
55
+ },
56
+ ];
57
+
58
+ describe("DataTableAuto", () => {
59
+ test("renders expanded child rows and includes them in select-all", () => {
60
+ render(
61
+ <DataTableAuto
62
+ columnDefinitions={columns}
63
+ data={data}
64
+ getRowId={(row) => row.id}
65
+ getSubRows={(row) => row.subRows ?? []}
66
+ selection={{ selectionMode: "multiple" }}
67
+ />,
68
+ );
69
+
70
+ expect(screen.queryByText("Child")).not.toBeInTheDocument();
71
+
72
+ fireEvent.click(screen.getByRole("button", { name: "Vis under-rader" }));
73
+
74
+ expect(screen.getByText("Child")).toBeInTheDocument();
75
+ expect(screen.getAllByRole("checkbox")).toHaveLength(3);
76
+
77
+ fireEvent.click(
78
+ screen.getByRole("checkbox", { name: "Velg alle synlige rader" }),
79
+ );
80
+
81
+ expect(
82
+ screen
83
+ .getAllByRole("checkbox")
84
+ .every((checkbox) => (checkbox as HTMLInputElement).checked),
85
+ ).toBe(true);
86
+ });
87
+
88
+ test("select-all checks all visible rows when fallback ids are used", () => {
89
+ render(
90
+ <DataTableAuto
91
+ columnDefinitions={columns}
92
+ data={fallbackIdData}
93
+ getSubRows={(row) => row.subRows ?? []}
94
+ defaultExpandedSubRowIds={[0]}
95
+ selection={{ selectionMode: "multiple" }}
96
+ />,
97
+ );
98
+
99
+ fireEvent.click(
100
+ screen.getByRole("checkbox", { name: "Velg alle synlige rader" }),
101
+ );
102
+
103
+ const rowCheckboxes = screen
104
+ .getAllByRole("checkbox")
105
+ .slice(1) as HTMLInputElement[];
106
+
107
+ expect(rowCheckboxes).toHaveLength(3);
108
+ expect(rowCheckboxes.every((checkbox) => checkbox.checked)).toBe(true);
109
+ });
110
+
111
+ test("parent row selection follows visible nested rows", () => {
112
+ render(
113
+ <DataTableAuto
114
+ columnDefinitions={columns}
115
+ data={data}
116
+ getRowId={(row) => row.id}
117
+ getSubRows={(row) => row.subRows ?? []}
118
+ selection={{ selectionMode: "multiple" }}
119
+ />,
120
+ );
121
+
122
+ fireEvent.click(screen.getByRole("button", { name: "Vis under-rader" }));
123
+
124
+ const getCheckboxes = () =>
125
+ screen.getAllByRole("checkbox") as HTMLInputElement[];
126
+
127
+ fireEvent.click(getCheckboxes()[2]);
128
+
129
+ expect(getCheckboxes()[1].checked).toBe(false);
130
+ expect(getCheckboxes()[1].indeterminate).toBe(true);
131
+
132
+ fireEvent.click(getCheckboxes()[1]);
133
+
134
+ expect(getCheckboxes()[1].checked).toBe(true);
135
+ expect(getCheckboxes()[2].checked).toBe(true);
136
+
137
+ fireEvent.click(getCheckboxes()[1]);
138
+
139
+ expect(getCheckboxes()[1].checked).toBe(false);
140
+ expect(getCheckboxes()[2].checked).toBe(false);
141
+ });
142
+
143
+ test("collapsed parent selection includes hidden descendants and can clear them again", () => {
144
+ render(
145
+ <DataTableAuto
146
+ columnDefinitions={columns}
147
+ data={deepNestedData}
148
+ getRowId={(row) => row.id}
149
+ getSubRows={(row) => row.subRows ?? []}
150
+ selection={{ selectionMode: "multiple" }}
151
+ />,
152
+ );
153
+
154
+ const getCheckboxes = () =>
155
+ screen.getAllByRole("checkbox") as HTMLInputElement[];
156
+
157
+ fireEvent.click(getCheckboxes()[1]);
158
+
159
+ fireEvent.click(screen.getByRole("button", { name: "Vis under-rader" }));
160
+
161
+ expect(getCheckboxes()[1].checked).toBe(true);
162
+ expect(getCheckboxes()[2].checked).toBe(true);
163
+
164
+ fireEvent.click(screen.getByRole("button", { name: "Vis under-rader" }));
165
+
166
+ expect(getCheckboxes()[3].checked).toBe(true);
167
+
168
+ fireEvent.click(
169
+ screen.getAllByRole("button", { name: "Skjul under-rader" })[0],
170
+ );
171
+ fireEvent.click(getCheckboxes()[1]);
172
+
173
+ fireEvent.click(screen.getByRole("button", { name: "Vis under-rader" }));
174
+
175
+ expect(getCheckboxes()[1].checked).toBe(false);
176
+ expect(getCheckboxes()[2].checked).toBe(false);
177
+ expect(getCheckboxes()[3].checked).toBe(false);
178
+ });
179
+
180
+ test("select-all includes hidden descendants for collapsed parents and clears them again", () => {
181
+ render(
182
+ <DataTableAuto
183
+ columnDefinitions={columns}
184
+ data={deepNestedData}
185
+ getRowId={(row) => row.id}
186
+ getSubRows={(row) => row.subRows ?? []}
187
+ selection={{ selectionMode: "multiple" }}
188
+ />,
189
+ );
190
+
191
+ const getCheckboxes = () =>
192
+ screen.getAllByRole("checkbox") as HTMLInputElement[];
193
+
194
+ fireEvent.click(
195
+ screen.getByRole("checkbox", { name: "Velg alle synlige rader" }),
196
+ );
197
+
198
+ fireEvent.click(screen.getByRole("button", { name: "Vis under-rader" }));
199
+
200
+ expect(getCheckboxes()[1].checked).toBe(true);
201
+ expect(getCheckboxes()[2].checked).toBe(true);
202
+
203
+ fireEvent.click(screen.getByRole("button", { name: "Vis under-rader" }));
204
+
205
+ expect(getCheckboxes()[3].checked).toBe(true);
206
+
207
+ fireEvent.click(
208
+ screen.getByRole("checkbox", { name: "Fjern alle synlige valgte rader" }),
209
+ );
210
+
211
+ expect(getCheckboxes()[0].checked).toBe(false);
212
+
213
+ fireEvent.click(
214
+ screen.getAllByRole("button", { name: "Skjul under-rader" })[0],
215
+ );
216
+ fireEvent.click(screen.getByRole("button", { name: "Vis under-rader" }));
217
+
218
+ expect(getCheckboxes()[1].checked).toBe(false);
219
+ expect(getCheckboxes()[2].checked).toBe(false);
220
+ expect(getCheckboxes()[3].checked).toBe(false);
221
+ });
222
+
223
+ test("does not render expansion controls in the manual table variant", () => {
224
+ render(
225
+ <DataTable>
226
+ <DataTable.Thead>
227
+ <DataTable.Tr>
228
+ <DataTableColumnHeader>Name</DataTableColumnHeader>
229
+ </DataTable.Tr>
230
+ </DataTable.Thead>
231
+ <DataTable.Tbody>
232
+ <DataTable.Tr>
233
+ <DataTable.Td>Root</DataTable.Td>
234
+ </DataTable.Tr>
235
+ </DataTable.Tbody>
236
+ </DataTable>,
237
+ );
238
+
239
+ expect(screen.getByText("Root")).toBeInTheDocument();
240
+ expect(
241
+ screen.queryByRole("button", { name: /vis detaljer|skjul detaljer/i }),
242
+ ).not.toBeInTheDocument();
243
+ });
244
+ });