@dbcdk/react-components 0.0.20 → 0.0.22

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 (40) hide show
  1. package/dist/components/button/Button.module.css +13 -6
  2. package/dist/components/chip/Chip.d.ts +3 -2
  3. package/dist/components/chip/Chip.js +2 -1
  4. package/dist/components/chip/Chip.module.css +107 -67
  5. package/dist/components/filter-field/FilterField.d.ts +2 -1
  6. package/dist/components/filter-field/FilterField.js +4 -9
  7. package/dist/components/filter-field/FilterField.module.css +203 -152
  8. package/dist/components/filtering/chip-multi-toggle/ChipMultiToggle.d.ts +2 -3
  9. package/dist/components/filtering/chip-multi-toggle/ChipMultiToggle.js +3 -5
  10. package/dist/components/filtering/chip-multi-toggle/ChipMultiToggle.module.css +13 -13
  11. package/dist/components/forms/input/Input.d.ts +1 -1
  12. package/dist/components/forms/input/Input.js +3 -9
  13. package/dist/components/forms/input/Input.module.css +106 -17
  14. package/dist/components/hyperlink/Hyperlink.module.css +14 -3
  15. package/dist/components/interval-select/IntervalSelect.js +2 -2
  16. package/dist/components/popover/Popover.module.css +4 -1
  17. package/dist/components/segmented-progress-bar/SegmentedProgressBar.d.ts +4 -2
  18. package/dist/components/segmented-progress-bar/SegmentedProgressBar.js +17 -19
  19. package/dist/components/segmented-progress-bar/SegmentedProgressBar.module.css +128 -20
  20. package/dist/components/sidebar/Sidebar.d.ts +2 -1
  21. package/dist/components/sidebar/Sidebar.js +2 -2
  22. package/dist/components/sidebar/components/sidebar-container/SidebarContainer.d.ts +2 -3
  23. package/dist/components/sidebar/components/sidebar-container/SidebarContainer.js +2 -4
  24. package/dist/components/sidebar/components/sidebar-container/SidebarContainer.module.css +9 -1
  25. package/dist/components/table/Table.d.ts +2 -7
  26. package/dist/components/table/Table.js +90 -47
  27. package/dist/components/table/Table.module.css +301 -72
  28. package/dist/components/table/TanstackTable.js +3 -27
  29. package/dist/components/table/table.utils.d.ts +1 -1
  30. package/dist/components/table/table.utils.js +2 -1
  31. package/dist/components/table/tanstackTable.utils.d.ts +9 -10
  32. package/dist/components/table/tanstackTable.utils.js +50 -30
  33. package/dist/hooks/useViewportFill.d.ts +6 -5
  34. package/dist/hooks/useViewportFill.js +43 -41
  35. package/dist/src/styles/styles.css +5 -2
  36. package/dist/styles/styles.css +5 -2
  37. package/dist/styles/themes/dbc/base.css +0 -3
  38. package/dist/styles/themes/dbc/dark.css +44 -12
  39. package/dist/styles/themes/dbc/light.css +33 -7
  40. package/package.json +1 -1
@@ -1,11 +1,9 @@
1
1
  /* Root control group */
2
2
  .container {
3
- /* inline-flex makes width behave weird in parents */
4
3
  display: inline-flex;
5
4
  align-items: stretch;
6
5
  flex-grow: 1;
7
6
  gap: 0;
8
- /* width control */
9
7
  inline-size: var(--input-width, auto);
10
8
  min-inline-size: var(--input-min-width, 0);
11
9
  max-inline-size: var(--input-max-width, none);
@@ -24,21 +22,23 @@
24
22
  display: flex;
25
23
  align-items: center;
26
24
  flex: 1 1 auto;
27
- min-inline-size: 0; /* critical for ellipsis inside flex */
25
+ min-inline-size: 0;
28
26
  color: var(--color-fg-default);
29
27
  }
30
28
 
31
29
  /* Actual input */
32
30
  .input {
33
31
  flex: 1 1 auto;
34
- min-inline-size: 0; /* critical */
32
+ min-inline-size: 0;
35
33
  inline-size: 100%;
34
+ box-sizing: border-box;
35
+ text-overflow: ellipsis;
36
+
37
+ color: var(--color-fg-default);
36
38
  background: var(--color-bg-surface);
37
39
  font-family: var(--font-family);
38
40
  font-size: var(--font-size-sm);
39
41
  line-height: var(--line-height-normal);
40
- box-sizing: border-box;
41
- text-overflow: ellipsis;
42
42
 
43
43
  border: var(--border-width-thin) solid var(--color-border-default);
44
44
  border-radius: var(--border-radius-default);
@@ -49,7 +49,8 @@
49
49
  transition:
50
50
  background-color var(--transition-fast) var(--ease-standard),
51
51
  border-color var(--transition-fast) var(--ease-standard),
52
- box-shadow var(--transition-fast) var(--ease-standard);
52
+ box-shadow var(--transition-fast) var(--ease-standard),
53
+ color var(--transition-fast) var(--ease-standard);
53
54
  }
54
55
 
55
56
  .input::placeholder {
@@ -58,11 +59,13 @@
58
59
 
59
60
  .input:disabled {
60
61
  background-color: var(--color-disabled-bg);
61
- border: 0;
62
+ border-color: transparent;
62
63
  color: var(--color-disabled-fg);
63
64
  cursor: not-allowed;
64
- opacity: 0.5;
65
+ opacity: 1;
66
+ box-shadow: none;
65
67
  }
68
+
66
69
  /* Button group styling */
67
70
  .withButton .input {
68
71
  border-top-right-radius: 0;
@@ -74,27 +77,99 @@
74
77
  padding-inline-end: calc(var(--spacing-md) + 28px);
75
78
  }
76
79
 
77
- /* Hover & focus */
78
- .input:hover {
80
+ /* Global focus reset - variants own visible focus treatment */
81
+ .input:focus-visible {
82
+ outline: none;
83
+ }
84
+
85
+ /* =========================
86
+ Variants
87
+ ========================= */
88
+
89
+ /* Stronger field chrome for forms/settings */
90
+ .outlined {
91
+ background-color: var(--color-bg-surface);
92
+ border-color: var(--color-border-default);
93
+ }
94
+
95
+ .outlined:hover:not(:disabled) {
79
96
  border-color: var(--color-border-strong);
80
97
  }
81
98
 
82
- .input:focus-visible {
99
+ .outlined:focus-visible:not(:disabled) {
83
100
  border-color: var(--color-border-selected);
101
+ box-shadow: inset 0 0 0 1px var(--color-border-selected);
84
102
  }
85
103
 
86
- /* Variants */
87
- .filled {
104
+ .surface {
88
105
  background-color: var(--color-bg-surface);
106
+ border: 1px solid var(--color-border-subtle);
107
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
108
+ }
109
+
110
+ .surface:hover:not(:disabled) {
111
+ border-color: var(--color-border-default);
112
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
113
+ }
114
+
115
+ .surface:focus-visible:not(:disabled) {
116
+ border-color: var(--color-border-selected);
117
+ box-shadow: inset 0 0 0 1px var(--color-border-selected);
118
+ }
119
+
120
+ /* Old filled/tinted behavior, now renamed subtle */
121
+ .subtle {
122
+ background-color: var(--color-bg-toolbar);
123
+ border-color: transparent;
124
+ box-shadow: inset 0 0 0 1px transparent;
125
+ }
126
+
127
+ .subtle:hover:not(:disabled) {
128
+ background-color: var(--color-bg-toolbar-hover);
89
129
  }
130
+
131
+ .subtle:focus-visible:not(:disabled) {
132
+ border-color: var(--color-border-selected);
133
+ box-shadow: inset 0 0 0 1px var(--color-border-selected);
134
+ }
135
+
136
+ /* Embedded = chromeless input for grouped controls like FilterField */
137
+ .embedded {
138
+ background-color: transparent;
139
+ border-color: transparent;
140
+ border-radius: 0;
141
+ box-shadow: none;
142
+ padding-inline: calc(var(--spacing-sm) + var(--spacing-2xs));
143
+ padding-block: 0;
144
+ }
145
+
146
+ .embedded:hover:not(:disabled),
147
+ .embedded:focus:not(:disabled),
148
+ .embedded:focus-visible:not(:disabled) {
149
+ background-color: transparent;
150
+ border-color: transparent;
151
+ box-shadow: none;
152
+ outline: none;
153
+ }
154
+
90
155
  .standalone {
91
- border-radius: var(--border-radius-rounded);
92
156
  background-color: var(--color-bg-surface);
157
+ border-color: var(--color-border-default);
158
+ border-radius: var(--border-radius-rounded);
93
159
  box-shadow: var(--shadow-xs), var(--shadow-md);
94
160
  }
95
161
 
96
- .outlined {
97
- background-color: transparent;
162
+ .standalone:hover:not(:disabled) {
163
+ border-color: var(--color-border-strong);
164
+ box-shadow: var(--shadow-sm), var(--shadow-md);
165
+ }
166
+
167
+ .standalone:focus-visible:not(:disabled) {
168
+ border-color: var(--color-border-selected);
169
+ box-shadow:
170
+ var(--shadow-xs),
171
+ var(--shadow-md),
172
+ inset 0 0 0 1px var(--color-border-selected);
98
173
  }
99
174
 
100
175
  /* Sizes */
@@ -103,14 +178,17 @@
103
178
  font-size: var(--font-size-sm);
104
179
  padding: 0 var(--spacing-xxs);
105
180
  }
181
+
106
182
  .sm {
107
183
  block-size: var(--component-size-sm);
108
184
  font-size: var(--font-size-sm);
109
185
  }
186
+
110
187
  .md {
111
188
  block-size: var(--component-size-md);
112
189
  font-size: var(--font-size-sm);
113
190
  }
191
+
114
192
  .lg {
115
193
  block-size: var(--component-size-lg);
116
194
  font-size: var(--font-size-lg);
@@ -121,6 +199,10 @@
121
199
  padding-inline-start: calc(var(--icon-size-md) + var(--spacing-lg));
122
200
  }
123
201
 
202
+ .embedded.inputWithIcon {
203
+ padding-inline-start: calc(var(--icon-size-md) + var(--spacing-xl));
204
+ }
205
+
124
206
  .icon {
125
207
  position: absolute;
126
208
  inset-inline-start: var(--spacing-md);
@@ -133,7 +215,13 @@
133
215
  block-size: var(--icon-size-md);
134
216
  pointer-events: none;
135
217
  color: var(--color-fg-subtle);
218
+ transition: color var(--transition-fast) var(--ease-standard);
136
219
  }
220
+
221
+ .field:focus-within .icon {
222
+ color: var(--color-fg-muted);
223
+ }
224
+
137
225
  .icon svg {
138
226
  inline-size: var(--icon-size-md);
139
227
  block-size: var(--icon-size-md);
@@ -147,6 +235,7 @@
147
235
  border-left: var(--border-width-thin) solid transparent;
148
236
  margin-left: calc(-1 * var(--border-width-thin));
149
237
  }
238
+
150
239
  .trailingButton:hover {
151
240
  border-color: var(--color-border-default);
152
241
  z-index: 2;
@@ -36,12 +36,24 @@
36
36
  }
37
37
  }
38
38
 
39
+ .link {
40
+ position: relative;
41
+ display: inline-block;
42
+ max-width: 100%;
43
+ }
44
+
45
+ .link {
46
+ position: relative;
47
+ display: inline-block;
48
+ max-width: 100%;
49
+ }
50
+
39
51
  .link::after {
40
52
  content: '';
41
53
  position: absolute;
42
54
  left: 0;
43
- bottom: -2px;
44
- width: 100%;
55
+ right: 0;
56
+ bottom: 1px;
45
57
  height: 1px;
46
58
  background-color: currentColor;
47
59
  transform: scaleX(0);
@@ -52,7 +64,6 @@
52
64
  .link:hover::after {
53
65
  transform: scaleX(1);
54
66
  }
55
-
56
67
  .link:focus-visible {
57
68
  outline: 2px solid var(--color-brand);
58
69
  outline-offset: 2px;
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Check, Clock } from 'lucide-react';
3
+ import { Check } from 'lucide-react';
4
4
  import { useEffect, useId, useMemo, useRef, useState } from 'react';
5
5
  import { Button } from '../../components/button/Button';
6
6
  import { ClearButton } from '../../components/clear-button/ClearButton';
@@ -87,7 +87,7 @@ id, options, selectedValue, onChange, baseDate, placeholder = 'Vælg interval',
87
87
  // Reset active to selected when opening
88
88
  setActiveIndex(selectedIndex >= 0 ? selectedIndex : 0);
89
89
  onClick(e);
90
- }, size: size, type: "button", "aria-haspopup": "listbox", "aria-expanded": !!isOpen, "aria-controls": listboxId, "aria-invalid": Boolean(error) || undefined, "aria-describedby": describedBy, children: _jsxs("span", { className: "dbc-flex dbc-justify-between dbc-items-center dbc-gap-xxs", style: { width: '100%' }, children: [_jsxs("span", { className: "dbc-flex dbc-items-center dbc-gap-xxs", children: [_jsx(Clock, { size: 14 }), selected ? selected.label : placeholder] }), onClear && selected && _jsx(ClearButton, { onClick: onClear }), icon] }) })), children: _jsx(Menu, { id: listboxId, onKeyDown: handleKeyDown, role: "listbox", children: options.map((opt, index) => {
90
+ }, size: size, type: "button", "aria-haspopup": "listbox", "aria-expanded": !!isOpen, "aria-controls": listboxId, "aria-invalid": Boolean(error) || undefined, "aria-describedby": describedBy, children: _jsxs("span", { className: "dbc-flex dbc-justify-between dbc-items-center dbc-gap-xxs", style: { width: '100%' }, children: [_jsx("span", { className: "dbc-flex dbc-items-center dbc-gap-xxs", children: selected ? selected.label : placeholder }), onClear && selected && _jsx(ClearButton, { onClick: onClear }), icon] }) })), children: _jsx(Menu, { id: listboxId, onKeyDown: handleKeyDown, role: "listbox", children: options.map((opt, index) => {
91
91
  const isSelected = opt.minutesAgo === selectedValue;
92
92
  const isActive = index === activeIndex;
93
93
  return (_jsx(Menu.Item, { active: isActive,
@@ -1,6 +1,9 @@
1
1
  .container {
2
2
  position: relative;
3
- display: inline-block;
3
+ display: inline-flex;
4
+ align-items: stretch;
5
+ height: 100%;
6
+ min-width: 0;
4
7
  }
5
8
 
6
9
  .content {
@@ -1,9 +1,10 @@
1
1
  import React from 'react';
2
2
  import { TooltipPlacement } from '../../components/overlay/tooltip/TooltipProvider';
3
3
  import type { Severity } from '../../constants/severity.types';
4
+ type ProgressSeverity = 'done' | 'progress' | 'missing';
4
5
  export type Segment = {
5
6
  value: number;
6
- severity?: Severity;
7
+ severity?: Severity | ProgressSeverity;
7
8
  color?: string;
8
9
  label?: React.ReactNode;
9
10
  };
@@ -11,7 +12,7 @@ export interface SegmentedProgressBarProps {
11
12
  segments: Segment[];
12
13
  total?: number;
13
14
  showRemainder?: boolean;
14
- remainderSeverity?: Severity;
15
+ remainderSeverity?: Severity | ProgressSeverity;
15
16
  centerLabel?: React.ReactNode | ((filledPct: number) => React.ReactNode);
16
17
  height?: number;
17
18
  rounded?: boolean;
@@ -22,3 +23,4 @@ export interface SegmentedProgressBarProps {
22
23
  'data-testid'?: string;
23
24
  }
24
25
  export declare const SegmentedProgressBar: React.FC<SegmentedProgressBarProps>;
26
+ export {};
@@ -1,13 +1,10 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useTooltipTrigger } from '../../components/overlay/tooltip/useTooltipTrigger';
4
- import { SeverityBgColor, SeverityTextColor } from '../../constants/severity';
5
4
  import styles from './SegmentedProgressBar.module.css';
6
5
  function SegmentWithTooltip({ seg, index, tooltipPlacement, }) {
7
- var _a, _b, _c, _d, _e;
8
- const bg = (_a = seg.color) !== null && _a !== void 0 ? _a : SeverityBgColor[(_b = seg.severity) !== null && _b !== void 0 ? _b : 'neutral'];
9
- const fg = SeverityTextColor[(_c = seg.severity) !== null && _c !== void 0 ? _c : 'neutral'];
10
- const tooltipContent = typeof seg.label !== 'undefined' ? seg.label : String((_d = seg.value) !== null && _d !== void 0 ? _d : 0);
6
+ var _a, _b;
7
+ const tooltipContent = typeof seg.label !== 'undefined' ? seg.label : String((_a = seg.value) !== null && _a !== void 0 ? _a : 0);
11
8
  const tooltipEnabled = tooltipContent !== null && tooltipContent !== undefined && tooltipContent !== '';
12
9
  const { triggerProps } = useTooltipTrigger({
13
10
  content: tooltipEnabled ? tooltipContent : null,
@@ -16,11 +13,13 @@ function SegmentWithTooltip({ seg, index, tooltipPlacement, }) {
16
13
  });
17
14
  return (_jsx("span", { className: styles.segmentWrapper, style: {
18
15
  flex: `${Math.max(seg.value || 0, 0)} 0 0`,
19
- height: '100%',
20
- minWidth: '2px',
21
- }, ...(tooltipEnabled ? triggerProps : {}), children: _jsx("div", { className: styles.progressSegment, "data-index": index, "data-severity": (_e = seg.severity) !== null && _e !== void 0 ? _e : 'neutral', style: { background: bg, color: fg } }) }));
16
+ }, ...(tooltipEnabled ? triggerProps : {}), children: _jsx("span", { className: styles.progressSegment, "data-index": index, "data-severity": (_b = seg.severity) !== null && _b !== void 0 ? _b : 'neutral', style: seg.color
17
+ ? {
18
+ ['--segment-color']: seg.color,
19
+ }
20
+ : undefined }) }));
22
21
  }
23
- export const SegmentedProgressBar = ({ segments, total, showRemainder = true, remainderSeverity = 'neutral', centerLabel, height, rounded = true, trackColor = 'var(--color-neutral)', tooltipPlacement = 'top', className, ...aria }) => {
22
+ export const SegmentedProgressBar = ({ segments, total, showRemainder = true, remainderSeverity = 'neutral', centerLabel, height, rounded = true, trackColor, tooltipPlacement = 'top', className, ...aria }) => {
24
23
  const sum = segments.reduce((acc, s) => acc + (s.value || 0), 0);
25
24
  const effectiveTotal = total !== null && total !== void 0 ? total : sum;
26
25
  const safeTotal = Math.max(effectiveTotal, 0.0001);
@@ -36,15 +35,14 @@ export const SegmentedProgressBar = ({ segments, total, showRemainder = true, re
36
35
  base.push(remainder);
37
36
  return base.join('/');
38
37
  })();
39
- const rootClass = [styles.container, className].filter(Boolean).join(' ');
40
38
  const filteredSegments = computedSegments.filter(x => x.value > 0);
41
- return (_jsx("div", { className: rootClass, role: "progressbar", "aria-valuemin": 0, "aria-valuemax": effectiveTotal, "aria-valuenow": Math.min(sum, effectiveTotal), ...aria, children: _jsxs("div", { className: styles.progressBar, style: {
42
- height: height ? `${height}px` : `var(--component-size-xs)`,
43
- borderRadius: rounded ? `var(--border-radius-rounded)` : `var(--border-radius-none)`,
44
- background: trackColor,
45
- }, children: [_jsx("span", { className: styles.segmentsContainer, children: filteredSegments.map((seg, i) => (_jsx(SegmentWithTooltip, { seg: seg, index: i, tooltipPlacement: tooltipPlacement }, `${i}`))) }), _jsx("div", { className: `${styles.progressCenter} ${filteredSegments.length === 0 ? styles.emptySegments : ''}`, children: centerLabel
46
- ? typeof centerLabel === 'function'
47
- ? centerLabel(pctFilled)
48
- : centerLabel
49
- : autoNumbers })] }) }));
39
+ const rootClass = [styles.container, className].filter(Boolean).join(' ');
40
+ return (_jsx("div", { className: rootClass, role: "progressbar", "aria-valuemin": 0, "aria-valuemax": effectiveTotal, "aria-valuenow": Math.min(sum, effectiveTotal), ...aria, children: _jsxs("div", { className: styles.progressBar, "data-rounded": rounded ? 'true' : 'false', style: {
41
+ height: height ? `${height}px` : '24px',
42
+ background: trackColor !== null && trackColor !== void 0 ? trackColor : 'var(--color-bg-surface-subtle)',
43
+ }, children: [_jsx("span", { className: styles.segmentsContainer, children: filteredSegments.map((seg, i) => (_jsx(SegmentWithTooltip, { seg: seg, index: i, tooltipPlacement: tooltipPlacement }, `${i}`))) }), _jsx("div", { className: `${styles.progressCenter} ${filteredSegments.length === 0 ? styles.emptySegments : ''}`, children: _jsx("span", { className: styles.progressCenterLabel, children: centerLabel
44
+ ? typeof centerLabel === 'function'
45
+ ? centerLabel(pctFilled)
46
+ : centerLabel
47
+ : autoNumbers }) })] }) }));
50
48
  };
@@ -1,59 +1,167 @@
1
1
  .container {
2
2
  width: 100%;
3
+ min-width: 0;
3
4
  display: flex;
4
5
  align-items: center;
5
6
  }
6
7
 
7
8
  .progressBar {
9
+ --progress-radius: 10px;
10
+ --progress-separator: color-mix(in srgb, var(--color-border-subtle) 55%, transparent);
11
+
8
12
  position: relative;
9
13
  width: 100%;
14
+ min-width: 0;
10
15
  display: flex;
11
- border-radius: var(--border-radius-default);
12
- background: var(--opac-bg-default);
16
+ align-items: stretch;
17
+ overflow: hidden;
18
+
19
+ border-radius: var(--progress-radius);
20
+ background: var(--color-bg-surface-subtle);
21
+ box-shadow: inset 0 0 0 1px var(--color-border-subtle);
13
22
  }
14
23
 
15
- .progressSegment {
24
+ .progressBar[data-rounded='false'] {
25
+ border-radius: 0;
26
+ }
27
+
28
+ .segmentsContainer {
29
+ display: flex;
30
+ width: 100%;
31
+ height: 100%;
32
+ min-width: 0;
33
+ }
34
+
35
+ .segmentWrapper {
36
+ display: flex;
16
37
  height: 100%;
17
- flex: 1 1 auto;
18
38
  min-width: 2px;
39
+ min-height: 0;
40
+ }
41
+
42
+ .progressSegment {
43
+ position: relative;
44
+ width: 100%;
45
+ height: 100%;
46
+ background: var(--segment-color, var(--color-bg-surface-strong));
19
47
  }
20
48
 
49
+ /* Subtle separators between segments */
50
+ .segmentWrapper + .segmentWrapper .progressSegment::before {
51
+ content: '';
52
+ position: absolute;
53
+ inset-inline-start: 0;
54
+ inset-block: 2px;
55
+ width: 1px;
56
+ background: var(--progress-separator);
57
+ pointer-events: none;
58
+ }
59
+
60
+ /* =====================================
61
+ Custom progress semantics (quiet)
62
+ ===================================== */
63
+
64
+ .progressSegment[data-severity='done'] {
65
+ background: color-mix(in srgb, var(--color-fg-default) 15%, var(--color-bg-surface));
66
+ }
67
+
68
+ .progressSegment[data-severity='progress'] {
69
+ background: color-mix(in srgb, var(--color-fg-subtle) 18%, var(--color-bg-surface));
70
+ }
71
+
72
+ .progressSegment[data-severity='missing'] {
73
+ background: color-mix(in srgb, var(--color-border-subtle) 65%, var(--color-bg-surface));
74
+ }
75
+
76
+ .progressSegment[data-severity='neutral'] {
77
+ background: var(--color-bg-surface-strong);
78
+ }
79
+
80
+ /* =====================================
81
+ Existing semantic severities
82
+ Keep these semantic and more colorful
83
+ for consumers who want that behavior
84
+ ===================================== */
85
+
86
+ .progressSegment[data-severity='success'] {
87
+ background: color-mix(in srgb, var(--color-status-success) 32%, var(--color-bg-surface));
88
+ }
89
+
90
+ .progressSegment[data-severity='info'] {
91
+ background: color-mix(in srgb, var(--color-status-info) 32%, var(--color-bg-surface));
92
+ }
93
+
94
+ .progressSegment[data-severity='warning'] {
95
+ background: color-mix(in srgb, var(--color-status-warning) 32%, var(--color-bg-surface));
96
+ }
97
+
98
+ .progressSegment[data-severity='error'] {
99
+ background: color-mix(in srgb, var(--color-status-error) 24%, var(--color-bg-surface));
100
+ }
101
+
102
+ /* Label overlay */
21
103
  .progressCenter {
22
104
  position: absolute;
23
105
  inset: 0;
24
106
  display: flex;
25
107
  align-items: center;
26
108
  justify-content: center;
27
- color: var(--color-fg-on-strong);
28
- font-size: inherit;
109
+ padding-inline: 8px;
29
110
  pointer-events: none;
30
111
  }
31
112
 
32
- .emptySegments.progressCenter {
33
- color: unset;
113
+ .progressCenterLabel {
114
+ display: inline-flex;
115
+ align-items: center;
116
+ justify-content: center;
117
+ min-width: 0;
118
+ max-width: calc(100% - 8px);
119
+ color: var(--color-fg-default);
120
+ font-size: var(--font-size-xs);
121
+ font-weight: 500;
122
+ font-variant-numeric: tabular-nums;
123
+ letter-spacing: 0.01em;
124
+ line-height: 1;
125
+ white-space: nowrap;
126
+ overflow: hidden;
127
+ text-overflow: ellipsis;
128
+
129
+ text-shadow: none;
34
130
  }
35
131
 
36
- .segmentWrapper,
37
- .segmentsContainer {
38
- display: flex;
39
- height: 100%;
40
- width: 100%;
132
+ .emptySegments .progressCenterLabel {
133
+ color: var(--color-fg-subtle);
134
+ }
135
+
136
+ /* Rounded ends only on the outer edges */
137
+ .segmentWrapper:first-child .progressSegment {
138
+ border-top-left-radius: var(--progress-radius);
139
+ border-bottom-left-radius: var(--progress-radius);
140
+ }
141
+
142
+ .segmentWrapper:last-child .progressSegment {
143
+ border-top-right-radius: var(--progress-radius);
144
+ border-bottom-right-radius: var(--progress-radius);
41
145
  }
42
146
 
43
- .segmentWrapper:first-of-type .progressSegment {
44
- border-top-left-radius: var(--border-radius-rounded);
45
- border-bottom-left-radius: var(--border-radius-rounded);
147
+ .progressBar[data-rounded='false'] .segmentWrapper:first-child .progressSegment,
148
+ .progressBar[data-rounded='false'] .segmentWrapper:last-child .progressSegment {
149
+ border-radius: 0;
46
150
  }
47
151
 
48
- .segmentWrapper:last-of-type .progressSegment {
49
- border-top-right-radius: var(--border-radius-rounded);
50
- border-bottom-right-radius: var(--border-radius-rounded);
152
+ .progressBar,
153
+ .progressSegment,
154
+ .progressCenterLabel {
155
+ transition:
156
+ background-color 140ms ease,
157
+ color 140ms ease,
158
+ box-shadow 140ms ease;
51
159
  }
52
160
 
53
161
  @media (prefers-reduced-motion: reduce) {
54
162
  .progressBar,
55
163
  .progressSegment,
56
- .progressCenter {
164
+ .progressCenterLabel {
57
165
  transition: none;
58
166
  }
59
167
  }
@@ -9,6 +9,7 @@ interface SidebarProps {
9
9
  productName?: string;
10
10
  productLogo?: React.ReactNode;
11
11
  activeLink?: string;
12
+ version?: string | number;
12
13
  }
13
- export declare function Sidebar({ items, productLogo, activeLink }: SidebarProps): JSX.Element;
14
+ export declare function Sidebar({ items, productLogo, activeLink, version }: SidebarProps): JSX.Element;
14
15
  export {};
@@ -2,6 +2,6 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { SidebarContainer } from './components/sidebar-container/SidebarContainer';
4
4
  import { SidebarProvider } from './providers/SidebarProvider';
5
- export function Sidebar({ items, productLogo, activeLink }) {
6
- return (_jsx(SidebarProvider, { items: items, children: _jsx(SidebarContainer, { productLogo: productLogo, activeLink: activeLink }) }));
5
+ export function Sidebar({ items, productLogo, activeLink, version }) {
6
+ return (_jsx(SidebarProvider, { items: items, children: _jsx(SidebarContainer, { productLogo: productLogo, activeLink: activeLink, version: version }) }));
7
7
  }
@@ -4,8 +4,7 @@ interface SidebarContainerProps {
4
4
  productName?: string;
5
5
  productLogo?: ReactNode;
6
6
  activeLink?: string;
7
+ version?: string | number;
7
8
  }
8
- export declare function SidebarContainer({ logo, // DBC Digital (company)
9
- productLogo, // DataIO (product)
10
- activeLink, }: SidebarContainerProps): JSX.Element;
9
+ export declare function SidebarContainer({ logo, productLogo, activeLink, version, }: SidebarContainerProps): JSX.Element;
11
10
  export {};
@@ -6,9 +6,7 @@ import { SidebarItems } from '../../../../components/sidebar/components/sidebar-
6
6
  import SidenavFiltering from '../../../../components/sidebar/components/sidenav-filteirng/SidenavFiltering';
7
7
  import { useSidebar } from '../../../../components/sidebar/providers/SidebarProvider';
8
8
  import styles from './SidebarContainer.module.css';
9
- export function SidebarContainer({ logo, // DBC Digital (company)
10
- productLogo, // DataIO (product)
11
- activeLink, }) {
9
+ export function SidebarContainer({ logo, productLogo, activeLink, version, }) {
12
10
  const { isSidebarCollapsed, handleSidebarCollapseChange } = useSidebar();
13
- return (_jsxs("div", { className: `${styles.container} ${isSidebarCollapsed ? styles.collapsed : ''}`, children: [_jsx("div", { className: styles.header, children: _jsxs("div", { className: styles.productHeader, children: [_jsx("div", { className: styles.productLogo, children: productLogo }), _jsx(Button, { size: "md", variant: "inline", shape: "round", "aria-label": "Collapse sidebar", icon: _jsx(ChevronLeft, { className: isSidebarCollapsed ? styles.collapsedIcon : '' }), onClick: () => handleSidebarCollapseChange(!isSidebarCollapsed) })] }) }), _jsxs("div", { className: styles.content, children: [_jsx("div", { className: styles.filter, children: _jsx(SidenavFiltering, {}) }), _jsx("div", { className: `${styles.links} hideScrollBar`, children: _jsx(SidebarItems, { activeLink: activeLink }) })] }), _jsx("div", { className: styles.footer, children: _jsx("div", { className: styles.companyLogo, children: logo !== null && logo !== void 0 ? logo : _jsx(Logo, {}) }) })] }));
11
+ return (_jsxs("div", { className: `${styles.container} ${isSidebarCollapsed ? styles.collapsed : ''}`, children: [_jsx("div", { className: styles.header, children: _jsxs("div", { className: styles.productHeader, children: [_jsx("div", { className: styles.productLogo, children: productLogo }), _jsx(Button, { size: "md", variant: "inline", shape: "round", "aria-label": "Collapse sidebar", icon: _jsx(ChevronLeft, { className: isSidebarCollapsed ? styles.collapsedIcon : '' }), onClick: () => handleSidebarCollapseChange(!isSidebarCollapsed) })] }) }), _jsxs("div", { className: styles.content, children: [_jsx("div", { className: styles.filter, children: _jsx(SidenavFiltering, {}) }), _jsx("div", { className: `${styles.links} hideScrollBar`, children: _jsx(SidebarItems, { activeLink: activeLink }) })] }), _jsxs("div", { className: styles.footer, children: [_jsx("div", { className: styles.companyLogo, children: logo !== null && logo !== void 0 ? logo : _jsx(Logo, {}) }), version && _jsx("div", { className: `${styles.version} dbc-muted-text dbc-sm-text`, children: version })] })] }));
14
12
  }
@@ -138,7 +138,9 @@
138
138
  border-top: 1px solid var(--color-border-default);
139
139
  padding: var(--spacing-sm);
140
140
  display: flex;
141
- justify-content: center;
141
+ justify-content: space-between;
142
+ align-items: center;
143
+ gap: var(--spacing-sm);
142
144
  }
143
145
 
144
146
  .companyLogo {
@@ -156,6 +158,12 @@
156
158
  display: none;
157
159
  }
158
160
 
161
+ .version {
162
+ overflow: hidden;
163
+ white-space: nowrap;
164
+ text-overflow: ellipsis;
165
+ min-width: 0;
166
+ }
159
167
  .logo {
160
168
  display: none;
161
169
  }
@@ -1,6 +1,6 @@
1
1
  import type { HTMLAttributes, JSX, ReactNode } from 'react';
2
- import { Severity } from '../../constants/severity.types';
3
2
  import { PageChangeEvent } from '../../components/pagination/Pagination';
3
+ import { Severity } from '../../constants/severity.types';
4
4
  import { ViewMode } from '../../hooks/useTableSettings';
5
5
  import { TableEmptyConfig } from './components/empty-state/EmptyState';
6
6
  import { SortDirection } from './table.utils';
@@ -14,6 +14,7 @@ export interface ColumnItem<T> {
14
14
  hidden?: boolean;
15
15
  align?: 'left' | 'right' | 'center';
16
16
  verticalAlign?: 'top' | 'middle' | 'bottom';
17
+ divider?: 'right' | 'left';
17
18
  allowWrap?: boolean;
18
19
  emptyPlaceholder?: ReactNode;
19
20
  canHide?: boolean;
@@ -39,12 +40,6 @@ export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTML
39
40
  sortDirection?: SortDirection;
40
41
  loading?: boolean;
41
42
  headerExtras?: (args: HeaderExtrasArgs<T>) => ReactNode;
42
- /**
43
- * Grid layout control
44
- *
45
- * Example:
46
- * "34px minmax(160px, 2fr) minmax(120px, 1fr) minmax(120px, 1fr)"
47
- */
48
43
  gridTemplateColumns?: string;
49
44
  toolbar?: ReactNode;
50
45
  striped?: boolean;