@dbcdk/react-components 0.0.194 → 0.0.196
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.
- package/README.md +78 -10
- package/dist/client.cjs +486 -614
- package/dist/client.d.ts +176 -102
- package/dist/client.js +102 -102
- package/dist/components/color-scheme-button/ColorSchemeButton.cjs +7 -4
- package/dist/components/color-scheme-button/ColorSchemeButton.d.ts +7 -3
- package/dist/components/color-scheme-button/ColorSchemeButton.js +7 -4
- package/dist/components/forms/text-area/Textarea.cjs +2 -1
- package/dist/components/forms/text-area/Textarea.d.ts +1 -0
- package/dist/components/forms/text-area/Textarea.js +2 -1
- package/dist/components/highlighted-text/HighlightedText.cjs +6 -3
- package/dist/components/highlighted-text/HighlightedText.js +7 -4
- package/dist/components/json-viewer/JsonNode.cjs +27 -67
- package/dist/components/json-viewer/JsonNode.d.ts +10 -0
- package/dist/components/json-viewer/JsonNode.js +28 -68
- package/dist/components/json-viewer/JsonRow.cjs +85 -0
- package/dist/components/json-viewer/JsonRow.d.ts +5 -0
- package/dist/components/json-viewer/JsonRow.js +79 -0
- package/dist/components/json-viewer/JsonViewer.cjs +36 -256
- package/dist/components/json-viewer/JsonViewer.js +37 -253
- package/dist/components/json-viewer/JsonViewerShell.cjs +208 -0
- package/dist/components/json-viewer/JsonViewerShell.d.ts +25 -0
- package/dist/components/json-viewer/JsonViewerShell.js +202 -0
- package/dist/components/json-viewer/TanstackJsonViewer.cjs +127 -0
- package/dist/components/json-viewer/TanstackJsonViewer.d.ts +17 -0
- package/dist/components/json-viewer/TanstackJsonViewer.js +121 -0
- package/dist/components/json-viewer/types.d.ts +27 -0
- package/dist/components/json-viewer/useJsonViewerState.cjs +111 -0
- package/dist/components/json-viewer/useJsonViewerState.d.ts +42 -0
- package/dist/components/json-viewer/useJsonViewerState.js +108 -0
- package/dist/components/json-viewer/utils.cjs +36 -0
- package/dist/components/json-viewer/utils.d.ts +21 -1
- package/dist/components/json-viewer/utils.js +35 -1
- package/dist/components/lightbox/Lightbox.cjs +2 -2
- package/dist/components/lightbox/Lightbox.d.ts +1 -1
- package/dist/components/lightbox/Lightbox.js +1 -1
- package/dist/components/line-viewer/LineViewer.cjs +2 -3
- package/dist/components/line-viewer/LineViewer.js +2 -3
- package/dist/components/line-viewer/tokenizeLineFormat.cjs +37 -17
- package/dist/components/line-viewer/tokenizeLineFormat.d.ts +5 -4
- package/dist/components/line-viewer/tokenizeLineFormat.js +37 -17
- package/dist/components/menu/Menu.cjs +3 -23
- package/dist/components/menu/Menu.js +3 -23
- package/dist/components/menu/Menu.module.css +4 -3
- package/dist/components/metric-tile/MetricTile.cjs +3 -2
- package/dist/components/metric-tile/MetricTile.js +2 -1
- package/dist/components/overlay/tooltip/Tooltip.cjs +7 -2
- package/dist/components/overlay/tooltip/Tooltip.d.ts +7 -1
- package/dist/components/overlay/tooltip/Tooltip.js +7 -2
- package/dist/components/overlay/tooltip/useTooltipTrigger.cjs +7 -1
- package/dist/components/overlay/tooltip/useTooltipTrigger.js +7 -1
- package/dist/components/page-layout/PageLayout.module.css +1 -1
- package/dist/components/table/Table.cjs +45 -16
- package/dist/components/table/Table.d.ts +1 -1
- package/dist/components/table/Table.js +47 -18
- package/dist/components/table/Table.module.css +135 -7
- package/dist/components/table/Table.types.d.ts +47 -1
- package/dist/components/table/TanstackTable.cjs +30 -2
- package/dist/components/table/TanstackTable.js +31 -3
- package/dist/components/table/components/TableBody.d.ts +1 -2
- package/dist/components/table/components/TableHeader.cjs +6 -4
- package/dist/components/table/components/TableHeader.d.ts +2 -1
- package/dist/components/table/components/TableHeader.js +6 -4
- package/dist/components/table/components/TableHeaderCell.cjs +5 -4
- package/dist/components/table/components/TableHeaderCell.d.ts +3 -1
- package/dist/components/table/components/TableHeaderCell.js +5 -4
- package/dist/components/table/components/TableRow.cjs +1 -1
- package/dist/components/table/components/TableRow.d.ts +1 -2
- package/dist/components/table/components/TableRow.js +1 -1
- package/dist/components/table/components/TableSkeletonBody.cjs +30 -0
- package/dist/components/table/components/TableSkeletonBody.d.ts +13 -0
- package/dist/components/table/components/TableSkeletonBody.js +24 -0
- package/dist/components/table/components/table-settings/TableHeaderSettings.cjs +28 -0
- package/dist/components/table/components/table-settings/TableHeaderSettings.d.ts +11 -0
- package/dist/components/table/components/table-settings/TableHeaderSettings.js +26 -0
- package/dist/components/table/components/table-settings/TableSettings.cjs +82 -32
- package/dist/components/table/components/table-settings/TableSettings.d.ts +14 -6
- package/dist/components/table/components/table-settings/TableSettings.js +84 -34
- package/dist/components/table/table.utils.cjs +2 -0
- package/dist/components/table/table.utils.d.ts +6 -0
- package/dist/components/table/table.utils.js +2 -1
- package/dist/components/table/tableSettings.utils.cjs +29 -0
- package/dist/components/table/tableSettings.utils.d.ts +9 -0
- package/dist/components/table/tableSettings.utils.js +24 -0
- package/dist/components/table/tanstackTable.utils.cjs +18 -0
- package/dist/components/table/tanstackTable.utils.js +19 -1
- package/dist/components/theme-button/ThemeButton.cjs +9 -4
- package/dist/components/theme-button/ThemeButton.d.ts +4 -2
- package/dist/components/theme-button/ThemeButton.js +9 -4
- package/dist/components/theme-script/ThemeScript.cjs +10 -4
- package/dist/components/theme-script/ThemeScript.d.ts +9 -1
- package/dist/components/theme-script/ThemeScript.js +10 -4
- package/dist/components/xml-viewer/XmlViewer.cjs +2 -3
- package/dist/components/xml-viewer/XmlViewer.js +2 -3
- package/dist/hooks/useColorScheme.cjs +18 -14
- package/dist/hooks/useColorScheme.d.ts +11 -1
- package/dist/hooks/useColorScheme.js +19 -15
- package/dist/hooks/useGetActiveTheme.cjs +4 -3
- package/dist/hooks/useGetActiveTheme.d.ts +7 -1
- package/dist/hooks/useGetActiveTheme.js +4 -3
- package/dist/hooks/useTableData.cjs +11 -7
- package/dist/hooks/useTableData.d.ts +8 -2
- package/dist/hooks/useTableData.js +11 -7
- package/dist/hooks/useTableSettings.cjs +25 -9
- package/dist/hooks/useTableSettings.d.ts +9 -6
- package/dist/hooks/useTableSettings.js +25 -9
- package/dist/hooks/useTheme.d.ts +6 -0
- package/dist/styles/styles.css +7 -3
- package/dist/styles/themes/dbc/colors.css +1 -1
- package/dist/styles.css +1 -476
- package/dist/tanstack-virtual.cjs +12 -0
- package/dist/tanstack-virtual.d.ts +1 -0
- package/dist/tanstack-virtual.js +1 -0
- package/package.json +13 -1
|
@@ -4,19 +4,23 @@
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var Pagination = require('../../components/pagination/Pagination');
|
|
7
|
-
var SkeletonLoader = require('../../components/skeleton-loader/SkeletonLoader');
|
|
8
7
|
var useViewportFill = require('../../hooks/useViewportFill');
|
|
9
8
|
var EmptyState = require('./components/empty-state/EmptyState');
|
|
9
|
+
var TableHeaderSettings = require('./components/table-settings/TableHeaderSettings');
|
|
10
10
|
var TableBody = require('./components/TableBody');
|
|
11
11
|
var TableHeader = require('./components/TableHeader');
|
|
12
|
+
var TableSkeletonBody = require('./components/TableSkeletonBody');
|
|
12
13
|
var table_classes = require('./table.classes');
|
|
13
14
|
var styles = require('./Table.module.css');
|
|
14
15
|
var table_utils = require('./table.utils');
|
|
16
|
+
var tableSettings_utils = require('./tableSettings.utils');
|
|
15
17
|
|
|
16
18
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
19
|
|
|
18
20
|
var styles__default = /*#__PURE__*/_interopDefault(styles);
|
|
19
21
|
|
|
22
|
+
const DEFAULT_SKELETON_ROWS = 10;
|
|
23
|
+
const MAX_SKELETON_ROWS = 20;
|
|
20
24
|
function Table({
|
|
21
25
|
data,
|
|
22
26
|
dataKey,
|
|
@@ -30,7 +34,8 @@ function Table({
|
|
|
30
34
|
emptyConfig,
|
|
31
35
|
variant = "primary",
|
|
32
36
|
size = "md",
|
|
33
|
-
viewMode,
|
|
37
|
+
viewMode: viewModeProp,
|
|
38
|
+
striped: stripedProp,
|
|
34
39
|
fillViewport = false,
|
|
35
40
|
fillViewportBottomOffset = 0,
|
|
36
41
|
containScrolling = true,
|
|
@@ -40,6 +45,9 @@ function Table({
|
|
|
40
45
|
measuringLayout = false,
|
|
41
46
|
toolbar,
|
|
42
47
|
headerExtras,
|
|
48
|
+
headerActions: headerActionsProp,
|
|
49
|
+
settings,
|
|
50
|
+
settingsOptions,
|
|
43
51
|
take,
|
|
44
52
|
skip,
|
|
45
53
|
totalItemsCount,
|
|
@@ -61,7 +69,22 @@ function Table({
|
|
|
61
69
|
onPageChange,
|
|
62
70
|
...rest
|
|
63
71
|
}) {
|
|
64
|
-
|
|
72
|
+
var _a;
|
|
73
|
+
const viewMode = viewModeProp != null ? viewModeProp : settings == null ? void 0 : settings.viewMode;
|
|
74
|
+
const striped = (_a = stripedProp != null ? stripedProp : settings == null ? void 0 : settings.striped) != null ? _a : false;
|
|
75
|
+
const settingsVisibleIds = settings == null ? void 0 : settings.visibleColumnIds;
|
|
76
|
+
const visibleColumns = react.useMemo(
|
|
77
|
+
() => (settingsVisibleIds == null ? void 0 : settingsVisibleIds.length) ? tableSettings_utils.filterColumnsBySettings(columns, settingsVisibleIds) : table_utils.getVisibleColumns(columns),
|
|
78
|
+
[columns, settingsVisibleIds]
|
|
79
|
+
);
|
|
80
|
+
const headerActions = headerActionsProp != null || settings ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.headerActions, children: [
|
|
81
|
+
headerActionsProp,
|
|
82
|
+
settings ? /* @__PURE__ */ jsxRuntime.jsx(TableHeaderSettings.TableHeaderSettings, { settings, options: settingsOptions, columns }) : null
|
|
83
|
+
] }) : null;
|
|
84
|
+
const toolbarContent = !showHeader && headerActions ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.toolbarWithHeaderActions, children: [
|
|
85
|
+
toolbar,
|
|
86
|
+
headerActions
|
|
87
|
+
] }) : toolbar;
|
|
65
88
|
const selectionInputName = react.useId();
|
|
66
89
|
const internalTableRootRef = react.useRef(null);
|
|
67
90
|
const tableRootRefWrapper = react.useRef(tableRootRef);
|
|
@@ -69,17 +92,14 @@ function Table({
|
|
|
69
92
|
const hasPagination = Boolean(onPageChange && (loading || data.length > 0));
|
|
70
93
|
const paginationRef = react.useRef(null);
|
|
71
94
|
const [paginationHeight, setPaginationHeight] = react.useState(0);
|
|
72
|
-
react.
|
|
95
|
+
react.useLayoutEffect(() => {
|
|
73
96
|
const element = paginationRef.current;
|
|
74
97
|
if (!element) return;
|
|
75
98
|
const measure = () => setPaginationHeight(element.getBoundingClientRect().height);
|
|
76
|
-
|
|
99
|
+
measure();
|
|
77
100
|
const observer = typeof ResizeObserver !== "undefined" ? new ResizeObserver(measure) : null;
|
|
78
101
|
observer == null ? void 0 : observer.observe(element);
|
|
79
|
-
return () =>
|
|
80
|
-
cancelAnimationFrame(frame);
|
|
81
|
-
observer == null ? void 0 : observer.disconnect();
|
|
82
|
-
};
|
|
102
|
+
return () => observer == null ? void 0 : observer.disconnect();
|
|
83
103
|
}, [hasPagination]);
|
|
84
104
|
const [expandedRows, setExpandedRows] = react.useState(() => /* @__PURE__ */ new Set());
|
|
85
105
|
const handleToggleRowExpand = react.useCallback((rowId) => {
|
|
@@ -99,7 +119,7 @@ function Table({
|
|
|
99
119
|
min: 0
|
|
100
120
|
});
|
|
101
121
|
const fillViewportActive = fillViewport && containScrolling;
|
|
102
|
-
const stickyTop = stickyHeader === "app-header" ? "var(--app-header-height, 60px)" : typeof stickyHeader === "number" ? `${stickyHeader}px` : void 0;
|
|
122
|
+
const stickyTop = stickyHeader === "app-header" ? "var(--app-header-height, 60px)" : typeof stickyHeader === "number" ? `${stickyHeader}px` : stickyHeader === void 0 && containScrolling ? "0px" : void 0;
|
|
103
123
|
const setTableRootRef = react.useCallback((node) => {
|
|
104
124
|
internalTableRootRef.current = node;
|
|
105
125
|
if (typeof tableRootRefWrapper.current === "function") {
|
|
@@ -167,16 +187,17 @@ function Table({
|
|
|
167
187
|
measuringLayout && styles__default.default.measuringLayout,
|
|
168
188
|
getRowSeverity && styles__default.default.severityTable
|
|
169
189
|
);
|
|
190
|
+
const tableElementClassName = table_classes.cx(styles__default.default.tableElement, striped && "dbc-table--striped");
|
|
170
191
|
const tableShell = /* @__PURE__ */ jsxRuntime.jsx("div", { ...rest, className: tableClassName, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
171
192
|
"div",
|
|
172
193
|
{
|
|
173
194
|
ref: setTableRootRef,
|
|
174
195
|
className: styles__default.default.tableScroll,
|
|
175
196
|
style: fillViewportActive ? viewportFillStyle : !containScrolling ? { overflow: "visible" } : void 0,
|
|
176
|
-
children: loading && !data.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.emptyStateSlot, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
197
|
+
children: !loading && !data.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.emptyStateSlot, children: /* @__PURE__ */ jsxRuntime.jsx(EmptyState.TableEmptyState, { config: emptyConfig }) }) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
177
198
|
"table",
|
|
178
199
|
{
|
|
179
|
-
className:
|
|
200
|
+
className: tableElementClassName,
|
|
180
201
|
"aria-rowcount": data.length,
|
|
181
202
|
"data-show-header": showHeader,
|
|
182
203
|
style: tableWidth != null ? { width: tableWidth } : void 0,
|
|
@@ -197,17 +218,25 @@ function Table({
|
|
|
197
218
|
columns: visibleColumns,
|
|
198
219
|
hasSelection,
|
|
199
220
|
selectionMode,
|
|
200
|
-
hasRowContextMenu: Boolean(getContextMenuItems),
|
|
221
|
+
hasRowContextMenu: Boolean(getContextMenuItems) || expandableRows,
|
|
201
222
|
allRowsSelected,
|
|
202
223
|
onSelectAllRows,
|
|
203
224
|
sortById,
|
|
204
225
|
sortDirection,
|
|
205
226
|
onSortChange,
|
|
206
227
|
headerExtras,
|
|
228
|
+
headerActions,
|
|
207
229
|
stickyTop
|
|
208
230
|
}
|
|
209
231
|
),
|
|
210
|
-
|
|
232
|
+
loading && !data.length ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
233
|
+
TableSkeletonBody.TableSkeletonBody,
|
|
234
|
+
{
|
|
235
|
+
columns: visibleColumns,
|
|
236
|
+
rows: Math.min(take != null ? take : DEFAULT_SKELETON_ROWS, MAX_SKELETON_ROWS),
|
|
237
|
+
hasSelection
|
|
238
|
+
}
|
|
239
|
+
) : bodyContent
|
|
211
240
|
]
|
|
212
241
|
}
|
|
213
242
|
)
|
|
@@ -223,7 +252,7 @@ function Table({
|
|
|
223
252
|
...!fillViewportActive && { blockSize: "auto", overflow: "visible" }
|
|
224
253
|
},
|
|
225
254
|
children: [
|
|
226
|
-
|
|
255
|
+
toolbarContent ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.toolbarSlot, children: toolbarContent }) : null,
|
|
227
256
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
228
257
|
"div",
|
|
229
258
|
{
|
|
@@ -246,7 +275,7 @@ function Table({
|
|
|
246
275
|
position: "relative"
|
|
247
276
|
},
|
|
248
277
|
children: [
|
|
249
|
-
|
|
278
|
+
toolbarContent ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.toolbarSlot, children: toolbarContent }) : null,
|
|
250
279
|
tableShell,
|
|
251
280
|
paginationEl
|
|
252
281
|
]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { JSX } from 'react';
|
|
2
2
|
import type { TableProps } from './Table.types';
|
|
3
|
-
export declare function Table<T extends Record<string, any>>({ data, dataKey, columns, selectedRows, selectionMode, allRowsSelected, sortById, sortDirection, loading, emptyConfig, variant, size, viewMode, fillViewport, fillViewportBottomOffset, containScrolling, stickyHeader, tableWidth, tableRootRef, measuringLayout, toolbar, headerExtras, take, skip, totalItemsCount, paginationPlacement, showFirstLast, showGoToPage, showPageSize, pageSizeOptions, showHeader, getRowSeverity, getContextMenuItems, showContextMenuOnHover, expandableRows, onRowClick, onRowMouseEnter, onRowSelect, onSelectAllRows, onSortChange, onPageChange, ...rest }: TableProps<T>): JSX.Element;
|
|
3
|
+
export declare function Table<T extends Record<string, any>>({ data, dataKey, columns, selectedRows, selectionMode, allRowsSelected, sortById, sortDirection, loading, emptyConfig, variant, size, viewMode: viewModeProp, striped: stripedProp, fillViewport, fillViewportBottomOffset, containScrolling, stickyHeader, tableWidth, tableRootRef, measuringLayout, toolbar, headerExtras, headerActions: headerActionsProp, settings, settingsOptions, take, skip, totalItemsCount, paginationPlacement, showFirstLast, showGoToPage, showPageSize, pageSizeOptions, showHeader, getRowSeverity, getContextMenuItems, showContextMenuOnHover, expandableRows, onRowClick, onRowMouseEnter, onRowSelect, onSelectAllRows, onSortChange, onPageChange, ...rest }: TableProps<T>): JSX.Element;
|
|
4
4
|
export type { ColumnItem } from './Table.types';
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import {
|
|
3
|
-
import { useMemo, useId, useRef, useState,
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useMemo, useId, useRef, useState, useLayoutEffect, useCallback } from 'react';
|
|
4
4
|
import { Pagination } from '../../components/pagination/Pagination';
|
|
5
|
-
import { SkeletonLoader } from '../../components/skeleton-loader/SkeletonLoader';
|
|
6
5
|
import { useViewportFill } from '../../hooks/useViewportFill';
|
|
7
6
|
import { TableEmptyState } from './components/empty-state/EmptyState';
|
|
7
|
+
import { TableHeaderSettings } from './components/table-settings/TableHeaderSettings';
|
|
8
8
|
import { TableBody } from './components/TableBody';
|
|
9
9
|
import { TableHeader } from './components/TableHeader';
|
|
10
|
+
import { TableSkeletonBody } from './components/TableSkeletonBody';
|
|
10
11
|
import { cx } from './table.classes';
|
|
11
12
|
import styles from './Table.module.css';
|
|
12
13
|
import { getVisibleColumns, SELECTION_COLUMN_PX } from './table.utils';
|
|
14
|
+
import { filterColumnsBySettings } from './tableSettings.utils';
|
|
13
15
|
|
|
16
|
+
const DEFAULT_SKELETON_ROWS = 10;
|
|
17
|
+
const MAX_SKELETON_ROWS = 20;
|
|
14
18
|
function Table({
|
|
15
19
|
data,
|
|
16
20
|
dataKey,
|
|
@@ -24,7 +28,8 @@ function Table({
|
|
|
24
28
|
emptyConfig,
|
|
25
29
|
variant = "primary",
|
|
26
30
|
size = "md",
|
|
27
|
-
viewMode,
|
|
31
|
+
viewMode: viewModeProp,
|
|
32
|
+
striped: stripedProp,
|
|
28
33
|
fillViewport = false,
|
|
29
34
|
fillViewportBottomOffset = 0,
|
|
30
35
|
containScrolling = true,
|
|
@@ -34,6 +39,9 @@ function Table({
|
|
|
34
39
|
measuringLayout = false,
|
|
35
40
|
toolbar,
|
|
36
41
|
headerExtras,
|
|
42
|
+
headerActions: headerActionsProp,
|
|
43
|
+
settings,
|
|
44
|
+
settingsOptions,
|
|
37
45
|
take,
|
|
38
46
|
skip,
|
|
39
47
|
totalItemsCount,
|
|
@@ -55,7 +63,22 @@ function Table({
|
|
|
55
63
|
onPageChange,
|
|
56
64
|
...rest
|
|
57
65
|
}) {
|
|
58
|
-
|
|
66
|
+
var _a;
|
|
67
|
+
const viewMode = viewModeProp != null ? viewModeProp : settings == null ? void 0 : settings.viewMode;
|
|
68
|
+
const striped = (_a = stripedProp != null ? stripedProp : settings == null ? void 0 : settings.striped) != null ? _a : false;
|
|
69
|
+
const settingsVisibleIds = settings == null ? void 0 : settings.visibleColumnIds;
|
|
70
|
+
const visibleColumns = useMemo(
|
|
71
|
+
() => (settingsVisibleIds == null ? void 0 : settingsVisibleIds.length) ? filterColumnsBySettings(columns, settingsVisibleIds) : getVisibleColumns(columns),
|
|
72
|
+
[columns, settingsVisibleIds]
|
|
73
|
+
);
|
|
74
|
+
const headerActions = headerActionsProp != null || settings ? /* @__PURE__ */ jsxs("div", { className: styles.headerActions, children: [
|
|
75
|
+
headerActionsProp,
|
|
76
|
+
settings ? /* @__PURE__ */ jsx(TableHeaderSettings, { settings, options: settingsOptions, columns }) : null
|
|
77
|
+
] }) : null;
|
|
78
|
+
const toolbarContent = !showHeader && headerActions ? /* @__PURE__ */ jsxs("div", { className: styles.toolbarWithHeaderActions, children: [
|
|
79
|
+
toolbar,
|
|
80
|
+
headerActions
|
|
81
|
+
] }) : toolbar;
|
|
59
82
|
const selectionInputName = useId();
|
|
60
83
|
const internalTableRootRef = useRef(null);
|
|
61
84
|
const tableRootRefWrapper = useRef(tableRootRef);
|
|
@@ -63,17 +86,14 @@ function Table({
|
|
|
63
86
|
const hasPagination = Boolean(onPageChange && (loading || data.length > 0));
|
|
64
87
|
const paginationRef = useRef(null);
|
|
65
88
|
const [paginationHeight, setPaginationHeight] = useState(0);
|
|
66
|
-
|
|
89
|
+
useLayoutEffect(() => {
|
|
67
90
|
const element = paginationRef.current;
|
|
68
91
|
if (!element) return;
|
|
69
92
|
const measure = () => setPaginationHeight(element.getBoundingClientRect().height);
|
|
70
|
-
|
|
93
|
+
measure();
|
|
71
94
|
const observer = typeof ResizeObserver !== "undefined" ? new ResizeObserver(measure) : null;
|
|
72
95
|
observer == null ? void 0 : observer.observe(element);
|
|
73
|
-
return () =>
|
|
74
|
-
cancelAnimationFrame(frame);
|
|
75
|
-
observer == null ? void 0 : observer.disconnect();
|
|
76
|
-
};
|
|
96
|
+
return () => observer == null ? void 0 : observer.disconnect();
|
|
77
97
|
}, [hasPagination]);
|
|
78
98
|
const [expandedRows, setExpandedRows] = useState(() => /* @__PURE__ */ new Set());
|
|
79
99
|
const handleToggleRowExpand = useCallback((rowId) => {
|
|
@@ -93,7 +113,7 @@ function Table({
|
|
|
93
113
|
min: 0
|
|
94
114
|
});
|
|
95
115
|
const fillViewportActive = fillViewport && containScrolling;
|
|
96
|
-
const stickyTop = stickyHeader === "app-header" ? "var(--app-header-height, 60px)" : typeof stickyHeader === "number" ? `${stickyHeader}px` : void 0;
|
|
116
|
+
const stickyTop = stickyHeader === "app-header" ? "var(--app-header-height, 60px)" : typeof stickyHeader === "number" ? `${stickyHeader}px` : stickyHeader === void 0 && containScrolling ? "0px" : void 0;
|
|
97
117
|
const setTableRootRef = useCallback((node) => {
|
|
98
118
|
internalTableRootRef.current = node;
|
|
99
119
|
if (typeof tableRootRefWrapper.current === "function") {
|
|
@@ -161,16 +181,17 @@ function Table({
|
|
|
161
181
|
measuringLayout && styles.measuringLayout,
|
|
162
182
|
getRowSeverity && styles.severityTable
|
|
163
183
|
);
|
|
184
|
+
const tableElementClassName = cx(styles.tableElement, striped && "dbc-table--striped");
|
|
164
185
|
const tableShell = /* @__PURE__ */ jsx("div", { ...rest, className: tableClassName, children: /* @__PURE__ */ jsx(
|
|
165
186
|
"div",
|
|
166
187
|
{
|
|
167
188
|
ref: setTableRootRef,
|
|
168
189
|
className: styles.tableScroll,
|
|
169
190
|
style: fillViewportActive ? viewportFillStyle : !containScrolling ? { overflow: "visible" } : void 0,
|
|
170
|
-
children: loading && !data.length ? /* @__PURE__ */ jsx("div", { className: styles.emptyStateSlot, children: /* @__PURE__ */ jsx(
|
|
191
|
+
children: !loading && !data.length ? /* @__PURE__ */ jsx("div", { className: styles.emptyStateSlot, children: /* @__PURE__ */ jsx(TableEmptyState, { config: emptyConfig }) }) : /* @__PURE__ */ jsxs(
|
|
171
192
|
"table",
|
|
172
193
|
{
|
|
173
|
-
className:
|
|
194
|
+
className: tableElementClassName,
|
|
174
195
|
"aria-rowcount": data.length,
|
|
175
196
|
"data-show-header": showHeader,
|
|
176
197
|
style: tableWidth != null ? { width: tableWidth } : void 0,
|
|
@@ -191,17 +212,25 @@ function Table({
|
|
|
191
212
|
columns: visibleColumns,
|
|
192
213
|
hasSelection,
|
|
193
214
|
selectionMode,
|
|
194
|
-
hasRowContextMenu: Boolean(getContextMenuItems),
|
|
215
|
+
hasRowContextMenu: Boolean(getContextMenuItems) || expandableRows,
|
|
195
216
|
allRowsSelected,
|
|
196
217
|
onSelectAllRows,
|
|
197
218
|
sortById,
|
|
198
219
|
sortDirection,
|
|
199
220
|
onSortChange,
|
|
200
221
|
headerExtras,
|
|
222
|
+
headerActions,
|
|
201
223
|
stickyTop
|
|
202
224
|
}
|
|
203
225
|
),
|
|
204
|
-
|
|
226
|
+
loading && !data.length ? /* @__PURE__ */ jsx(
|
|
227
|
+
TableSkeletonBody,
|
|
228
|
+
{
|
|
229
|
+
columns: visibleColumns,
|
|
230
|
+
rows: Math.min(take != null ? take : DEFAULT_SKELETON_ROWS, MAX_SKELETON_ROWS),
|
|
231
|
+
hasSelection
|
|
232
|
+
}
|
|
233
|
+
) : bodyContent
|
|
205
234
|
]
|
|
206
235
|
}
|
|
207
236
|
)
|
|
@@ -217,7 +246,7 @@ function Table({
|
|
|
217
246
|
...!fillViewportActive && { blockSize: "auto", overflow: "visible" }
|
|
218
247
|
},
|
|
219
248
|
children: [
|
|
220
|
-
|
|
249
|
+
toolbarContent ? /* @__PURE__ */ jsx("div", { className: styles.toolbarSlot, children: toolbarContent }) : null,
|
|
221
250
|
/* @__PURE__ */ jsx(
|
|
222
251
|
"div",
|
|
223
252
|
{
|
|
@@ -240,7 +269,7 @@ function Table({
|
|
|
240
269
|
position: "relative"
|
|
241
270
|
},
|
|
242
271
|
children: [
|
|
243
|
-
|
|
272
|
+
toolbarContent ? /* @__PURE__ */ jsx("div", { className: styles.toolbarSlot, children: toolbarContent }) : null,
|
|
244
273
|
tableShell,
|
|
245
274
|
paginationEl
|
|
246
275
|
]
|
|
@@ -58,7 +58,9 @@
|
|
|
58
58
|
--table-component-cell-fg: var(--table-cell-fg);
|
|
59
59
|
--table-component-cell-border: var(--table-border-subtle);
|
|
60
60
|
--table-component-divider: var(--table-divider);
|
|
61
|
-
|
|
61
|
+
/* Row actions button (component-size-sm) plus its inline-end offset. Keep in
|
|
62
|
+
sync with ROW_ACTIONS_RESERVE_PX in table.utils.ts. */
|
|
63
|
+
--table-row-actions-reserve-inline: calc(var(--component-size-sm) + var(--spacing-2xs));
|
|
62
64
|
|
|
63
65
|
display: flex;
|
|
64
66
|
flex-direction: column;
|
|
@@ -78,7 +80,7 @@
|
|
|
78
80
|
|
|
79
81
|
.embedded {
|
|
80
82
|
--table-component-header-bg: transparent;
|
|
81
|
-
--table-component-header-fg: var(--color-fg-
|
|
83
|
+
--table-component-header-fg: var(--color-fg-muted);
|
|
82
84
|
--table-component-header-font-weight: var(--font-weight-default);
|
|
83
85
|
--table-component-row-bg: transparent;
|
|
84
86
|
--table-component-row-bg-hover: var(--color-bg-contextual-subtle);
|
|
@@ -101,6 +103,9 @@
|
|
|
101
103
|
min-block-size: 0;
|
|
102
104
|
min-inline-size: 0;
|
|
103
105
|
overflow: auto;
|
|
106
|
+
/* Always reserve the scrollbar's space, so the column widths don't change
|
|
107
|
+
when the body starts or stops scrolling (e.g. skeleton rows vs. data). */
|
|
108
|
+
scrollbar-gutter: stable;
|
|
104
109
|
background: var(--table-component-row-bg);
|
|
105
110
|
-webkit-overflow-scrolling: touch;
|
|
106
111
|
}
|
|
@@ -450,6 +455,75 @@
|
|
|
450
455
|
pointer-events: auto;
|
|
451
456
|
}
|
|
452
457
|
|
|
458
|
+
/*
|
|
459
|
+
* Header actions (e.g. the settings trigger) sit at the inline end of the last
|
|
460
|
+
* header cell, lined up with the row-actions buttons below. Stacked above
|
|
461
|
+
* .thOverlayExtras so the column resizer doesn't swallow clicks on them.
|
|
462
|
+
*/
|
|
463
|
+
.thEndAction {
|
|
464
|
+
position: absolute;
|
|
465
|
+
inset-block-start: 50%;
|
|
466
|
+
inset-inline-end: var(--spacing-2xs);
|
|
467
|
+
transform: translateY(-50%);
|
|
468
|
+
display: inline-flex;
|
|
469
|
+
align-items: center;
|
|
470
|
+
z-index: 8;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
.headerActions {
|
|
474
|
+
display: inline-flex;
|
|
475
|
+
align-items: center;
|
|
476
|
+
gap: var(--spacing-2xs);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/*
|
|
480
|
+
* Keep header actions low-key: the settings trigger uses the same colour as
|
|
481
|
+
* the header's sort arrows and a compact square button, and header actions are
|
|
482
|
+
* only shown while the table is hovered - like the row-actions buttons. They
|
|
483
|
+
* stay visible while focused or while their menu is open, and always on
|
|
484
|
+
* devices without hover. They remain clickable while faded out.
|
|
485
|
+
* `button[data-…]` outranks Button's own `.button.inline` colour rule.
|
|
486
|
+
*/
|
|
487
|
+
.thEndAction button[data-table-settings-trigger] {
|
|
488
|
+
color: var(--color-disabled-fg);
|
|
489
|
+
inline-size: var(--component-size-sm);
|
|
490
|
+
min-inline-size: var(--component-size-sm);
|
|
491
|
+
padding: 0;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
.thEndAction button[data-table-settings-trigger]:hover,
|
|
495
|
+
.thEndAction button[data-table-settings-trigger][aria-expanded='true'] {
|
|
496
|
+
color: var(--color-fg-subtle);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
.thEndAction {
|
|
500
|
+
opacity: 0;
|
|
501
|
+
transition: opacity 0.15s;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
.tableElement:hover .thEndAction,
|
|
505
|
+
.thEndAction:focus-within,
|
|
506
|
+
.thEndAction:has([aria-expanded='true']) {
|
|
507
|
+
opacity: 1;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
@media (hover: none) {
|
|
511
|
+
.thEndAction {
|
|
512
|
+
opacity: 1;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
.toolbarWithHeaderActions {
|
|
517
|
+
display: flex;
|
|
518
|
+
align-items: center;
|
|
519
|
+
justify-content: space-between;
|
|
520
|
+
gap: var(--spacing-sm);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
.toolbarWithHeaderActions > .headerActions {
|
|
524
|
+
margin-inline-start: auto;
|
|
525
|
+
}
|
|
526
|
+
|
|
453
527
|
.sortIndicator {
|
|
454
528
|
display: inline-flex;
|
|
455
529
|
flex: 0 0 auto;
|
|
@@ -475,6 +549,22 @@
|
|
|
475
549
|
color: var(--color-disabled-fg);
|
|
476
550
|
}
|
|
477
551
|
|
|
552
|
+
/* Loading placeholder: a full text line (the cell's line-height) with the bar
|
|
553
|
+
centred in it, matching the height of a real single-line row. */
|
|
554
|
+
.skeletonCellContent {
|
|
555
|
+
display: flex;
|
|
556
|
+
align-items: center;
|
|
557
|
+
block-size: 1lh;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/* Table rows (incl. striped ones) need stronger bars than the default
|
|
561
|
+
skeleton to be visible. [role='status'] outranks .skeletonLoader, which
|
|
562
|
+
sets these variables on the item itself. */
|
|
563
|
+
.skeletonCellContent > [role='status'] {
|
|
564
|
+
--skeleton-base: var(--opac-bg-dark);
|
|
565
|
+
--skeleton-sheen: var(--opac-bg-default);
|
|
566
|
+
}
|
|
567
|
+
|
|
478
568
|
.cellContent {
|
|
479
569
|
display: flex;
|
|
480
570
|
inline-size: 100%;
|
|
@@ -558,8 +648,19 @@
|
|
|
558
648
|
text-overflow: clip;
|
|
559
649
|
}
|
|
560
650
|
|
|
561
|
-
|
|
562
|
-
|
|
651
|
+
/*
|
|
652
|
+
* Unwrap the row's content only for keyboard focus. Mouse clicks on the row
|
|
653
|
+
* don't match :focus-visible, so the row keeps its height.
|
|
654
|
+
* The row-actions button is excluded outright: its menu returns focus to it
|
|
655
|
+
* programmatically on close, and browsers (notably Safari/Firefox on macOS,
|
|
656
|
+
* where clicking a button doesn't focus it) may treat that as :focus-visible.
|
|
657
|
+
*/
|
|
658
|
+
.row:focus-visible > .cell:not(.selectionCell) .cellContent,
|
|
659
|
+
.row:focus-visible > .cell:not(.selectionCell) .cellValueEllipsis,
|
|
660
|
+
.row:has(:focus-visible:not([data-row-context-menu])) > .cell:not(.selectionCell) .cellContent,
|
|
661
|
+
.row:has(:focus-visible:not([data-row-context-menu]))
|
|
662
|
+
> .cell:not(.selectionCell)
|
|
663
|
+
.cellValueEllipsis {
|
|
563
664
|
white-space: normal;
|
|
564
665
|
overflow-wrap: break-word;
|
|
565
666
|
word-break: normal;
|
|
@@ -569,8 +670,8 @@
|
|
|
569
670
|
|
|
570
671
|
.contextMenuTrigger {
|
|
571
672
|
color: var(--color-fg-subtle);
|
|
572
|
-
min-inline-size:
|
|
573
|
-
min-block-size:
|
|
673
|
+
min-inline-size: var(--component-size-sm);
|
|
674
|
+
min-block-size: var(--component-size-sm);
|
|
574
675
|
border-radius: 999px;
|
|
575
676
|
background-color: transparent;
|
|
576
677
|
position: relative;
|
|
@@ -578,9 +679,17 @@
|
|
|
578
679
|
overflow: hidden;
|
|
579
680
|
}
|
|
580
681
|
|
|
682
|
+
/*
|
|
683
|
+
* The row-actions button is centred on the cell's first line of text (cell
|
|
684
|
+
* padding + half the 20px line height) rather than on the whole cell, so it
|
|
685
|
+
* stays put when the row grows (wrapping, selection, expansion). For a
|
|
686
|
+
* single-line row this is the same spot as centring on the cell.
|
|
687
|
+
*/
|
|
581
688
|
.contextMenuOverlay {
|
|
689
|
+
--table-row-actions-cell-padding-block: 6px;
|
|
690
|
+
|
|
582
691
|
position: absolute;
|
|
583
|
-
inset-block-start:
|
|
692
|
+
inset-block-start: calc(var(--table-row-actions-cell-padding-block) + 10px);
|
|
584
693
|
inset-inline-end: var(--spacing-2xs);
|
|
585
694
|
transform: translateY(-50%);
|
|
586
695
|
display: inline-flex;
|
|
@@ -595,6 +704,25 @@
|
|
|
595
704
|
z-index: 2;
|
|
596
705
|
}
|
|
597
706
|
|
|
707
|
+
.md .contextMenuOverlay {
|
|
708
|
+
--table-row-actions-cell-padding-block: var(--spacing-xs);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
.sm .contextMenuOverlay {
|
|
712
|
+
--table-row-actions-cell-padding-block: var(--spacing-xxs);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/* Follow the cell's own vertical alignment when it isn't top-aligned. */
|
|
716
|
+
.cell[data-vertical-align='middle'] .contextMenuOverlay {
|
|
717
|
+
inset-block-start: 50%;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
.cell[data-vertical-align='bottom'] .contextMenuOverlay {
|
|
721
|
+
inset-block-start: auto;
|
|
722
|
+
inset-block-end: calc(var(--table-row-actions-cell-padding-block) + 10px);
|
|
723
|
+
transform: translateY(50%);
|
|
724
|
+
}
|
|
725
|
+
|
|
598
726
|
.contextMenuHoverOnly .contextMenuOverlay {
|
|
599
727
|
opacity: 0;
|
|
600
728
|
pointer-events: none;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { HTMLAttributes, ReactNode, Ref } from 'react';
|
|
2
2
|
import type { PageChangeEvent } from '../../components/pagination/Pagination';
|
|
3
3
|
import type { Severity } from '../../constants/severity.types';
|
|
4
|
-
|
|
4
|
+
export type ViewMode = 'compact' | 'wrapped';
|
|
5
5
|
export interface ColumnItem<T> {
|
|
6
6
|
id: string;
|
|
7
7
|
header: string | (() => ReactNode);
|
|
@@ -21,6 +21,35 @@ export interface ColumnItem<T> {
|
|
|
21
21
|
severity?: any;
|
|
22
22
|
allowOverflow?: boolean;
|
|
23
23
|
}
|
|
24
|
+
/** Visibility fields shared by Table columns and accessor-shaped adapters. */
|
|
25
|
+
export interface TableSettingsColumn extends Partial<Pick<ColumnItem<unknown>, 'id' | 'hidden' | 'canHide'>> {
|
|
26
|
+
accessorKey?: PropertyKey;
|
|
27
|
+
header?: unknown;
|
|
28
|
+
enableHiding?: boolean;
|
|
29
|
+
meta?: unknown;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Settings state + setters that drive the table's built-in header settings
|
|
33
|
+
* menu. This is the shape `useTableSettings` returns, so its result can be
|
|
34
|
+
* passed straight through: `settings={useTableSettings(...)}`.
|
|
35
|
+
*/
|
|
36
|
+
export interface TableSettingsController {
|
|
37
|
+
viewMode: ViewMode;
|
|
38
|
+
setViewMode: (mode: ViewMode) => void;
|
|
39
|
+
visibleColumnIds?: string[];
|
|
40
|
+
setVisibleColumnIds?: (ids: string[]) => void;
|
|
41
|
+
striped?: boolean;
|
|
42
|
+
setStriped?: (nextStriped: boolean) => void;
|
|
43
|
+
}
|
|
44
|
+
/** Labels and extra items for the table's built-in header settings menu. */
|
|
45
|
+
export interface TableSettingsMenuOptions {
|
|
46
|
+
/** Accessible name and tooltip for the trigger. Defaults to "Visningsindstillinger". */
|
|
47
|
+
triggerLabel?: string;
|
|
48
|
+
columnsLabel?: string;
|
|
49
|
+
allPresetLabel?: string;
|
|
50
|
+
standardPresetLabel?: string;
|
|
51
|
+
additionalSettings?: (close?: () => void) => ReactNode;
|
|
52
|
+
}
|
|
24
53
|
export type HeaderExtrasArgs<T> = {
|
|
25
54
|
column: ColumnItem<T>;
|
|
26
55
|
index: number;
|
|
@@ -57,16 +86,33 @@ export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTML
|
|
|
57
86
|
variant?: TableVariant;
|
|
58
87
|
size?: 'sm' | 'md';
|
|
59
88
|
viewMode?: ViewMode;
|
|
89
|
+
striped?: boolean;
|
|
60
90
|
fillViewport?: boolean;
|
|
61
91
|
/** Extra space below the table, in addition to measured layout/pagination spacing. Defaults to 0. */
|
|
62
92
|
fillViewportBottomOffset?: number;
|
|
63
93
|
containScrolling?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Pins the header while scrolling. Defaults to the top of the table's own
|
|
96
|
+
* scroll area when `containScrolling` is on; `false` turns it off.
|
|
97
|
+
*/
|
|
64
98
|
stickyHeader?: StickyHeader;
|
|
65
99
|
tableWidth?: number;
|
|
66
100
|
tableRootRef?: Ref<HTMLDivElement>;
|
|
67
101
|
measuringLayout?: boolean;
|
|
68
102
|
toolbar?: ReactNode;
|
|
69
103
|
headerExtras?: (args: HeaderExtrasArgs<T>) => ReactNode;
|
|
104
|
+
/**
|
|
105
|
+
* Content rendered at the inline end of the header row, above the row
|
|
106
|
+
* actions column. Falls back to the toolbar when `showHeader` is false.
|
|
107
|
+
*/
|
|
108
|
+
headerActions?: ReactNode;
|
|
109
|
+
/**
|
|
110
|
+
* Shows a settings menu (stripes, text wrapping, column visibility) in the
|
|
111
|
+
* header and applies its state to the table. Pass the result of
|
|
112
|
+
* `useTableSettings`. Explicit `viewMode`/`striped` props take precedence.
|
|
113
|
+
*/
|
|
114
|
+
settings?: TableSettingsController;
|
|
115
|
+
settingsOptions?: TableSettingsMenuOptions;
|
|
70
116
|
take?: number;
|
|
71
117
|
skip?: number;
|
|
72
118
|
totalItemsCount?: number;
|