@dbcdk/react-components 0.0.197 → 0.0.198

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 (55) hide show
  1. package/dist/components/json-viewer/JsonViewer.module.css +52 -0
  2. package/dist/components/json-viewer/JsonViewerShell.cjs +147 -143
  3. package/dist/components/json-viewer/JsonViewerShell.js +149 -145
  4. package/dist/components/line-viewer/LineViewer.cjs +15 -10
  5. package/dist/components/line-viewer/LineViewer.d.ts +1 -1
  6. package/dist/components/line-viewer/LineViewer.js +15 -10
  7. package/dist/components/line-viewer/LineViewer.module.css +58 -3
  8. package/dist/components/page-layout/PageLayout.module.css +1 -1
  9. package/dist/components/scroll-fade/ScrollFade.cjs +42 -0
  10. package/dist/components/scroll-fade/ScrollFade.d.ts +18 -0
  11. package/dist/components/scroll-fade/ScrollFade.js +36 -0
  12. package/dist/components/scroll-fade/ScrollFade.module.css +71 -0
  13. package/dist/components/search-box/SearchBox.cjs +39 -35
  14. package/dist/components/search-box/SearchBox.d.ts +2 -0
  15. package/dist/components/search-box/SearchBox.js +39 -35
  16. package/dist/components/table/Table.cjs +52 -23
  17. package/dist/components/table/Table.d.ts +1 -1
  18. package/dist/components/table/Table.js +53 -24
  19. package/dist/components/table/Table.module.css +4 -0
  20. package/dist/components/table/Table.types.d.ts +27 -0
  21. package/dist/components/table/TanstackTable.cjs +64 -64
  22. package/dist/components/table/TanstackTable.js +67 -67
  23. package/dist/components/table/columnLayout.utils.cjs +146 -0
  24. package/dist/components/table/columnLayout.utils.d.ts +44 -0
  25. package/dist/components/table/columnLayout.utils.js +141 -0
  26. package/dist/components/table/components/TableHeader.cjs +3 -1
  27. package/dist/components/table/components/TableHeader.d.ts +2 -1
  28. package/dist/components/table/components/TableHeader.js +3 -1
  29. package/dist/components/table/components/TableHeaderCell.cjs +29 -19
  30. package/dist/components/table/components/TableHeaderCell.d.ts +2 -1
  31. package/dist/components/table/components/TableHeaderCell.js +29 -19
  32. package/dist/components/table/hooks/useElementWidth.cjs +40 -0
  33. package/dist/components/table/hooks/useElementWidth.d.ts +7 -0
  34. package/dist/components/table/hooks/useElementWidth.js +38 -0
  35. package/dist/components/table/table.utils.cjs +24 -2
  36. package/dist/components/table/table.utils.d.ts +40 -2
  37. package/dist/components/table/table.utils.js +20 -2
  38. package/dist/components/table/tanstackTable.utils.cjs +33 -97
  39. package/dist/components/table/tanstackTable.utils.d.ts +24 -8
  40. package/dist/components/table/tanstackTable.utils.js +34 -99
  41. package/dist/components/xml-viewer/XmlViewer.cjs +15 -10
  42. package/dist/components/xml-viewer/XmlViewer.d.ts +1 -1
  43. package/dist/components/xml-viewer/XmlViewer.js +15 -10
  44. package/dist/components/xml-viewer/XmlViewer.module.css +58 -3
  45. package/dist/hooks/useScrollOverflow.cjs +71 -0
  46. package/dist/hooks/useScrollOverflow.d.ts +23 -0
  47. package/dist/hooks/useScrollOverflow.js +69 -0
  48. package/dist/hooks/useTableSettings.cjs +2 -1
  49. package/dist/hooks/useTableSettings.d.ts +1 -0
  50. package/dist/hooks/useTableSettings.js +2 -1
  51. package/dist/index.css +1 -0
  52. package/dist/utils/refs.utils.cjs +13 -0
  53. package/dist/utils/refs.utils.d.ts +7 -0
  54. package/dist/utils/refs.utils.js +11 -0
  55. package/package.json +1 -1
@@ -0,0 +1,71 @@
1
+ /* Positions the fades over the scroll container without scrolling along with it. */
2
+ .frame {
3
+ --scroll-fade-color-resolved: var(--scroll-fade-color, var(--color-bg-surface));
4
+ --scroll-fade-size-resolved: var(--scroll-fade-size, var(--spacing-lg));
5
+
6
+ position: relative;
7
+ display: flex;
8
+ flex-direction: column;
9
+ flex: 1 1 auto;
10
+ min-height: 0;
11
+ min-width: 0;
12
+ /* Clips the fades to the parent's rounded corners. */
13
+ overflow: hidden;
14
+ border-radius: inherit;
15
+ }
16
+
17
+ /* The scroll container fills the frame and shrinks with it. */
18
+ .frame > :first-child {
19
+ flex: 1 1 auto;
20
+ min-height: 0;
21
+ }
22
+
23
+ .fadeTop,
24
+ .fadeBottom,
25
+ .fadeLeft,
26
+ .fadeRight {
27
+ position: absolute;
28
+ pointer-events: none;
29
+ opacity: 0;
30
+ transition: opacity var(--transition-fast) ease;
31
+ }
32
+
33
+ .fadeTop[data-visible='true'],
34
+ .fadeBottom[data-visible='true'],
35
+ .fadeLeft[data-visible='true'],
36
+ .fadeRight[data-visible='true'] {
37
+ opacity: 1;
38
+ }
39
+
40
+ /* Kept clear of classic scrollbars, whose sizes are 0 when overlaid. */
41
+ .fadeTop,
42
+ .fadeBottom {
43
+ inset-inline: 0 var(--scroll-fade-scrollbar-width);
44
+ height: var(--scroll-fade-size-resolved);
45
+ }
46
+
47
+ .fadeLeft,
48
+ .fadeRight {
49
+ inset-block: 0 var(--scroll-fade-scrollbar-height);
50
+ width: var(--scroll-fade-size-resolved);
51
+ }
52
+
53
+ .fadeTop {
54
+ top: 0;
55
+ background: linear-gradient(to bottom, var(--scroll-fade-color-resolved), transparent);
56
+ }
57
+
58
+ .fadeBottom {
59
+ bottom: var(--scroll-fade-scrollbar-height);
60
+ background: linear-gradient(to top, var(--scroll-fade-color-resolved), transparent);
61
+ }
62
+
63
+ .fadeLeft {
64
+ left: 0;
65
+ background: linear-gradient(to right, var(--scroll-fade-color-resolved), transparent);
66
+ }
67
+
68
+ .fadeRight {
69
+ right: var(--scroll-fade-scrollbar-width);
70
+ background: linear-gradient(to left, var(--scroll-fade-color-resolved), transparent);
71
+ }
@@ -22,6 +22,7 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
22
22
  debounce = true,
23
23
  debounceMs = 800,
24
24
  onSearch,
25
+ onClear,
25
26
  onSelect,
26
27
  displayPopover,
27
28
  resultKeys,
@@ -33,6 +34,7 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
33
34
  loading,
34
35
  enableHotkey = true,
35
36
  onButtonClick,
37
+ submitOnEnter = false,
36
38
  buttonLabel,
37
39
  buttonIcon,
38
40
  buttonAriaLabel,
@@ -86,7 +88,7 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
86
88
  return () => clearTimeout(handler);
87
89
  }, [draft, debounce, debounceMs]);
88
90
  react.useEffect(() => {
89
- function handleKeyDown(event) {
91
+ function handleKeyDown2(event) {
90
92
  var _a2;
91
93
  if (event.key === "k" && (event.metaKey || event.ctrlKey)) {
92
94
  event.preventDefault();
@@ -94,8 +96,8 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
94
96
  }
95
97
  }
96
98
  if (enableHotkey) {
97
- window.addEventListener("keydown", handleKeyDown);
98
- return () => window.removeEventListener("keydown", handleKeyDown);
99
+ window.addEventListener("keydown", handleKeyDown2);
100
+ return () => window.removeEventListener("keydown", handleKeyDown2);
99
101
  }
100
102
  }, [enableHotkey]);
101
103
  const hasInitialTemplate = initialTemplate !== void 0 && initialTemplate !== null;
@@ -134,9 +136,10 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
134
136
  const handleClear = react.useCallback(() => {
135
137
  var _a2;
136
138
  reset();
139
+ onClear == null ? void 0 : onClear();
137
140
  onSearch == null ? void 0 : onSearch("");
138
141
  (_a2 = internalInputRef.current) == null ? void 0 : _a2.focus();
139
- }, [onSearch]);
142
+ }, [onClear, onSearch]);
140
143
  react.useEffect(() => {
141
144
  setActiveIndex(null);
142
145
  }, [result]);
@@ -154,6 +157,36 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
154
157
  value: draft,
155
158
  onChange: handleChange
156
159
  };
160
+ const handleKeyDown = (e) => {
161
+ var _a2;
162
+ if (result == null ? void 0 : result.length) {
163
+ if (e.key === "ArrowDown") {
164
+ e.preventDefault();
165
+ setActiveIndex((prev) => prev === null || prev === result.length - 1 ? 0 : prev + 1);
166
+ } else if (e.key === "ArrowUp") {
167
+ e.preventDefault();
168
+ setActiveIndex((prev) => prev === null || prev === 0 ? result.length - 1 : prev - 1);
169
+ } else if (e.key === "Home") {
170
+ e.preventDefault();
171
+ setActiveIndex(0);
172
+ } else if (e.key === "End") {
173
+ e.preventDefault();
174
+ setActiveIndex(result.length - 1);
175
+ } else if (e.key === "Enter") {
176
+ e.preventDefault();
177
+ if (activeIndex !== null) {
178
+ handleSelect(result[activeIndex]);
179
+ } else if (onButtonClick) {
180
+ onButtonClick();
181
+ }
182
+ }
183
+ } else if (e.key === "Enter" && submitOnEnter && onButtonClick) {
184
+ e.preventDefault();
185
+ onButtonClick();
186
+ }
187
+ if (e.key === "Escape") reset();
188
+ (_a2 = inputProps.onKeyDown) == null ? void 0 : _a2.call(inputProps, e);
189
+ };
157
190
  if (!displayPopover) {
158
191
  return /* @__PURE__ */ jsxRuntime.jsx(
159
192
  "div",
@@ -177,6 +210,7 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
177
210
  buttonIcon: trailingButtonIcon,
178
211
  buttonAriaLabel: trailingButtonAriaLabel,
179
212
  ...inputProps,
213
+ onKeyDown: handleKeyDown,
180
214
  placeholder: (_a = rest.placeholder) != null ? _a : "Indtast s\xF8geord"
181
215
  }
182
216
  )
@@ -263,37 +297,7 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
263
297
  buttonIcon: trailingButtonIcon,
264
298
  buttonAriaLabel: trailingButtonAriaLabel,
265
299
  ...inputProps,
266
- onKeyDown: (e) => {
267
- var _a3;
268
- if (result == null ? void 0 : result.length) {
269
- if (e.key === "ArrowDown") {
270
- e.preventDefault();
271
- setActiveIndex(
272
- (prev) => prev === null || prev === result.length - 1 ? 0 : prev + 1
273
- );
274
- } else if (e.key === "ArrowUp") {
275
- e.preventDefault();
276
- setActiveIndex(
277
- (prev) => prev === null || prev === 0 ? result.length - 1 : prev - 1
278
- );
279
- } else if (e.key === "Home") {
280
- e.preventDefault();
281
- setActiveIndex(0);
282
- } else if (e.key === "End") {
283
- e.preventDefault();
284
- setActiveIndex(result.length - 1);
285
- } else if (e.key === "Enter") {
286
- e.preventDefault();
287
- if (activeIndex !== null) {
288
- handleSelect(result[activeIndex]);
289
- } else if (onButtonClick) {
290
- onButtonClick();
291
- }
292
- }
293
- }
294
- if (e.key === "Escape") reset();
295
- (_a3 = inputProps.onKeyDown) == null ? void 0 : _a3.call(inputProps, e);
296
- },
300
+ onKeyDown: handleKeyDown,
297
301
  placeholder: (_a2 = rest.placeholder) != null ? _a2 : "Indtast s\xF8geord"
298
302
  }
299
303
  );
@@ -12,6 +12,7 @@ export type SearchBoxProps<T extends Record<string, unknown>> = Omit<InputProps,
12
12
  debounce?: boolean;
13
13
  debounceMs?: number;
14
14
  onSearch?: (query: string) => void;
15
+ onClear?: () => void;
15
16
  onSelect?: (item: T) => void;
16
17
  displayPopover?: boolean;
17
18
  initialTemplate?: React.ReactNode;
@@ -28,6 +29,7 @@ export type SearchBoxProps<T extends Record<string, unknown>> = Omit<InputProps,
28
29
  enableHotkey?: boolean;
29
30
  fullWidth?: boolean;
30
31
  onButtonClick?: () => void;
32
+ submitOnEnter?: boolean;
31
33
  buttonLabel?: string;
32
34
  buttonIcon?: React.ReactNode;
33
35
  buttonAriaLabel?: string;
@@ -16,6 +16,7 @@ const SearchBox = forwardRef(function SearchBoxInner({
16
16
  debounce = true,
17
17
  debounceMs = 800,
18
18
  onSearch,
19
+ onClear,
19
20
  onSelect,
20
21
  displayPopover,
21
22
  resultKeys,
@@ -27,6 +28,7 @@ const SearchBox = forwardRef(function SearchBoxInner({
27
28
  loading,
28
29
  enableHotkey = true,
29
30
  onButtonClick,
31
+ submitOnEnter = false,
30
32
  buttonLabel,
31
33
  buttonIcon,
32
34
  buttonAriaLabel,
@@ -80,7 +82,7 @@ const SearchBox = forwardRef(function SearchBoxInner({
80
82
  return () => clearTimeout(handler);
81
83
  }, [draft, debounce, debounceMs]);
82
84
  useEffect(() => {
83
- function handleKeyDown(event) {
85
+ function handleKeyDown2(event) {
84
86
  var _a2;
85
87
  if (event.key === "k" && (event.metaKey || event.ctrlKey)) {
86
88
  event.preventDefault();
@@ -88,8 +90,8 @@ const SearchBox = forwardRef(function SearchBoxInner({
88
90
  }
89
91
  }
90
92
  if (enableHotkey) {
91
- window.addEventListener("keydown", handleKeyDown);
92
- return () => window.removeEventListener("keydown", handleKeyDown);
93
+ window.addEventListener("keydown", handleKeyDown2);
94
+ return () => window.removeEventListener("keydown", handleKeyDown2);
93
95
  }
94
96
  }, [enableHotkey]);
95
97
  const hasInitialTemplate = initialTemplate !== void 0 && initialTemplate !== null;
@@ -128,9 +130,10 @@ const SearchBox = forwardRef(function SearchBoxInner({
128
130
  const handleClear = useCallback(() => {
129
131
  var _a2;
130
132
  reset();
133
+ onClear == null ? void 0 : onClear();
131
134
  onSearch == null ? void 0 : onSearch("");
132
135
  (_a2 = internalInputRef.current) == null ? void 0 : _a2.focus();
133
- }, [onSearch]);
136
+ }, [onClear, onSearch]);
134
137
  useEffect(() => {
135
138
  setActiveIndex(null);
136
139
  }, [result]);
@@ -148,6 +151,36 @@ const SearchBox = forwardRef(function SearchBoxInner({
148
151
  value: draft,
149
152
  onChange: handleChange
150
153
  };
154
+ const handleKeyDown = (e) => {
155
+ var _a2;
156
+ if (result == null ? void 0 : result.length) {
157
+ if (e.key === "ArrowDown") {
158
+ e.preventDefault();
159
+ setActiveIndex((prev) => prev === null || prev === result.length - 1 ? 0 : prev + 1);
160
+ } else if (e.key === "ArrowUp") {
161
+ e.preventDefault();
162
+ setActiveIndex((prev) => prev === null || prev === 0 ? result.length - 1 : prev - 1);
163
+ } else if (e.key === "Home") {
164
+ e.preventDefault();
165
+ setActiveIndex(0);
166
+ } else if (e.key === "End") {
167
+ e.preventDefault();
168
+ setActiveIndex(result.length - 1);
169
+ } else if (e.key === "Enter") {
170
+ e.preventDefault();
171
+ if (activeIndex !== null) {
172
+ handleSelect(result[activeIndex]);
173
+ } else if (onButtonClick) {
174
+ onButtonClick();
175
+ }
176
+ }
177
+ } else if (e.key === "Enter" && submitOnEnter && onButtonClick) {
178
+ e.preventDefault();
179
+ onButtonClick();
180
+ }
181
+ if (e.key === "Escape") reset();
182
+ (_a2 = inputProps.onKeyDown) == null ? void 0 : _a2.call(inputProps, e);
183
+ };
151
184
  if (!displayPopover) {
152
185
  return /* @__PURE__ */ jsx(
153
186
  "div",
@@ -171,6 +204,7 @@ const SearchBox = forwardRef(function SearchBoxInner({
171
204
  buttonIcon: trailingButtonIcon,
172
205
  buttonAriaLabel: trailingButtonAriaLabel,
173
206
  ...inputProps,
207
+ onKeyDown: handleKeyDown,
174
208
  placeholder: (_a = rest.placeholder) != null ? _a : "Indtast s\xF8geord"
175
209
  }
176
210
  )
@@ -257,37 +291,7 @@ const SearchBox = forwardRef(function SearchBoxInner({
257
291
  buttonIcon: trailingButtonIcon,
258
292
  buttonAriaLabel: trailingButtonAriaLabel,
259
293
  ...inputProps,
260
- onKeyDown: (e) => {
261
- var _a3;
262
- if (result == null ? void 0 : result.length) {
263
- if (e.key === "ArrowDown") {
264
- e.preventDefault();
265
- setActiveIndex(
266
- (prev) => prev === null || prev === result.length - 1 ? 0 : prev + 1
267
- );
268
- } else if (e.key === "ArrowUp") {
269
- e.preventDefault();
270
- setActiveIndex(
271
- (prev) => prev === null || prev === 0 ? result.length - 1 : prev - 1
272
- );
273
- } else if (e.key === "Home") {
274
- e.preventDefault();
275
- setActiveIndex(0);
276
- } else if (e.key === "End") {
277
- e.preventDefault();
278
- setActiveIndex(result.length - 1);
279
- } else if (e.key === "Enter") {
280
- e.preventDefault();
281
- if (activeIndex !== null) {
282
- handleSelect(result[activeIndex]);
283
- } else if (onButtonClick) {
284
- onButtonClick();
285
- }
286
- }
287
- }
288
- if (e.key === "Escape") reset();
289
- (_a3 = inputProps.onKeyDown) == null ? void 0 : _a3.call(inputProps, e);
290
- },
294
+ onKeyDown: handleKeyDown,
291
295
  placeholder: (_a2 = rest.placeholder) != null ? _a2 : "Indtast s\xF8geord"
292
296
  }
293
297
  );
@@ -5,11 +5,14 @@ var jsxRuntime = require('react/jsx-runtime');
5
5
  var react = require('react');
6
6
  var Pagination = require('../../components/pagination/Pagination');
7
7
  var useViewportFill = require('../../hooks/useViewportFill');
8
+ var refs_utils = require('../../utils/refs.utils');
9
+ var columnLayout_utils = require('./columnLayout.utils');
8
10
  var EmptyState = require('./components/empty-state/EmptyState');
9
11
  var TableHeaderSettings = require('./components/table-settings/TableHeaderSettings');
10
12
  var TableBody = require('./components/TableBody');
11
13
  var TableHeader = require('./components/TableHeader');
12
14
  var TableSkeletonBody = require('./components/TableSkeletonBody');
15
+ var useElementWidth = require('./hooks/useElementWidth');
13
16
  var table_classes = require('./table.classes');
14
17
  var styles = require('./Table.module.css');
15
18
  var table_utils = require('./table.utils');
@@ -48,6 +51,7 @@ function Table({
48
51
  headerActions: headerActionsProp,
49
52
  settings,
50
53
  settingsOptions,
54
+ settingsColumns,
51
55
  take,
52
56
  skip,
53
57
  totalItemsCount,
@@ -69,9 +73,9 @@ function Table({
69
73
  onPageChange,
70
74
  ...rest
71
75
  }) {
72
- var _a;
73
- const viewMode = viewModeProp != null ? viewModeProp : settings == null ? void 0 : settings.viewMode;
74
- const striped = (_a = stripedProp != null ? stripedProp : settings == null ? void 0 : settings.striped) != null ? _a : false;
76
+ var _a, _b;
77
+ const viewMode = (_a = viewModeProp != null ? viewModeProp : settings == null ? void 0 : settings.viewMode) != null ? _a : table_utils.DEFAULT_VIEW_MODE;
78
+ const striped = (_b = stripedProp != null ? stripedProp : settings == null ? void 0 : settings.striped) != null ? _b : false;
75
79
  const settingsVisibleIds = settings == null ? void 0 : settings.visibleColumnIds;
76
80
  const visibleColumns = react.useMemo(
77
81
  () => (settingsVisibleIds == null ? void 0 : settingsVisibleIds.length) ? tableSettings_utils.filterColumnsBySettings(columns, settingsVisibleIds) : table_utils.getVisibleColumns(columns),
@@ -79,7 +83,14 @@ function Table({
79
83
  );
80
84
  const headerActions = headerActionsProp != null || settings ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.headerActions, children: [
81
85
  headerActionsProp,
82
- settings ? /* @__PURE__ */ jsxRuntime.jsx(TableHeaderSettings.TableHeaderSettings, { settings, options: settingsOptions, columns }) : null
86
+ settings ? /* @__PURE__ */ jsxRuntime.jsx(
87
+ TableHeaderSettings.TableHeaderSettings,
88
+ {
89
+ settings,
90
+ options: settingsOptions,
91
+ columns: settingsColumns != null ? settingsColumns : columns
92
+ }
93
+ ) : null
83
94
  ] }) : null;
84
95
  const toolbarContent = !showHeader && headerActions ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.toolbarWithHeaderActions, children: [
85
96
  toolbar,
@@ -87,8 +98,30 @@ function Table({
87
98
  ] }) : toolbar;
88
99
  const selectionInputName = react.useId();
89
100
  const internalTableRootRef = react.useRef(null);
90
- const tableRootRefWrapper = react.useRef(tableRootRef);
91
101
  const hasSelection = Boolean(selectedRows && onRowSelect);
102
+ const hasRowActions = Boolean(getContextMenuItems) || table_utils.showsExpandToggle(expandableRows, viewMode);
103
+ const hasHeaderActions = headerActionsProp != null || Boolean(settings);
104
+ const { px: actionReservePx, compactHeader: compactHeaderActionReserve } = table_utils.getActionsReserve({
105
+ hasRowActions,
106
+ hasSettings: Boolean(settings),
107
+ hasOtherHeaderActions: headerActionsProp != null,
108
+ showHeader
109
+ });
110
+ const distributeWidths = react.useMemo(
111
+ () => tableWidth == null && (columnLayout_utils.usesDistributedWidths(visibleColumns) || showHeader && hasHeaderActions),
112
+ [tableWidth, visibleColumns, showHeader, hasHeaderActions]
113
+ );
114
+ const availableWidth = useElementWidth.useElementWidth(internalTableRootRef, distributeWidths);
115
+ const distributedLayout = react.useMemo(
116
+ () => distributeWidths && availableWidth != null ? columnLayout_utils.distributeColumnWidths({
117
+ tracks: columnLayout_utils.buildColumnTracks(visibleColumns),
118
+ hasSelection,
119
+ hasContextMenu: actionReservePx > 0,
120
+ contextMenuReservePx: actionReservePx,
121
+ availableWidth
122
+ }) : null,
123
+ [distributeWidths, availableWidth, visibleColumns, hasSelection, actionReservePx]
124
+ );
92
125
  const hasPagination = Boolean(onPageChange && (loading || data.length > 0));
93
126
  const paginationRef = react.useRef(null);
94
127
  const [paginationHeight, setPaginationHeight] = react.useState(0);
@@ -120,14 +153,10 @@ function Table({
120
153
  });
121
154
  const fillViewportActive = fillViewport && containScrolling;
122
155
  const stickyTop = stickyHeader === "app-header" ? "var(--app-header-height, 60px)" : typeof stickyHeader === "number" ? `${stickyHeader}px` : stickyHeader === void 0 && containScrolling ? "0px" : void 0;
123
- const setTableRootRef = react.useCallback((node) => {
124
- internalTableRootRef.current = node;
125
- if (typeof tableRootRefWrapper.current === "function") {
126
- tableRootRefWrapper.current(node);
127
- } else if (tableRootRefWrapper.current) {
128
- tableRootRefWrapper.current.current = node;
129
- }
130
- }, []);
156
+ const setTableRootRef = react.useMemo(
157
+ () => refs_utils.mergeRefs(internalTableRootRef, tableRootRef),
158
+ [tableRootRef]
159
+ );
131
160
  const handlePageChange = react.useCallback(
132
161
  (e) => {
133
162
  onPageChange == null ? void 0 : onPageChange(e);
@@ -184,9 +213,10 @@ function Table({
184
213
  styles__default.default.tableRoot,
185
214
  styles__default.default[variant],
186
215
  styles__default.default[size],
187
- measuringLayout && styles__default.default.measuringLayout,
216
+ (measuringLayout || distributeWidths && !distributedLayout) && styles__default.default.measuringLayout,
188
217
  getRowSeverity && styles__default.default.severityTable
189
218
  );
219
+ const resolvedTableWidth = tableWidth != null ? tableWidth : distributedLayout == null ? void 0 : distributedLayout.totalWidth;
190
220
  const tableElementClassName = table_classes.cx(styles__default.default.tableElement, striped && "dbc-table--striped");
191
221
  const tableShell = /* @__PURE__ */ jsxRuntime.jsx("div", { ...rest, className: tableClassName, children: /* @__PURE__ */ jsxRuntime.jsx(
192
222
  "div",
@@ -200,17 +230,15 @@ function Table({
200
230
  className: tableElementClassName,
201
231
  "aria-rowcount": data.length,
202
232
  "data-show-header": showHeader,
203
- style: tableWidth != null ? { width: tableWidth } : void 0,
233
+ style: resolvedTableWidth != null ? { width: resolvedTableWidth } : void 0,
204
234
  children: [
205
235
  /* @__PURE__ */ jsxRuntime.jsxs("colgroup", { children: [
206
236
  hasSelection ? /* @__PURE__ */ jsxRuntime.jsx("col", { style: { width: table_utils.SELECTION_COLUMN_PX } }) : null,
207
- visibleColumns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
208
- "col",
209
- {
210
- style: column.width != null ? { width: column.width } : void 0
211
- },
212
- column.id
213
- ))
237
+ visibleColumns.map((column) => {
238
+ var _a2;
239
+ const width = (_a2 = distributedLayout == null ? void 0 : distributedLayout.widths[column.id]) != null ? _a2 : column.width;
240
+ return /* @__PURE__ */ jsxRuntime.jsx("col", { style: width != null ? { width } : void 0 }, column.id);
241
+ })
214
242
  ] }),
215
243
  showHeader && /* @__PURE__ */ jsxRuntime.jsx(
216
244
  TableHeader.TableHeader,
@@ -218,7 +246,7 @@ function Table({
218
246
  columns: visibleColumns,
219
247
  hasSelection,
220
248
  selectionMode,
221
- hasRowContextMenu: Boolean(getContextMenuItems) || expandableRows,
249
+ hasRowContextMenu: hasRowActions,
222
250
  allRowsSelected,
223
251
  onSelectAllRows,
224
252
  sortById,
@@ -226,6 +254,7 @@ function Table({
226
254
  onSortChange,
227
255
  headerExtras,
228
256
  headerActions,
257
+ compactHeaderActionReserve,
229
258
  stickyTop
230
259
  }
231
260
  ),
@@ -1,4 +1,4 @@
1
1
  import type { JSX } from 'react';
2
2
  import type { TableProps } from './Table.types';
3
- export declare function Table<T extends Record<string, any>>({ data, dataKey, columns, selectedRows, selectionMode, allRowsSelected, sortById, sortDirection, loading, emptyConfig, variant, size, viewMode: viewModeProp, striped: stripedProp, fillViewport, fillViewportBottomOffset, containScrolling, stickyHeader, tableWidth, tableRootRef, measuringLayout, toolbar, headerExtras, headerActions: headerActionsProp, settings, settingsOptions, take, skip, totalItemsCount, paginationPlacement, showFirstLast, showGoToPage, showPageSize, pageSizeOptions, showHeader, getRowSeverity, getContextMenuItems, showContextMenuOnHover, expandableRows, onRowClick, onRowMouseEnter, onRowSelect, onSelectAllRows, onSortChange, onPageChange, ...rest }: TableProps<T>): JSX.Element;
3
+ export declare function Table<T extends Record<string, any>>({ data, dataKey, columns, selectedRows, selectionMode, allRowsSelected, sortById, sortDirection, loading, emptyConfig, variant, size, viewMode: viewModeProp, striped: stripedProp, fillViewport, fillViewportBottomOffset, containScrolling, stickyHeader, tableWidth, tableRootRef, measuringLayout, toolbar, headerExtras, headerActions: headerActionsProp, settings, settingsOptions, settingsColumns, take, skip, totalItemsCount, paginationPlacement, showFirstLast, showGoToPage, showPageSize, pageSizeOptions, showHeader, getRowSeverity, getContextMenuItems, showContextMenuOnHover, expandableRows, onRowClick, onRowMouseEnter, onRowSelect, onSelectAllRows, onSortChange, onPageChange, ...rest }: TableProps<T>): JSX.Element;
4
4
  export type { ColumnItem } from './Table.types';
@@ -3,14 +3,17 @@ import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import { useMemo, useId, useRef, useState, useLayoutEffect, useCallback } from 'react';
4
4
  import { Pagination } from '../../components/pagination/Pagination';
5
5
  import { useViewportFill } from '../../hooks/useViewportFill';
6
+ import { mergeRefs } from '../../utils/refs.utils';
7
+ import { usesDistributedWidths, distributeColumnWidths, buildColumnTracks } from './columnLayout.utils';
6
8
  import { TableEmptyState } from './components/empty-state/EmptyState';
7
9
  import { TableHeaderSettings } from './components/table-settings/TableHeaderSettings';
8
10
  import { TableBody } from './components/TableBody';
9
11
  import { TableHeader } from './components/TableHeader';
10
12
  import { TableSkeletonBody } from './components/TableSkeletonBody';
13
+ import { useElementWidth } from './hooks/useElementWidth';
11
14
  import { cx } from './table.classes';
12
15
  import styles from './Table.module.css';
13
- import { getVisibleColumns, SELECTION_COLUMN_PX } from './table.utils';
16
+ import { DEFAULT_VIEW_MODE, getVisibleColumns, showsExpandToggle, getActionsReserve, SELECTION_COLUMN_PX } from './table.utils';
14
17
  import { filterColumnsBySettings } from './tableSettings.utils';
15
18
 
16
19
  const DEFAULT_SKELETON_ROWS = 10;
@@ -42,6 +45,7 @@ function Table({
42
45
  headerActions: headerActionsProp,
43
46
  settings,
44
47
  settingsOptions,
48
+ settingsColumns,
45
49
  take,
46
50
  skip,
47
51
  totalItemsCount,
@@ -63,9 +67,9 @@ function Table({
63
67
  onPageChange,
64
68
  ...rest
65
69
  }) {
66
- var _a;
67
- const viewMode = viewModeProp != null ? viewModeProp : settings == null ? void 0 : settings.viewMode;
68
- const striped = (_a = stripedProp != null ? stripedProp : settings == null ? void 0 : settings.striped) != null ? _a : false;
70
+ var _a, _b;
71
+ const viewMode = (_a = viewModeProp != null ? viewModeProp : settings == null ? void 0 : settings.viewMode) != null ? _a : DEFAULT_VIEW_MODE;
72
+ const striped = (_b = stripedProp != null ? stripedProp : settings == null ? void 0 : settings.striped) != null ? _b : false;
69
73
  const settingsVisibleIds = settings == null ? void 0 : settings.visibleColumnIds;
70
74
  const visibleColumns = useMemo(
71
75
  () => (settingsVisibleIds == null ? void 0 : settingsVisibleIds.length) ? filterColumnsBySettings(columns, settingsVisibleIds) : getVisibleColumns(columns),
@@ -73,7 +77,14 @@ function Table({
73
77
  );
74
78
  const headerActions = headerActionsProp != null || settings ? /* @__PURE__ */ jsxs("div", { className: styles.headerActions, children: [
75
79
  headerActionsProp,
76
- settings ? /* @__PURE__ */ jsx(TableHeaderSettings, { settings, options: settingsOptions, columns }) : null
80
+ settings ? /* @__PURE__ */ jsx(
81
+ TableHeaderSettings,
82
+ {
83
+ settings,
84
+ options: settingsOptions,
85
+ columns: settingsColumns != null ? settingsColumns : columns
86
+ }
87
+ ) : null
77
88
  ] }) : null;
78
89
  const toolbarContent = !showHeader && headerActions ? /* @__PURE__ */ jsxs("div", { className: styles.toolbarWithHeaderActions, children: [
79
90
  toolbar,
@@ -81,8 +92,30 @@ function Table({
81
92
  ] }) : toolbar;
82
93
  const selectionInputName = useId();
83
94
  const internalTableRootRef = useRef(null);
84
- const tableRootRefWrapper = useRef(tableRootRef);
85
95
  const hasSelection = Boolean(selectedRows && onRowSelect);
96
+ const hasRowActions = Boolean(getContextMenuItems) || showsExpandToggle(expandableRows, viewMode);
97
+ const hasHeaderActions = headerActionsProp != null || Boolean(settings);
98
+ const { px: actionReservePx, compactHeader: compactHeaderActionReserve } = getActionsReserve({
99
+ hasRowActions,
100
+ hasSettings: Boolean(settings),
101
+ hasOtherHeaderActions: headerActionsProp != null,
102
+ showHeader
103
+ });
104
+ const distributeWidths = useMemo(
105
+ () => tableWidth == null && (usesDistributedWidths(visibleColumns) || showHeader && hasHeaderActions),
106
+ [tableWidth, visibleColumns, showHeader, hasHeaderActions]
107
+ );
108
+ const availableWidth = useElementWidth(internalTableRootRef, distributeWidths);
109
+ const distributedLayout = useMemo(
110
+ () => distributeWidths && availableWidth != null ? distributeColumnWidths({
111
+ tracks: buildColumnTracks(visibleColumns),
112
+ hasSelection,
113
+ hasContextMenu: actionReservePx > 0,
114
+ contextMenuReservePx: actionReservePx,
115
+ availableWidth
116
+ }) : null,
117
+ [distributeWidths, availableWidth, visibleColumns, hasSelection, actionReservePx]
118
+ );
86
119
  const hasPagination = Boolean(onPageChange && (loading || data.length > 0));
87
120
  const paginationRef = useRef(null);
88
121
  const [paginationHeight, setPaginationHeight] = useState(0);
@@ -114,14 +147,10 @@ function Table({
114
147
  });
115
148
  const fillViewportActive = fillViewport && containScrolling;
116
149
  const stickyTop = stickyHeader === "app-header" ? "var(--app-header-height, 60px)" : typeof stickyHeader === "number" ? `${stickyHeader}px` : stickyHeader === void 0 && containScrolling ? "0px" : void 0;
117
- const setTableRootRef = useCallback((node) => {
118
- internalTableRootRef.current = node;
119
- if (typeof tableRootRefWrapper.current === "function") {
120
- tableRootRefWrapper.current(node);
121
- } else if (tableRootRefWrapper.current) {
122
- tableRootRefWrapper.current.current = node;
123
- }
124
- }, []);
150
+ const setTableRootRef = useMemo(
151
+ () => mergeRefs(internalTableRootRef, tableRootRef),
152
+ [tableRootRef]
153
+ );
125
154
  const handlePageChange = useCallback(
126
155
  (e) => {
127
156
  onPageChange == null ? void 0 : onPageChange(e);
@@ -178,9 +207,10 @@ function Table({
178
207
  styles.tableRoot,
179
208
  styles[variant],
180
209
  styles[size],
181
- measuringLayout && styles.measuringLayout,
210
+ (measuringLayout || distributeWidths && !distributedLayout) && styles.measuringLayout,
182
211
  getRowSeverity && styles.severityTable
183
212
  );
213
+ const resolvedTableWidth = tableWidth != null ? tableWidth : distributedLayout == null ? void 0 : distributedLayout.totalWidth;
184
214
  const tableElementClassName = cx(styles.tableElement, striped && "dbc-table--striped");
185
215
  const tableShell = /* @__PURE__ */ jsx("div", { ...rest, className: tableClassName, children: /* @__PURE__ */ jsx(
186
216
  "div",
@@ -194,17 +224,15 @@ function Table({
194
224
  className: tableElementClassName,
195
225
  "aria-rowcount": data.length,
196
226
  "data-show-header": showHeader,
197
- style: tableWidth != null ? { width: tableWidth } : void 0,
227
+ style: resolvedTableWidth != null ? { width: resolvedTableWidth } : void 0,
198
228
  children: [
199
229
  /* @__PURE__ */ jsxs("colgroup", { children: [
200
230
  hasSelection ? /* @__PURE__ */ jsx("col", { style: { width: SELECTION_COLUMN_PX } }) : null,
201
- visibleColumns.map((column) => /* @__PURE__ */ jsx(
202
- "col",
203
- {
204
- style: column.width != null ? { width: column.width } : void 0
205
- },
206
- column.id
207
- ))
231
+ visibleColumns.map((column) => {
232
+ var _a2;
233
+ const width = (_a2 = distributedLayout == null ? void 0 : distributedLayout.widths[column.id]) != null ? _a2 : column.width;
234
+ return /* @__PURE__ */ jsx("col", { style: width != null ? { width } : void 0 }, column.id);
235
+ })
208
236
  ] }),
209
237
  showHeader && /* @__PURE__ */ jsx(
210
238
  TableHeader,
@@ -212,7 +240,7 @@ function Table({
212
240
  columns: visibleColumns,
213
241
  hasSelection,
214
242
  selectionMode,
215
- hasRowContextMenu: Boolean(getContextMenuItems) || expandableRows,
243
+ hasRowContextMenu: hasRowActions,
216
244
  allRowsSelected,
217
245
  onSelectAllRows,
218
246
  sortById,
@@ -220,6 +248,7 @@ function Table({
220
248
  onSortChange,
221
249
  headerExtras,
222
250
  headerActions,
251
+ compactHeaderActionReserve,
223
252
  stickyTop
224
253
  }
225
254
  ),