@dbcdk/react-components 0.0.196 → 0.0.198
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/dist/components/json-viewer/JsonViewer.module.css +52 -0
- package/dist/components/json-viewer/JsonViewerShell.cjs +147 -143
- package/dist/components/json-viewer/JsonViewerShell.js +149 -145
- package/dist/components/line-viewer/LineViewer.cjs +15 -10
- package/dist/components/line-viewer/LineViewer.d.ts +1 -1
- package/dist/components/line-viewer/LineViewer.js +15 -10
- package/dist/components/line-viewer/LineViewer.module.css +58 -3
- package/dist/components/page-layout/PageLayout.module.css +1 -1
- package/dist/components/scroll-fade/ScrollFade.cjs +42 -0
- package/dist/components/scroll-fade/ScrollFade.d.ts +18 -0
- package/dist/components/scroll-fade/ScrollFade.js +36 -0
- package/dist/components/scroll-fade/ScrollFade.module.css +71 -0
- package/dist/components/search-box/SearchBox.cjs +39 -35
- package/dist/components/search-box/SearchBox.d.ts +2 -0
- package/dist/components/search-box/SearchBox.js +39 -35
- package/dist/components/table/Table.cjs +52 -23
- package/dist/components/table/Table.d.ts +1 -1
- package/dist/components/table/Table.js +53 -24
- package/dist/components/table/Table.module.css +4 -0
- package/dist/components/table/Table.types.d.ts +27 -0
- package/dist/components/table/TanstackTable.cjs +64 -64
- package/dist/components/table/TanstackTable.js +67 -67
- package/dist/components/table/columnLayout.utils.cjs +146 -0
- package/dist/components/table/columnLayout.utils.d.ts +44 -0
- package/dist/components/table/columnLayout.utils.js +141 -0
- package/dist/components/table/components/TableHeader.cjs +3 -1
- package/dist/components/table/components/TableHeader.d.ts +2 -1
- package/dist/components/table/components/TableHeader.js +3 -1
- package/dist/components/table/components/TableHeaderCell.cjs +29 -19
- package/dist/components/table/components/TableHeaderCell.d.ts +2 -1
- package/dist/components/table/components/TableHeaderCell.js +29 -19
- package/dist/components/table/hooks/useElementWidth.cjs +40 -0
- package/dist/components/table/hooks/useElementWidth.d.ts +7 -0
- package/dist/components/table/hooks/useElementWidth.js +38 -0
- package/dist/components/table/table.utils.cjs +24 -2
- package/dist/components/table/table.utils.d.ts +40 -2
- package/dist/components/table/table.utils.js +20 -2
- package/dist/components/table/tanstackTable.utils.cjs +33 -97
- package/dist/components/table/tanstackTable.utils.d.ts +24 -8
- package/dist/components/table/tanstackTable.utils.js +34 -99
- package/dist/components/xml-viewer/XmlViewer.cjs +15 -10
- package/dist/components/xml-viewer/XmlViewer.d.ts +1 -1
- package/dist/components/xml-viewer/XmlViewer.js +15 -10
- package/dist/components/xml-viewer/XmlViewer.module.css +58 -3
- package/dist/hooks/useColorScheme.cjs +15 -15
- package/dist/hooks/useColorScheme.d.ts +1 -0
- package/dist/hooks/useColorScheme.js +15 -15
- package/dist/hooks/useScrollOverflow.cjs +71 -0
- package/dist/hooks/useScrollOverflow.d.ts +23 -0
- package/dist/hooks/useScrollOverflow.js +69 -0
- package/dist/hooks/useTableSettings.cjs +2 -1
- package/dist/hooks/useTableSettings.d.ts +1 -0
- package/dist/hooks/useTableSettings.js +2 -1
- package/dist/hooks/useTheme.cjs +15 -15
- package/dist/hooks/useTheme.d.ts +3 -1
- package/dist/hooks/useTheme.js +15 -15
- package/dist/index.css +1 -0
- package/dist/utils/refs.utils.cjs +13 -0
- package/dist/utils/refs.utils.d.ts +7 -0
- package/dist/utils/refs.utils.js +11 -0
- package/package.json +1 -1
|
@@ -379,6 +379,10 @@
|
|
|
379
379
|
padding-inline-end: var(--table-row-actions-reserve-inline);
|
|
380
380
|
}
|
|
381
381
|
|
|
382
|
+
.thMainWithHeaderActionsReserve {
|
|
383
|
+
padding-inline-end: calc(var(--component-size-sm) - var(--spacing-sm) + var(--spacing-2xs));
|
|
384
|
+
}
|
|
385
|
+
|
|
382
386
|
.thMainRight {
|
|
383
387
|
justify-content: flex-end;
|
|
384
388
|
}
|
|
@@ -6,7 +6,22 @@ export interface ColumnItem<T> {
|
|
|
6
6
|
id: string;
|
|
7
7
|
header: string | (() => ReactNode);
|
|
8
8
|
accessor?: keyof T;
|
|
9
|
+
/**
|
|
10
|
+
* Column width. When any column sets `minWidth`, `maxWidth` or `weight`,
|
|
11
|
+
* a numeric width pins the column to exactly that many pixels.
|
|
12
|
+
*/
|
|
9
13
|
width?: number | string;
|
|
14
|
+
/**
|
|
15
|
+
* Smallest width in pixels. Setting `minWidth`, `maxWidth` or `weight` on any
|
|
16
|
+
* column makes the table measure its container and distribute the width:
|
|
17
|
+
* each column starts at its minimum (default 80) and grows by `weight`
|
|
18
|
+
* towards `maxWidth`. Columns whose minimums don't fit scroll horizontally.
|
|
19
|
+
*/
|
|
20
|
+
minWidth?: number;
|
|
21
|
+
/** Largest width in pixels. See `minWidth`. */
|
|
22
|
+
maxWidth?: number;
|
|
23
|
+
/** Relative share of the leftover width (default 1). See `minWidth`. */
|
|
24
|
+
weight?: number;
|
|
10
25
|
sortable?: boolean;
|
|
11
26
|
sortFunction?: (a: T, b: T) => -1 | 0 | 1;
|
|
12
27
|
render?: (item: T) => ReactNode;
|
|
@@ -85,6 +100,12 @@ export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTML
|
|
|
85
100
|
emptyConfig?: any;
|
|
86
101
|
variant?: TableVariant;
|
|
87
102
|
size?: 'sm' | 'md';
|
|
103
|
+
/**
|
|
104
|
+
* `'wrapped'` (default) wraps cell text so all content is visible.
|
|
105
|
+
* `'compact'` keeps each row on one line with truncated text, for even row
|
|
106
|
+
* heights; rows can then be expanded with `expandableRows`.
|
|
107
|
+
* Overrides the view mode from `settings`.
|
|
108
|
+
*/
|
|
88
109
|
viewMode?: ViewMode;
|
|
89
110
|
striped?: boolean;
|
|
90
111
|
fillViewport?: boolean;
|
|
@@ -106,6 +127,12 @@ export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTML
|
|
|
106
127
|
* actions column. Falls back to the toolbar when `showHeader` is false.
|
|
107
128
|
*/
|
|
108
129
|
headerActions?: ReactNode;
|
|
130
|
+
/**
|
|
131
|
+
* Columns listed in the settings menu. Defaults to `columns`; pass the
|
|
132
|
+
* original definitions when `columns` is derived from them with `hidden`
|
|
133
|
+
* already applied (as TanstackTable does).
|
|
134
|
+
*/
|
|
135
|
+
settingsColumns?: ReadonlyArray<ColumnItem<T> | TableSettingsColumn>;
|
|
109
136
|
/**
|
|
110
137
|
* Shows a settings menu (stripes, text wrapping, column visibility) in the
|
|
111
138
|
* header and applies its state to the table. Pass the result of
|
|
@@ -5,7 +5,7 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
5
5
|
var reactTable = require('@tanstack/react-table');
|
|
6
6
|
var React = require('react');
|
|
7
7
|
var ColumnResizer = require('./components/column-resizer/ColumnResizer');
|
|
8
|
-
var
|
|
8
|
+
var useElementWidth = require('./hooks/useElementWidth');
|
|
9
9
|
var Table = require('./Table');
|
|
10
10
|
var table_utils = require('./table.utils');
|
|
11
11
|
var tanstackTable_utils = require('./tanstackTable.utils');
|
|
@@ -34,6 +34,7 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
|
34
34
|
var ColumnResizer__default = /*#__PURE__*/_interopDefault(ColumnResizer);
|
|
35
35
|
|
|
36
36
|
function TanstackTable(props) {
|
|
37
|
+
var _a, _b;
|
|
37
38
|
const {
|
|
38
39
|
data,
|
|
39
40
|
dataKey,
|
|
@@ -65,8 +66,9 @@ function TanstackTable(props) {
|
|
|
65
66
|
[columns, visibleColumnIds]
|
|
66
67
|
);
|
|
67
68
|
const [columnSizing, setColumnSizing] = React__namespace.useState({});
|
|
69
|
+
const neighborResizeRef = React__namespace.useRef(null);
|
|
68
70
|
const containerRef = React__namespace.useRef(null);
|
|
69
|
-
const
|
|
71
|
+
const availableWidth = useElementWidth.useElementWidth(containerRef);
|
|
70
72
|
const table = reactTable.useReactTable({
|
|
71
73
|
data,
|
|
72
74
|
columns,
|
|
@@ -80,7 +82,13 @@ function TanstackTable(props) {
|
|
|
80
82
|
if (optimisticSortingUi) setUiSorting(next);
|
|
81
83
|
onSortingChange == null ? void 0 : onSortingChange(next);
|
|
82
84
|
},
|
|
83
|
-
onColumnSizingChange:
|
|
85
|
+
onColumnSizingChange: (updater) => {
|
|
86
|
+
setColumnSizing((prev) => {
|
|
87
|
+
const next = typeof updater === "function" ? updater(prev) : updater;
|
|
88
|
+
const resize = neighborResizeRef.current;
|
|
89
|
+
return resize && table.getState().columnSizingInfo.isResizingColumn === resize.columnId ? tanstackTable_utils.applyNeighborResize(next, resize) : next;
|
|
90
|
+
});
|
|
91
|
+
},
|
|
84
92
|
getCoreRowModel: reactTable.getCoreRowModel(),
|
|
85
93
|
getSortedRowModel: reactTable.getSortedRowModel(),
|
|
86
94
|
manualSorting: manualSorting != null ? manualSorting : false,
|
|
@@ -92,58 +100,25 @@ function TanstackTable(props) {
|
|
|
92
100
|
size: table_utils.DEFAULT_COLUMN_PX
|
|
93
101
|
}
|
|
94
102
|
});
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
updateWidth();
|
|
103
|
-
if (typeof ResizeObserver === "undefined") {
|
|
104
|
-
window.addEventListener("resize", updateWidth);
|
|
105
|
-
return () => window.removeEventListener("resize", updateWidth);
|
|
106
|
-
}
|
|
107
|
-
const observer = new ResizeObserver((entries) => {
|
|
108
|
-
var _a, _b, _c;
|
|
109
|
-
const entry = entries[0];
|
|
110
|
-
if (!entry) {
|
|
111
|
-
updateWidth();
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
const contentWidth = (_c = (_b = (_a = entry.contentBoxSize) == null ? void 0 : _a[0]) == null ? void 0 : _b.inlineSize) != null ? _c : entry.contentRect.width;
|
|
115
|
-
const next = Math.floor(contentWidth);
|
|
116
|
-
setAvailableWidth(next > 0 ? next : void 0);
|
|
117
|
-
});
|
|
118
|
-
observer.observe(el);
|
|
119
|
-
return () => observer.disconnect();
|
|
120
|
-
}, []);
|
|
103
|
+
const resolvedViewMode = (_a = viewMode != null ? viewMode : settings == null ? void 0 : settings.viewMode) != null ? _a : table_utils.DEFAULT_VIEW_MODE;
|
|
104
|
+
const { px: actionReservePx } = table_utils.getActionsReserve({
|
|
105
|
+
hasRowActions: Boolean(tableProps.getContextMenuItems) || table_utils.showsExpandToggle(tableProps.expandableRows, resolvedViewMode),
|
|
106
|
+
hasSettings: Boolean(settings),
|
|
107
|
+
hasOtherHeaderActions: headerActionsProp != null,
|
|
108
|
+
showHeader: (_b = tableProps.showHeader) != null ? _b : true
|
|
109
|
+
});
|
|
121
110
|
const distributedLayout = React__namespace.useMemo(() => {
|
|
122
111
|
if (availableWidth == null) return null;
|
|
123
112
|
return tanstackTable_utils.buildDistributedColumnWidths({
|
|
124
113
|
table,
|
|
125
114
|
hasSelection: Boolean(selectedRows && onRowSelect && dataKey),
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
hasContextMenu: Boolean(
|
|
129
|
-
tableProps.getContextMenuItems || tableProps.expandableRows || settings || headerActionsProp != null
|
|
130
|
-
),
|
|
115
|
+
hasContextMenu: actionReservePx > 0,
|
|
116
|
+
contextMenuReservePx: actionReservePx,
|
|
131
117
|
defaultMinPx: 80,
|
|
132
118
|
columnSizing,
|
|
133
119
|
availableWidth
|
|
134
120
|
});
|
|
135
|
-
}, [
|
|
136
|
-
table,
|
|
137
|
-
selectedRows,
|
|
138
|
-
onRowSelect,
|
|
139
|
-
dataKey,
|
|
140
|
-
tableProps.getContextMenuItems,
|
|
141
|
-
tableProps.expandableRows,
|
|
142
|
-
settings,
|
|
143
|
-
headerActionsProp,
|
|
144
|
-
columnSizing,
|
|
145
|
-
availableWidth
|
|
146
|
-
]);
|
|
121
|
+
}, [table, selectedRows, onRowSelect, dataKey, actionReservePx, columnSizing, availableWidth]);
|
|
147
122
|
const initialLayoutReady = availableWidth != null;
|
|
148
123
|
const resolvedLayout = React__namespace.useMemo(() => {
|
|
149
124
|
const next = {};
|
|
@@ -170,36 +145,61 @@ function TanstackTable(props) {
|
|
|
170
145
|
);
|
|
171
146
|
const headerExtras = React__namespace.useCallback(
|
|
172
147
|
({ index }) => {
|
|
173
|
-
var
|
|
148
|
+
var _a2, _b2, _c, _d;
|
|
174
149
|
const headerGroups = table.getHeaderGroups();
|
|
175
150
|
const leafHeaders = headerGroups.length > 0 ? headerGroups[headerGroups.length - 1].headers : [];
|
|
176
151
|
const header = leafHeaders[index];
|
|
177
|
-
|
|
178
|
-
|
|
152
|
+
const neighbor = leafHeaders[index + 1];
|
|
153
|
+
if (!header || !neighbor) return null;
|
|
154
|
+
const canResize = (_c = (_b2 = (_a2 = header.column).getCanResize) == null ? void 0 : _b2.call(_a2)) != null ? _c : false;
|
|
179
155
|
const handler = (_d = header.getResizeHandler) == null ? void 0 : _d.call(header);
|
|
180
156
|
if (!canResize || !handler) return null;
|
|
181
|
-
|
|
157
|
+
const handleResizeStart = (event) => {
|
|
158
|
+
var _a3, _b3, _c2, _d2, _e;
|
|
159
|
+
const startWidth = distributedLayout == null ? void 0 : distributedLayout.widths[header.column.id];
|
|
160
|
+
const neighborStartWidth = distributedLayout == null ? void 0 : distributedLayout.widths[neighbor.column.id];
|
|
161
|
+
if (startWidth == null || neighborStartWidth == null) return;
|
|
162
|
+
const neighborReserve = index + 1 === leafHeaders.length - 1 ? actionReservePx : 0;
|
|
163
|
+
const { columnDef } = header.column;
|
|
164
|
+
const neighborDef = neighbor.column.columnDef;
|
|
165
|
+
neighborResizeRef.current = {
|
|
166
|
+
columnId: header.column.id,
|
|
167
|
+
neighborId: neighbor.column.id,
|
|
168
|
+
// TanStack drags from its own size (columnDef.size), not the width on
|
|
169
|
+
// screen; applyNeighborResize only uses its offset from this.
|
|
170
|
+
tanstackStartWidth: header.getSize(),
|
|
171
|
+
startWidth,
|
|
172
|
+
neighborStartWidth,
|
|
173
|
+
min: (_a3 = columnDef.minSize) != null ? _a3 : 0,
|
|
174
|
+
max: (_b3 = columnDef.maxSize) != null ? _b3 : Infinity,
|
|
175
|
+
neighborMin: ((_c2 = neighborDef.minSize) != null ? _c2 : 0) + neighborReserve,
|
|
176
|
+
neighborMax: ((_d2 = neighborDef.maxSize) != null ? _d2 : Infinity) + neighborReserve
|
|
177
|
+
};
|
|
178
|
+
const displayedWidths = (_e = distributedLayout == null ? void 0 : distributedLayout.widths) != null ? _e : {};
|
|
179
|
+
setColumnSizing(
|
|
180
|
+
(prev) => Object.fromEntries(
|
|
181
|
+
Object.entries(prev).map(([id, width]) => {
|
|
182
|
+
var _a4;
|
|
183
|
+
return [id, (_a4 = displayedWidths[id]) != null ? _a4 : width];
|
|
184
|
+
})
|
|
185
|
+
)
|
|
186
|
+
);
|
|
187
|
+
handler(event);
|
|
188
|
+
};
|
|
189
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ColumnResizer__default.default, { id: header.column.id, handler: handleResizeStart });
|
|
182
190
|
},
|
|
183
|
-
[table]
|
|
191
|
+
[table, distributedLayout, actionReservePx]
|
|
184
192
|
);
|
|
185
|
-
const headerActions = headerActionsProp != null || settings ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
186
|
-
headerActionsProp,
|
|
187
|
-
settings ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
188
|
-
TableHeaderSettings.TableHeaderSettings,
|
|
189
|
-
{
|
|
190
|
-
settings,
|
|
191
|
-
options: settingsOptions,
|
|
192
|
-
columns
|
|
193
|
-
}
|
|
194
|
-
) : null
|
|
195
|
-
] }) : void 0;
|
|
196
193
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
197
194
|
Table.Table,
|
|
198
195
|
{
|
|
199
196
|
...tableProps,
|
|
200
|
-
viewMode:
|
|
197
|
+
viewMode: resolvedViewMode,
|
|
201
198
|
striped: striped != null ? striped : settings == null ? void 0 : settings.striped,
|
|
202
|
-
headerActions,
|
|
199
|
+
headerActions: headerActionsProp,
|
|
200
|
+
settings,
|
|
201
|
+
settingsOptions,
|
|
202
|
+
settingsColumns: columns,
|
|
203
203
|
tableRootRef: containerRef,
|
|
204
204
|
onSortChange: handleSortChange,
|
|
205
205
|
dataKey,
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { useReactTable, getSortedRowModel, getCoreRowModel } from '@tanstack/react-table';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import ColumnResizer from './components/column-resizer/ColumnResizer';
|
|
6
|
-
import {
|
|
6
|
+
import { useElementWidth } from './hooks/useElementWidth';
|
|
7
7
|
import { Table } from './Table';
|
|
8
|
-
import { DEFAULT_COLUMN_PX } from './table.utils';
|
|
9
|
-
import { sortingEqual, buildColumnVisibilityFromVisibleIds, buildDistributedColumnWidths, mapDefsToColumnItems, getSortPropsFromSorting } from './tanstackTable.utils';
|
|
8
|
+
import { DEFAULT_COLUMN_PX, DEFAULT_VIEW_MODE, getActionsReserve, showsExpandToggle } from './table.utils';
|
|
9
|
+
import { sortingEqual, buildColumnVisibilityFromVisibleIds, applyNeighborResize, buildDistributedColumnWidths, mapDefsToColumnItems, getSortPropsFromSorting } from './tanstackTable.utils';
|
|
10
10
|
|
|
11
11
|
function TanstackTable(props) {
|
|
12
|
+
var _a, _b;
|
|
12
13
|
const {
|
|
13
14
|
data,
|
|
14
15
|
dataKey,
|
|
@@ -40,8 +41,9 @@ function TanstackTable(props) {
|
|
|
40
41
|
[columns, visibleColumnIds]
|
|
41
42
|
);
|
|
42
43
|
const [columnSizing, setColumnSizing] = React.useState({});
|
|
44
|
+
const neighborResizeRef = React.useRef(null);
|
|
43
45
|
const containerRef = React.useRef(null);
|
|
44
|
-
const
|
|
46
|
+
const availableWidth = useElementWidth(containerRef);
|
|
45
47
|
const table = useReactTable({
|
|
46
48
|
data,
|
|
47
49
|
columns,
|
|
@@ -55,7 +57,13 @@ function TanstackTable(props) {
|
|
|
55
57
|
if (optimisticSortingUi) setUiSorting(next);
|
|
56
58
|
onSortingChange == null ? void 0 : onSortingChange(next);
|
|
57
59
|
},
|
|
58
|
-
onColumnSizingChange:
|
|
60
|
+
onColumnSizingChange: (updater) => {
|
|
61
|
+
setColumnSizing((prev) => {
|
|
62
|
+
const next = typeof updater === "function" ? updater(prev) : updater;
|
|
63
|
+
const resize = neighborResizeRef.current;
|
|
64
|
+
return resize && table.getState().columnSizingInfo.isResizingColumn === resize.columnId ? applyNeighborResize(next, resize) : next;
|
|
65
|
+
});
|
|
66
|
+
},
|
|
59
67
|
getCoreRowModel: getCoreRowModel(),
|
|
60
68
|
getSortedRowModel: getSortedRowModel(),
|
|
61
69
|
manualSorting: manualSorting != null ? manualSorting : false,
|
|
@@ -67,58 +75,25 @@ function TanstackTable(props) {
|
|
|
67
75
|
size: DEFAULT_COLUMN_PX
|
|
68
76
|
}
|
|
69
77
|
});
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
updateWidth();
|
|
78
|
-
if (typeof ResizeObserver === "undefined") {
|
|
79
|
-
window.addEventListener("resize", updateWidth);
|
|
80
|
-
return () => window.removeEventListener("resize", updateWidth);
|
|
81
|
-
}
|
|
82
|
-
const observer = new ResizeObserver((entries) => {
|
|
83
|
-
var _a, _b, _c;
|
|
84
|
-
const entry = entries[0];
|
|
85
|
-
if (!entry) {
|
|
86
|
-
updateWidth();
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
const contentWidth = (_c = (_b = (_a = entry.contentBoxSize) == null ? void 0 : _a[0]) == null ? void 0 : _b.inlineSize) != null ? _c : entry.contentRect.width;
|
|
90
|
-
const next = Math.floor(contentWidth);
|
|
91
|
-
setAvailableWidth(next > 0 ? next : void 0);
|
|
92
|
-
});
|
|
93
|
-
observer.observe(el);
|
|
94
|
-
return () => observer.disconnect();
|
|
95
|
-
}, []);
|
|
78
|
+
const resolvedViewMode = (_a = viewMode != null ? viewMode : settings == null ? void 0 : settings.viewMode) != null ? _a : DEFAULT_VIEW_MODE;
|
|
79
|
+
const { px: actionReservePx } = getActionsReserve({
|
|
80
|
+
hasRowActions: Boolean(tableProps.getContextMenuItems) || showsExpandToggle(tableProps.expandableRows, resolvedViewMode),
|
|
81
|
+
hasSettings: Boolean(settings),
|
|
82
|
+
hasOtherHeaderActions: headerActionsProp != null,
|
|
83
|
+
showHeader: (_b = tableProps.showHeader) != null ? _b : true
|
|
84
|
+
});
|
|
96
85
|
const distributedLayout = React.useMemo(() => {
|
|
97
86
|
if (availableWidth == null) return null;
|
|
98
87
|
return buildDistributedColumnWidths({
|
|
99
88
|
table,
|
|
100
89
|
hasSelection: Boolean(selectedRows && onRowSelect && dataKey),
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
hasContextMenu: Boolean(
|
|
104
|
-
tableProps.getContextMenuItems || tableProps.expandableRows || settings || headerActionsProp != null
|
|
105
|
-
),
|
|
90
|
+
hasContextMenu: actionReservePx > 0,
|
|
91
|
+
contextMenuReservePx: actionReservePx,
|
|
106
92
|
defaultMinPx: 80,
|
|
107
93
|
columnSizing,
|
|
108
94
|
availableWidth
|
|
109
95
|
});
|
|
110
|
-
}, [
|
|
111
|
-
table,
|
|
112
|
-
selectedRows,
|
|
113
|
-
onRowSelect,
|
|
114
|
-
dataKey,
|
|
115
|
-
tableProps.getContextMenuItems,
|
|
116
|
-
tableProps.expandableRows,
|
|
117
|
-
settings,
|
|
118
|
-
headerActionsProp,
|
|
119
|
-
columnSizing,
|
|
120
|
-
availableWidth
|
|
121
|
-
]);
|
|
96
|
+
}, [table, selectedRows, onRowSelect, dataKey, actionReservePx, columnSizing, availableWidth]);
|
|
122
97
|
const initialLayoutReady = availableWidth != null;
|
|
123
98
|
const resolvedLayout = React.useMemo(() => {
|
|
124
99
|
const next = {};
|
|
@@ -145,36 +120,61 @@ function TanstackTable(props) {
|
|
|
145
120
|
);
|
|
146
121
|
const headerExtras = React.useCallback(
|
|
147
122
|
({ index }) => {
|
|
148
|
-
var
|
|
123
|
+
var _a2, _b2, _c, _d;
|
|
149
124
|
const headerGroups = table.getHeaderGroups();
|
|
150
125
|
const leafHeaders = headerGroups.length > 0 ? headerGroups[headerGroups.length - 1].headers : [];
|
|
151
126
|
const header = leafHeaders[index];
|
|
152
|
-
|
|
153
|
-
|
|
127
|
+
const neighbor = leafHeaders[index + 1];
|
|
128
|
+
if (!header || !neighbor) return null;
|
|
129
|
+
const canResize = (_c = (_b2 = (_a2 = header.column).getCanResize) == null ? void 0 : _b2.call(_a2)) != null ? _c : false;
|
|
154
130
|
const handler = (_d = header.getResizeHandler) == null ? void 0 : _d.call(header);
|
|
155
131
|
if (!canResize || !handler) return null;
|
|
156
|
-
|
|
132
|
+
const handleResizeStart = (event) => {
|
|
133
|
+
var _a3, _b3, _c2, _d2, _e;
|
|
134
|
+
const startWidth = distributedLayout == null ? void 0 : distributedLayout.widths[header.column.id];
|
|
135
|
+
const neighborStartWidth = distributedLayout == null ? void 0 : distributedLayout.widths[neighbor.column.id];
|
|
136
|
+
if (startWidth == null || neighborStartWidth == null) return;
|
|
137
|
+
const neighborReserve = index + 1 === leafHeaders.length - 1 ? actionReservePx : 0;
|
|
138
|
+
const { columnDef } = header.column;
|
|
139
|
+
const neighborDef = neighbor.column.columnDef;
|
|
140
|
+
neighborResizeRef.current = {
|
|
141
|
+
columnId: header.column.id,
|
|
142
|
+
neighborId: neighbor.column.id,
|
|
143
|
+
// TanStack drags from its own size (columnDef.size), not the width on
|
|
144
|
+
// screen; applyNeighborResize only uses its offset from this.
|
|
145
|
+
tanstackStartWidth: header.getSize(),
|
|
146
|
+
startWidth,
|
|
147
|
+
neighborStartWidth,
|
|
148
|
+
min: (_a3 = columnDef.minSize) != null ? _a3 : 0,
|
|
149
|
+
max: (_b3 = columnDef.maxSize) != null ? _b3 : Infinity,
|
|
150
|
+
neighborMin: ((_c2 = neighborDef.minSize) != null ? _c2 : 0) + neighborReserve,
|
|
151
|
+
neighborMax: ((_d2 = neighborDef.maxSize) != null ? _d2 : Infinity) + neighborReserve
|
|
152
|
+
};
|
|
153
|
+
const displayedWidths = (_e = distributedLayout == null ? void 0 : distributedLayout.widths) != null ? _e : {};
|
|
154
|
+
setColumnSizing(
|
|
155
|
+
(prev) => Object.fromEntries(
|
|
156
|
+
Object.entries(prev).map(([id, width]) => {
|
|
157
|
+
var _a4;
|
|
158
|
+
return [id, (_a4 = displayedWidths[id]) != null ? _a4 : width];
|
|
159
|
+
})
|
|
160
|
+
)
|
|
161
|
+
);
|
|
162
|
+
handler(event);
|
|
163
|
+
};
|
|
164
|
+
return /* @__PURE__ */ jsx(ColumnResizer, { id: header.column.id, handler: handleResizeStart });
|
|
157
165
|
},
|
|
158
|
-
[table]
|
|
166
|
+
[table, distributedLayout, actionReservePx]
|
|
159
167
|
);
|
|
160
|
-
const headerActions = headerActionsProp != null || settings ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
161
|
-
headerActionsProp,
|
|
162
|
-
settings ? /* @__PURE__ */ jsx(
|
|
163
|
-
TableHeaderSettings,
|
|
164
|
-
{
|
|
165
|
-
settings,
|
|
166
|
-
options: settingsOptions,
|
|
167
|
-
columns
|
|
168
|
-
}
|
|
169
|
-
) : null
|
|
170
|
-
] }) : void 0;
|
|
171
168
|
return /* @__PURE__ */ jsx(
|
|
172
169
|
Table,
|
|
173
170
|
{
|
|
174
171
|
...tableProps,
|
|
175
|
-
viewMode:
|
|
172
|
+
viewMode: resolvedViewMode,
|
|
176
173
|
striped: striped != null ? striped : settings == null ? void 0 : settings.striped,
|
|
177
|
-
headerActions,
|
|
174
|
+
headerActions: headerActionsProp,
|
|
175
|
+
settings,
|
|
176
|
+
settingsOptions,
|
|
177
|
+
settingsColumns: columns,
|
|
178
178
|
tableRootRef: containerRef,
|
|
179
179
|
onSortChange: handleSortChange,
|
|
180
180
|
dataKey,
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var table_utils = require('./table.utils');
|
|
4
|
+
|
|
5
|
+
const DEFAULT_MIN_COLUMN_PX = 80;
|
|
6
|
+
function toIntegerTrackWidths(tracks, targetWidth) {
|
|
7
|
+
const floored = tracks.map((track) => ({
|
|
8
|
+
id: track.id,
|
|
9
|
+
width: Math.floor(track.width),
|
|
10
|
+
fraction: track.width - Math.floor(track.width)
|
|
11
|
+
}));
|
|
12
|
+
const baseTotal = floored.reduce((sum, track) => sum + track.width, 0);
|
|
13
|
+
let remainder = Math.max(0, targetWidth - baseTotal);
|
|
14
|
+
floored.slice().sort((a, b) => b.fraction - a.fraction).forEach((track) => {
|
|
15
|
+
if (remainder <= 0) return;
|
|
16
|
+
track.width += 1;
|
|
17
|
+
remainder -= 1;
|
|
18
|
+
});
|
|
19
|
+
return Object.fromEntries(floored.map((track) => [track.id, track.width]));
|
|
20
|
+
}
|
|
21
|
+
function distributeColumnWidths(args) {
|
|
22
|
+
const {
|
|
23
|
+
hasSelection,
|
|
24
|
+
hasContextMenu = false,
|
|
25
|
+
contextMenuReservePx = table_utils.ROW_ACTIONS_RESERVE_PX,
|
|
26
|
+
availableWidth
|
|
27
|
+
} = args;
|
|
28
|
+
const selectionWidth = hasSelection ? table_utils.SELECTION_COLUMN_PX : 0;
|
|
29
|
+
const tracks = args.tracks.map((track) => {
|
|
30
|
+
const min = Math.max(1, track.min);
|
|
31
|
+
const max = track.max != null ? Math.max(min, track.max) : void 0;
|
|
32
|
+
if (track.fixedWidth != null) {
|
|
33
|
+
return {
|
|
34
|
+
id: track.id,
|
|
35
|
+
width: track.fixedWidth,
|
|
36
|
+
weight: 0,
|
|
37
|
+
min,
|
|
38
|
+
max: track.fixedWidth,
|
|
39
|
+
fixed: true
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
id: track.id,
|
|
44
|
+
width: min,
|
|
45
|
+
weight: Number.isFinite(track.weight) && track.weight > 0 ? track.weight : 1,
|
|
46
|
+
min,
|
|
47
|
+
max,
|
|
48
|
+
fixed: false
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
const lastTrack = tracks[tracks.length - 1];
|
|
52
|
+
if (hasContextMenu && lastTrack && !lastTrack.fixed) {
|
|
53
|
+
lastTrack.width += contextMenuReservePx;
|
|
54
|
+
lastTrack.min += contextMenuReservePx;
|
|
55
|
+
if (lastTrack.max != null) lastTrack.max += contextMenuReservePx;
|
|
56
|
+
}
|
|
57
|
+
const fixedWidth = selectionWidth + tracks.reduce((sum, track) => sum + track.width, 0);
|
|
58
|
+
let remaining = Math.max(0, availableWidth - fixedWidth);
|
|
59
|
+
let active = tracks.filter(
|
|
60
|
+
(track) => !track.fixed && (track.max == null || track.width < track.max)
|
|
61
|
+
);
|
|
62
|
+
while (remaining > 0.5 && active.length > 0) {
|
|
63
|
+
const totalWeight = active.reduce((sum, track) => sum + track.weight, 0);
|
|
64
|
+
if (totalWeight <= 0) break;
|
|
65
|
+
let consumed = 0;
|
|
66
|
+
const nextActive = [];
|
|
67
|
+
for (const track of active) {
|
|
68
|
+
const share = remaining * track.weight / totalWeight;
|
|
69
|
+
const maxGrow = track.max == null ? share : Math.max(0, track.max - track.width);
|
|
70
|
+
const growth = Math.min(share, maxGrow);
|
|
71
|
+
track.width += growth;
|
|
72
|
+
consumed += growth;
|
|
73
|
+
if (track.max == null || track.width < track.max - 0.5) {
|
|
74
|
+
nextActive.push(track);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (consumed <= 0.5) break;
|
|
78
|
+
remaining -= consumed;
|
|
79
|
+
active = nextActive;
|
|
80
|
+
}
|
|
81
|
+
const flexible = tracks.filter((track) => !track.fixed);
|
|
82
|
+
if (remaining > 0.5 && flexible.length > 0 && flexible.every((track) => track.max != null)) {
|
|
83
|
+
const stretchable = flexible.filter((track) => track.max > track.min);
|
|
84
|
+
const totalWeight = stretchable.reduce((sum, track) => sum + track.weight, 0);
|
|
85
|
+
if (totalWeight > 0) {
|
|
86
|
+
for (const track of stretchable) {
|
|
87
|
+
track.width += remaining * track.weight / totalWeight;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (tracks.length > 0 && flexible.length === 0) {
|
|
92
|
+
const target = availableWidth - selectionWidth;
|
|
93
|
+
const minOf = (track) => track.min + (hasContextMenu && track === lastTrack ? contextMenuReservePx : 0);
|
|
94
|
+
let scalable = tracks;
|
|
95
|
+
while (scalable.length > 0) {
|
|
96
|
+
const frozenWidth = tracks.filter((track) => !scalable.includes(track)).reduce((sum, track) => sum + track.width, 0);
|
|
97
|
+
const scalableWidth = scalable.reduce((sum, track) => sum + track.width, 0);
|
|
98
|
+
const factor = (target - frozenWidth) / scalableWidth;
|
|
99
|
+
const belowMin = scalable.filter((track) => track.width * factor < minOf(track));
|
|
100
|
+
if (belowMin.length === 0) {
|
|
101
|
+
for (const track of scalable) track.width *= factor;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
for (const track of belowMin) track.width = minOf(track);
|
|
105
|
+
scalable = scalable.filter((track) => !belowMin.includes(track));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const floatTrackTotal = tracks.reduce((sum, track) => sum + track.width, 0);
|
|
109
|
+
const targetTrackWidth = Math.min(
|
|
110
|
+
Math.floor(floatTrackTotal + 1e-6),
|
|
111
|
+
availableWidth - selectionWidth
|
|
112
|
+
);
|
|
113
|
+
const widths = toIntegerTrackWidths(tracks, targetTrackWidth);
|
|
114
|
+
const totalWidth = selectionWidth + Object.values(widths).reduce((sum, width) => sum + width, 0);
|
|
115
|
+
return {
|
|
116
|
+
selectionWidth: hasSelection ? table_utils.SELECTION_COLUMN_PX : void 0,
|
|
117
|
+
widths,
|
|
118
|
+
totalWidth,
|
|
119
|
+
availableWidth,
|
|
120
|
+
shouldOverflow: totalWidth > availableWidth
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function usesDistributedWidths(columns) {
|
|
124
|
+
return columns.some(
|
|
125
|
+
(column) => column.minWidth != null || column.maxWidth != null || column.weight != null
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
function buildColumnTracks(columns) {
|
|
129
|
+
return columns.map((column) => {
|
|
130
|
+
var _a, _b;
|
|
131
|
+
if (typeof column.width === "number") {
|
|
132
|
+
return { id: column.id, min: column.width, max: column.width, weight: 1 };
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
id: column.id,
|
|
136
|
+
min: (_a = column.minWidth) != null ? _a : DEFAULT_MIN_COLUMN_PX,
|
|
137
|
+
max: column.maxWidth,
|
|
138
|
+
weight: (_b = column.weight) != null ? _b : 1
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
exports.DEFAULT_MIN_COLUMN_PX = DEFAULT_MIN_COLUMN_PX;
|
|
144
|
+
exports.buildColumnTracks = buildColumnTracks;
|
|
145
|
+
exports.distributeColumnWidths = distributeColumnWidths;
|
|
146
|
+
exports.usesDistributedWidths = usesDistributedWidths;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ColumnItem } from './Table.types';
|
|
2
|
+
/** Minimum width of a flexible column that doesn't set `minWidth`. */
|
|
3
|
+
export declare const DEFAULT_MIN_COLUMN_PX: 80;
|
|
4
|
+
/**
|
|
5
|
+
* Sizing constraints for one column, as input to `distributeColumnWidths`.
|
|
6
|
+
* A track grows from `min` towards `max` by its share of `weight`; a track
|
|
7
|
+
* with `fixedWidth` (e.g. resized by the user) keeps exactly that width.
|
|
8
|
+
*/
|
|
9
|
+
export type ColumnTrack = {
|
|
10
|
+
id: string;
|
|
11
|
+
min: number;
|
|
12
|
+
max?: number;
|
|
13
|
+
weight: number;
|
|
14
|
+
fixedWidth?: number;
|
|
15
|
+
};
|
|
16
|
+
export type DistributedColumnWidths = {
|
|
17
|
+
selectionWidth?: number;
|
|
18
|
+
widths: Record<string, number>;
|
|
19
|
+
totalWidth: number;
|
|
20
|
+
availableWidth: number;
|
|
21
|
+
shouldOverflow: boolean;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Spreads `availableWidth` over the tracks: every track starts at its `min`,
|
|
25
|
+
* then the remaining space is shared by `weight` until each track hits its
|
|
26
|
+
* `max`. Fixed tracks keep their width. If the minimums don't fit, the result
|
|
27
|
+
* is wider than `availableWidth` and the table scrolls horizontally.
|
|
28
|
+
*/
|
|
29
|
+
export declare function distributeColumnWidths(args: {
|
|
30
|
+
tracks: ReadonlyArray<ColumnTrack>;
|
|
31
|
+
hasSelection: boolean;
|
|
32
|
+
hasContextMenu?: boolean;
|
|
33
|
+
contextMenuReservePx?: number;
|
|
34
|
+
availableWidth: number;
|
|
35
|
+
}): DistributedColumnWidths;
|
|
36
|
+
/** True when any column opts into distributed sizing via `minWidth`, `maxWidth` or `weight`. */
|
|
37
|
+
export declare function usesDistributedWidths<T>(columns: ReadonlyArray<ColumnItem<T>>): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Maps Table columns to tracks. A numeric `width` pins the column
|
|
40
|
+
* (min = max = width); other columns flex between `minWidth` (default
|
|
41
|
+
* `DEFAULT_MIN_COLUMN_PX`) and `maxWidth`, sharing leftover space by
|
|
42
|
+
* `weight` (default 1).
|
|
43
|
+
*/
|
|
44
|
+
export declare function buildColumnTracks<T>(columns: ReadonlyArray<ColumnItem<T>>): ColumnTrack[];
|