@dbcdk/react-components 0.0.190 → 0.0.192

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 (128) hide show
  1. package/dist/client.cjs +14 -0
  2. package/dist/client.d.ts +2 -0
  3. package/dist/client.js +2 -0
  4. package/dist/components/button-select/ButtonSelect.cjs +2 -2
  5. package/dist/components/button-select/ButtonSelect.d.ts +1 -0
  6. package/dist/components/button-select/ButtonSelect.js +2 -2
  7. package/dist/components/button-select/ButtonSelect.module.css +14 -0
  8. package/dist/components/chip/Chip.module.css +25 -2
  9. package/dist/components/forms/checkbox/Checkbox.cjs +6 -1
  10. package/dist/components/forms/checkbox/Checkbox.js +6 -1
  11. package/dist/components/forms/checkbox/Checkbox.module.css +26 -0
  12. package/dist/components/forms/input/Input.module.css +93 -0
  13. package/dist/components/forms/input-container/InputContainer.module.css +0 -7
  14. package/dist/components/grid/Grid.cjs +4 -2
  15. package/dist/components/grid/Grid.d.ts +2 -2
  16. package/dist/components/grid/Grid.js +4 -2
  17. package/dist/components/json-viewer/JsonViewer.cjs +2 -1
  18. package/dist/components/json-viewer/JsonViewer.js +3 -2
  19. package/dist/components/line-viewer/LineViewer.cjs +2 -1
  20. package/dist/components/line-viewer/LineViewer.js +3 -2
  21. package/dist/components/overlay/side-panel/SidePanel.module.css +3 -1
  22. package/dist/components/page-layout/PageLayout.module.css +12 -3
  23. package/dist/components/popover/Popover.cjs +2 -1
  24. package/dist/components/popover/Popover.d.ts +8 -1
  25. package/dist/components/popover/Popover.js +2 -1
  26. package/dist/components/search-box/SearchBox.cjs +10 -7
  27. package/dist/components/search-box/SearchBox.d.ts +7 -0
  28. package/dist/components/search-box/SearchBox.js +10 -7
  29. package/dist/components/sidebar/components/sidenav-filteirng/SidenavFiltering.cjs +2 -1
  30. package/dist/components/sidebar/components/sidenav-filteirng/SidenavFiltering.js +2 -1
  31. package/dist/components/tabs/Tabs.cjs +58 -56
  32. package/dist/components/tabs/Tabs.js +58 -56
  33. package/dist/components/tabs/Tabs.module.css +32 -16
  34. package/dist/components/timeline/Timeline.d.ts +1 -0
  35. package/dist/components/timeline/components/TimelineRow.cjs +1 -1
  36. package/dist/components/timeline/components/TimelineRow.js +1 -1
  37. package/dist/components/timeline/components/TimelineRow.module.css +4 -0
  38. package/dist/components/tree-view/TreeNodeRow.cjs +9 -1
  39. package/dist/components/tree-view/TreeNodeRow.d.ts +2 -1
  40. package/dist/components/tree-view/TreeNodeRow.js +9 -1
  41. package/dist/components/tree-view/TreeView.cjs +2 -0
  42. package/dist/components/tree-view/TreeView.d.ts +1 -1
  43. package/dist/components/tree-view/TreeView.js +2 -0
  44. package/dist/components/tree-view/TreeView.module.css +8 -0
  45. package/dist/components/tree-view/types.d.ts +2 -0
  46. package/dist/components/tree-view/useTreeExpansion.cjs +12 -2
  47. package/dist/components/tree-view/useTreeExpansion.d.ts +1 -0
  48. package/dist/components/tree-view/useTreeExpansion.js +12 -2
  49. package/dist/components/xml-viewer/XmlViewer.cjs +2 -1
  50. package/dist/components/xml-viewer/XmlViewer.js +3 -2
  51. package/dist/hooks/useStickyLayout.cjs +99 -0
  52. package/dist/hooks/useStickyLayout.d.ts +22 -0
  53. package/dist/hooks/useStickyLayout.js +97 -0
  54. package/dist/hooks/useTreeViewSettings.cjs +87 -0
  55. package/dist/hooks/useTreeViewSettings.d.ts +35 -0
  56. package/dist/hooks/useTreeViewSettings.js +84 -0
  57. package/dist/index.cjs +7 -0
  58. package/dist/index.d.ts +1 -0
  59. package/dist/index.js +1 -0
  60. package/dist/styles/css-helper-classes/scrollbar.css +10 -0
  61. package/dist/styles/styles.css +1 -21
  62. package/dist/styles/themes/dbc/base.css +2 -2
  63. package/dist/styles.css +1 -21
  64. package/package.json +1 -1
  65. package/dist/styles/fonts/Roboto/OFL.txt +0 -93
  66. package/dist/styles/fonts/Roboto/README.txt +0 -118
  67. package/dist/styles/fonts/Roboto/Roboto-Black.ttf +0 -0
  68. package/dist/styles/fonts/Roboto/Roboto-BlackItalic.ttf +0 -0
  69. package/dist/styles/fonts/Roboto/Roboto-Bold.ttf +0 -0
  70. package/dist/styles/fonts/Roboto/Roboto-BoldItalic.ttf +0 -0
  71. package/dist/styles/fonts/Roboto/Roboto-ExtraBold.ttf +0 -0
  72. package/dist/styles/fonts/Roboto/Roboto-ExtraBoldItalic.ttf +0 -0
  73. package/dist/styles/fonts/Roboto/Roboto-ExtraLight.ttf +0 -0
  74. package/dist/styles/fonts/Roboto/Roboto-ExtraLightItalic.ttf +0 -0
  75. package/dist/styles/fonts/Roboto/Roboto-Italic.ttf +0 -0
  76. package/dist/styles/fonts/Roboto/Roboto-Light.ttf +0 -0
  77. package/dist/styles/fonts/Roboto/Roboto-LightItalic.ttf +0 -0
  78. package/dist/styles/fonts/Roboto/Roboto-Medium.ttf +0 -0
  79. package/dist/styles/fonts/Roboto/Roboto-MediumItalic.ttf +0 -0
  80. package/dist/styles/fonts/Roboto/Roboto-Regular.ttf +0 -0
  81. package/dist/styles/fonts/Roboto/Roboto-SemiBold.ttf +0 -0
  82. package/dist/styles/fonts/Roboto/Roboto-SemiBoldItalic.ttf +0 -0
  83. package/dist/styles/fonts/Roboto/Roboto-Thin.ttf +0 -0
  84. package/dist/styles/fonts/Roboto/Roboto-ThinItalic.ttf +0 -0
  85. package/dist/styles/fonts/Roboto/Roboto_Condensed-Black.ttf +0 -0
  86. package/dist/styles/fonts/Roboto/Roboto_Condensed-BlackItalic.ttf +0 -0
  87. package/dist/styles/fonts/Roboto/Roboto_Condensed-Bold.ttf +0 -0
  88. package/dist/styles/fonts/Roboto/Roboto_Condensed-BoldItalic.ttf +0 -0
  89. package/dist/styles/fonts/Roboto/Roboto_Condensed-ExtraBold.ttf +0 -0
  90. package/dist/styles/fonts/Roboto/Roboto_Condensed-ExtraBoldItalic.ttf +0 -0
  91. package/dist/styles/fonts/Roboto/Roboto_Condensed-ExtraLight.ttf +0 -0
  92. package/dist/styles/fonts/Roboto/Roboto_Condensed-ExtraLightItalic.ttf +0 -0
  93. package/dist/styles/fonts/Roboto/Roboto_Condensed-Italic.ttf +0 -0
  94. package/dist/styles/fonts/Roboto/Roboto_Condensed-Light.ttf +0 -0
  95. package/dist/styles/fonts/Roboto/Roboto_Condensed-LightItalic.ttf +0 -0
  96. package/dist/styles/fonts/Roboto/Roboto_Condensed-Medium.ttf +0 -0
  97. package/dist/styles/fonts/Roboto/Roboto_Condensed-MediumItalic.ttf +0 -0
  98. package/dist/styles/fonts/Roboto/Roboto_Condensed-Regular.ttf +0 -0
  99. package/dist/styles/fonts/Roboto/Roboto_Condensed-SemiBold.ttf +0 -0
  100. package/dist/styles/fonts/Roboto/Roboto_Condensed-SemiBoldItalic.ttf +0 -0
  101. package/dist/styles/fonts/Roboto/Roboto_Condensed-Thin.ttf +0 -0
  102. package/dist/styles/fonts/Roboto/Roboto_Condensed-ThinItalic.ttf +0 -0
  103. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-Black.ttf +0 -0
  104. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-BlackItalic.ttf +0 -0
  105. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-Bold.ttf +0 -0
  106. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-BoldItalic.ttf +0 -0
  107. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-ExtraBold.ttf +0 -0
  108. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-ExtraBoldItalic.ttf +0 -0
  109. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-ExtraLight.ttf +0 -0
  110. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-ExtraLightItalic.ttf +0 -0
  111. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-Italic.ttf +0 -0
  112. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-Light.ttf +0 -0
  113. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-LightItalic.ttf +0 -0
  114. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-Medium.ttf +0 -0
  115. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-MediumItalic.ttf +0 -0
  116. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-Regular.ttf +0 -0
  117. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-SemiBold.ttf +0 -0
  118. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-SemiBoldItalic.ttf +0 -0
  119. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-Thin.ttf +0 -0
  120. package/dist/styles/fonts/Roboto/Roboto_SemiCondensed-ThinItalic.ttf +0 -0
  121. package/dist/styles/fonts/Tajawal/OFL.txt +0 -93
  122. package/dist/styles/fonts/Tajawal/Tajawal-Black.ttf +0 -0
  123. package/dist/styles/fonts/Tajawal/Tajawal-Bold.ttf +0 -0
  124. package/dist/styles/fonts/Tajawal/Tajawal-ExtraBold.ttf +0 -0
  125. package/dist/styles/fonts/Tajawal/Tajawal-ExtraLight.ttf +0 -0
  126. package/dist/styles/fonts/Tajawal/Tajawal-Light.ttf +0 -0
  127. package/dist/styles/fonts/Tajawal/Tajawal-Medium.ttf +0 -0
  128. package/dist/styles/fonts/Tajawal/Tajawal-Regular.ttf +0 -0
@@ -27,6 +27,7 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
27
27
  resultKeys,
28
28
  resultTemplate,
29
29
  initialTemplate,
30
+ initialTemplateOnly = false,
30
31
  popoverMinWidth = "500px",
31
32
  noResultText = "Ingen resultater",
32
33
  loading,
@@ -99,34 +100,36 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
99
100
  }, [enableHotkey]);
100
101
  const hasInitialTemplate = initialTemplate !== void 0 && initialTemplate !== null;
101
102
  const hasQuery = draft.trim().length > 0;
102
- const canShowPopover = hasQuery || hasInitialTemplate;
103
+ const canShowPopover = initialTemplateOnly ? !hasQuery && hasInitialTemplate : hasQuery || hasInitialTemplate;
103
104
  const handleChange = react.useCallback(
104
105
  (e) => {
105
106
  var _a2, _b, _c;
106
107
  const nextDraft = e.target.value;
107
108
  const nextHasQuery = nextDraft.trim().length > 0;
108
109
  setDraft(nextDraft);
109
- if (nextHasQuery || hasInitialTemplate) {
110
+ const nextCanShow = initialTemplateOnly ? !nextHasQuery && hasInitialTemplate : nextHasQuery || hasInitialTemplate;
111
+ if (nextCanShow) {
110
112
  if (!((_a2 = popoverRef.current) == null ? void 0 : _a2.isOpen())) (_b = popoverRef.current) == null ? void 0 : _b.open();
111
113
  } else {
112
114
  (_c = popoverRef.current) == null ? void 0 : _c.close();
113
115
  }
114
116
  onChange == null ? void 0 : onChange(e);
115
117
  },
116
- [hasInitialTemplate, onChange]
118
+ [hasInitialTemplate, initialTemplateOnly, onChange]
117
119
  );
118
120
  const handleSelect = react.useCallback(
119
121
  (item) => {
120
122
  onSelect == null ? void 0 : onSelect(item);
121
- reset();
123
+ reset({ returnFocus: false });
124
+ onSearch == null ? void 0 : onSearch("");
122
125
  },
123
- [onSelect]
126
+ [onSelect, onSearch]
124
127
  );
125
- function reset() {
128
+ function reset(opts) {
126
129
  var _a2;
127
130
  setDraft("");
128
131
  setActiveIndex(null);
129
- (_a2 = popoverRef.current) == null ? void 0 : _a2.close();
132
+ (_a2 = popoverRef.current) == null ? void 0 : _a2.close(opts);
130
133
  }
131
134
  const handleClear = react.useCallback(() => {
132
135
  var _a2;
@@ -15,6 +15,13 @@ export type SearchBoxProps<T extends Record<string, unknown>> = Omit<InputProps,
15
15
  onSelect?: (item: T) => void;
16
16
  displayPopover?: boolean;
17
17
  initialTemplate?: React.ReactNode;
18
+ /**
19
+ * When true, the popover only ever shows `initialTemplate` (on an empty
20
+ * field) and never opens once there's a query - for a box with no live
21
+ * results/resultTemplate of its own (e.g. one that just navigates via a
22
+ * URL param), so it doesn't pop open an empty dropdown while typing.
23
+ */
24
+ initialTemplateOnly?: boolean;
18
25
  noResultText?: string;
19
26
  popoverMinWidth?: string;
20
27
  loading?: boolean;
@@ -21,6 +21,7 @@ const SearchBox = forwardRef(function SearchBoxInner({
21
21
  resultKeys,
22
22
  resultTemplate,
23
23
  initialTemplate,
24
+ initialTemplateOnly = false,
24
25
  popoverMinWidth = "500px",
25
26
  noResultText = "Ingen resultater",
26
27
  loading,
@@ -93,34 +94,36 @@ const SearchBox = forwardRef(function SearchBoxInner({
93
94
  }, [enableHotkey]);
94
95
  const hasInitialTemplate = initialTemplate !== void 0 && initialTemplate !== null;
95
96
  const hasQuery = draft.trim().length > 0;
96
- const canShowPopover = hasQuery || hasInitialTemplate;
97
+ const canShowPopover = initialTemplateOnly ? !hasQuery && hasInitialTemplate : hasQuery || hasInitialTemplate;
97
98
  const handleChange = useCallback(
98
99
  (e) => {
99
100
  var _a2, _b, _c;
100
101
  const nextDraft = e.target.value;
101
102
  const nextHasQuery = nextDraft.trim().length > 0;
102
103
  setDraft(nextDraft);
103
- if (nextHasQuery || hasInitialTemplate) {
104
+ const nextCanShow = initialTemplateOnly ? !nextHasQuery && hasInitialTemplate : nextHasQuery || hasInitialTemplate;
105
+ if (nextCanShow) {
104
106
  if (!((_a2 = popoverRef.current) == null ? void 0 : _a2.isOpen())) (_b = popoverRef.current) == null ? void 0 : _b.open();
105
107
  } else {
106
108
  (_c = popoverRef.current) == null ? void 0 : _c.close();
107
109
  }
108
110
  onChange == null ? void 0 : onChange(e);
109
111
  },
110
- [hasInitialTemplate, onChange]
112
+ [hasInitialTemplate, initialTemplateOnly, onChange]
111
113
  );
112
114
  const handleSelect = useCallback(
113
115
  (item) => {
114
116
  onSelect == null ? void 0 : onSelect(item);
115
- reset();
117
+ reset({ returnFocus: false });
118
+ onSearch == null ? void 0 : onSearch("");
116
119
  },
117
- [onSelect]
120
+ [onSelect, onSearch]
118
121
  );
119
- function reset() {
122
+ function reset(opts) {
120
123
  var _a2;
121
124
  setDraft("");
122
125
  setActiveIndex(null);
123
- (_a2 = popoverRef.current) == null ? void 0 : _a2.close();
126
+ (_a2 = popoverRef.current) == null ? void 0 : _a2.close(opts);
124
127
  }
125
128
  const handleClear = useCallback(() => {
126
129
  var _a2;
@@ -4,6 +4,7 @@
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var lucideReact = require('lucide-react');
6
6
  var React = require('react');
7
+ var Icon = require('../../../../components/icon/Icon');
7
8
  var Button = require('../../../button/Button');
8
9
  var Menu = require('../../../menu/Menu');
9
10
  var Popover = require('../../../popover/Popover');
@@ -73,7 +74,7 @@ const SidenavFiltering = ({
73
74
  variant: "outlined",
74
75
  "aria-label": "\xC5bn indstillinger for sidemenu",
75
76
  onClick: toggle,
76
- icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings2, {})
77
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { customIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings2, { "aria-hidden": "true" }) })
77
78
  }
78
79
  ),
79
80
  children: (close) => /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu, { children: /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Item, { active: wrapItemText, children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -2,6 +2,7 @@
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
3
  import { Search, Settings2 } from 'lucide-react';
4
4
  import React from 'react';
5
+ import { Icon } from '../../../../components/icon/Icon';
5
6
  import { Button } from '../../../button/Button';
6
7
  import { Menu } from '../../../menu/Menu';
7
8
  import { Popover } from '../../../popover/Popover';
@@ -67,7 +68,7 @@ const SidenavFiltering = ({
67
68
  variant: "outlined",
68
69
  "aria-label": "\xC5bn indstillinger for sidemenu",
69
70
  onClick: toggle,
70
- icon: /* @__PURE__ */ jsx(Settings2, {})
71
+ icon: /* @__PURE__ */ jsx(Icon, { customIcon: /* @__PURE__ */ jsx(Settings2, { "aria-hidden": "true" }) })
71
72
  }
72
73
  ),
73
74
  children: (close) => /* @__PURE__ */ jsx(Menu, { children: /* @__PURE__ */ jsx(Menu.Item, { active: wrapItemText, children: /* @__PURE__ */ jsx(
@@ -150,62 +150,64 @@ function Tabs({
150
150
  ) : null,
151
151
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${styles__default.default.tabs} ${styles__default.default[variant]} ${panelStyle ? styles__default.default.panelStyle : ""}`, children: [
152
152
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.tabList, children: [
153
- /* @__PURE__ */ jsxRuntime.jsx(
154
- "div",
155
- {
156
- className: onAddTab ? styles__default.default.tabButtons : `${styles__default.default.tabButtons} ${styles__default.default.tabButtonsEnd}`,
157
- role: "tablist",
158
- "aria-label": header != null ? header : "Tabs",
159
- children: visibleTabs.map((tab, index) => {
160
- const selected = index === activeIndex;
161
- const tabDomId = `${uid}-tab-${String(tab.id)}`;
162
- const panelDomId = `${uid}-panel-${String(tab.id)}`;
163
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${styles__default.default.tab} ${selected ? styles__default.default.active : ""}`, children: [
164
- /* @__PURE__ */ jsxRuntime.jsxs(
165
- "button",
166
- {
167
- id: tabDomId,
168
- type: "button",
169
- className: styles__default.default.tabButton,
170
- role: "tab",
171
- "aria-selected": selected,
172
- "aria-controls": panelDomId,
173
- tabIndex: selected ? 0 : -1,
174
- disabled: tab.disabled,
175
- onClick: () => setValue(tab.id),
176
- onKeyDown: (e) => onKeyDownTab(e, index),
177
- children: [
178
- tab.headerIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.icon, children: tab.headerIcon }) : null,
179
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.label, children: tab.header }),
180
- tab.badge ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.badge, children: /* @__PURE__ */ jsxRuntime.jsx(Chip.Chip, { size: "sm", children: tab.badge.toLocaleString("da-DK") }) }) : null
181
- ]
182
- }
183
- ),
184
- tab.removable && onRemoveTab ? /* @__PURE__ */ jsxRuntime.jsx(
185
- "button",
186
- {
187
- type: "button",
188
- className: styles__default.default.removeTabButton,
189
- "aria-label": `Fjern fane ${tab.header}`,
190
- disabled: tab.disabled,
191
- onClick: () => onRemoveTab(tab.id, tab, index),
192
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { "aria-hidden": "true" })
193
- }
194
- ) : null
195
- ] }, tab.id);
196
- })
197
- }
198
- ),
199
- onAddTab ? /* @__PURE__ */ jsxRuntime.jsx(
200
- "button",
201
- {
202
- type: "button",
203
- className: styles__default.default.addTabButton,
204
- onClick: onAddTab,
205
- "aria-label": "Tilf\xF8j fane",
206
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { "aria-hidden": "true" })
207
- }
208
- ) : null,
153
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.tabStrip, children: [
154
+ /* @__PURE__ */ jsxRuntime.jsx(
155
+ "div",
156
+ {
157
+ className: onAddTab ? styles__default.default.tabButtons : `${styles__default.default.tabButtons} ${styles__default.default.tabButtonsEnd}`,
158
+ role: "tablist",
159
+ "aria-label": header != null ? header : "Tabs",
160
+ children: visibleTabs.map((tab, index) => {
161
+ const selected = index === activeIndex;
162
+ const tabDomId = `${uid}-tab-${String(tab.id)}`;
163
+ const panelDomId = `${uid}-panel-${String(tab.id)}`;
164
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${styles__default.default.tab} ${selected ? styles__default.default.active : ""}`, children: [
165
+ /* @__PURE__ */ jsxRuntime.jsxs(
166
+ "button",
167
+ {
168
+ id: tabDomId,
169
+ type: "button",
170
+ className: styles__default.default.tabButton,
171
+ role: "tab",
172
+ "aria-selected": selected,
173
+ "aria-controls": panelDomId,
174
+ tabIndex: selected ? 0 : -1,
175
+ disabled: tab.disabled,
176
+ onClick: () => setValue(tab.id),
177
+ onKeyDown: (e) => onKeyDownTab(e, index),
178
+ children: [
179
+ tab.headerIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.icon, children: tab.headerIcon }) : null,
180
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.label, children: tab.header }),
181
+ tab.badge ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.badge, children: /* @__PURE__ */ jsxRuntime.jsx(Chip.Chip, { size: "sm", children: tab.badge.toLocaleString("da-DK") }) }) : null
182
+ ]
183
+ }
184
+ ),
185
+ tab.removable && onRemoveTab ? /* @__PURE__ */ jsxRuntime.jsx(
186
+ "button",
187
+ {
188
+ type: "button",
189
+ className: styles__default.default.removeTabButton,
190
+ "aria-label": `Fjern fane ${tab.header}`,
191
+ disabled: tab.disabled,
192
+ onClick: () => onRemoveTab(tab.id, tab, index),
193
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { "aria-hidden": "true" })
194
+ }
195
+ ) : null
196
+ ] }, tab.id);
197
+ })
198
+ }
199
+ ),
200
+ onAddTab ? /* @__PURE__ */ jsxRuntime.jsx(
201
+ "button",
202
+ {
203
+ type: "button",
204
+ className: styles__default.default.addTabButton,
205
+ onClick: onAddTab,
206
+ "aria-label": "Tilf\xF8j fane",
207
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { "aria-hidden": "true" })
208
+ }
209
+ ) : null
210
+ ] }),
209
211
  tabListAddition ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.tabListAddition, children: tabListAddition }) : null
210
212
  ] }),
211
213
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -144,62 +144,64 @@ function Tabs({
144
144
  ) : null,
145
145
  /* @__PURE__ */ jsxs("div", { className: `${styles.tabs} ${styles[variant]} ${panelStyle ? styles.panelStyle : ""}`, children: [
146
146
  /* @__PURE__ */ jsxs("div", { className: styles.tabList, children: [
147
- /* @__PURE__ */ jsx(
148
- "div",
149
- {
150
- className: onAddTab ? styles.tabButtons : `${styles.tabButtons} ${styles.tabButtonsEnd}`,
151
- role: "tablist",
152
- "aria-label": header != null ? header : "Tabs",
153
- children: visibleTabs.map((tab, index) => {
154
- const selected = index === activeIndex;
155
- const tabDomId = `${uid}-tab-${String(tab.id)}`;
156
- const panelDomId = `${uid}-panel-${String(tab.id)}`;
157
- return /* @__PURE__ */ jsxs("div", { className: `${styles.tab} ${selected ? styles.active : ""}`, children: [
158
- /* @__PURE__ */ jsxs(
159
- "button",
160
- {
161
- id: tabDomId,
162
- type: "button",
163
- className: styles.tabButton,
164
- role: "tab",
165
- "aria-selected": selected,
166
- "aria-controls": panelDomId,
167
- tabIndex: selected ? 0 : -1,
168
- disabled: tab.disabled,
169
- onClick: () => setValue(tab.id),
170
- onKeyDown: (e) => onKeyDownTab(e, index),
171
- children: [
172
- tab.headerIcon ? /* @__PURE__ */ jsx("span", { className: styles.icon, children: tab.headerIcon }) : null,
173
- /* @__PURE__ */ jsx("span", { className: styles.label, children: tab.header }),
174
- tab.badge ? /* @__PURE__ */ jsx("span", { className: styles.badge, children: /* @__PURE__ */ jsx(Chip, { size: "sm", children: tab.badge.toLocaleString("da-DK") }) }) : null
175
- ]
176
- }
177
- ),
178
- tab.removable && onRemoveTab ? /* @__PURE__ */ jsx(
179
- "button",
180
- {
181
- type: "button",
182
- className: styles.removeTabButton,
183
- "aria-label": `Fjern fane ${tab.header}`,
184
- disabled: tab.disabled,
185
- onClick: () => onRemoveTab(tab.id, tab, index),
186
- children: /* @__PURE__ */ jsx(X, { "aria-hidden": "true" })
187
- }
188
- ) : null
189
- ] }, tab.id);
190
- })
191
- }
192
- ),
193
- onAddTab ? /* @__PURE__ */ jsx(
194
- "button",
195
- {
196
- type: "button",
197
- className: styles.addTabButton,
198
- onClick: onAddTab,
199
- "aria-label": "Tilf\xF8j fane",
200
- children: /* @__PURE__ */ jsx(Plus, { "aria-hidden": "true" })
201
- }
202
- ) : null,
147
+ /* @__PURE__ */ jsxs("div", { className: styles.tabStrip, children: [
148
+ /* @__PURE__ */ jsx(
149
+ "div",
150
+ {
151
+ className: onAddTab ? styles.tabButtons : `${styles.tabButtons} ${styles.tabButtonsEnd}`,
152
+ role: "tablist",
153
+ "aria-label": header != null ? header : "Tabs",
154
+ children: visibleTabs.map((tab, index) => {
155
+ const selected = index === activeIndex;
156
+ const tabDomId = `${uid}-tab-${String(tab.id)}`;
157
+ const panelDomId = `${uid}-panel-${String(tab.id)}`;
158
+ return /* @__PURE__ */ jsxs("div", { className: `${styles.tab} ${selected ? styles.active : ""}`, children: [
159
+ /* @__PURE__ */ jsxs(
160
+ "button",
161
+ {
162
+ id: tabDomId,
163
+ type: "button",
164
+ className: styles.tabButton,
165
+ role: "tab",
166
+ "aria-selected": selected,
167
+ "aria-controls": panelDomId,
168
+ tabIndex: selected ? 0 : -1,
169
+ disabled: tab.disabled,
170
+ onClick: () => setValue(tab.id),
171
+ onKeyDown: (e) => onKeyDownTab(e, index),
172
+ children: [
173
+ tab.headerIcon ? /* @__PURE__ */ jsx("span", { className: styles.icon, children: tab.headerIcon }) : null,
174
+ /* @__PURE__ */ jsx("span", { className: styles.label, children: tab.header }),
175
+ tab.badge ? /* @__PURE__ */ jsx("span", { className: styles.badge, children: /* @__PURE__ */ jsx(Chip, { size: "sm", children: tab.badge.toLocaleString("da-DK") }) }) : null
176
+ ]
177
+ }
178
+ ),
179
+ tab.removable && onRemoveTab ? /* @__PURE__ */ jsx(
180
+ "button",
181
+ {
182
+ type: "button",
183
+ className: styles.removeTabButton,
184
+ "aria-label": `Fjern fane ${tab.header}`,
185
+ disabled: tab.disabled,
186
+ onClick: () => onRemoveTab(tab.id, tab, index),
187
+ children: /* @__PURE__ */ jsx(X, { "aria-hidden": "true" })
188
+ }
189
+ ) : null
190
+ ] }, tab.id);
191
+ })
192
+ }
193
+ ),
194
+ onAddTab ? /* @__PURE__ */ jsx(
195
+ "button",
196
+ {
197
+ type: "button",
198
+ className: styles.addTabButton,
199
+ onClick: onAddTab,
200
+ "aria-label": "Tilf\xF8j fane",
201
+ children: /* @__PURE__ */ jsx(Plus, { "aria-hidden": "true" })
202
+ }
203
+ ) : null
204
+ ] }),
203
205
  tabListAddition ? /* @__PURE__ */ jsx("div", { className: styles.tabListAddition, children: tabListAddition }) : null
204
206
  ] }),
205
207
  /* @__PURE__ */ jsx(
@@ -26,8 +26,18 @@
26
26
 
27
27
  /* Tablist */
28
28
  .tabList {
29
+ display: grid;
30
+ grid-template-columns: minmax(0, 1fr) auto;
31
+ grid-template-rows: auto var(--spacing-sm);
32
+ min-width: 0;
33
+ }
34
+
35
+ .tabStrip {
29
36
  display: flex;
37
+ grid-column: 1;
38
+ grid-row: 1 / span 2;
30
39
  min-width: 0;
40
+ align-self: end;
31
41
  }
32
42
 
33
43
  .tabButtons {
@@ -40,6 +50,12 @@
40
50
  here. */
41
51
  overflow-y: hidden;
42
52
  min-width: 0;
53
+ scrollbar-width: none;
54
+ -ms-overflow-style: none;
55
+ }
56
+
57
+ .tabButtons::-webkit-scrollbar {
58
+ display: none;
43
59
  }
44
60
 
45
61
  /* Extra content next to the tab buttons, pushed into the free space on the
@@ -48,6 +64,8 @@
48
64
  .tabListAddition {
49
65
  display: flex;
50
66
  align-items: start;
67
+ grid-column: 2;
68
+ grid-row: 1;
51
69
  flex-shrink: 0;
52
70
  gap: var(--spacing-sm);
53
71
  margin-inline-start: auto;
@@ -94,8 +112,6 @@
94
112
  border-color var(--transition-fast) var(--ease-standard);
95
113
  }
96
114
 
97
- .active .tabButton {
98
- }
99
115
  .tabButton:focus-visible {
100
116
  outline: none;
101
117
  box-shadow: var(--focus-ring);
@@ -236,37 +252,37 @@
236
252
  /* One continuous backdrop behind the whole button row, so the curved gap
237
253
  next to the active tab's rounded corners shows toolbar gray, not the
238
254
  surface color behind the row. */
239
- .filled > .tabList > .tabButtons {
255
+ .filled > .tabList > .tabStrip > .tabButtons {
240
256
  display: flex;
241
257
  background: var(--color-bg-toolbar);
242
258
  border-start-start-radius: var(--border-radius-md);
243
259
  }
244
260
 
245
- .filled > .tabList > .tabButtons > .tab > .tabButton {
261
+ .filled > .tabList > .tabStrip > .tabButtons > .tab > .tabButton {
246
262
  padding-block: var(--spacing-xs);
247
263
  }
248
264
 
249
- .filled > .tabList > .tabButtons > .tab > .tabButton .icon svg {
265
+ .filled > .tabList > .tabStrip > .tabButtons > .tab > .tabButton .icon svg {
250
266
  inline-size: var(--icon-size-sm);
251
267
  block-size: var(--icon-size-sm);
252
268
  }
253
269
 
254
- .filled > .tabList > .tabButtons.tabButtonsEnd {
270
+ .filled > .tabList > .tabStrip > .tabButtons.tabButtonsEnd {
255
271
  border-start-end-radius: var(--border-radius-md);
256
272
  }
257
273
 
258
- .filled > .tabList > .addTabButton {
274
+ .filled > .tabList > .tabStrip > .addTabButton {
259
275
  background: var(--color-bg-toolbar);
260
276
  border: 1px solid transparent;
261
277
  border-block-end: 0;
262
278
  border-start-end-radius: var(--border-radius-md);
263
279
  }
264
280
 
265
- .filled > .tabList > .addTabButton:hover {
281
+ .filled > .tabList > .tabStrip > .addTabButton:hover {
266
282
  background: var(--color-bg-toolbar-hover);
267
283
  }
268
284
 
269
- .filled > .tabList > .tabButtons > .tab {
285
+ .filled > .tabList > .tabStrip > .tabButtons > .tab {
270
286
  border: 1px solid transparent;
271
287
  border-block-end-width: 1px;
272
288
  margin-block-end: -1px;
@@ -278,14 +294,14 @@
278
294
  border-color var(--transition-fast) var(--ease-standard);
279
295
  }
280
296
 
281
- .filled > .tabList > .tabButtons > .tab:not(.active):hover {
297
+ .filled > .tabList > .tabStrip > .tabButtons > .tab:not(.active):hover {
282
298
  background: var(--color-bg-toolbar-hover);
283
299
  color: var(--color-fg-default);
284
300
  }
285
301
 
286
302
  /* Active tab physically overlaps the tabList separator by 1px so its
287
303
  erased bottom border seamlessly merges with the panel below. */
288
- .filled > .tabList > .tabButtons > .tab.active {
304
+ .filled > .tabList > .tabStrip > .tabButtons > .tab.active {
289
305
  background: var(--color-bg-surface);
290
306
  border-color: var(--color-border-subtle);
291
307
  border-block-end-color: var(--color-bg-surface);
@@ -295,7 +311,7 @@
295
311
  color: var(--color-fg-default);
296
312
  }
297
313
 
298
- .filled > .tabList > .tabButtons > .tab.active::after {
314
+ .filled > .tabList > .tabStrip > .tabButtons > .tab.active::after {
299
315
  content: '';
300
316
  position: absolute;
301
317
  inset-inline: -1px;
@@ -325,17 +341,17 @@
325
341
  padding-block-end: var(--spacing-xs);
326
342
  }
327
343
 
328
- .outlined > .tabList > .tabButtons > .tab {
344
+ .outlined > .tabList > .tabStrip > .tabButtons > .tab {
329
345
  color: var(--color-fg-muted);
330
346
  border-block-end: 2px solid var(--color-border-default);
331
347
  transition: color var(--transition-fast) var(--ease-standard);
332
348
  }
333
349
 
334
- .outlined > .tabList > .tabButtons > .tab:not(.active):hover {
350
+ .outlined > .tabList > .tabStrip > .tabButtons > .tab:not(.active):hover {
335
351
  color: var(--color-brand);
336
352
  }
337
353
 
338
- .outlined > .tabList > .tabButtons > .tab.active {
354
+ .outlined > .tabList > .tabStrip > .tabButtons > .tab.active {
339
355
  color: var(--color-brand);
340
356
  border-block-end-color: var(--color-brand);
341
357
  }
@@ -355,7 +371,7 @@
355
371
  }
356
372
 
357
373
  /* When panelStyle is on, tabs look “embedded” (no bottom border indicators) */
358
- .panelStyle > .tabList > .tabButtons > .tab {
374
+ .panelStyle > .tabList > .tabStrip > .tabButtons > .tab {
359
375
  border-block-end: 0;
360
376
  }
361
377
 
@@ -20,6 +20,7 @@ export interface TimelineItem {
20
20
  id?: string;
21
21
  label: ReactNode;
22
22
  content: ReactNode;
23
+ active?: boolean;
23
24
  collapsible?: boolean;
24
25
  severity?: Severity;
25
26
  icon?: ReactNode;
@@ -58,7 +58,7 @@ function TimelineRow({
58
58
  ] }),
59
59
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.body, children: [
60
60
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${styles__default.default.headerRow} ${hasContextMenu ? styles__default.default.headerRowWithActions : ""}`, children: [
61
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.label, children: item.label }),
61
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${styles__default.default.label} ${item.active ? styles__default.default.labelActive : ""}`.trim(), children: item.label }),
62
62
  item.date !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.date, children: formatDate.formatDate(item.date, { userFriendlyLabel: true, ...item.dateOptions }) }) : null,
63
63
  isCollapsible ? /* @__PURE__ */ jsxRuntime.jsx(
64
64
  "button",
@@ -52,7 +52,7 @@ function TimelineRow({
52
52
  ] }),
53
53
  /* @__PURE__ */ jsxs("div", { className: styles.body, children: [
54
54
  /* @__PURE__ */ jsxs("div", { className: `${styles.headerRow} ${hasContextMenu ? styles.headerRowWithActions : ""}`, children: [
55
- /* @__PURE__ */ jsx("div", { className: styles.label, children: item.label }),
55
+ /* @__PURE__ */ jsx("div", { className: `${styles.label} ${item.active ? styles.labelActive : ""}`.trim(), children: item.label }),
56
56
  item.date !== void 0 ? /* @__PURE__ */ jsx("span", { className: styles.date, children: formatDate(item.date, { userFriendlyLabel: true, ...item.dateOptions }) }) : null,
57
57
  isCollapsible ? /* @__PURE__ */ jsx(
58
58
  "button",
@@ -73,6 +73,10 @@
73
73
  min-width: 0;
74
74
  }
75
75
 
76
+ .labelActive {
77
+ color: var(--color-fg-default);
78
+ }
79
+
76
80
  .date {
77
81
  font-size: var(--font-size-xs);
78
82
  font-weight: 400;
@@ -13,6 +13,7 @@ var styles__default = /*#__PURE__*/_interopDefault(styles);
13
13
  function TreeNodeRow({
14
14
  node,
15
15
  depth,
16
+ wrapLabels,
16
17
  isExpanded,
17
18
  toggle,
18
19
  resolvedChildren,
@@ -66,7 +67,13 @@ function TreeNodeRow({
66
67
  ),
67
68
  /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: styles__default.default.labelButton, onClick: () => onSelectNode == null ? void 0 : onSelectNode(node), children: [
68
69
  node.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.icon, "aria-hidden": "true", children: node.icon }) : null,
69
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.label, children: renderLabel ? renderLabel(node) : node.label })
70
+ /* @__PURE__ */ jsxRuntime.jsx(
71
+ "span",
72
+ {
73
+ className: [styles__default.default.label, wrapLabels ? styles__default.default.labelWrap : styles__default.default.labelTruncate].filter(Boolean).join(" "),
74
+ children: renderLabel ? renderLabel(node) : node.label
75
+ }
76
+ )
70
77
  ] })
71
78
  ] }),
72
79
  error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.errorRow, children: [
@@ -78,6 +85,7 @@ function TreeNodeRow({
78
85
  {
79
86
  node: child,
80
87
  depth: depth + 1,
88
+ wrapLabels,
81
89
  isExpanded,
82
90
  toggle,
83
91
  resolvedChildren,
@@ -3,6 +3,7 @@ import type { LoadTreeChildren, TreeNode } from './types';
3
3
  type TreeNodeRowProps<T> = {
4
4
  node: TreeNode<T>;
5
5
  depth: number;
6
+ wrapLabels: boolean;
6
7
  isExpanded: (id: string) => boolean;
7
8
  toggle: (id: string) => void;
8
9
  resolvedChildren: Record<string, TreeNode<T>[]>;
@@ -14,5 +15,5 @@ type TreeNodeRowProps<T> = {
14
15
  onSelectNode?: (node: TreeNode<T>) => void;
15
16
  renderLabel?: (node: TreeNode<T>) => ReactNode;
16
17
  };
17
- export declare function TreeNodeRow<T>({ node, depth, isExpanded, toggle, resolvedChildren, loadingIds, errorIds, requestLoad, loadChildren, selectedId, onSelectNode, renderLabel, }: TreeNodeRowProps<T>): JSX.Element;
18
+ export declare function TreeNodeRow<T>({ node, depth, wrapLabels, isExpanded, toggle, resolvedChildren, loadingIds, errorIds, requestLoad, loadChildren, selectedId, onSelectNode, renderLabel, }: TreeNodeRowProps<T>): JSX.Element;
18
19
  export {};