@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
@@ -1,4 +1,4 @@
1
- import React, { forwardRef, useCallback } from "react";
1
+ import React, { forwardRef } from "react";
2
2
  import {
3
3
  ChevronDownUpIcon,
4
4
  ChevronUpDownIcon,
@@ -14,7 +14,10 @@ import { useId } from "../../../utils-external";
14
14
  import { cl, composeEventHandlers } from "../../../utils/helpers";
15
15
  import { DataTableBaseCell } from "../base-cell/DataTableBaseCell";
16
16
  import { DataTableColumnHeader } from "../column-header/DataTableColumnHeader";
17
- import { useDataTableExpansion } from "../hooks/useTableExpansion";
17
+ import {
18
+ getDataTableExpansionId,
19
+ useDataTableExpansion,
20
+ } from "../hooks/useTableExpansion";
18
21
  import {
19
22
  useDataTableContext,
20
23
  useDataTableLocation,
@@ -59,45 +62,41 @@ const DataTableTr = forwardRef<HTMLTableRowElement, DataTableTrProps>(
59
62
 
60
63
  const isSticky = location === "thead" && stickyHeader;
61
64
 
62
- const handleClick = useCallback(
63
- (event: React.MouseEvent<HTMLTableRowElement>) => {
64
- if (
65
- location !== "tbody" ||
66
- rowId === undefined ||
67
- isInteractiveTarget(event.target) ||
68
- (event.target as HTMLElement | null)?.closest(
69
- "[data-prevent-row-click]",
70
- )
71
- ) {
72
- return;
73
- }
74
-
75
- const selection = window.getSelection();
76
- if (selection && selection.toString().length > 0) {
77
- return;
78
- }
79
-
80
- if (
81
- !disableRowSelectionOnClick &&
82
- selectionState.selection.selectionMode !== "none"
83
- ) {
84
- selectionState.selection.toggleSelection(rowId);
85
- }
86
- onRowClick?.(rowId, event);
87
- },
88
- [
89
- disableRowSelectionOnClick,
90
- location,
91
- onRowClick,
92
- rowId,
93
- selectionState.selection,
94
- ],
95
- );
65
+ const handleClick =
66
+ location === "tbody" && rowId !== undefined
67
+ ? (event: React.MouseEvent<HTMLTableRowElement>) => {
68
+ if (
69
+ rowId === undefined ||
70
+ isInteractiveTarget(event.target) ||
71
+ (event.target as HTMLElement | null)?.closest(
72
+ "[data-prevent-row-click]",
73
+ )
74
+ ) {
75
+ return;
76
+ }
77
+
78
+ const selection = window.getSelection();
79
+ if (selection && selection.toString().length > 0) {
80
+ return;
81
+ }
82
+
83
+ if (
84
+ !disableRowSelectionOnClick &&
85
+ selectionState.selection.selectionMode !== "none"
86
+ ) {
87
+ selectionState.selection.toggleSelection(rowId);
88
+ }
89
+ onRowClick?.(rowId, event);
90
+ }
91
+ : undefined;
96
92
 
97
93
  return (
98
94
  <tr
99
95
  {...rest}
100
- onClick={composeEventHandlers(onClick, handleClick)}
96
+ // Avoid setting onClick if not needed, since this causes NVDA to announce the row as clickable.
97
+ onClick={
98
+ (onClick || handleClick) && composeEventHandlers(onClick, handleClick)
99
+ }
101
100
  ref={forwardedRef}
102
101
  className={cl("aksel-data-table__tr", className)}
103
102
  data-selected={selected}
@@ -122,22 +121,18 @@ const DataTableTr = forwardRef<HTMLTableRowElement, DataTableTrProps>(
122
121
  function RowExpansionCell({ rowId }: { rowId?: string | number }) {
123
122
  const { tableId, showLoadingSkeletons } = useDataTableContext();
124
123
  const { location } = useDataTableLocation();
125
- const expansionContext = useDataTableExpansion(false);
126
-
127
- if (!expansionContext) {
128
- return null;
129
- }
130
124
 
131
125
  const {
132
126
  isExpanded,
127
+ isDetailsPanelExpandable,
133
128
  toggleExpansion,
134
- enableExpansion,
129
+ enableDetailsPanel,
135
130
  isAllExpanded,
136
131
  toggleAll,
137
132
  showExpandAll,
138
- } = expansionContext;
133
+ } = useDataTableExpansion();
139
134
 
140
- if (!enableExpansion) {
135
+ if (!enableDetailsPanel) {
141
136
  return null;
142
137
  }
143
138
 
@@ -202,6 +197,12 @@ function RowExpansionCell({ rowId }: { rowId?: string | number }) {
202
197
  }
203
198
 
204
199
  const isRowExpanded = isExpanded(rowId);
200
+ const canExpandRow = isDetailsPanelExpandable(rowId);
201
+ const expansionId = getDataTableExpansionId(tableId, rowId);
202
+
203
+ if (!canExpandRow) {
204
+ return <DataTableTd UNSAFE_isSelection preventRowClick />;
205
+ }
205
206
 
206
207
  return (
207
208
  <DataTableTd UNSAFE_isSelection preventRowClick>
@@ -214,7 +215,7 @@ function RowExpansionCell({ rowId }: { rowId?: string | number }) {
214
215
  toggleExpansion(rowId);
215
216
  }}
216
217
  aria-expanded={isRowExpanded}
217
- aria-controls={`${tableId}-expansion-${rowId}`}
218
+ aria-controls={expansionId}
218
219
  aria-label={isRowExpanded ? "Skjul detaljer" : "Vis detaljer"}
219
220
  icon={
220
221
  isRowExpanded ? <MinusIcon aria-hidden /> : <PlusIcon aria-hidden />
@@ -225,7 +226,7 @@ function RowExpansionCell({ rowId }: { rowId?: string | number }) {
225
226
  }
226
227
 
227
228
  /**
228
- * TODO: How do these cells handle multiple thead rows, or col/rowspans?
229
+ * TODO: How do these cells handle multiple thead rows, or col/row-spans?
229
230
  * TODO: a11y for labels
230
231
  */
231
232
  function RowSelectionCell({ rowId }: { rowId?: string | number }) {
@@ -35,6 +35,7 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
35
35
  "indeterminate",
36
36
  "errorId",
37
37
  "readOnly",
38
+ "className",
38
39
  ])}
39
40
  {...omit(inputProps, ["aria-invalid", "aria-describedby"])}
40
41
  aria-describedby={
@@ -24,7 +24,13 @@ export const Radio = forwardRef<HTMLInputElement, RadioProps>(
24
24
  >
25
25
  <RadioInput
26
26
  ref={forwardedRef}
27
- {...omit(props, ["children", "size", "description", "readOnly"])}
27
+ {...omit(props, [
28
+ "children",
29
+ "size",
30
+ "description",
31
+ "readOnly",
32
+ "className",
33
+ ])}
28
34
  {...omit(inputProps, ["aria-invalid", "aria-describedby"])}
29
35
  aria-describedby={
30
36
  cl(inputProps["aria-describedby"], {
@@ -39,7 +39,8 @@ interface ModalPropsBase extends React.DialogHTMLAttributes<HTMLDialogElement> {
39
39
  /**
40
40
  * Called when the user tries to close the modal by one of the built-in methods.
41
41
  * Used if you want to ask the user for confirmation before closing.
42
- * @warning Will not always be called when pressing Esc. See `onCancel` for more info.
42
+ *
43
+ * **NB:** Will not always be called when pressing Esc. See `onCancel` for more info.
43
44
  * @returns Whether to close the modal or not
44
45
  */
45
46
  onBeforeClose?: () => boolean;
@@ -52,7 +53,8 @@ interface ModalPropsBase extends React.DialogHTMLAttributes<HTMLDialogElement> {
52
53
  onCancel?: React.ReactEventHandler<HTMLDialogElement>;
53
54
  /**
54
55
  * Whether to close when clicking on the backdrop.
55
- * @warning Users may click outside by accident. Don't use if closing can cause data loss, or the modal contains important info.
56
+ *
57
+ * **NB:** Users may click outside by accident. Don't use if closing can cause data loss, or the modal contains important info.
56
58
  * @default false
57
59
  */
58
60
  closeOnBackdropClick?: boolean;
@@ -77,13 +79,15 @@ interface ModalPropsBase extends React.DialogHTMLAttributes<HTMLDialogElement> {
77
79
  /**
78
80
  * ID of the element that labels the modal.
79
81
  * No need to set this manually if the `header` prop is used. A reference to `header.heading` will be created automatically.
80
- * @warning If not using `header`, you should set either `aria-labelledby` or `aria-label`.
82
+ *
83
+ * **NB:** If not using `header`, you should set either `aria-labelledby` or `aria-label`.
81
84
  */
82
85
  "aria-labelledby"?: string;
83
86
  /**
84
87
  * String value that labels the modal.
85
88
  * No need to set this if the `header` prop is used.
86
- * @warning If not using `header`, you should set either `aria-labelledby` or `aria-label`.
89
+ *
90
+ * **NB:** If not using `header`, you should set either `aria-labelledby` or `aria-label`.
87
91
  */
88
92
  "aria-label"?: string;
89
93
  }