@dbcdk/react-components 0.0.22 → 0.0.24

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.
@@ -23,6 +23,7 @@
23
23
  user-select: none;
24
24
  white-space: nowrap;
25
25
  }
26
+
26
27
  .buttonLink {
27
28
  color: inherit;
28
29
  text-decoration: none;
@@ -35,9 +36,11 @@
35
36
  border-color var(--transition-fast) var(--ease-standard),
36
37
  box-shadow var(--transition-fast) var(--ease-standard);
37
38
  }
39
+
38
40
  .button:focus-visible {
39
41
  outline: none;
40
- box-shadow: var(--focus-ring);
42
+ border-color: var(--color-border-selected);
43
+ box-shadow: inset 0 0 0 1px var(--color-border-selected);
41
44
  }
42
45
 
43
46
  .round {
@@ -47,6 +50,7 @@
47
50
  .rounded {
48
51
  border-radius: var(--border-radius-rounded);
49
52
  }
53
+
50
54
  .button:disabled,
51
55
  .button[aria-disabled='true'] {
52
56
  cursor: not-allowed;
@@ -73,7 +77,8 @@
73
77
 
74
78
  .link:focus-visible {
75
79
  outline: none;
76
- box-shadow: var(--focus-ring);
80
+ text-decoration: underline;
81
+ text-decoration-color: currentColor;
77
82
  }
78
83
 
79
84
  /* Icons */
@@ -93,8 +98,9 @@
93
98
 
94
99
  .button.xs {
95
100
  height: var(--component-size-xs);
96
- min-block-size: var(--component-size-sm);
97
- padding-inline: var(--spacing-sm);
101
+ min-block-size: var(--component-size-xs);
102
+ padding-inline: var(--spacing-xs);
103
+ font-size: var(--font-size-xs);
98
104
  }
99
105
 
100
106
  .button.sm {
@@ -103,13 +109,6 @@
103
109
  padding-inline: var(--spacing-xs);
104
110
  }
105
111
 
106
- .button.xs {
107
- height: var(--component-size-xs);
108
- min-block-size: var(--component-size-xs);
109
- padding-inline: var(--spacing-xs);
110
- font-size: var(--font-size-xs);
111
- }
112
-
113
112
  .button.sm svg {
114
113
  inline-size: var(--icon-size-sm);
115
114
  block-size: var(--icon-size-sm);
@@ -163,9 +162,8 @@
163
162
 
164
163
  .default:focus-visible {
165
164
  outline: none;
166
- box-shadow:
167
- inset 0 0 0 1px var(--color-border-selected),
168
- var(--focus-ring);
165
+ border-color: var(--color-border-selected);
166
+ box-shadow: inset 0 0 0 1px var(--color-border-selected);
169
167
  }
170
168
 
171
169
  .outlined {
@@ -223,6 +221,13 @@
223
221
  background-color: var(--opac-bg-light);
224
222
  }
225
223
 
224
+ .button.inline:focus-visible {
225
+ outline: none;
226
+ background-color: var(--opac-bg-light);
227
+ border-color: transparent;
228
+ box-shadow: inset 0 0 0 1px var(--color-border-selected);
229
+ }
230
+
226
231
  .active {
227
232
  background-color: var(--button-bg-primary);
228
233
  color: var(--button-fg-primary);
@@ -43,6 +43,7 @@ type BaseProps = {
43
43
  locale: string;
44
44
  enableTime: boolean;
45
45
  }) => string;
46
+ onOpenChange?: (open: boolean) => void;
46
47
  };
47
48
  export type DateTimePickerProps = (BaseProps & {
48
49
  mode?: 'single';
@@ -52,7 +52,7 @@ function defaultFormatRange(s, e, opts) {
52
52
  return '';
53
53
  }
54
54
  const cx = (...classes) => classes.filter(Boolean).join(' ');
55
- export const DateTimePicker = forwardRef(function DateTimePicker({ mode = 'single', value, onChange, enableTime = false, timeStep = 15, min, max, locale = typeof navigator !== 'undefined' ? navigator.language : 'da-DK', weekStartsOn = 1, presets, inputProps, formatDate = defaultFormatDate, formatRange = defaultFormatRange, }, _ref) {
55
+ export const DateTimePicker = forwardRef(function DateTimePicker({ mode = 'single', value, onChange, enableTime = false, timeStep = 15, min, max, locale = typeof navigator !== 'undefined' ? navigator.language : 'da-DK', weekStartsOn = 1, presets, inputProps, formatDate = defaultFormatDate, formatRange = defaultFormatRange, onOpenChange, }, _ref) {
56
56
  void formatDate;
57
57
  void formatRange;
58
58
  const popRef = useRef(null);
@@ -314,6 +314,19 @@ export const DateTimePicker = forwardRef(function DateTimePicker({ mode = 'singl
314
314
  setDirty(false);
315
315
  }
316
316
  }, [text, mode, enableTime, onChangeDateOnly, onChangeIso, onChangeRange]);
317
+ const emitTimeChange = useCallback((nextHH, nextMM) => {
318
+ if (mode !== 'single' || !enableTime)
319
+ return;
320
+ if (typeof value !== 'string')
321
+ return;
322
+ const current = localDateFromIso(value);
323
+ if (!current)
324
+ return;
325
+ const iso = isoFromLocalParts(current.getFullYear(), current.getMonth(), current.getDate(), nextHH, nextMM);
326
+ if (!iso)
327
+ return;
328
+ onChangeIso(iso);
329
+ }, [mode, enableTime, value, onChangeIso]);
317
330
  const clear = useCallback(() => {
318
331
  if (mode === 'single') {
319
332
  if (enableTime)
@@ -328,7 +341,7 @@ export const DateTimePicker = forwardRef(function DateTimePicker({ mode = 'singl
328
341
  setText('');
329
342
  }, [mode, enableTime, onChangeDateOnly, onChangeIso, onChangeRange]);
330
343
  const fallbackPlaceholder = mode === 'single' ? 'Vælg dato' : 'Vælg interval';
331
- return (_jsx(Popover, { matchTriggerWidth: false, ref: popRef, trigger: toggle => {
344
+ return (_jsx(Popover, { matchTriggerWidth: false, ref: popRef, onOpenChange: onOpenChange, trigger: toggle => {
332
345
  var _a, _b;
333
346
  return (_jsx("div", { onClick: toggle, className: styles.triggerWrap, children: _jsx(Input, { ...inputProps, autoComplete: "off", autoCorrect: "off", autoCapitalize: "off", spellCheck: "false", placeholder: (_a = inputProps === null || inputProps === void 0 ? void 0 : inputProps.placeholder) !== null && _a !== void 0 ? _a : fallbackPlaceholder, value: dirty ? text : formatted, onInput: e => {
334
347
  setDirty(true);
@@ -374,6 +387,14 @@ export const DateTimePicker = forwardRef(function DateTimePicker({ mode = 'singl
374
387
  }
375
388
  const dayNum = utcDay.getUTCDate();
376
389
  return (_jsx("button", { role: "gridcell", "aria-selected": selected, "aria-disabled": disabledDay, onMouseEnter: () => setHoverUTC(utcDay), onClick: () => selectDay(utcDay), disabled: disabledDay, className: cx(styles.dayCell, inThisMonth ? styles.dayInMonth : styles.dayOutside, selected && styles.daySelected, inRange && styles.dayInRange, isToday && !selected && styles.dayToday, disabledDay && styles.dayDisabled), title: new Date(utcDay).toLocaleDateString(locale), children: dayNum }, idx));
377
- }) }), enableTime && mode === 'single' && (_jsxs("div", { className: styles.timeRow, children: [_jsxs("div", { className: styles.timeLabel, children: [_jsx(Clock, { size: 14 }), " Tid"] }), _jsx("select", { value: timeHH, onChange: e => setTimeHH(parseInt(e.target.value, 10)), className: styles.timeSelect, children: hours.map(h => (_jsx("option", { value: h, children: String(h).padStart(2, '0') }, h))) }), _jsx("select", { value: timeMM, onChange: e => setTimeMM(parseInt(e.target.value, 10)), className: styles.timeSelect, children: minutes.map(m => (_jsx("option", { value: m, children: String(m).padStart(2, '0') }, m))) })] })), mode === 'range' && (_jsxs("div", { className: styles.footer, children: [_jsx(Button, { variant: "outlined", size: "sm", onClick: clear, icon: _jsx(X, { size: 14 }), children: "Ryd" }), _jsx(Button, { variant: "primary", size: "sm", onClick: () => { var _a; return (_a = popRef.current) === null || _a === void 0 ? void 0 : _a.close(); }, children: "OK" })] }))] })] }) }));
390
+ }) }), enableTime && mode === 'single' && (_jsxs("div", { className: styles.timeRow, children: [_jsxs("div", { className: styles.timeLabel, children: [_jsx(Clock, { size: 14 }), " Tid"] }), _jsx("select", { value: timeHH, onChange: e => {
391
+ const nextHH = parseInt(e.target.value, 10);
392
+ setTimeHH(nextHH);
393
+ emitTimeChange(nextHH, timeMM);
394
+ }, className: styles.timeSelect, children: hours.map(h => (_jsx("option", { value: h, children: String(h).padStart(2, '0') }, h))) }), _jsx("select", { value: timeMM, onChange: e => {
395
+ const nextMM = parseInt(e.target.value, 10);
396
+ setTimeMM(nextMM);
397
+ emitTimeChange(timeHH, nextMM);
398
+ }, className: styles.timeSelect, children: minutes.map(m => (_jsx("option", { value: m, children: String(m).padStart(2, '0') }, m))) })] })), mode === 'range' && (_jsxs("div", { className: styles.footer, children: [_jsx(Button, { variant: "outlined", size: "sm", onClick: clear, icon: _jsx(X, { size: 14 }), children: "Ryd" }), _jsx(Button, { variant: "primary", size: "sm", onClick: () => { var _a; return (_a = popRef.current) === null || _a === void 0 ? void 0 : _a.close(); }, children: "OK" })] }))] })] }) }));
378
399
  });
379
400
  DateTimePicker.displayName = 'DateTimePicker';
@@ -56,7 +56,7 @@ function OperatorDropdown({ value, onChange, operators, size = 'sm', disabled, }
56
56
  setActiveIndex(operators.indexOf(op));
57
57
  (_a = popRef.current) === null || _a === void 0 ? void 0 : _a.close();
58
58
  };
59
- return (_jsx(Popover, { ref: popRef, minWidth: "220px", trigger: (toggle, icon) => (_jsxs("button", { type: "button", onClick: toggle, disabled: disabled, "aria-label": "Change operator", className: `${styles.operatorTrigger} ${styles[size]}`, children: [_jsx("span", { className: styles.operatorText, children: LABELS[value] }), icon] })), children: _jsx(Menu, { children: operators.map(op => {
59
+ return (_jsx(Popover, { ref: popRef, minWidth: "220px", trigger: (toggle, icon) => (_jsxs("button", { type: "button", onClick: toggle, disabled: disabled, "aria-label": "Skift operator", className: `${styles.operatorTrigger} ${styles[size]}`, children: [_jsx("span", { className: styles.operatorText, children: LABELS[value] }), icon] })), children: _jsx(Menu, { children: operators.map(op => {
60
60
  const selected = op === value;
61
61
  return (_jsx(Menu.Item, { active: selected, children: _jsxs("button", { type: "button", onClick: () => handleSelect(op), disabled: disabled, children: [_jsx("span", { style: { width: 16, display: 'inline-flex', justifyContent: 'center' }, children: selected ? _jsx(Check, { size: 16 }) : null }), LABELS[op]] }) }, op));
62
62
  }) }) }));
@@ -137,7 +137,7 @@ export function FilterField({ field, control, operator, value, onChange, operato
137
137
  isTypingRef.current = true;
138
138
  setLocalValue(next);
139
139
  scheduleEmitValue(next);
140
- }, fullWidth: true, inputSize: size, placeholder: placeholder, width: "160px", minWidth: "120px", disabled: disabled, onClear: () => {
140
+ }, fullWidth: true, inputSize: size, placeholder: placeholder, disabled: disabled, onClear: () => {
141
141
  isTypingRef.current = false;
142
142
  if (debounceRef.current)
143
143
  clearTimeout(debounceRef.current);
@@ -15,6 +15,7 @@
15
15
  border-color var(--transition-fast) var(--ease-standard),
16
16
  box-shadow var(--transition-fast) var(--ease-standard),
17
17
  color var(--transition-fast) var(--ease-standard);
18
+ line-height: 20px;
18
19
  }
19
20
 
20
21
  /* =========================
@@ -96,6 +97,15 @@
96
97
  z-index: 2;
97
98
  }
98
99
 
100
+ .filterField.outlined.active::before {
101
+ inset-inline-start: -1px;
102
+ top: -1px;
103
+ bottom: -1px;
104
+ width: 4px;
105
+ border-top-left-radius: var(--border-radius-default);
106
+ border-bottom-left-radius: var(--border-radius-default);
107
+ }
108
+
99
109
  /* =========================
100
110
  FOCUS
101
111
  ========================= */
@@ -157,9 +167,10 @@
157
167
  display: inline-flex;
158
168
  align-items: center;
159
169
  padding-block: var(--spacing-2xs);
160
- padding-inline: var(--spacing-sm);
170
+ padding-inline: var(--spacing-xs);
171
+ padding-inline-end: var(--spacing-xxs);
161
172
  font-size: var(--font-size-sm);
162
- color: var(--color-fg-muted);
173
+ color: var(--color-fg-subtle);
163
174
  white-space: nowrap;
164
175
  user-select: none;
165
176
  }
@@ -175,8 +186,7 @@
175
186
  gap: var(--spacing-xxs);
176
187
  height: 100%;
177
188
  padding-block: var(--spacing-2xs);
178
- padding-inline: var(--spacing-sm);
179
-
189
+ padding-inline: var(--spacing-xxs);
180
190
  color: var(--color-fg-default);
181
191
  background: transparent;
182
192
  border: 0;
@@ -184,7 +194,7 @@
184
194
  position: relative;
185
195
  z-index: 0;
186
196
  font-weight: var(--font-weight-default);
187
-
197
+ font-size: var(--font-size-sm);
188
198
  transition:
189
199
  background-color var(--transition-fast) var(--ease-standard),
190
200
  color var(--transition-fast) var(--ease-standard);
@@ -206,6 +216,17 @@
206
216
  z-index: 1;
207
217
  }
208
218
 
219
+ .filterField .operatorTrigger:hover:not(:disabled) {
220
+ color: var(--color-fg-default);
221
+ }
222
+
223
+ .filterField .operatorTrigger:hover:not(:disabled)::after {
224
+ background: color-mix(
225
+ in srgb,
226
+ var(--color-fg-default) 8%,
227
+ var(--filter-operator-bg, transparent)
228
+ );
229
+ }
209
230
  /* =========================
210
231
  SEPARATORS
211
232
  ========================= */
@@ -244,6 +265,10 @@
244
265
  );
245
266
  }
246
267
 
268
+ .operatorTrigger svg {
269
+ height: var(--component-size-xxs);
270
+ width: var(--component-size-xxs);
271
+ }
247
272
  /* =========================
248
273
  VALUE WRAPPER
249
274
  ========================= */
@@ -272,8 +297,6 @@
272
297
  min-width: 0;
273
298
  }
274
299
 
275
- /* subtle highlight when active */
276
-
277
300
  .filterField.active .valueWrapper {
278
301
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-border-selected) 18%, transparent);
279
302
  }
@@ -284,6 +307,8 @@
284
307
 
285
308
  .filterField .operatorText {
286
309
  white-space: nowrap;
310
+ font-family: var(--font-family-mono);
311
+ font-size: var(--font-size-xs);
287
312
  }
288
313
 
289
314
  .filterField input::placeholder {
@@ -12,8 +12,6 @@ interface ChipMultiToggleProps {
12
12
  onChange: (nextSelectedValues: string[]) => void;
13
13
  onToggle?: (toggledValue: string, isSelected: boolean) => void;
14
14
  size?: 'sm' | 'md' | 'lg';
15
- selectedSeverity: 'neutral' | 'info' | 'success' | 'warning' | 'danger' | 'brand';
16
- unselectedSeverity?: 'neutral' | 'info' | 'success' | 'warning' | 'danger' | null;
17
15
  fullWidth?: boolean;
18
16
  disabled?: boolean;
19
17
  showAllOption?: boolean;
@@ -72,9 +72,8 @@
72
72
  border-bottom-right-radius: 0;
73
73
  }
74
74
 
75
- /* Optional: if ClearButton is absolutely positioned, reserve space */
76
75
  .withClear .input {
77
- padding-inline-end: calc(var(--spacing-md) + 28px);
76
+ padding-inline-end: calc(var(--spacing-md) + 16px);
78
77
  }
79
78
 
80
79
  /* Global focus reset - variants own visible focus treatment */
@@ -133,13 +132,12 @@
133
132
  box-shadow: inset 0 0 0 1px var(--color-border-selected);
134
133
  }
135
134
 
136
- /* Embedded = chromeless input for grouped controls like FilterField */
137
135
  .embedded {
138
136
  background-color: transparent;
139
137
  border-color: transparent;
140
138
  border-radius: 0;
141
139
  box-shadow: none;
142
- padding-inline: calc(var(--spacing-sm) + var(--spacing-2xs));
140
+ padding-inline: var(--spacing-xs);
143
141
  padding-block: 0;
144
142
  }
145
143
 
@@ -175,7 +173,7 @@
175
173
  /* Sizes */
176
174
  .xs {
177
175
  block-size: var(--component-size-xs);
178
- font-size: var(--font-size-sm);
176
+ font-size: var(--font-size-xs);
179
177
  padding: 0 var(--spacing-xxs);
180
178
  }
181
179
 
@@ -1,13 +1,15 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { ArrowLeft, ArrowRight, ChevronDown, ChevronsLeft, ChevronsRight } from 'lucide-react';
4
- import { useMemo, useCallback } from 'react';
4
+ import { useMemo, useCallback, useRef } from 'react';
5
5
  import styles from './Pagination.module.css';
6
6
  import { Button } from '../button/Button';
7
7
  import { Menu } from '../menu/Menu';
8
8
  import { Popover } from '../popover/Popover';
9
9
  const DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];
10
10
  export function Pagination({ itemsCount = 0, skip = 0, take = DEFAULT_PAGE_SIZE_OPTIONS[1], onPageChange, pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS, showFirstLast = true, showGoToPage = true, }) {
11
+ const popoverRef = useRef(null);
12
+ const pageSizeRef = useRef(null);
11
13
  const totalPages = useMemo(() => Math.max(1, Math.ceil(itemsCount / Math.max(1, take))), [itemsCount, take]);
12
14
  const currentPage = useMemo(() => {
13
15
  const p = Math.floor(skip / Math.max(1, take)) + 1;
@@ -40,5 +42,13 @@ export function Pagination({ itemsCount = 0, skip = 0, take = DEFAULT_PAGE_SIZE_
40
42
  }, [itemsCount, skip, take]);
41
43
  const pages = useMemo(() => Array.from({ length: totalPages }, (_, i) => i + 1), [totalPages]);
42
44
  const handlePageSizeChange = useCallback((size) => emit(1, size), [emit]);
43
- return (_jsxs("div", { className: styles.container, children: [showFirstLast && (_jsx(Button, { size: "sm", icon: _jsx(ChevronsLeft, {}), disabled: !canPrev, onClick: firstPage, "aria-label": "First page" })), _jsx(Button, { size: "sm", icon: _jsx(ArrowLeft, {}), disabled: !canPrev, onClick: prevPage, "aria-label": "Previous page" }), _jsx("div", { className: styles.range, "aria-live": "polite", children: rangeLabel }), _jsx(Button, { size: "sm", icon: _jsx(ArrowRight, {}), disabled: !canNext, onClick: nextPage, "aria-label": "Next page" }), showFirstLast && (_jsx(Button, { size: "sm", icon: _jsx(ChevronsRight, {}), disabled: !canNext, onClick: lastPage, "aria-label": "Last page" })), showGoToPage && (_jsx(Popover, { trigger: open => (_jsxs(Button, { size: "sm", variant: "outlined", onClick: open, children: ["Side ", currentPage, "/", totalPages, " ", _jsx(ChevronDown, { size: 16 })] })), children: _jsx(Menu, { children: pages.map(page => (_jsx(Menu.Item, { active: page === currentPage, children: _jsx("button", { onClick: () => goToPage(page), children: page }) }, page))) }) })), _jsx(Popover, { trigger: open => (_jsxs(Button, { size: "sm", variant: "outlined", onClick: open, children: ["Vis ", take, " ", _jsx(ChevronDown, { size: 16 })] })), children: _jsx(Menu, { children: pageSizeOptions.map(size => (_jsx(Menu.Item, { active: size === take, children: _jsx("button", { onClick: () => handlePageSizeChange(size), children: size }) }, size))) }) })] }));
45
+ return (_jsxs("div", { className: styles.container, children: [showFirstLast && (_jsx(Button, { size: "sm", icon: _jsx(ChevronsLeft, {}), disabled: !canPrev, onClick: firstPage, "aria-label": "First page" })), _jsx(Button, { size: "sm", icon: _jsx(ArrowLeft, {}), disabled: !canPrev, onClick: prevPage, "aria-label": "Previous page" }), _jsx("div", { className: styles.range, "aria-live": "polite", children: rangeLabel }), _jsx(Button, { size: "sm", icon: _jsx(ArrowRight, {}), disabled: !canNext, onClick: nextPage, "aria-label": "Next page" }), showFirstLast && (_jsx(Button, { size: "sm", icon: _jsx(ChevronsRight, {}), disabled: !canNext, onClick: lastPage, "aria-label": "Last page" })), showGoToPage && (_jsx(Popover, { ref: popoverRef, trigger: open => (_jsxs(Button, { size: "sm", variant: "outlined", onClick: open, children: ["Side ", currentPage, "/", totalPages, " ", _jsx(ChevronDown, { size: 16 })] })), children: _jsx(Menu, { children: pages === null || pages === void 0 ? void 0 : pages.map(page => (_jsx(Menu.Item, { active: page === currentPage, children: _jsx("button", { onClick: () => {
46
+ var _a;
47
+ goToPage(page);
48
+ (_a = popoverRef.current) === null || _a === void 0 ? void 0 : _a.close();
49
+ }, children: page }) }, page))) }) })), _jsx(Popover, { ref: pageSizeRef, trigger: open => (_jsxs(Button, { size: "sm", variant: "outlined", onClick: open, children: ["Vis ", take, " ", _jsx(ChevronDown, { size: 16 })] })), children: _jsx(Menu, { children: pageSizeOptions === null || pageSizeOptions === void 0 ? void 0 : pageSizeOptions.map(size => (_jsx(Menu.Item, { active: size === take, children: _jsx("button", { onClick: () => {
50
+ var _a;
51
+ handlePageSizeChange(size);
52
+ (_a = pageSizeRef.current) === null || _a === void 0 ? void 0 : _a.close();
53
+ }, children: size }) }, size))) }) })] }));
44
54
  }
@@ -66,11 +66,11 @@
66
66
  }
67
67
 
68
68
  .progressSegment[data-severity='progress'] {
69
- background: color-mix(in srgb, var(--color-fg-subtle) 18%, var(--color-bg-surface));
69
+ background: color-mix(in srgb, var(--color-fg-subtle) 5%, var(--color-bg-surface));
70
70
  }
71
71
 
72
72
  .progressSegment[data-severity='missing'] {
73
- background: color-mix(in srgb, var(--color-border-subtle) 65%, var(--color-bg-surface));
73
+ background: color-mix(in srgb, var(--color-fg-subtle) 2.5%, var(--color-bg-surface));
74
74
  }
75
75
 
76
76
  .progressSegment[data-severity='neutral'] {
@@ -10,6 +10,7 @@ interface SidebarProps {
10
10
  productLogo?: React.ReactNode;
11
11
  activeLink?: string;
12
12
  version?: string | number;
13
+ hideSearch?: boolean;
13
14
  }
14
- export declare function Sidebar({ items, productLogo, activeLink, version }: SidebarProps): JSX.Element;
15
+ export declare function Sidebar({ items, productLogo, activeLink, version, hideSearch, }: SidebarProps): JSX.Element;
15
16
  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, version }) {
6
- return (_jsx(SidebarProvider, { items: items, children: _jsx(SidebarContainer, { productLogo: productLogo, activeLink: activeLink, version: version }) }));
5
+ export function Sidebar({ items, productLogo, activeLink, version, hideSearch, }) {
6
+ return (_jsx(SidebarProvider, { items: items, children: _jsx(SidebarContainer, { productLogo: productLogo, activeLink: activeLink, version: version, hideSearch: hideSearch }) }));
7
7
  }
@@ -5,6 +5,7 @@ interface SidebarContainerProps {
5
5
  productLogo?: ReactNode;
6
6
  activeLink?: string;
7
7
  version?: string | number;
8
+ hideSearch?: boolean;
8
9
  }
9
- export declare function SidebarContainer({ logo, productLogo, activeLink, version, }: SidebarContainerProps): JSX.Element;
10
+ export declare function SidebarContainer({ logo, productLogo, activeLink, version, hideSearch, }: SidebarContainerProps): JSX.Element;
10
11
  export {};
@@ -6,7 +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, productLogo, activeLink, version, }) {
9
+ export function SidebarContainer({ logo, productLogo, activeLink, version, hideSearch, }) {
10
10
  const { isSidebarCollapsed, handleSidebarCollapseChange } = useSidebar();
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 })] })] }));
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: [!hideSearch && (_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 })] })] }));
12
12
  }
@@ -25,7 +25,7 @@ type HeaderExtrasArgs<T> = {
25
25
  index: number;
26
26
  };
27
27
  export type TableVariant = 'primary' | 'embedded';
28
- export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTMLDivElement>, 'onClick'> & {
28
+ export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTMLDivElement>, 'onClick' | 'onMouseEnter'> & {
29
29
  data: T[];
30
30
  dataKey: keyof T;
31
31
  columns: ColumnItem<T>[];
@@ -33,6 +33,7 @@ export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTML
33
33
  selectionMode?: 'single' | 'multiple';
34
34
  allRowsSelected?: boolean;
35
35
  onRowClick?: (row: T) => void;
36
+ onRowMouseEnter?: (row: T) => void;
36
37
  onRowSelect?: (rowId: number | string, isSelected: boolean) => void;
37
38
  onSelectAllRows?: (isSelected: boolean) => void;
38
39
  onSortChange?: (column: ColumnItem<T>, direction: SortDirection) => void;
@@ -59,5 +60,5 @@ export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTML
59
60
  viewMode?: ViewMode;
60
61
  emptyConfig?: TableEmptyConfig;
61
62
  };
62
- export declare function Table<T extends Record<string, any>>({ data, columns, selectedRows, onRowSelect, selectionMode, onSortChange, onRowClick, sortById, sortDirection, dataKey, headerExtras, gridTemplateColumns, toolbar, striped, fillViewport, viewportBottomOffset, viewportMin, viewportIncludeMarginTop, take, skip, paginationPlacement, totalItemsCount, onPageChange, loading, variant, size, getRowSeverity, showFirstLast, allRowsSelected, onSelectAllRows, viewMode, emptyConfig, ...rest }: TableProps<T>): JSX.Element;
63
+ export declare function Table<T extends Record<string, any>>({ data, columns, selectedRows, onRowSelect, selectionMode, onSortChange, onRowClick, onRowMouseEnter, sortById, sortDirection, dataKey, headerExtras, gridTemplateColumns, toolbar, striped, fillViewport, viewportBottomOffset, viewportMin, viewportIncludeMarginTop, take, skip, paginationPlacement, totalItemsCount, onPageChange, loading, variant, size, getRowSeverity, showFirstLast, allRowsSelected, onSelectAllRows, viewMode, emptyConfig, ...rest }: TableProps<T>): JSX.Element;
63
64
  export {};
@@ -18,7 +18,7 @@ function buildDefaultGridTemplate(args) {
18
18
  parts.push('minmax(120px, 1fr)');
19
19
  return parts.join(' ');
20
20
  }
21
- export function Table({ data, columns, selectedRows, onRowSelect, selectionMode = 'single', onSortChange, onRowClick, sortById, sortDirection, dataKey, headerExtras, gridTemplateColumns, toolbar, striped, fillViewport = false, viewportBottomOffset, viewportMin, viewportIncludeMarginTop, take, skip, paginationPlacement = 'bottom', totalItemsCount, onPageChange, loading, variant = 'primary', size = 'md', getRowSeverity, showFirstLast = false, allRowsSelected, onSelectAllRows, viewMode, emptyConfig, ...rest }) {
21
+ export function Table({ data, columns, selectedRows, onRowSelect, selectionMode = 'single', onSortChange, onRowClick, onRowMouseEnter, sortById, sortDirection, dataKey, headerExtras, gridTemplateColumns, toolbar, striped, fillViewport = false, viewportBottomOffset, viewportMin, viewportIncludeMarginTop, take, skip, paginationPlacement = 'bottom', totalItemsCount, onPageChange, loading, variant = 'primary', size = 'md', getRowSeverity, showFirstLast = false, allRowsSelected, onSelectAllRows, viewMode, emptyConfig, ...rest }) {
22
22
  void viewportBottomOffset;
23
23
  void viewportMin;
24
24
  void viewportIncludeMarginTop;
@@ -115,7 +115,7 @@ export function Table({ data, columns, selectedRows, onRowSelect, selectionMode
115
115
  e.preventDefault();
116
116
  onRowClick(row);
117
117
  }
118
- }, onClick: e => {
118
+ }, onMouseEnter: () => onRowMouseEnter === null || onRowMouseEnter === void 0 ? void 0 : onRowMouseEnter(row), onClick: e => {
119
119
  const canSelect = Boolean(selectedRows && onRowSelect && dataKey);
120
120
  if (isModifierClick(e) && canSelect) {
121
121
  e.preventDefault();
@@ -154,7 +154,7 @@ export function Table({ data, columns, selectedRows, onRowSelect, selectionMode
154
154
  ]
155
155
  .filter(Boolean)
156
156
  .join(' ');
157
- const tableShell = (_jsxs("div", { ...rest, className: tableClassName, role: "table", "aria-rowcount": data.length, children: [_jsx("div", { className: styles.header, role: "rowgroup", children: headerEl }), _jsx("div", { className: styles.bodyScroll, children: !data.length && !loading ? (_jsx("div", { className: styles.emptyStateSlot, children: _jsx(TableEmptyState, { config: emptyConfig }) })) : (bodyContent) })] }));
157
+ const tableShell = (_jsx("div", { ...rest, className: tableClassName, role: "table", "aria-rowcount": data.length, children: _jsxs("div", { className: styles.tableContent, children: [_jsx("div", { className: styles.header, role: "rowgroup", children: headerEl }), _jsx("div", { className: styles.bodyScroll, children: !data.length && !loading ? (_jsx("div", { className: styles.emptyStateSlot, children: _jsx(TableEmptyState, { config: emptyConfig }) })) : (bodyContent) })] }) }));
158
158
  const paginationEl = onPageChange && data.length > 0 ? (_jsx("div", { className: `${styles.paginationSlot} ${paginationPlacement === 'top' ? styles.paginationSlotTop : ''}`, children: _jsx(Pagination, { itemsCount: totalItemsCount, take: take, skip: skip, onPageChange: handlePageChange, showFirstLast: showFirstLast }) })) : null;
159
159
  if (fillViewport) {
160
160
  return (_jsxs("div", { className: styles.fillViewportRoot, style: {
@@ -74,7 +74,6 @@
74
74
  flex: 1 1 auto;
75
75
  min-block-size: 0;
76
76
  min-inline-size: 0;
77
- max-inline-size: 100%;
78
77
  -webkit-overflow-scrolling: touch;
79
78
  }
80
79
 
@@ -103,11 +102,15 @@
103
102
  display: none;
104
103
  }
105
104
 
105
+ .tableContent {
106
+ inline-size: fit-content;
107
+ min-inline-size: 100%;
108
+ }
109
+
106
110
  .headerCell {
107
111
  display: flex;
108
112
  align-items: center;
109
113
  position: relative;
110
- min-block-size: 44px;
111
114
  padding-block: var(--spacing-xxs);
112
115
  padding-inline: var(--spacing-sm);
113
116
  font-size: var(--font-size-xs);
@@ -122,7 +125,6 @@
122
125
  }
123
126
 
124
127
  .sm .headerCell {
125
- min-block-size: 40px;
126
128
  padding-block: var(--spacing-xxs);
127
129
  padding-inline: var(--spacing-sm);
128
130
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dbcdk/react-components",
3
- "version": "0.0.22",
3
+ "version": "0.0.24",
4
4
  "description": "Reusable React components for DBC projects",
5
5
  "license": "ISC",
6
6
  "author": "",