@dbcdk/react-components 0.0.194 → 0.0.196

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/README.md +78 -10
  2. package/dist/client.cjs +486 -614
  3. package/dist/client.d.ts +176 -102
  4. package/dist/client.js +102 -102
  5. package/dist/components/color-scheme-button/ColorSchemeButton.cjs +7 -4
  6. package/dist/components/color-scheme-button/ColorSchemeButton.d.ts +7 -3
  7. package/dist/components/color-scheme-button/ColorSchemeButton.js +7 -4
  8. package/dist/components/forms/text-area/Textarea.cjs +2 -1
  9. package/dist/components/forms/text-area/Textarea.d.ts +1 -0
  10. package/dist/components/forms/text-area/Textarea.js +2 -1
  11. package/dist/components/highlighted-text/HighlightedText.cjs +6 -3
  12. package/dist/components/highlighted-text/HighlightedText.js +7 -4
  13. package/dist/components/json-viewer/JsonNode.cjs +27 -67
  14. package/dist/components/json-viewer/JsonNode.d.ts +10 -0
  15. package/dist/components/json-viewer/JsonNode.js +28 -68
  16. package/dist/components/json-viewer/JsonRow.cjs +85 -0
  17. package/dist/components/json-viewer/JsonRow.d.ts +5 -0
  18. package/dist/components/json-viewer/JsonRow.js +79 -0
  19. package/dist/components/json-viewer/JsonViewer.cjs +36 -256
  20. package/dist/components/json-viewer/JsonViewer.js +37 -253
  21. package/dist/components/json-viewer/JsonViewerShell.cjs +208 -0
  22. package/dist/components/json-viewer/JsonViewerShell.d.ts +25 -0
  23. package/dist/components/json-viewer/JsonViewerShell.js +202 -0
  24. package/dist/components/json-viewer/TanstackJsonViewer.cjs +127 -0
  25. package/dist/components/json-viewer/TanstackJsonViewer.d.ts +17 -0
  26. package/dist/components/json-viewer/TanstackJsonViewer.js +121 -0
  27. package/dist/components/json-viewer/types.d.ts +27 -0
  28. package/dist/components/json-viewer/useJsonViewerState.cjs +111 -0
  29. package/dist/components/json-viewer/useJsonViewerState.d.ts +42 -0
  30. package/dist/components/json-viewer/useJsonViewerState.js +108 -0
  31. package/dist/components/json-viewer/utils.cjs +36 -0
  32. package/dist/components/json-viewer/utils.d.ts +21 -1
  33. package/dist/components/json-viewer/utils.js +35 -1
  34. package/dist/components/lightbox/Lightbox.cjs +2 -2
  35. package/dist/components/lightbox/Lightbox.d.ts +1 -1
  36. package/dist/components/lightbox/Lightbox.js +1 -1
  37. package/dist/components/line-viewer/LineViewer.cjs +2 -3
  38. package/dist/components/line-viewer/LineViewer.js +2 -3
  39. package/dist/components/line-viewer/tokenizeLineFormat.cjs +37 -17
  40. package/dist/components/line-viewer/tokenizeLineFormat.d.ts +5 -4
  41. package/dist/components/line-viewer/tokenizeLineFormat.js +37 -17
  42. package/dist/components/menu/Menu.cjs +3 -23
  43. package/dist/components/menu/Menu.js +3 -23
  44. package/dist/components/menu/Menu.module.css +4 -3
  45. package/dist/components/metric-tile/MetricTile.cjs +3 -2
  46. package/dist/components/metric-tile/MetricTile.js +2 -1
  47. package/dist/components/overlay/tooltip/Tooltip.cjs +7 -2
  48. package/dist/components/overlay/tooltip/Tooltip.d.ts +7 -1
  49. package/dist/components/overlay/tooltip/Tooltip.js +7 -2
  50. package/dist/components/overlay/tooltip/useTooltipTrigger.cjs +7 -1
  51. package/dist/components/overlay/tooltip/useTooltipTrigger.js +7 -1
  52. package/dist/components/page-layout/PageLayout.module.css +1 -1
  53. package/dist/components/table/Table.cjs +45 -16
  54. package/dist/components/table/Table.d.ts +1 -1
  55. package/dist/components/table/Table.js +47 -18
  56. package/dist/components/table/Table.module.css +135 -7
  57. package/dist/components/table/Table.types.d.ts +47 -1
  58. package/dist/components/table/TanstackTable.cjs +30 -2
  59. package/dist/components/table/TanstackTable.js +31 -3
  60. package/dist/components/table/components/TableBody.d.ts +1 -2
  61. package/dist/components/table/components/TableHeader.cjs +6 -4
  62. package/dist/components/table/components/TableHeader.d.ts +2 -1
  63. package/dist/components/table/components/TableHeader.js +6 -4
  64. package/dist/components/table/components/TableHeaderCell.cjs +5 -4
  65. package/dist/components/table/components/TableHeaderCell.d.ts +3 -1
  66. package/dist/components/table/components/TableHeaderCell.js +5 -4
  67. package/dist/components/table/components/TableRow.cjs +1 -1
  68. package/dist/components/table/components/TableRow.d.ts +1 -2
  69. package/dist/components/table/components/TableRow.js +1 -1
  70. package/dist/components/table/components/TableSkeletonBody.cjs +30 -0
  71. package/dist/components/table/components/TableSkeletonBody.d.ts +13 -0
  72. package/dist/components/table/components/TableSkeletonBody.js +24 -0
  73. package/dist/components/table/components/table-settings/TableHeaderSettings.cjs +28 -0
  74. package/dist/components/table/components/table-settings/TableHeaderSettings.d.ts +11 -0
  75. package/dist/components/table/components/table-settings/TableHeaderSettings.js +26 -0
  76. package/dist/components/table/components/table-settings/TableSettings.cjs +82 -32
  77. package/dist/components/table/components/table-settings/TableSettings.d.ts +14 -6
  78. package/dist/components/table/components/table-settings/TableSettings.js +84 -34
  79. package/dist/components/table/table.utils.cjs +2 -0
  80. package/dist/components/table/table.utils.d.ts +6 -0
  81. package/dist/components/table/table.utils.js +2 -1
  82. package/dist/components/table/tableSettings.utils.cjs +29 -0
  83. package/dist/components/table/tableSettings.utils.d.ts +9 -0
  84. package/dist/components/table/tableSettings.utils.js +24 -0
  85. package/dist/components/table/tanstackTable.utils.cjs +18 -0
  86. package/dist/components/table/tanstackTable.utils.js +19 -1
  87. package/dist/components/theme-button/ThemeButton.cjs +9 -4
  88. package/dist/components/theme-button/ThemeButton.d.ts +4 -2
  89. package/dist/components/theme-button/ThemeButton.js +9 -4
  90. package/dist/components/theme-script/ThemeScript.cjs +10 -4
  91. package/dist/components/theme-script/ThemeScript.d.ts +9 -1
  92. package/dist/components/theme-script/ThemeScript.js +10 -4
  93. package/dist/components/xml-viewer/XmlViewer.cjs +2 -3
  94. package/dist/components/xml-viewer/XmlViewer.js +2 -3
  95. package/dist/hooks/useColorScheme.cjs +18 -14
  96. package/dist/hooks/useColorScheme.d.ts +11 -1
  97. package/dist/hooks/useColorScheme.js +19 -15
  98. package/dist/hooks/useGetActiveTheme.cjs +4 -3
  99. package/dist/hooks/useGetActiveTheme.d.ts +7 -1
  100. package/dist/hooks/useGetActiveTheme.js +4 -3
  101. package/dist/hooks/useTableData.cjs +11 -7
  102. package/dist/hooks/useTableData.d.ts +8 -2
  103. package/dist/hooks/useTableData.js +11 -7
  104. package/dist/hooks/useTableSettings.cjs +25 -9
  105. package/dist/hooks/useTableSettings.d.ts +9 -6
  106. package/dist/hooks/useTableSettings.js +25 -9
  107. package/dist/hooks/useTheme.d.ts +6 -0
  108. package/dist/styles/styles.css +7 -3
  109. package/dist/styles/themes/dbc/colors.css +1 -1
  110. package/dist/styles.css +1 -476
  111. package/dist/tanstack-virtual.cjs +12 -0
  112. package/dist/tanstack-virtual.d.ts +1 -0
  113. package/dist/tanstack-virtual.js +1 -0
  114. package/package.json +13 -1
@@ -7,10 +7,13 @@ var react = require('react');
7
7
  var Button = require('../../../button/Button');
8
8
  var Menu = require('../../../menu/Menu');
9
9
  var Popover = require('../../../popover/Popover');
10
+ var tableSettings_utils = require('../../tableSettings.utils');
10
11
 
11
12
  function TableSettingsMenuSection({
12
13
  viewMode,
13
14
  handleChangeViewMode,
15
+ striped,
16
+ onStripedChange,
14
17
  columns = [],
15
18
  visibleColumnIds = [],
16
19
  onVisibleColumnIdsChange,
@@ -20,31 +23,36 @@ function TableSettingsMenuSection({
20
23
  additionalSettings,
21
24
  close
22
25
  }) {
23
- const handleViewModeChange = (mode, close2) => {
26
+ const handleViewModeChange = (mode) => {
24
27
  handleChangeViewMode(mode === "wrapped" ? "compact" : "wrapped");
25
- close2 == null ? void 0 : close2();
26
28
  };
27
- const hideableColumns = react.useMemo(() => columns.filter((c) => c.enableHiding !== false), [columns]);
28
- const allPresetIds = react.useMemo(() => hideableColumns.map((c) => c.id), [hideableColumns]);
29
+ const hideableColumns = react.useMemo(() => columns.filter(tableSettings_utils.canHideSettingsColumn), [columns]);
30
+ const allPresetIds = react.useMemo(
31
+ () => hideableColumns.map(tableSettings_utils.getSettingsColumnId).filter((id) => !!id),
32
+ [hideableColumns]
33
+ );
29
34
  const standardPresetIds = react.useMemo(
30
- () => hideableColumns.filter((c) => {
31
- var _a;
32
- return ((_a = c.meta) == null ? void 0 : _a.hidden) !== true;
33
- }).map((c) => c.id),
35
+ () => hideableColumns.filter((c) => !tableSettings_utils.isSettingsColumnHidden(c)).map(tableSettings_utils.getSettingsColumnId).filter((id) => !!id),
34
36
  [hideableColumns]
35
37
  );
36
38
  const visibleSet = react.useMemo(() => new Set(visibleColumnIds), [visibleColumnIds]);
37
39
  const visibleCount = react.useMemo(() => {
38
- return hideableColumns.reduce((acc, c) => {
39
- var _a;
40
- return acc + (visibleSet.has((_a = c.id) != null ? _a : "") ? 1 : 0);
41
- }, 0);
40
+ return hideableColumns.reduce(
41
+ (acc, c) => {
42
+ var _a;
43
+ return acc + (visibleSet.has((_a = tableSettings_utils.getSettingsColumnId(c)) != null ? _a : "") ? 1 : 0);
44
+ },
45
+ 0
46
+ );
42
47
  }, [hideableColumns, visibleSet]);
43
48
  const setVisibleIds = (nextIds) => {
44
49
  if (!onVisibleColumnIdsChange) return;
45
50
  const safe = nextIds.length > 0 ? nextIds : standardPresetIds.length > 0 ? standardPresetIds : allPresetIds;
51
+ const lockedVisibleIds = columns.filter((column) => !tableSettings_utils.canHideSettingsColumn(column)).map(tableSettings_utils.getSettingsColumnId).filter((id) => id != null && visibleSet.has(id));
46
52
  onVisibleColumnIdsChange(
47
- safe.filter((id) => typeof id === "string" && Boolean(id))
53
+ Array.from(/* @__PURE__ */ new Set([...safe, ...lockedVisibleIds])).filter(
54
+ (id) => typeof id === "string" && Boolean(id)
55
+ )
48
56
  );
49
57
  };
50
58
  const toggleColumn = (id, nextVisible) => {
@@ -55,20 +63,32 @@ function TableSettingsMenuSection({
55
63
  };
56
64
  const isAllActive = react.useMemo(() => {
57
65
  if (!hideableColumns.length) return false;
58
- return hideableColumns.every((c) => c.id && visibleSet.has(c.id));
59
- }, [hideableColumns, visibleSet]);
66
+ return allPresetIds.length > 0 && allPresetIds.every((id) => visibleSet.has(id));
67
+ }, [hideableColumns, allPresetIds, visibleSet]);
60
68
  const isStandardActive = react.useMemo(() => {
61
69
  if (!hideableColumns.length) return false;
62
70
  const std = new Set(standardPresetIds);
63
- return hideableColumns.every((c) => c.id && visibleSet.has(c.id) === std.has(c.id));
64
- }, [hideableColumns, visibleSet, standardPresetIds]);
71
+ return allPresetIds.length > 0 && allPresetIds.every((id) => visibleSet.has(id) === std.has(id));
72
+ }, [hideableColumns, allPresetIds, visibleSet, standardPresetIds]);
65
73
  const presetRadioName = "table-columns-preset";
66
74
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
67
75
  additionalSettings == null ? void 0 : additionalSettings(close),
68
- /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Item, { active: viewMode === "wrapped", children: /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: () => handleViewModeChange(viewMode, close), children: [
69
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListChevronsUpDown, {}),
70
- "Ombryd tekst"
71
- ] }) }),
76
+ onStripedChange ? /* @__PURE__ */ jsxRuntime.jsx(
77
+ Menu.Menu.SwitchItem,
78
+ {
79
+ checked: Boolean(striped),
80
+ label: "Stribet",
81
+ onCheckedChange: (nextChecked) => onStripedChange(nextChecked)
82
+ }
83
+ ) : null,
84
+ /* @__PURE__ */ jsxRuntime.jsx(
85
+ Menu.Menu.SwitchItem,
86
+ {
87
+ checked: viewMode === "wrapped",
88
+ label: "Ombryd tekst",
89
+ onCheckedChange: () => handleViewModeChange(viewMode)
90
+ }
91
+ ),
72
92
  hideableColumns.length > 0 && onVisibleColumnIdsChange ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
73
93
  /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Separator, {}),
74
94
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "6px 10px", fontSize: 12, opacity: 0.7 }, children: columnsLabel }),
@@ -83,7 +103,6 @@ function TableSettingsMenuSection({
83
103
  setVisibleIds(
84
104
  allPresetIds.filter((id) => typeof id === "string" && Boolean(id))
85
105
  );
86
- close == null ? void 0 : close();
87
106
  }
88
107
  }
89
108
  ),
@@ -100,15 +119,16 @@ function TableSettingsMenuSection({
100
119
  (id) => typeof id === "string" && Boolean(id)
101
120
  )
102
121
  );
103
- close == null ? void 0 : close();
104
122
  }
105
123
  }
106
124
  ),
107
125
  /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Separator, {}),
108
126
  hideableColumns.map((col) => {
109
- const isVisible = col.id ? visibleSet.has(col.id) : false;
127
+ const colId = tableSettings_utils.getSettingsColumnId(col);
128
+ const isVisible = colId ? visibleSet.has(colId) : false;
110
129
  const disableUncheckingLast = isVisible && visibleCount <= 1;
111
- const label = col.header;
130
+ const header = col.header;
131
+ const label = typeof header === "function" && header.length === 0 ? header() : typeof header === "string" || typeof header === "number" || react.isValidElement(header) ? header : colId;
112
132
  return /* @__PURE__ */ jsxRuntime.jsx(
113
133
  Menu.Menu.CheckItem,
114
134
  {
@@ -116,11 +136,11 @@ function TableSettingsMenuSection({
116
136
  disabled: disableUncheckingLast,
117
137
  label,
118
138
  onCheckedChange: (nextChecked) => {
119
- if (disableUncheckingLast) return;
120
- toggleColumn(col.id, nextChecked);
139
+ if (disableUncheckingLast || !colId) return;
140
+ toggleColumn(colId, nextChecked);
121
141
  }
122
142
  },
123
- col.id
143
+ colId != null ? colId : String(label)
124
144
  );
125
145
  })
126
146
  ] }) : null
@@ -128,15 +148,45 @@ function TableSettingsMenuSection({
128
148
  }
129
149
  function TableSettings({
130
150
  buttonSize = "sm",
151
+ triggerLabel = "Visningsindstillinger",
152
+ triggerVariant = "button",
131
153
  ...sectionProps
132
154
  }) {
155
+ const isIcon = triggerVariant === "icon";
133
156
  return /* @__PURE__ */ jsxRuntime.jsx(
134
157
  Popover.Popover,
135
158
  {
136
- trigger: (onClick, icon) => /* @__PURE__ */ jsxRuntime.jsxs(Button.Button, { size: buttonSize, onClick, type: "button", children: [
137
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings, {}),
138
- icon
139
- ] }),
159
+ matchTriggerWidth: !isIcon,
160
+ minWidth: isIcon ? "220px" : void 0,
161
+ trigger: (onClick, icon, isOpen) => isIcon ? /* @__PURE__ */ jsxRuntime.jsx(
162
+ Button.Button,
163
+ {
164
+ type: "button",
165
+ size: "sm",
166
+ variant: "inline",
167
+ shape: "round",
168
+ "aria-label": triggerLabel,
169
+ "aria-haspopup": "menu",
170
+ "aria-expanded": isOpen ? true : false,
171
+ tooltip: triggerLabel,
172
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SlidersHorizontal, { size: 16 }),
173
+ "data-table-settings-trigger": "true",
174
+ onClick
175
+ }
176
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(
177
+ Button.Button,
178
+ {
179
+ size: buttonSize,
180
+ onClick,
181
+ type: "button",
182
+ "aria-label": triggerLabel,
183
+ tooltip: triggerLabel,
184
+ children: [
185
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SlidersHorizontal, {}),
186
+ icon
187
+ ]
188
+ }
189
+ ),
140
190
  children: (close) => /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu, { children: /* @__PURE__ */ jsxRuntime.jsx(TableSettingsMenuSection, { ...sectionProps, close }) })
141
191
  }
142
192
  );
@@ -1,27 +1,35 @@
1
- import { ColumnDef } from '@tanstack/react-table';
2
1
  import type { JSX, ReactNode } from 'react';
3
- import { ViewMode } from '../../../../hooks/useTableSettings';
4
2
  import { ButtonSize } from '../../../button/Button';
3
+ import type { ColumnItem, TableSettingsColumn, ViewMode } from '../../Table.types';
5
4
  export interface TableSettingsMenuSectionProps<T extends Record<string, any>> {
6
5
  handleChangeViewMode: (mode: ViewMode) => void;
7
6
  viewMode: ViewMode;
8
- columns?: ColumnDef<T>[];
7
+ striped?: boolean;
8
+ onStripedChange?: (nextStriped: boolean) => void;
9
+ columns?: ReadonlyArray<ColumnItem<T> | TableSettingsColumn>;
9
10
  visibleColumnIds?: string[];
10
11
  onVisibleColumnIdsChange?: (nextVisibleIds: string[]) => void;
11
12
  columnsLabel?: string;
12
13
  allPresetLabel?: string;
13
14
  standardPresetLabel?: string;
14
15
  additionalSettings?: (close?: () => void) => ReactNode;
15
- /** Called after an action closes the surrounding menu/popover, if any. */
16
+ /** Closes the surrounding menu/popover, if any. Only passed on to `additionalSettings`. */
16
17
  close?: () => void;
17
18
  }
18
19
  export interface TableSettingsProps<T extends Record<string, any>> extends Omit<TableSettingsMenuSectionProps<T>, 'close'> {
19
20
  buttonSize?: ButtonSize;
21
+ /** Accessible name and tooltip for the icon-only trigger button. */
22
+ triggerLabel?: string;
23
+ /**
24
+ * `button` (default) is a regular button with a dropdown chevron, for
25
+ * toolbars. `icon` is a small round icon button, as used in the table header.
26
+ */
27
+ triggerVariant?: 'button' | 'icon';
20
28
  }
21
29
  /**
22
30
  * The table settings menu items (view mode toggle + column visibility), with
23
31
  * no `Menu`/`Popover`/trigger wrapper. Use this to fold table settings into
24
32
  * another menu; use `TableSettings` for the standalone button + popover.
25
33
  */
26
- export declare function TableSettingsMenuSection<T extends Record<string, any>>({ viewMode, handleChangeViewMode, columns, visibleColumnIds, onVisibleColumnIdsChange, columnsLabel, allPresetLabel, standardPresetLabel, additionalSettings, close, }: TableSettingsMenuSectionProps<T>): JSX.Element;
27
- export declare function TableSettings<T extends Record<string, any>>({ buttonSize, ...sectionProps }: TableSettingsProps<T>): JSX.Element;
34
+ export declare function TableSettingsMenuSection<T extends Record<string, any>>({ viewMode, handleChangeViewMode, striped, onStripedChange, columns, visibleColumnIds, onVisibleColumnIdsChange, columnsLabel, allPresetLabel, standardPresetLabel, additionalSettings, close, }: TableSettingsMenuSectionProps<T>): JSX.Element;
35
+ export declare function TableSettings<T extends Record<string, any>>({ buttonSize, triggerLabel, triggerVariant, ...sectionProps }: TableSettingsProps<T>): JSX.Element;
@@ -1,14 +1,17 @@
1
1
  'use client';
2
2
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
- import { ListChevronsUpDown, Settings } from 'lucide-react';
4
- import { useMemo } from 'react';
3
+ import { SlidersHorizontal } from 'lucide-react';
4
+ import { useMemo, isValidElement } from 'react';
5
5
  import { Button } from '../../../button/Button';
6
6
  import { Menu } from '../../../menu/Menu';
7
7
  import { Popover } from '../../../popover/Popover';
8
+ import { canHideSettingsColumn, getSettingsColumnId, isSettingsColumnHidden } from '../../tableSettings.utils';
8
9
 
9
10
  function TableSettingsMenuSection({
10
11
  viewMode,
11
12
  handleChangeViewMode,
13
+ striped,
14
+ onStripedChange,
12
15
  columns = [],
13
16
  visibleColumnIds = [],
14
17
  onVisibleColumnIdsChange,
@@ -18,31 +21,36 @@ function TableSettingsMenuSection({
18
21
  additionalSettings,
19
22
  close
20
23
  }) {
21
- const handleViewModeChange = (mode, close2) => {
24
+ const handleViewModeChange = (mode) => {
22
25
  handleChangeViewMode(mode === "wrapped" ? "compact" : "wrapped");
23
- close2 == null ? void 0 : close2();
24
26
  };
25
- const hideableColumns = useMemo(() => columns.filter((c) => c.enableHiding !== false), [columns]);
26
- const allPresetIds = useMemo(() => hideableColumns.map((c) => c.id), [hideableColumns]);
27
+ const hideableColumns = useMemo(() => columns.filter(canHideSettingsColumn), [columns]);
28
+ const allPresetIds = useMemo(
29
+ () => hideableColumns.map(getSettingsColumnId).filter((id) => !!id),
30
+ [hideableColumns]
31
+ );
27
32
  const standardPresetIds = useMemo(
28
- () => hideableColumns.filter((c) => {
29
- var _a;
30
- return ((_a = c.meta) == null ? void 0 : _a.hidden) !== true;
31
- }).map((c) => c.id),
33
+ () => hideableColumns.filter((c) => !isSettingsColumnHidden(c)).map(getSettingsColumnId).filter((id) => !!id),
32
34
  [hideableColumns]
33
35
  );
34
36
  const visibleSet = useMemo(() => new Set(visibleColumnIds), [visibleColumnIds]);
35
37
  const visibleCount = useMemo(() => {
36
- return hideableColumns.reduce((acc, c) => {
37
- var _a;
38
- return acc + (visibleSet.has((_a = c.id) != null ? _a : "") ? 1 : 0);
39
- }, 0);
38
+ return hideableColumns.reduce(
39
+ (acc, c) => {
40
+ var _a;
41
+ return acc + (visibleSet.has((_a = getSettingsColumnId(c)) != null ? _a : "") ? 1 : 0);
42
+ },
43
+ 0
44
+ );
40
45
  }, [hideableColumns, visibleSet]);
41
46
  const setVisibleIds = (nextIds) => {
42
47
  if (!onVisibleColumnIdsChange) return;
43
48
  const safe = nextIds.length > 0 ? nextIds : standardPresetIds.length > 0 ? standardPresetIds : allPresetIds;
49
+ const lockedVisibleIds = columns.filter((column) => !canHideSettingsColumn(column)).map(getSettingsColumnId).filter((id) => id != null && visibleSet.has(id));
44
50
  onVisibleColumnIdsChange(
45
- safe.filter((id) => typeof id === "string" && Boolean(id))
51
+ Array.from(/* @__PURE__ */ new Set([...safe, ...lockedVisibleIds])).filter(
52
+ (id) => typeof id === "string" && Boolean(id)
53
+ )
46
54
  );
47
55
  };
48
56
  const toggleColumn = (id, nextVisible) => {
@@ -53,20 +61,32 @@ function TableSettingsMenuSection({
53
61
  };
54
62
  const isAllActive = useMemo(() => {
55
63
  if (!hideableColumns.length) return false;
56
- return hideableColumns.every((c) => c.id && visibleSet.has(c.id));
57
- }, [hideableColumns, visibleSet]);
64
+ return allPresetIds.length > 0 && allPresetIds.every((id) => visibleSet.has(id));
65
+ }, [hideableColumns, allPresetIds, visibleSet]);
58
66
  const isStandardActive = useMemo(() => {
59
67
  if (!hideableColumns.length) return false;
60
68
  const std = new Set(standardPresetIds);
61
- return hideableColumns.every((c) => c.id && visibleSet.has(c.id) === std.has(c.id));
62
- }, [hideableColumns, visibleSet, standardPresetIds]);
69
+ return allPresetIds.length > 0 && allPresetIds.every((id) => visibleSet.has(id) === std.has(id));
70
+ }, [hideableColumns, allPresetIds, visibleSet, standardPresetIds]);
63
71
  const presetRadioName = "table-columns-preset";
64
72
  return /* @__PURE__ */ jsxs(Fragment, { children: [
65
73
  additionalSettings == null ? void 0 : additionalSettings(close),
66
- /* @__PURE__ */ jsx(Menu.Item, { active: viewMode === "wrapped", children: /* @__PURE__ */ jsxs("button", { type: "button", onClick: () => handleViewModeChange(viewMode, close), children: [
67
- /* @__PURE__ */ jsx(ListChevronsUpDown, {}),
68
- "Ombryd tekst"
69
- ] }) }),
74
+ onStripedChange ? /* @__PURE__ */ jsx(
75
+ Menu.SwitchItem,
76
+ {
77
+ checked: Boolean(striped),
78
+ label: "Stribet",
79
+ onCheckedChange: (nextChecked) => onStripedChange(nextChecked)
80
+ }
81
+ ) : null,
82
+ /* @__PURE__ */ jsx(
83
+ Menu.SwitchItem,
84
+ {
85
+ checked: viewMode === "wrapped",
86
+ label: "Ombryd tekst",
87
+ onCheckedChange: () => handleViewModeChange(viewMode)
88
+ }
89
+ ),
70
90
  hideableColumns.length > 0 && onVisibleColumnIdsChange ? /* @__PURE__ */ jsxs(Fragment, { children: [
71
91
  /* @__PURE__ */ jsx(Menu.Separator, {}),
72
92
  /* @__PURE__ */ jsx("div", { style: { padding: "6px 10px", fontSize: 12, opacity: 0.7 }, children: columnsLabel }),
@@ -81,7 +101,6 @@ function TableSettingsMenuSection({
81
101
  setVisibleIds(
82
102
  allPresetIds.filter((id) => typeof id === "string" && Boolean(id))
83
103
  );
84
- close == null ? void 0 : close();
85
104
  }
86
105
  }
87
106
  ),
@@ -98,15 +117,16 @@ function TableSettingsMenuSection({
98
117
  (id) => typeof id === "string" && Boolean(id)
99
118
  )
100
119
  );
101
- close == null ? void 0 : close();
102
120
  }
103
121
  }
104
122
  ),
105
123
  /* @__PURE__ */ jsx(Menu.Separator, {}),
106
124
  hideableColumns.map((col) => {
107
- const isVisible = col.id ? visibleSet.has(col.id) : false;
125
+ const colId = getSettingsColumnId(col);
126
+ const isVisible = colId ? visibleSet.has(colId) : false;
108
127
  const disableUncheckingLast = isVisible && visibleCount <= 1;
109
- const label = col.header;
128
+ const header = col.header;
129
+ const label = typeof header === "function" && header.length === 0 ? header() : typeof header === "string" || typeof header === "number" || isValidElement(header) ? header : colId;
110
130
  return /* @__PURE__ */ jsx(
111
131
  Menu.CheckItem,
112
132
  {
@@ -114,11 +134,11 @@ function TableSettingsMenuSection({
114
134
  disabled: disableUncheckingLast,
115
135
  label,
116
136
  onCheckedChange: (nextChecked) => {
117
- if (disableUncheckingLast) return;
118
- toggleColumn(col.id, nextChecked);
137
+ if (disableUncheckingLast || !colId) return;
138
+ toggleColumn(colId, nextChecked);
119
139
  }
120
140
  },
121
- col.id
141
+ colId != null ? colId : String(label)
122
142
  );
123
143
  })
124
144
  ] }) : null
@@ -126,15 +146,45 @@ function TableSettingsMenuSection({
126
146
  }
127
147
  function TableSettings({
128
148
  buttonSize = "sm",
149
+ triggerLabel = "Visningsindstillinger",
150
+ triggerVariant = "button",
129
151
  ...sectionProps
130
152
  }) {
153
+ const isIcon = triggerVariant === "icon";
131
154
  return /* @__PURE__ */ jsx(
132
155
  Popover,
133
156
  {
134
- trigger: (onClick, icon) => /* @__PURE__ */ jsxs(Button, { size: buttonSize, onClick, type: "button", children: [
135
- /* @__PURE__ */ jsx(Settings, {}),
136
- icon
137
- ] }),
157
+ matchTriggerWidth: !isIcon,
158
+ minWidth: isIcon ? "220px" : void 0,
159
+ trigger: (onClick, icon, isOpen) => isIcon ? /* @__PURE__ */ jsx(
160
+ Button,
161
+ {
162
+ type: "button",
163
+ size: "sm",
164
+ variant: "inline",
165
+ shape: "round",
166
+ "aria-label": triggerLabel,
167
+ "aria-haspopup": "menu",
168
+ "aria-expanded": isOpen ? true : false,
169
+ tooltip: triggerLabel,
170
+ icon: /* @__PURE__ */ jsx(SlidersHorizontal, { size: 16 }),
171
+ "data-table-settings-trigger": "true",
172
+ onClick
173
+ }
174
+ ) : /* @__PURE__ */ jsxs(
175
+ Button,
176
+ {
177
+ size: buttonSize,
178
+ onClick,
179
+ type: "button",
180
+ "aria-label": triggerLabel,
181
+ tooltip: triggerLabel,
182
+ children: [
183
+ /* @__PURE__ */ jsx(SlidersHorizontal, {}),
184
+ icon
185
+ ]
186
+ }
187
+ ),
138
188
  children: (close) => /* @__PURE__ */ jsx(Menu, { children: /* @__PURE__ */ jsx(TableSettingsMenuSection, { ...sectionProps, close }) })
139
189
  }
140
190
  );
@@ -2,6 +2,7 @@
2
2
 
3
3
  const SELECTION_COLUMN_PX = 32;
4
4
  const ACTIONS_COLUMN_PX = 0;
5
+ const ROW_ACTIONS_RESERVE_PX = 32;
5
6
  const DEFAULT_COLUMN_PX = 150;
6
7
  function getVisibleColumns(columns) {
7
8
  return columns.filter((column) => !column.hidden);
@@ -47,6 +48,7 @@ function getCellDisplayValue(row, column) {
47
48
 
48
49
  exports.ACTIONS_COLUMN_PX = ACTIONS_COLUMN_PX;
49
50
  exports.DEFAULT_COLUMN_PX = DEFAULT_COLUMN_PX;
51
+ exports.ROW_ACTIONS_RESERVE_PX = ROW_ACTIONS_RESERVE_PX;
50
52
  exports.SELECTION_COLUMN_PX = SELECTION_COLUMN_PX;
51
53
  exports.getAriaSort = getAriaSort;
52
54
  exports.getCellDisplayValue = getCellDisplayValue;
@@ -2,6 +2,12 @@ import type { ReactNode } from 'react';
2
2
  import type { ColumnItem } from './Table.types';
3
3
  export declare const SELECTION_COLUMN_PX: 32;
4
4
  export declare const ACTIONS_COLUMN_PX: 0;
5
+ /**
6
+ * Space kept free at the inline end of the last column for the row actions
7
+ * button and header actions. Must match `--table-row-actions-reserve-inline`
8
+ * in Table.module.css (component-size-sm 30px + spacing-2xs 2px).
9
+ */
10
+ export declare const ROW_ACTIONS_RESERVE_PX: 32;
5
11
  export declare const DEFAULT_COLUMN_PX: 150;
6
12
  export type SortDirection = 'asc' | 'desc' | null;
7
13
  export declare function getVisibleColumns<T>(columns: Array<ColumnItem<T>>): Array<ColumnItem<T>>;
@@ -1,5 +1,6 @@
1
1
  const SELECTION_COLUMN_PX = 32;
2
2
  const ACTIONS_COLUMN_PX = 0;
3
+ const ROW_ACTIONS_RESERVE_PX = 32;
3
4
  const DEFAULT_COLUMN_PX = 150;
4
5
  function getVisibleColumns(columns) {
5
6
  return columns.filter((column) => !column.hidden);
@@ -43,4 +44,4 @@ function getCellDisplayValue(row, column) {
43
44
  return empty;
44
45
  }
45
46
 
46
- export { ACTIONS_COLUMN_PX, DEFAULT_COLUMN_PX, SELECTION_COLUMN_PX, getAriaSort, getCellDisplayValue, getHeaderLabel, getNextSortDirection, getVisibleColumns, isActiveSort, isModifierClick, shouldAllowWrap, shouldToggleOnKey };
47
+ export { ACTIONS_COLUMN_PX, DEFAULT_COLUMN_PX, ROW_ACTIONS_RESERVE_PX, SELECTION_COLUMN_PX, getAriaSort, getCellDisplayValue, getHeaderLabel, getNextSortDirection, getVisibleColumns, isActiveSort, isModifierClick, shouldAllowWrap, shouldToggleOnKey };
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ function getSettingsColumnId(column) {
4
+ if (typeof column.id === "string" && column.id.length > 0) return column.id;
5
+ if (typeof column.accessorKey === "string" && column.accessorKey.length > 0) {
6
+ return column.accessorKey;
7
+ }
8
+ return void 0;
9
+ }
10
+ function isSettingsColumnHidden(column) {
11
+ if (column.hidden != null) return column.hidden;
12
+ return typeof column.meta === "object" && column.meta !== null && "hidden" in column.meta && column.meta.hidden === true;
13
+ }
14
+ function canHideSettingsColumn(column) {
15
+ return column.canHide !== false && column.enableHiding !== false;
16
+ }
17
+ function filterColumnsBySettings(columns, visibleColumnIds) {
18
+ const visible = new Set(visibleColumnIds);
19
+ return columns.filter((column) => {
20
+ if (!canHideSettingsColumn(column)) return column.hidden !== true;
21
+ const id = getSettingsColumnId(column);
22
+ return id != null && visible.has(id);
23
+ });
24
+ }
25
+
26
+ exports.canHideSettingsColumn = canHideSettingsColumn;
27
+ exports.filterColumnsBySettings = filterColumnsBySettings;
28
+ exports.getSettingsColumnId = getSettingsColumnId;
29
+ exports.isSettingsColumnHidden = isSettingsColumnHidden;
@@ -0,0 +1,9 @@
1
+ import type { TableSettingsColumn } from './Table.types';
2
+ export declare function getSettingsColumnId(column: TableSettingsColumn): string | undefined;
3
+ export declare function isSettingsColumnHidden(column: TableSettingsColumn): boolean;
4
+ export declare function canHideSettingsColumn(column: TableSettingsColumn): boolean;
5
+ /**
6
+ * Columns to render for a set of visible ids from table settings. Columns that
7
+ * can't be hidden stay governed by their own `hidden` flag.
8
+ */
9
+ export declare function filterColumnsBySettings<C extends TableSettingsColumn>(columns: ReadonlyArray<C>, visibleColumnIds: ReadonlyArray<string>): C[];
@@ -0,0 +1,24 @@
1
+ function getSettingsColumnId(column) {
2
+ if (typeof column.id === "string" && column.id.length > 0) return column.id;
3
+ if (typeof column.accessorKey === "string" && column.accessorKey.length > 0) {
4
+ return column.accessorKey;
5
+ }
6
+ return void 0;
7
+ }
8
+ function isSettingsColumnHidden(column) {
9
+ if (column.hidden != null) return column.hidden;
10
+ return typeof column.meta === "object" && column.meta !== null && "hidden" in column.meta && column.meta.hidden === true;
11
+ }
12
+ function canHideSettingsColumn(column) {
13
+ return column.canHide !== false && column.enableHiding !== false;
14
+ }
15
+ function filterColumnsBySettings(columns, visibleColumnIds) {
16
+ const visible = new Set(visibleColumnIds);
17
+ return columns.filter((column) => {
18
+ if (!canHideSettingsColumn(column)) return column.hidden !== true;
19
+ const id = getSettingsColumnId(column);
20
+ return id != null && visible.has(id);
21
+ });
22
+ }
23
+
24
+ export { canHideSettingsColumn, filterColumnsBySettings, getSettingsColumnId, isSettingsColumnHidden };
@@ -118,6 +118,7 @@ function buildDistributedColumnWidths(args) {
118
118
  id: c.id,
119
119
  width: resizedPx,
120
120
  weight: 0,
121
+ min,
121
122
  max: resizedPx,
122
123
  fixed: true
123
124
  };
@@ -128,10 +129,17 @@ function buildDistributedColumnWidths(args) {
128
129
  id: c.id,
129
130
  width: min,
130
131
  weight,
132
+ min,
131
133
  max,
132
134
  fixed: false
133
135
  };
134
136
  });
137
+ const lastTrack = tracks[tracks.length - 1];
138
+ if (hasContextMenu && lastTrack && !lastTrack.fixed) {
139
+ lastTrack.min += table_utils.ROW_ACTIONS_RESERVE_PX;
140
+ lastTrack.width += table_utils.ROW_ACTIONS_RESERVE_PX;
141
+ if (lastTrack.max != null) lastTrack.max += table_utils.ROW_ACTIONS_RESERVE_PX;
142
+ }
135
143
  const fixedWidth = selectionWidth + contextMenuWidth + tracks.reduce((sum, track) => sum + track.width, 0);
136
144
  let remaining = Math.max(0, availableWidth - fixedWidth);
137
145
  let active = tracks.filter(
@@ -156,6 +164,16 @@ function buildDistributedColumnWidths(args) {
156
164
  remaining -= consumed;
157
165
  active = nextActive;
158
166
  }
167
+ const flexible = tracks.filter((track) => !track.fixed);
168
+ if (remaining > 0.5 && flexible.length > 0 && flexible.every((track) => track.max != null)) {
169
+ const stretchable = flexible.filter((track) => track.max > track.min);
170
+ const totalWeight = stretchable.reduce((sum, track) => sum + track.weight, 0);
171
+ if (totalWeight > 0) {
172
+ for (const track of stretchable) {
173
+ track.width += remaining * track.weight / totalWeight;
174
+ }
175
+ }
176
+ }
159
177
  const floatTrackTotal = tracks.reduce((sum, track) => sum + track.width, 0);
160
178
  const maxTrackWidth = availableWidth - selectionWidth - contextMenuWidth;
161
179
  const targetTrackWidth = Math.min(
@@ -1,4 +1,4 @@
1
- import { DEFAULT_COLUMN_PX, SELECTION_COLUMN_PX } from './table.utils';
1
+ import { DEFAULT_COLUMN_PX, ROW_ACTIONS_RESERVE_PX, SELECTION_COLUMN_PX } from './table.utils';
2
2
 
3
3
  function getColumnId(def, index) {
4
4
  const d = def;
@@ -116,6 +116,7 @@ function buildDistributedColumnWidths(args) {
116
116
  id: c.id,
117
117
  width: resizedPx,
118
118
  weight: 0,
119
+ min,
119
120
  max: resizedPx,
120
121
  fixed: true
121
122
  };
@@ -126,10 +127,17 @@ function buildDistributedColumnWidths(args) {
126
127
  id: c.id,
127
128
  width: min,
128
129
  weight,
130
+ min,
129
131
  max,
130
132
  fixed: false
131
133
  };
132
134
  });
135
+ const lastTrack = tracks[tracks.length - 1];
136
+ if (hasContextMenu && lastTrack && !lastTrack.fixed) {
137
+ lastTrack.min += ROW_ACTIONS_RESERVE_PX;
138
+ lastTrack.width += ROW_ACTIONS_RESERVE_PX;
139
+ if (lastTrack.max != null) lastTrack.max += ROW_ACTIONS_RESERVE_PX;
140
+ }
133
141
  const fixedWidth = selectionWidth + contextMenuWidth + tracks.reduce((sum, track) => sum + track.width, 0);
134
142
  let remaining = Math.max(0, availableWidth - fixedWidth);
135
143
  let active = tracks.filter(
@@ -154,6 +162,16 @@ function buildDistributedColumnWidths(args) {
154
162
  remaining -= consumed;
155
163
  active = nextActive;
156
164
  }
165
+ const flexible = tracks.filter((track) => !track.fixed);
166
+ if (remaining > 0.5 && flexible.length > 0 && flexible.every((track) => track.max != null)) {
167
+ const stretchable = flexible.filter((track) => track.max > track.min);
168
+ const totalWeight = stretchable.reduce((sum, track) => sum + track.weight, 0);
169
+ if (totalWeight > 0) {
170
+ for (const track of stretchable) {
171
+ track.width += remaining * track.weight / totalWeight;
172
+ }
173
+ }
174
+ }
157
175
  const floatTrackTotal = tracks.reduce((sum, track) => sum + track.width, 0);
158
176
  const maxTrackWidth = availableWidth - selectionWidth - contextMenuWidth;
159
177
  const targetTrackWidth = Math.min(