@dbcdk/react-components 0.0.19 → 0.0.21

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 (46) hide show
  1. package/dist/components/button/Button.module.css +21 -10
  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/code-block/CodeBlock.js +28 -19
  6. package/dist/components/code-block/CodeBlock.module.css +69 -67
  7. package/dist/components/filter-field/FilterField.d.ts +2 -1
  8. package/dist/components/filter-field/FilterField.js +4 -9
  9. package/dist/components/filter-field/FilterField.module.css +203 -152
  10. package/dist/components/filtering/chip-multi-toggle/ChipMultiToggle.d.ts +2 -3
  11. package/dist/components/filtering/chip-multi-toggle/ChipMultiToggle.js +3 -5
  12. package/dist/components/filtering/chip-multi-toggle/ChipMultiToggle.module.css +13 -13
  13. package/dist/components/forms/input/Input.d.ts +1 -1
  14. package/dist/components/forms/input/Input.js +3 -9
  15. package/dist/components/forms/input/Input.module.css +106 -17
  16. package/dist/components/hyperlink/Hyperlink.module.css +14 -3
  17. package/dist/components/interval-select/IntervalSelect.js +2 -2
  18. package/dist/components/overlay/modal/Modal.d.ts +2 -1
  19. package/dist/components/overlay/modal/Modal.js +6 -6
  20. package/dist/components/overlay/modal/Modal.module.css +52 -19
  21. package/dist/components/popover/Popover.module.css +4 -1
  22. package/dist/components/segmented-progress-bar/SegmentedProgressBar.d.ts +4 -2
  23. package/dist/components/segmented-progress-bar/SegmentedProgressBar.js +17 -19
  24. package/dist/components/segmented-progress-bar/SegmentedProgressBar.module.css +128 -20
  25. package/dist/components/sidebar/Sidebar.d.ts +2 -1
  26. package/dist/components/sidebar/Sidebar.js +2 -2
  27. package/dist/components/sidebar/components/sidebar-container/SidebarContainer.d.ts +2 -3
  28. package/dist/components/sidebar/components/sidebar-container/SidebarContainer.js +2 -4
  29. package/dist/components/sidebar/components/sidebar-container/SidebarContainer.module.css +2 -1
  30. package/dist/components/table/Table.d.ts +6 -6
  31. package/dist/components/table/Table.js +153 -78
  32. package/dist/components/table/Table.module.css +335 -171
  33. package/dist/components/table/TanstackTable.d.ts +1 -1
  34. package/dist/components/table/TanstackTable.js +14 -12
  35. package/dist/components/table/table.utils.d.ts +1 -1
  36. package/dist/components/table/table.utils.js +2 -3
  37. package/dist/components/table/tanstackTable.utils.d.ts +9 -10
  38. package/dist/components/table/tanstackTable.utils.js +50 -30
  39. package/dist/hooks/useViewportFill.d.ts +6 -5
  40. package/dist/hooks/useViewportFill.js +43 -41
  41. package/dist/src/styles/styles.css +9 -3
  42. package/dist/styles/styles.css +9 -3
  43. package/dist/styles/themes/dbc/base.css +0 -3
  44. package/dist/styles/themes/dbc/dark.css +44 -12
  45. package/dist/styles/themes/dbc/light.css +33 -7
  46. package/package.json +1 -1
@@ -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: "dbc-muted-text dbc-sm-text", children: version })] })] }));
14
12
  }
@@ -138,7 +138,8 @@
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;
142
143
  }
143
144
 
144
145
  .companyLogo {
@@ -1,7 +1,6 @@
1
- import React from 'react';
2
1
  import type { HTMLAttributes, JSX, ReactNode } from 'react';
3
- import { Severity } from '../../constants/severity.types';
4
2
  import { PageChangeEvent } from '../../components/pagination/Pagination';
3
+ import { Severity } from '../../constants/severity.types';
5
4
  import { ViewMode } from '../../hooks/useTableSettings';
6
5
  import { TableEmptyConfig } from './components/empty-state/EmptyState';
7
6
  import { SortDirection } from './table.utils';
@@ -15,6 +14,7 @@ export interface ColumnItem<T> {
15
14
  hidden?: boolean;
16
15
  align?: 'left' | 'right' | 'center';
17
16
  verticalAlign?: 'top' | 'middle' | 'bottom';
17
+ divider?: 'right' | 'left';
18
18
  allowWrap?: boolean;
19
19
  emptyPlaceholder?: ReactNode;
20
20
  canHide?: boolean;
@@ -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<HTMLTableElement>, 'onClick'> & {
28
+ export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTMLDivElement>, 'onClick'> & {
29
29
  data: T[];
30
30
  dataKey: keyof T;
31
31
  columns: ColumnItem<T>[];
@@ -40,7 +40,7 @@ export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTML
40
40
  sortDirection?: SortDirection;
41
41
  loading?: boolean;
42
42
  headerExtras?: (args: HeaderExtrasArgs<T>) => ReactNode;
43
- columnStyles?: Partial<Record<string, React.CSSProperties>>;
43
+ gridTemplateColumns?: string;
44
44
  toolbar?: ReactNode;
45
45
  striped?: boolean;
46
46
  fillViewport?: boolean;
@@ -58,6 +58,6 @@ export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTML
58
58
  showFirstLast?: boolean;
59
59
  viewMode?: ViewMode;
60
60
  emptyConfig?: TableEmptyConfig;
61
- } & Omit<HTMLAttributes<HTMLTableElement>, 'onClick'>;
62
- export declare function Table<T extends Record<string, any>>({ data, columns, selectedRows, onRowSelect, selectionMode, onSortChange, onRowClick, sortById, sortDirection, dataKey, headerExtras, columnStyles, 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;
61
+ };
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
63
  export {};
@@ -1,93 +1,168 @@
1
1
  'use client';
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { ArrowDown, ArrowUp } from 'lucide-react';
4
- import { useCallback, useMemo, useRef } from 'react';
5
- import { SeverityBgColor } from '../../constants/severity';
6
- import { useViewportFill } from '../../hooks/useViewportFill';
4
+ import { useCallback, useMemo } from 'react';
7
5
  import { Checkbox } from '../../components/forms/checkbox/Checkbox';
8
6
  import { Pagination } from '../../components/pagination/Pagination';
9
7
  import { SkeletonLoaderItem } from '../../components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem';
8
+ import { SeverityBgColor } from '../../constants/severity';
10
9
  import { TableEmptyState } from './components/empty-state/EmptyState';
11
10
  import styles from './Table.module.css';
12
- import { getAriaSort, getCellDisplayValue, getColumnStyle, getHeaderLabel, getNextSortDirection, getRowKey, getVisibleColumns, isModifierClick, shouldAllowWrap, shouldToggleOnKey, isActiveSort, } from './table.utils';
13
- export function Table({ data, columns, selectedRows, onRowSelect, selectionMode = 'single', onSortChange, onRowClick, sortById, sortDirection, dataKey, headerExtras, columnStyles, toolbar, striped, fillViewport = false, viewportBottomOffset = 0, viewportMin = 120, viewportIncludeMarginTop = false, take, skip, paginationPlacement = 'bottom', totalItemsCount, onPageChange, loading, variant = 'primary', size = 'md', getRowSeverity, showFirstLast = false, allRowsSelected, onSelectAllRows, viewMode, emptyConfig, ...rest }) {
11
+ import { getAriaSort, getCellDisplayValue, getHeaderLabel, getNextSortDirection, getVisibleColumns, isModifierClick, shouldAllowWrap, shouldToggleOnKey, isActiveSort, } from './table.utils';
12
+ function buildDefaultGridTemplate(args) {
13
+ const { hasSelection, colCount } = args;
14
+ const parts = [];
15
+ if (hasSelection)
16
+ parts.push('34px');
17
+ for (let i = 0; i < colCount; i++)
18
+ parts.push('minmax(120px, 1fr)');
19
+ return parts.join(' ');
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 }) {
22
+ void viewportBottomOffset;
23
+ void viewportMin;
24
+ void viewportIncludeMarginTop;
14
25
  const filteredColumns = useMemo(() => getVisibleColumns(columns), [columns]);
15
26
  const handlePageChange = useCallback((e) => onPageChange === null || onPageChange === void 0 ? void 0 : onPageChange(e), [onPageChange]);
16
- const scrollRef = useRef(null);
17
- const { style: viewportStyle } = useViewportFill(scrollRef, {
18
- bottomOffset: viewportBottomOffset + (onPageChange ? 60 : 0),
19
- min: viewportMin,
20
- includeMarginTop: viewportIncludeMarginTop,
21
- });
22
- const tableEl = (_jsxs(_Fragment, { children: [toolbar ? _jsx("div", { style: { marginBottom: 12 }, children: toolbar }) : null, _jsxs("table", { ...rest, className: `${styles.table} ${styles[variant]} ${styles[size]} ${getRowSeverity ? styles.severityTable : ''}`, children: [_jsx("thead", { children: _jsxs("tr", { children: [selectedRows && onRowSelect && dataKey && (_jsx("th", { className: `${styles.th} ${styles.selectionCell}`, children: selectionMode === 'multiple' ? (_jsx(Checkbox, { size: "sm", variant: "primary", checked: allRowsSelected, onChange: checked => onSelectAllRows === null || onSelectAllRows === void 0 ? void 0 : onSelectAllRows(checked) })) : null })), filteredColumns.map((column, index) => {
23
- const active = isActiveSort(sortById, column.id);
24
- const ariaSort = getAriaSort(column.sortable, active, sortDirection !== null && sortDirection !== void 0 ? sortDirection : null);
25
- const toggleSort = () => {
26
- if (!onSortChange || !column.sortable)
27
- return;
28
- const nextDir = getNextSortDirection(column.sortable, active, sortDirection !== null && sortDirection !== void 0 ? sortDirection : null);
29
- onSortChange(column, nextDir);
30
- };
31
- return (_jsx("th", { style: getColumnStyle(column.id, columnStyles, column.align, 'middle'), "aria-sort": ariaSort, className: `${styles.th}`, children: _jsxs("div", { className: styles.thInner, children: [column.sortable ? (_jsxs("button", { type: "button", className: [
32
- styles.thButton,
33
- column.align === 'right' ? styles.thButtonRight : '',
34
- column.align === 'center' ? styles.thButtonCenter : '',
35
- ].join(' '), onClick: toggleSort, onKeyDown: e => {
36
- if (shouldToggleOnKey(e.key)) {
37
- e.preventDefault();
38
- toggleSort();
39
- }
40
- }, children: [_jsx("span", { className: [
41
- styles.thLabel,
42
- column.align === 'right' ? styles.thLabelRight : '',
43
- column.align === 'center' ? styles.thLabelCenter : '',
44
- ].join(' '), children: getHeaderLabel(column.header) }), _jsxs("span", { className: styles.sortIndicator, "aria-hidden": "true", children: [active && sortDirection === 'asc' && _jsx(ArrowUp, {}), active && sortDirection === 'desc' && (_jsx(ArrowDown, { className: styles.descending })), !active && (_jsx(ArrowDown, { className: `${styles.descending} ${styles.inActiveSort}` }))] })] })) : (_jsx("span", { className: [
45
- styles.thLabel,
46
- column.align === 'right' ? styles.thLabelRight : '',
47
- column.align === 'center' ? styles.thLabelCenter : '',
48
- ].join(' '), children: getHeaderLabel(column.header) })), headerExtras ? (_jsx("div", { className: styles.thExtras, children: headerExtras({ column, index }) })) : null] }) }, column.id));
49
- })] }) }), loading && !data.length ? (_jsx("tbody", { className: `${styles.tBody} ${striped ? styles.striped : ''}`, children: Array.from({ length: take !== null && take !== void 0 ? take : 5 }).map((_, rowIndex) => (_jsx("tr", { children: filteredColumns.map((column, colIndex) => (_jsx("td", { style: getColumnStyle(column.id, columnStyles, column.align, 'middle'), className: `${styles.tableCell}`, children: _jsx(SkeletonLoaderItem, { height: 20, width: "100%" }) }, `${column.id}-${colIndex}`))) }, `loading-row-${rowIndex}`))) })) : (_jsx("tbody", { className: `${styles.tBody} ${striped ? styles.striped : ''}`, children: data === null || data === void 0 ? void 0 : data.map(row => {
50
- const rowSeverity = getRowSeverity === null || getRowSeverity === void 0 ? void 0 : getRowSeverity(row);
51
- const rowId = row[dataKey];
52
- const isSelected = Boolean(selectedRows === null || selectedRows === void 0 ? void 0 : selectedRows.has(rowId));
53
- return (_jsxs("tr", { tabIndex: onRowClick ? 0 : -1, onKeyDown: e => {
54
- if (!onRowClick)
55
- return;
56
- if (shouldToggleOnKey(e.key)) {
57
- e.preventDefault();
58
- onRowClick(row);
59
- }
60
- }, onClick: e => {
61
- const canSelect = Boolean(selectedRows && onRowSelect && dataKey);
62
- if (isModifierClick(e) && canSelect) {
63
- e.preventDefault();
64
- e.stopPropagation();
65
- onRowSelect(rowId, !selectedRows.has(rowId));
66
- return;
67
- }
68
- onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row);
69
- }, style: {
70
- ['--row-severity-color']: rowSeverity
71
- ? SeverityBgColor[rowSeverity]
72
- : undefined,
73
- }, className: `${onRowClick ? styles.clickableRow : ''} ${isSelected ? styles.selectedRow : ''} ${rowSeverity ? styles.severity : ''}`, children: [selectedRows && onRowSelect && dataKey && (_jsx("td", { className: `${styles.selectionCell}`, children: _jsx(Checkbox, { variant: "primary", checked: selectedRows.has(rowId), size: "sm", onChange: (checked, e) => {
74
- e.stopPropagation();
75
- onRowSelect === null || onRowSelect === void 0 ? void 0 : onRowSelect(rowId, checked);
76
- } }) })), filteredColumns.map(column => (_jsx("td", { style: getColumnStyle(column.id, columnStyles, column.align, column.verticalAlign), className: `${styles.tableCell} ${shouldAllowWrap(column.allowWrap, isSelected, viewMode)
77
- ? styles.allowWrap
78
- : styles.nowrap}`, children: getCellDisplayValue(row, column) }, column.id)))] }, getRowKey(rowId)));
79
- }) }))] }), !data.length && !loading && _jsx(TableEmptyState, { config: emptyConfig })] }));
27
+ const hasSelection = Boolean(selectedRows && onRowSelect && dataKey);
28
+ const template = useMemo(() => {
29
+ return (gridTemplateColumns !== null && gridTemplateColumns !== void 0 ? gridTemplateColumns : buildDefaultGridTemplate({ hasSelection, colCount: filteredColumns.length }));
30
+ }, [gridTemplateColumns, hasSelection, filteredColumns.length]);
31
+ const gridStyle = useMemo(() => ({ ['--grid-template']: template }), [template]);
32
+ const headerEl = (_jsxs("div", { className: styles.headerRow, style: gridStyle, role: "row", children: [hasSelection && (_jsx("div", { className: `${styles.headerCell} ${styles.selectionCell}`, role: "columnheader", children: selectionMode === 'multiple' ? (_jsx(Checkbox, { size: "sm", variant: "primary", checked: allRowsSelected, onChange: checked => onSelectAllRows === null || onSelectAllRows === void 0 ? void 0 : onSelectAllRows(checked) })) : null })), filteredColumns.map((column, index) => {
33
+ var _a;
34
+ const active = isActiveSort(sortById, column.id);
35
+ const ariaSort = getAriaSort(column.sortable, active, sortDirection !== null && sortDirection !== void 0 ? sortDirection : null);
36
+ const align = (_a = column.align) !== null && _a !== void 0 ? _a : 'left';
37
+ const extraContent = headerExtras === null || headerExtras === void 0 ? void 0 : headerExtras({ column, index });
38
+ const toggleSort = () => {
39
+ if (!onSortChange || !column.sortable)
40
+ return;
41
+ const nextDir = getNextSortDirection(column.sortable, active, sortDirection !== null && sortDirection !== void 0 ? sortDirection : null);
42
+ onSortChange(column, nextDir);
43
+ };
44
+ const dividerClass = column.divider === 'left'
45
+ ? styles.dividerLeft
46
+ : column.divider === 'right'
47
+ ? styles.dividerRight
48
+ : '';
49
+ return (_jsxs("div", { className: [styles.headerCell, dividerClass].filter(Boolean).join(' '), role: "columnheader", "aria-sort": ariaSort, "data-align": align, "data-divider": column.divider, children: [_jsx("div", { className: [
50
+ styles.thInner,
51
+ align === 'right' ? styles.thInnerRight : '',
52
+ align === 'center' ? styles.thInnerCenter : '',
53
+ ]
54
+ .filter(Boolean)
55
+ .join(' '), children: _jsx("div", { className: [
56
+ styles.thMain,
57
+ align === 'right' ? styles.thMainRight : '',
58
+ align === 'center' ? styles.thMainCenter : '',
59
+ ]
60
+ .filter(Boolean)
61
+ .join(' '), children: column.sortable ? (_jsxs("button", { type: "button", className: [
62
+ styles.thButton,
63
+ align === 'right' ? styles.thButtonRight : '',
64
+ align === 'center' ? styles.thButtonCenter : '',
65
+ ]
66
+ .filter(Boolean)
67
+ .join(' '), onClick: toggleSort, onKeyDown: e => {
68
+ if (shouldToggleOnKey(e.key)) {
69
+ e.preventDefault();
70
+ toggleSort();
71
+ }
72
+ }, children: [_jsx("span", { className: [
73
+ styles.thLabel,
74
+ align === 'right' ? styles.thLabelRight : '',
75
+ align === 'center' ? styles.thLabelCenter : '',
76
+ ]
77
+ .filter(Boolean)
78
+ .join(' '), children: getHeaderLabel(column.header) }), _jsxs("span", { className: styles.sortIndicator, "aria-hidden": "true", children: [active && sortDirection === 'asc' && _jsx(ArrowUp, {}), active && sortDirection === 'desc' && (_jsx(ArrowDown, { className: styles.descending })), !active && (_jsx(ArrowDown, { className: `${styles.descending} ${styles.inActiveSort}` }))] })] })) : (_jsx("span", { className: [
79
+ styles.thLabel,
80
+ align === 'right' ? styles.thLabelRight : '',
81
+ align === 'center' ? styles.thLabelCenter : '',
82
+ ]
83
+ .filter(Boolean)
84
+ .join(' '), children: getHeaderLabel(column.header) })) }) }), extraContent != null ? (_jsx("div", { className: styles.thOverlayExtras, children: extraContent })) : null] }, column.id));
85
+ })] }));
86
+ const loadingBodyEl = (_jsx("div", { className: styles.body, role: "rowgroup", children: Array.from({ length: take !== null && take !== void 0 ? take : 5 }).map((_, rowIndex) => (_jsxs("div", { className: styles.row, style: gridStyle, role: "row", children: [hasSelection ? (_jsx("div", { className: `${styles.cell} ${styles.selectionCell}`, role: "cell" })) : null, filteredColumns.map(column => {
87
+ var _a;
88
+ const dividerClass = column.divider === 'left'
89
+ ? styles.dividerLeft
90
+ : column.divider === 'right'
91
+ ? styles.dividerRight
92
+ : '';
93
+ return (_jsx("div", { className: [styles.cell, dividerClass].filter(Boolean).join(' '), role: "cell", "data-align": (_a = column.align) !== null && _a !== void 0 ? _a : 'left', "data-divider": column.divider, children: _jsx("div", { className: styles.cellContent, children: _jsx("div", { className: styles.cellValueEllipsis, children: _jsx(SkeletonLoaderItem, { height: 20, width: "100%" }) }) }) }, column.id));
94
+ })] }, `loading-row-${rowIndex}`))) }));
95
+ const dataBodyEl = (_jsx("div", { className: `${styles.body} ${striped ? styles.striped : ''}`, role: "rowgroup", children: data.map(row => {
96
+ const rowSeverity = getRowSeverity === null || getRowSeverity === void 0 ? void 0 : getRowSeverity(row);
97
+ const rowId = row[dataKey];
98
+ const isSelected = Boolean(selectedRows === null || selectedRows === void 0 ? void 0 : selectedRows.has(rowId));
99
+ return (_jsxs("div", { className: [
100
+ styles.row,
101
+ onRowClick ? styles.clickableRow : '',
102
+ isSelected ? styles.selectedRow : '',
103
+ rowSeverity ? styles.severity : '',
104
+ ]
105
+ .filter(Boolean)
106
+ .join(' '), style: {
107
+ ...gridStyle,
108
+ ['--row-severity-color']: rowSeverity
109
+ ? SeverityBgColor[rowSeverity]
110
+ : undefined,
111
+ }, role: "row", tabIndex: onRowClick ? 0 : -1, onKeyDown: e => {
112
+ if (!onRowClick)
113
+ return;
114
+ if (shouldToggleOnKey(e.key)) {
115
+ e.preventDefault();
116
+ onRowClick(row);
117
+ }
118
+ }, onClick: e => {
119
+ const canSelect = Boolean(selectedRows && onRowSelect && dataKey);
120
+ if (isModifierClick(e) && canSelect) {
121
+ e.preventDefault();
122
+ e.stopPropagation();
123
+ onRowSelect(rowId, !selectedRows.has(rowId));
124
+ return;
125
+ }
126
+ onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row);
127
+ }, children: [hasSelection && (_jsx("div", { className: `${styles.cell} ${styles.selectionCell}`, role: "cell", children: _jsx(Checkbox, { variant: "primary", checked: selectedRows.has(rowId), size: "sm", onChange: (checked, e) => {
128
+ e.stopPropagation();
129
+ onRowSelect === null || onRowSelect === void 0 ? void 0 : onRowSelect(rowId, checked);
130
+ } }) })), filteredColumns.map(column => {
131
+ var _a;
132
+ const dividerClass = column.divider === 'left'
133
+ ? styles.dividerLeft
134
+ : column.divider === 'right'
135
+ ? styles.dividerRight
136
+ : '';
137
+ const allowWrap = shouldAllowWrap(column.allowWrap, isSelected, viewMode);
138
+ const cellValue = getCellDisplayValue(row, column);
139
+ return (_jsx("div", { className: [
140
+ styles.cell,
141
+ allowWrap ? styles.allowWrap : styles.nowrap,
142
+ dividerClass,
143
+ ]
144
+ .filter(Boolean)
145
+ .join(' '), role: "cell", "data-align": (_a = column.align) !== null && _a !== void 0 ? _a : 'left', "data-divider": column.divider, children: _jsx("div", { className: styles.cellContent, children: allowWrap ? (cellValue) : (_jsx("div", { className: styles.cellValueEllipsis, children: cellValue })) }) }, column.id));
146
+ })] }, `gridRow-${String(rowId)}`));
147
+ }) }));
148
+ const bodyContent = loading && !data.length ? loadingBodyEl : dataBodyEl;
149
+ const tableClassName = [
150
+ styles.tableRoot,
151
+ styles[variant],
152
+ styles[size],
153
+ getRowSeverity ? styles.severityTable : '',
154
+ ]
155
+ .filter(Boolean)
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) })] }));
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;
80
159
  if (fillViewport) {
81
- return (_jsxs("div", { style: {
82
- display: 'flex',
83
- flexDirection: 'column',
84
- gap: '20px',
85
- flexFlow: paginationPlacement === 'top' ? 'column-reverse' : 'column',
86
- position: 'relative',
87
- }, children: [_jsx("div", { ref: scrollRef, style: viewportStyle, className: styles.tableScroll, children: tableEl }), onPageChange && data.length > 0 && (_jsx(Pagination, { itemsCount: totalItemsCount, take: take, skip: skip, onPageChange: handlePageChange, showFirstLast: showFirstLast }))] }));
160
+ return (_jsxs("div", { className: styles.fillViewportRoot, style: {
161
+ flexDirection: paginationPlacement === 'top' ? 'column-reverse' : 'column',
162
+ }, children: [toolbar ? _jsx("div", { className: styles.toolbarSlot, children: toolbar }) : null, _jsx("div", { className: styles.tableViewport, children: tableShell }), paginationEl] }));
88
163
  }
89
164
  return (_jsxs("div", { className: "dbc-flex dbc-flex-column dbc-gap-md", style: {
90
165
  flexFlow: paginationPlacement === 'top' ? 'column-reverse' : 'column',
91
166
  position: 'relative',
92
- }, children: [tableEl, onPageChange && data.length > 0 && (_jsx(Pagination, { itemsCount: totalItemsCount, take: take, skip: skip, onPageChange: handlePageChange }))] }));
167
+ }, children: [toolbar ? _jsx("div", { className: styles.toolbarSlot, children: toolbar }) : null, tableShell, paginationEl] }));
93
168
  }