@dbcdk/react-components 0.0.12 → 0.0.14

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 (76) hide show
  1. package/dist/components/accordion/Accordion.d.ts +2 -2
  2. package/dist/components/accordion/Accordion.js +34 -41
  3. package/dist/components/accordion/Accordion.module.css +13 -72
  4. package/dist/components/accordion/components/AccordionRow.d.ts +10 -0
  5. package/dist/components/accordion/components/AccordionRow.js +51 -0
  6. package/dist/components/accordion/components/AccordionRow.module.css +82 -0
  7. package/dist/components/breadcrumbs/Breadcrumbs.module.css +0 -1
  8. package/dist/components/button/Button.module.css +7 -7
  9. package/dist/components/card/Card.d.ts +9 -18
  10. package/dist/components/card/Card.js +34 -23
  11. package/dist/components/card/Card.module.css +22 -87
  12. package/dist/components/card/components/CardMeta.d.ts +15 -0
  13. package/dist/components/card/components/CardMeta.js +20 -0
  14. package/dist/components/card/components/CardMeta.module.css +51 -0
  15. package/dist/components/card-container/CardContainer.js +1 -1
  16. package/dist/components/card-container/CardContainer.module.css +3 -1
  17. package/dist/components/chip/Chip.module.css +7 -2
  18. package/dist/components/datetime-picker/DateTimePicker.d.ts +33 -8
  19. package/dist/components/datetime-picker/DateTimePicker.js +119 -78
  20. package/dist/components/datetime-picker/DateTimePicker.module.css +2 -0
  21. package/dist/components/datetime-picker/dateTimeHelpers.d.ts +15 -3
  22. package/dist/components/datetime-picker/dateTimeHelpers.js +137 -23
  23. package/dist/components/filter-field/FilterField.js +21 -6
  24. package/dist/components/filter-field/FilterField.module.css +5 -5
  25. package/dist/components/forms/form-select/FormSelect.d.ts +35 -0
  26. package/dist/components/forms/form-select/FormSelect.js +86 -0
  27. package/dist/components/forms/form-select/FormSelect.module.css +236 -0
  28. package/dist/components/forms/input/Input.d.ts +0 -3
  29. package/dist/components/forms/input/Input.js +0 -3
  30. package/dist/components/forms/input/Input.module.css +7 -7
  31. package/dist/components/forms/radio-buttons/RadioButtons.module.css +1 -0
  32. package/dist/components/forms/select/Select.js +55 -16
  33. package/dist/components/interval-select/IntervalSelect.d.ts +9 -2
  34. package/dist/components/interval-select/IntervalSelect.js +21 -6
  35. package/dist/components/menu/Menu.d.ts +11 -14
  36. package/dist/components/menu/Menu.js +18 -33
  37. package/dist/components/menu/Menu.module.css +2 -2
  38. package/dist/components/overlay/modal/Modal.module.css +2 -1
  39. package/dist/components/overlay/modal/provider/ModalProvider.js +1 -3
  40. package/dist/components/overlay/side-panel/SidePanel.js +1 -1
  41. package/dist/components/overlay/side-panel/SidePanel.module.css +1 -1
  42. package/dist/components/page-layout/PageLayout.d.ts +16 -4
  43. package/dist/components/page-layout/PageLayout.js +57 -28
  44. package/dist/components/page-layout/PageLayout.module.css +153 -33
  45. package/dist/components/popover/Popover.d.ts +17 -4
  46. package/dist/components/popover/Popover.js +147 -65
  47. package/dist/components/popover/Popover.module.css +5 -0
  48. package/dist/components/split-pane/SplitPane.d.ts +10 -24
  49. package/dist/components/split-pane/SplitPane.js +83 -54
  50. package/dist/components/split-pane/SplitPane.module.css +11 -6
  51. package/dist/components/split-pane/provider/SplitPaneContext.js +5 -11
  52. package/dist/components/sticky-footer-layout/StickyFooterLayout.d.ts +3 -8
  53. package/dist/components/sticky-footer-layout/StickyFooterLayout.js +57 -20
  54. package/dist/components/table/Table.d.ts +3 -8
  55. package/dist/components/table/Table.js +37 -76
  56. package/dist/components/table/Table.module.css +45 -42
  57. package/dist/components/table/{tanstack.d.ts → TanstackTable.d.ts} +5 -12
  58. package/dist/components/table/TanstackTable.js +84 -0
  59. package/dist/components/table/components/column-resizer/ColumnResizer.js +1 -1
  60. package/dist/components/table/components/column-resizer/ColumnResizer.module.css +17 -7
  61. package/dist/components/table/table.utils.d.ts +17 -0
  62. package/dist/components/table/table.utils.js +61 -0
  63. package/dist/components/table/tanstackTable.utils.d.ts +22 -0
  64. package/dist/components/table/tanstackTable.utils.js +104 -0
  65. package/dist/components/tabs/Tabs.d.ts +35 -12
  66. package/dist/components/tabs/Tabs.js +114 -26
  67. package/dist/components/tabs/Tabs.module.css +158 -71
  68. package/dist/index.d.ts +1 -1
  69. package/dist/index.js +1 -1
  70. package/dist/src/styles/styles.css +0 -1
  71. package/dist/styles/styles.css +0 -1
  72. package/dist/styles/themes/dbc/base.css +136 -0
  73. package/dist/styles/themes/dbc/dark.css +39 -202
  74. package/dist/styles/themes/dbc/light.css +17 -174
  75. package/package.json +4 -4
  76. package/dist/components/table/tanstack.js +0 -214
@@ -1,3 +1,5 @@
1
+ /* Table.module.css (updated) */
2
+
1
3
  /* =========================
2
4
  Base table
3
5
  ========================= */
@@ -11,6 +13,7 @@
11
13
  font-size: var(--font-size-sm);
12
14
  color: var(--color-fg-default);
13
15
  background: var(--color-bg-surface);
16
+ table-layout: auto;
14
17
  }
15
18
 
16
19
  .tableScroll {
@@ -26,7 +29,7 @@
26
29
 
27
30
  .table thead {
28
31
  position: sticky;
29
- inset-block-start: 0;
32
+ top: 0;
30
33
  z-index: 10;
31
34
  background-color: var(--color-bg-surface);
32
35
  }
@@ -62,7 +65,6 @@
62
65
 
63
66
  /* Width control */
64
67
  min-width: 0;
65
- max-width: var(--card-label-width);
66
68
  }
67
69
 
68
70
  /* Small variant: header padding */
@@ -70,28 +72,56 @@
70
72
  padding-inline: var(--spacing-md);
71
73
  }
72
74
 
73
- /* Sortable header behavior */
74
- .th.sortable {
75
+ /* Header layout */
76
+ .th > .thInner {
77
+ display: flex;
78
+ align-items: center;
79
+ gap: var(--spacing-xxs);
80
+ inline-size: 100%;
81
+ }
82
+
83
+ /* Actual interactive control for sorting */
84
+ .thButton {
85
+ all: unset;
86
+ display: inline-flex;
87
+ align-items: center;
88
+ gap: var(--spacing-xxs);
89
+ inline-size: 100%;
90
+
75
91
  cursor: pointer;
76
92
  user-select: none;
77
- transition:
78
- background-color var(--transition-fast) var(--ease-standard),
79
- color var(--transition-fast) var(--ease-standard);
93
+
94
+ /* make it feel like a button */
95
+ border-radius: var(--border-radius-default);
96
+ padding-block: 2px;
97
+ padding-inline: 2px;
80
98
  }
81
99
 
82
- .th.sortable:hover,
83
- th.sortable:hover {
100
+ .thButton:hover {
84
101
  background-color: var(--color-bg-contextual);
85
102
  }
86
103
 
87
- .th.sortable:focus-visible,
88
- th.sortable:focus-visible {
104
+ .thButton:focus-visible {
89
105
  outline: none;
90
106
  box-shadow: var(--focus-ring);
91
107
  }
92
108
 
109
+ .thLabel {
110
+ overflow: hidden;
111
+ text-overflow: ellipsis;
112
+ white-space: nowrap;
113
+ flex-grow: 1;
114
+ }
115
+
116
+ .thExtras {
117
+ margin-inline-start: auto;
118
+ display: inline-flex;
119
+ align-items: center;
120
+ }
121
+
93
122
  .inActiveSort {
94
123
  color: var(--color-fg-subtle);
124
+ opacity: 0.4;
95
125
  }
96
126
 
97
127
  .sortIndicator {
@@ -103,17 +133,6 @@ th.sortable:focus-visible {
103
133
  block-size: var(--icon-size-sm);
104
134
  }
105
135
 
106
- .th > .thInner {
107
- display: inline-block;
108
- }
109
-
110
- .th > .thInner > span {
111
- display: inline-flex;
112
- align-items: center;
113
- gap: var(--spacing-xxs);
114
- inline-size: 100%;
115
- }
116
-
117
136
  /* =========================
118
137
  Body + cells
119
138
  ========================= */
@@ -150,37 +169,24 @@ th.sortable:focus-visible {
150
169
  Selection column
151
170
  ========================= */
152
171
 
153
- /*
154
- Default (no severity rails):
155
- Remove ALL inline padding for selection/checkbox cells in both header + body.
156
-
157
- We deliberately use padding-inline (shorthand) so it reliably beats other
158
- padding-inline shorthands (like .table.sm .tBody tr td).
159
- */
160
-
161
- /* Body selection cells (covers td with .selectionCell even if markup differs) */
162
172
  .tBody tr td.selectionCell,
163
173
  .table .tBody tr td.selectionCell,
164
174
  .table td.selectionCell {
165
175
  padding-inline: var(--spacing-xxs);
166
176
  }
167
177
 
168
- /* Header selection cells:
169
- - covers your .th class
170
- - AND real <th> elements that might not have the .th class */
171
178
  .table .th.selectionCell,
172
179
  .table th.selectionCell,
173
180
  th.selectionCell {
174
- padding-inline: var(--spacing-xxs);
181
+ width: 34px !important;
175
182
  }
176
183
 
177
- /* Override the .table.sm .tBody tr td padding-inline (must be as-specific or more) */
184
+ /* Override the .table.sm .tBody tr td padding-inline */
178
185
  .table.sm .tBody tr td.selectionCell,
179
186
  .table.table.sm .tBody tr td.selectionCell {
180
187
  padding-inline: var(--spacing-xxs);
181
188
  }
182
189
 
183
- /* If severity rails are enabled, reserve a left gutter (still no right padding) */
184
190
  .table.severityTable .tBody tr td.selectionCell,
185
191
  .table.severityTable td.selectionCell,
186
192
  .table.severityTable .th.selectionCell,
@@ -189,7 +195,6 @@ th.selectionCell {
189
195
  padding-inline-start: 14px;
190
196
  }
191
197
 
192
- /* Ensure severityTable also wins in sm */
193
198
  .table.sm.severityTable .tBody tr td.selectionCell,
194
199
  .table.table.sm.severityTable .tBody tr td.selectionCell,
195
200
  .table.sm.severityTable .th.selectionCell,
@@ -227,8 +232,8 @@ th.selectionCell {
227
232
  background-color: var(--color-bg-surface-subtle);
228
233
  }
229
234
 
230
- /* Focus ring */
231
- .table .tbody tr:focus-within {
235
+ /* Focus ring (fix selector: .tBody, not .tbody) */
236
+ .table .tBody tr:focus-within {
232
237
  outline: none;
233
238
  box-shadow:
234
239
  inset 2px 0 0 var(--color-brand),
@@ -272,7 +277,6 @@ th.selectionCell {
272
277
  position: relative;
273
278
  }
274
279
 
275
- /* Only render the rail when the table actually uses severity rails */
276
280
  .table.severityTable .tBody tr.severity td:first-child::before {
277
281
  content: '';
278
282
  position: absolute;
@@ -288,7 +292,6 @@ th.selectionCell {
288
292
  z-index: 0;
289
293
  }
290
294
 
291
- /* keep checkbox/content above the rail */
292
295
  .table.severityTable .tBody tr.severity td:first-child > * {
293
296
  position: relative;
294
297
  z-index: 1;
@@ -1,4 +1,4 @@
1
- import { type ColumnDef } from '@tanstack/react-table';
1
+ import { type ColumnDef, type SortingState } from '@tanstack/react-table';
2
2
  import * as React from 'react';
3
3
  import { type TableProps, type TableVariant } from './Table';
4
4
  import { ViewMode } from '../../hooks/useTableSettings';
@@ -6,19 +6,12 @@ type Filterable<T> = Array<keyof T>;
6
6
  export type TanstackTableProps<T extends Record<string, any>> = Omit<TableProps<T>, 'columns' | 'onSortChange' | 'sortById' | 'sortDirection' | 'headerBelowRow' | 'headerExtras' | 'columnStyles' | 'toolbar'> & {
7
7
  columns: ReadonlyArray<ColumnDef<T, any>>;
8
8
  filterable?: Filterable<T>;
9
- onSortingChange?: (sortBy: string | number | symbol | null, direction: 'asc' | 'desc' | null) => void;
10
- initialSortBy?: string;
11
- initialSortDirection?: 'asc' | 'desc';
9
+ sorting?: SortingState;
10
+ manualSorting?: boolean;
11
+ onSortingChange?: (next: SortingState) => void;
12
+ optimisticSortingUi?: boolean;
12
13
  variant?: TableVariant;
13
14
  viewMode?: ViewMode;
14
- /**
15
- * TanStack-agnostic column visibility input.
16
- *
17
- * If provided, this list is the single source of truth for which columns are visible.
18
- * If not provided (or empty), defaults are derived from ColumnDef meta.hidden.
19
- *
20
- * NOTE: Passing [] is treated as "unset" and will fall back to defaults.
21
- */
22
15
  visibleColumnIds?: string[];
23
16
  };
24
17
  export declare function TanstackTable<T extends Record<string, any>>(props: TanstackTableProps<T>): React.ReactNode;
@@ -0,0 +1,84 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useReactTable, getCoreRowModel, getSortedRowModel, getFilteredRowModel, } from '@tanstack/react-table';
4
+ import * as React from 'react';
5
+ import ColumnResizer from './components/column-resizer/ColumnResizer';
6
+ import { Table } from './Table';
7
+ import { buildColumnVisibilityFromVisibleIds, mapDefsToColumnItems, sortingEqual, getSortPropsFromSorting, buildColumnStyles, columnItemsToIdSet, } from './tanstackTable.utils';
8
+ export function TanstackTable(props) {
9
+ const { data, dataKey, columns, filterable = [], sorting: controlledSorting, onSortingChange, optimisticSortingUi = true, visibleColumnIds, manualSorting, ...tableProps } = props;
10
+ const isControlledSorting = controlledSorting != null;
11
+ const [uiSorting, setUiSorting] = React.useState(controlledSorting !== null && controlledSorting !== void 0 ? controlledSorting : []);
12
+ React.useEffect(() => {
13
+ if (!isControlledSorting)
14
+ return;
15
+ if (sortingEqual(uiSorting, controlledSorting))
16
+ return;
17
+ setUiSorting(controlledSorting);
18
+ }, [isControlledSorting, controlledSorting, uiSorting]);
19
+ const columnVisibility = React.useMemo(() => buildColumnVisibilityFromVisibleIds(columns, visibleColumnIds), [columns, visibleColumnIds]);
20
+ const [columnFilters, setColumnFilters] = React.useState([]);
21
+ const [columnSizing, setColumnSizing] = React.useState({});
22
+ const table = useReactTable({
23
+ data,
24
+ columns: columns,
25
+ state: {
26
+ sorting: uiSorting,
27
+ columnFilters,
28
+ columnSizing,
29
+ columnVisibility,
30
+ },
31
+ onSortingChange: updater => {
32
+ const next = typeof updater === 'function' ? updater(uiSorting) : updater;
33
+ if (optimisticSortingUi)
34
+ setUiSorting(next);
35
+ onSortingChange === null || onSortingChange === void 0 ? void 0 : onSortingChange(next);
36
+ },
37
+ onColumnFiltersChange: setColumnFilters,
38
+ onColumnSizingChange: setColumnSizing,
39
+ getCoreRowModel: getCoreRowModel(),
40
+ getSortedRowModel: getSortedRowModel(),
41
+ getFilteredRowModel: getFilteredRowModel(),
42
+ manualSorting: manualSorting !== null && manualSorting !== void 0 ? manualSorting : false,
43
+ enableColumnResizing: true,
44
+ columnResizeMode: 'onChange',
45
+ defaultColumn: {
46
+ enableResizing: true,
47
+ minSize: 80,
48
+ size: 180,
49
+ maxSize: 300,
50
+ },
51
+ });
52
+ const columnItems = React.useMemo(() => mapDefsToColumnItems(columns, columnVisibility), [columns, columnVisibility]);
53
+ const allowedIds = React.useMemo(() => columnItemsToIdSet(columnItems), [columnItems]);
54
+ const visibleData = table.getRowModel().rows.map(r => r.original);
55
+ const { sortById, sortDirection } = getSortPropsFromSorting(uiSorting);
56
+ const columnStyles = React.useMemo(() => {
57
+ const leafCols = table.getAllLeafColumns();
58
+ return buildColumnStyles(leafCols, allowedIds, { minWidth: 80, maxWidth: 800 });
59
+ }, [table, columnSizing, allowedIds]);
60
+ const handleSortChange = React.useCallback((column, direction) => {
61
+ // Translate Table's direction -> TanStack SortingState
62
+ const next = direction == null ? [] : [{ id: column.id, desc: direction === 'desc' }];
63
+ // Mirror TanStack's onSortingChange behavior
64
+ if (optimisticSortingUi)
65
+ setUiSorting(next);
66
+ onSortingChange === null || onSortingChange === void 0 ? void 0 : onSortingChange(next);
67
+ // If you are doing server-side sorting, you likely also want:
68
+ // table.resetPageIndex?.() or external pagination reset (depends on your setup)
69
+ }, [optimisticSortingUi, onSortingChange]);
70
+ const headerExtras = React.useCallback(({ index }) => {
71
+ var _a, _b, _c, _d;
72
+ const headerGroups = table.getHeaderGroups();
73
+ const leafHeaders = headerGroups.length > 0 ? headerGroups[headerGroups.length - 1].headers : [];
74
+ const header = leafHeaders[index];
75
+ if (!header)
76
+ return null;
77
+ const canResize = (_c = (_b = (_a = header.column).getCanResize) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : false;
78
+ const handler = (_d = header.getResizeHandler) === null || _d === void 0 ? void 0 : _d.call(header);
79
+ if (!canResize || !handler)
80
+ return null;
81
+ return _jsx(ColumnResizer, { id: header.column.id, handler: handler });
82
+ }, [table]);
83
+ return (_jsx(Table, { ...tableProps, onSortChange: handleSortChange, dataKey: dataKey, data: visibleData, columns: columnItems, sortById: sortById, sortDirection: sortDirection, columnStyles: columnStyles, headerExtras: headerExtras }));
84
+ }
@@ -1,5 +1,5 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import styles from './ColumnResizer.module.css';
4
- const ColumnResizer = ({ id, handler }) => (_jsx("span", { className: styles.resizer, onMouseDown: handler, onTouchStart: handler, role: "separator", "aria-label": `Resize ${id}` }));
4
+ const ColumnResizer = ({ id, handler }) => (_jsx("span", { className: styles.resizer, "data-resizer": "true", onMouseDown: handler, onTouchStart: handler, role: "separator", "aria-orientation": "vertical", "aria-label": `Resize ${id}` }));
5
5
  export default ColumnResizer;
@@ -1,13 +1,23 @@
1
1
  .resizer {
2
- display: inline-block;
3
- width: 1px;
4
- background-color: var(--opac-bg-default);
5
- height: 60%;
6
2
  position: absolute;
7
- right: 0;
8
- top: 50%;
9
- transform: translateY(-50%);
3
+ right: -6px; /* extend hit area into both columns */
4
+ top: 0;
5
+ height: 100%;
6
+ width: 12px; /* big invisible hit area */
10
7
  cursor: col-resize;
11
8
  user-select: none;
12
9
  touch-action: none;
10
+ z-index: 20;
11
+ }
12
+
13
+ .resizer::after {
14
+ content: '';
15
+ position: absolute;
16
+ left: 50%;
17
+ transform: translateX(-50%);
18
+ width: 1px; /* visual thickness */
19
+ height: 60%;
20
+ top: 50%;
21
+ transform: translate(-50%, -50%);
22
+ background-color: var(--opac-bg-default);
13
23
  }
@@ -0,0 +1,17 @@
1
+ import type { CSSProperties, ReactNode } from 'react';
2
+ import type { ColumnItem } from './Table';
3
+ export type SortDirection = 'asc' | 'desc' | null;
4
+ export declare function getVisibleColumns<T>(columns: Array<ColumnItem<T>>): Array<ColumnItem<T>>;
5
+ export declare function getColumnStyle(columnId: string, columnStyles: Partial<Record<string, CSSProperties>> | undefined, alignment?: 'left' | 'right' | 'center', verticalAlignment?: 'top' | 'middle' | 'bottom'): CSSProperties;
6
+ export declare function getHeaderLabel(header: string | (() => ReactNode)): ReactNode;
7
+ export declare function isActiveSort(sortById: string | undefined, columnId: string): boolean;
8
+ export declare function getAriaSort(sortable: boolean | undefined, active: boolean, direction: SortDirection): 'ascending' | 'descending' | 'none';
9
+ export declare function getNextSortDirection(sortable: boolean | undefined, active: boolean, currentDirection: SortDirection): SortDirection;
10
+ export declare function shouldToggleOnKey(key: string): boolean;
11
+ export declare function isModifierClick(e: {
12
+ metaKey?: boolean;
13
+ ctrlKey?: boolean;
14
+ }): boolean;
15
+ export declare function shouldAllowWrap(columnAllowWrap: boolean | undefined, isRowSelected: boolean, viewMode?: 'wrapped' | string): boolean;
16
+ export declare function getCellDisplayValue<T extends Record<string, any>>(row: T, column: ColumnItem<T>): ReactNode;
17
+ export declare function getRowKey(rowId: string | number): string;
@@ -0,0 +1,61 @@
1
+ export function getVisibleColumns(columns) {
2
+ return columns.filter(c => !c.hidden);
3
+ }
4
+ export function getColumnStyle(columnId, columnStyles, alignment, verticalAlignment) {
5
+ var _a;
6
+ const baseStyle = columnStyles === null || columnStyles === void 0 ? void 0 : columnStyles[columnId];
7
+ return {
8
+ ...(baseStyle !== null && baseStyle !== void 0 ? baseStyle : {}),
9
+ ...(alignment === 'right' ? { fontVariantNumeric: 'tabular-nums' } : null),
10
+ verticalAlign: verticalAlignment !== null && verticalAlignment !== void 0 ? verticalAlignment : 'top',
11
+ textAlign: alignment !== null && alignment !== void 0 ? alignment : 'left',
12
+ minWidth: (_a = baseStyle === null || baseStyle === void 0 ? void 0 : baseStyle.minWidth) !== null && _a !== void 0 ? _a : 0,
13
+ };
14
+ }
15
+ export function getHeaderLabel(header) {
16
+ return typeof header === 'function' ? header() : header;
17
+ }
18
+ export function isActiveSort(sortById, columnId) {
19
+ return sortById === columnId;
20
+ }
21
+ export function getAriaSort(sortable, active, direction) {
22
+ if (!sortable)
23
+ return 'none';
24
+ if (!active)
25
+ return 'none';
26
+ return direction === 'asc' ? 'ascending' : 'descending';
27
+ }
28
+ export function getNextSortDirection(sortable, active, currentDirection) {
29
+ if (!sortable)
30
+ return null;
31
+ if (!active)
32
+ return 'asc';
33
+ if (currentDirection === 'asc')
34
+ return 'desc';
35
+ return null;
36
+ }
37
+ export function shouldToggleOnKey(key) {
38
+ return key === 'Enter' || key === ' ';
39
+ }
40
+ export function isModifierClick(e) {
41
+ return Boolean(e.metaKey || e.ctrlKey);
42
+ }
43
+ export function shouldAllowWrap(columnAllowWrap, isRowSelected, viewMode) {
44
+ return Boolean(columnAllowWrap || isRowSelected || viewMode === 'wrapped');
45
+ }
46
+ export function getCellDisplayValue(row, column) {
47
+ var _a;
48
+ const empty = (_a = column.emptyPlaceholder) !== null && _a !== void 0 ? _a : '';
49
+ if (column.render) {
50
+ const rendered = column.render(row);
51
+ return rendered || empty;
52
+ }
53
+ if (column.accessor) {
54
+ const value = row[column.accessor];
55
+ return value || empty;
56
+ }
57
+ return null;
58
+ }
59
+ export function getRowKey(rowId) {
60
+ return `tableRow-${String(rowId)}`;
61
+ }
@@ -0,0 +1,22 @@
1
+ import type { ColumnDef, SortingState, VisibilityState, Column } from '@tanstack/react-table';
2
+ import type { CSSProperties } from 'react';
3
+ import type { ColumnItem } from './Table';
4
+ type AnyRecord = Record<string, any>;
5
+ export declare function getColumnId<T>(def: ColumnDef<T, any>, index: number): string;
6
+ export declare function buildColumnVisibilityFromVisibleIds<T>(defs: ReadonlyArray<ColumnDef<T, any>>, visibleColumnIds?: string[]): VisibilityState;
7
+ export declare function mapDefsToColumnItems<T extends AnyRecord>(defs: ReadonlyArray<ColumnDef<T, any>>, columnVisibility: VisibilityState): ColumnItem<T>[];
8
+ export declare function sortingEqual(a: SortingState, b: SortingState): boolean;
9
+ export declare function getSortPropsFromSorting(sorting: SortingState): {
10
+ sortById?: string;
11
+ sortDirection: 'asc' | 'desc' | null;
12
+ };
13
+ /**
14
+ * Builds `columnStyles` where TanStack is source of truth.
15
+ * Keep this util pure by passing in the leaf columns and the set of allowed IDs.
16
+ */
17
+ export declare function buildColumnStyles(leafColumns: Array<Pick<Column<any, any>, 'id' | 'getSize' | 'columnDef'>>, allowedIds: Set<string>, defaults?: {
18
+ minWidth: number;
19
+ maxWidth: number;
20
+ }): Record<string, CSSProperties>;
21
+ export declare function columnItemsToIdSet<T>(items: Array<ColumnItem<T>>): Set<string>;
22
+ export {};
@@ -0,0 +1,104 @@
1
+ export function getColumnId(def, index) {
2
+ const d = def;
3
+ if (d.id != null && String(d.id).length)
4
+ return String(d.id);
5
+ if (d.accessorKey != null && String(d.accessorKey).length)
6
+ return String(d.accessorKey);
7
+ return `col_${index}`;
8
+ }
9
+ export function buildColumnVisibilityFromVisibleIds(defs, visibleColumnIds) {
10
+ if (!(visibleColumnIds === null || visibleColumnIds === void 0 ? void 0 : visibleColumnIds.length))
11
+ return {};
12
+ const visible = new Set(visibleColumnIds);
13
+ const next = {};
14
+ defs.forEach((def, index) => {
15
+ const id = getColumnId(def, index);
16
+ next[id] = visible.has(id);
17
+ });
18
+ return next;
19
+ }
20
+ export function mapDefsToColumnItems(defs, columnVisibility) {
21
+ return defs.map((def, index) => {
22
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
23
+ const id = getColumnId(def, index);
24
+ const accessorKey = def.accessorKey;
25
+ const accessorFn = def.accessorFn;
26
+ const cell = def.cell;
27
+ let render;
28
+ if (typeof cell === 'function') {
29
+ render = (row) => cell({
30
+ row: { original: row },
31
+ getValue: () => accessorKey != null
32
+ ? row[accessorKey]
33
+ : accessorFn
34
+ ? accessorFn(row)
35
+ : undefined,
36
+ });
37
+ }
38
+ else if (accessorFn) {
39
+ render = (row) => accessorFn(row);
40
+ }
41
+ else if (accessorKey != null) {
42
+ render = (row) => row[accessorKey];
43
+ }
44
+ else {
45
+ render = () => null;
46
+ }
47
+ const isVisible = (_a = columnVisibility[id]) !== null && _a !== void 0 ? _a : true;
48
+ return {
49
+ id,
50
+ header: def.header,
51
+ accessor: accessorKey,
52
+ sortable: (_b = def.enableSorting) !== null && _b !== void 0 ? _b : !!accessorKey,
53
+ render,
54
+ hidden: !isVisible,
55
+ align: (_d = (_c = def.meta) === null || _c === void 0 ? void 0 : _c.align) !== null && _d !== void 0 ? _d : undefined,
56
+ verticalAlign: (_f = (_e = def.meta) === null || _e === void 0 ? void 0 : _e.verticalAlign) !== null && _f !== void 0 ? _f : undefined,
57
+ emptyPlaceholder: (_h = (_g = def.meta) === null || _g === void 0 ? void 0 : _g.emptyPlaceholder) !== null && _h !== void 0 ? _h : '-',
58
+ allowWrap: (_k = (_j = def.meta) === null || _j === void 0 ? void 0 : _j.allowWrap) !== null && _k !== void 0 ? _k : false,
59
+ severity: (_m = (_l = def.meta) === null || _l === void 0 ? void 0 : _l.severity) !== null && _m !== void 0 ? _m : undefined,
60
+ };
61
+ });
62
+ }
63
+ export function sortingEqual(a, b) {
64
+ const A = a === null || a === void 0 ? void 0 : a[0];
65
+ const B = b === null || b === void 0 ? void 0 : b[0];
66
+ if (!A && !B)
67
+ return true;
68
+ if (!A || !B)
69
+ return false;
70
+ return A.id === B.id && A.desc === B.desc;
71
+ }
72
+ export function getSortPropsFromSorting(sorting) {
73
+ const s = sorting === null || sorting === void 0 ? void 0 : sorting[0];
74
+ return {
75
+ sortById: s === null || s === void 0 ? void 0 : s.id,
76
+ sortDirection: s ? (s.desc ? 'desc' : 'asc') : null,
77
+ };
78
+ }
79
+ /**
80
+ * Builds `columnStyles` where TanStack is source of truth.
81
+ * Keep this util pure by passing in the leaf columns and the set of allowed IDs.
82
+ */
83
+ export function buildColumnStyles(leafColumns, allowedIds, defaults = { minWidth: 80, maxWidth: 800 }) {
84
+ var _a, _b;
85
+ const styles = {};
86
+ for (const c of leafColumns) {
87
+ const id = c.id;
88
+ if (!allowedIds.has(id))
89
+ continue;
90
+ const anyDef = c.columnDef;
91
+ styles[id] = {
92
+ width: c.getSize(),
93
+ minWidth: (_a = anyDef.minSize) !== null && _a !== void 0 ? _a : defaults.minWidth,
94
+ maxWidth: (_b = anyDef.maxSize) !== null && _b !== void 0 ? _b : defaults.maxWidth,
95
+ };
96
+ }
97
+ return styles;
98
+ }
99
+ export function columnItemsToIdSet(items) {
100
+ const s = new Set();
101
+ for (const c of items)
102
+ s.add(c.id);
103
+ return s;
104
+ }
@@ -1,22 +1,45 @@
1
- import React from 'react';
1
+ import type { JSX, ReactNode } from 'react';
2
+ export type TabId = string | number;
2
3
  export type TabItem = {
3
4
  header: string;
4
- id: string | number;
5
- headerIcon?: React.ReactNode;
6
- content: React.ReactNode;
5
+ id: TabId;
6
+ headerIcon?: ReactNode;
7
+ content: ReactNode;
7
8
  disabled?: boolean;
8
9
  hidden?: boolean;
9
10
  badge?: number;
10
11
  };
11
- interface TabsProps {
12
+ type TabsVariant = 'filled' | 'outlined';
13
+ export interface TabsProps {
12
14
  header?: string;
13
- variant: 'filled' | 'outlined';
15
+ variant: TabsVariant;
14
16
  panelStyle?: boolean;
15
- tabs: TabItem[];
16
- activeId?: number | string;
17
- onTabChange?: (index: number, tabItem: TabItem) => void;
18
- manuallySetActiveTab?: boolean;
19
- addition?: React.ReactNode;
17
+ /** Data-driven API */
18
+ tabs?: TabItem[];
19
+ /** Controlled */
20
+ value?: TabId;
21
+ /** Uncontrolled initial */
22
+ defaultValue?: TabId;
23
+ onValueChange?: (id: TabId, tab: TabItem, index: number) => void;
24
+ addition?: ReactNode;
25
+ /** Composition API */
26
+ children?: ReactNode;
27
+ }
28
+ export interface TabsItemProps {
29
+ id: TabId;
30
+ header: string;
31
+ headerIcon?: ReactNode;
32
+ disabled?: boolean;
33
+ hidden?: boolean;
34
+ badge?: number;
35
+ children?: ReactNode;
36
+ }
37
+ type SlotName = 'Item';
38
+ type TabsItemComponent = ((props: TabsItemProps) => JSX.Element) & {
39
+ __TABS_SLOT__?: SlotName;
40
+ };
41
+ export declare function Tabs({ header, variant, panelStyle, tabs, value, defaultValue, onValueChange, addition, children, }: TabsProps): JSX.Element;
42
+ export declare namespace Tabs {
43
+ var Item: TabsItemComponent;
20
44
  }
21
- export declare function Tabs({ variant, header, tabs, activeId, onTabChange, manuallySetActiveTab, addition, panelStyle, }: TabsProps): React.ReactNode;
22
45
  export {};