@undevy-org/tablewright 0.8.1 → 0.9.1
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/es/components/data-table/sticky-utils.js +45 -0
- package/dist/es/hooks/table-orchestration-store.js +14 -0
- package/dist/es/hooks/useTableOrchestration.js +45 -1
- package/dist/es/index.js +2 -0
- package/dist/styles.css +3 -0
- package/dist/tablewright.cjs +100 -1
- package/dist/tablewright.css +3 -0
- package/dist/types/components/data-table/sticky-utils.d.ts +11 -0
- package/dist/types/hooks/table-orchestration-store.d.ts +4 -1
- package/dist/types/hooks/useTableOrchestration.d.ts +11 -1
- package/dist/types/index.d.ts +2 -0
- package/package.json +1 -1
|
@@ -1,3 +1,46 @@
|
|
|
1
|
+
function columnWidthPx(columnId, meta, columnWidths) {
|
|
2
|
+
return columnWidths?.[columnId] ?? meta[columnId]?.minW ?? 0;
|
|
3
|
+
}
|
|
4
|
+
function applyColumnPinningToMeta(baseMeta, pinning, options) {
|
|
5
|
+
const order = options?.columnOrder ?? Object.keys(baseMeta);
|
|
6
|
+
const pinnedLeft = new Set(pinning.left ?? []);
|
|
7
|
+
const pinnedRight = new Set(pinning.right ?? []);
|
|
8
|
+
const result = {};
|
|
9
|
+
for (const [id, meta] of Object.entries(baseMeta)) {
|
|
10
|
+
if (pinnedLeft.has(id)) {
|
|
11
|
+
result[id] = { ...meta, sticky: "left" };
|
|
12
|
+
} else if (pinnedRight.has(id)) {
|
|
13
|
+
result[id] = { ...meta, sticky: "right" };
|
|
14
|
+
} else {
|
|
15
|
+
result[id] = { ...meta };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
let leftOffset = 0;
|
|
19
|
+
for (const id of order) {
|
|
20
|
+
const meta = result[id];
|
|
21
|
+
if (meta?.sticky !== "left") continue;
|
|
22
|
+
const width = columnWidthPx(id, baseMeta, options?.columnWidths);
|
|
23
|
+
if (pinnedLeft.has(id)) {
|
|
24
|
+
result[id] = { ...meta, stickyOffset: leftOffset };
|
|
25
|
+
leftOffset += width;
|
|
26
|
+
} else {
|
|
27
|
+
leftOffset = (meta.stickyOffset ?? 0) + width;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
let rightOffset = 0;
|
|
31
|
+
for (const id of [...order].reverse()) {
|
|
32
|
+
const meta = result[id];
|
|
33
|
+
if (meta?.sticky !== "right") continue;
|
|
34
|
+
const width = columnWidthPx(id, baseMeta, options?.columnWidths);
|
|
35
|
+
if (pinnedRight.has(id)) {
|
|
36
|
+
result[id] = { ...meta, stickyOffset: rightOffset };
|
|
37
|
+
rightOffset += width;
|
|
38
|
+
} else {
|
|
39
|
+
rightOffset = (meta.stickyOffset ?? 0) + width;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
1
44
|
function stickyStyle(meta, isHeader) {
|
|
2
45
|
if (isHeader) {
|
|
3
46
|
return {
|
|
@@ -20,6 +63,8 @@ function stickyBorderClass(meta) {
|
|
|
20
63
|
return edge === "right" ? "[box-shadow:1px_0_0_0_var(--border-subtle)]" : "[box-shadow:-1px_0_0_0_var(--border-subtle)]";
|
|
21
64
|
}
|
|
22
65
|
export {
|
|
66
|
+
applyColumnPinningToMeta,
|
|
67
|
+
columnWidthPx,
|
|
23
68
|
stickyBorderClass,
|
|
24
69
|
stickyStyle
|
|
25
70
|
};
|
|
@@ -28,6 +28,7 @@ function createTableOrchestrationStore({
|
|
|
28
28
|
requestOpenFilterId: null,
|
|
29
29
|
currentSort: null,
|
|
30
30
|
columnVisibility: initialColumnVisibility ?? {},
|
|
31
|
+
columnPinning: { left: [], right: [] },
|
|
31
32
|
page: 1,
|
|
32
33
|
rowsPerPage: initialRowsPerPage,
|
|
33
34
|
density: "normal",
|
|
@@ -108,6 +109,19 @@ function createTableOrchestrationStore({
|
|
|
108
109
|
set({ columnVisibility: {} });
|
|
109
110
|
goCustom();
|
|
110
111
|
},
|
|
112
|
+
pinColumn: (columnId, side) => set((s) => {
|
|
113
|
+
const left = (s.columnPinning.left ?? []).filter((id) => id !== columnId);
|
|
114
|
+
const right = (s.columnPinning.right ?? []).filter((id) => id !== columnId);
|
|
115
|
+
if (side === "left") left.push(columnId);
|
|
116
|
+
else right.push(columnId);
|
|
117
|
+
return { columnPinning: { left, right } };
|
|
118
|
+
}),
|
|
119
|
+
unpinColumn: (columnId) => set((s) => ({
|
|
120
|
+
columnPinning: {
|
|
121
|
+
left: (s.columnPinning.left ?? []).filter((id) => id !== columnId),
|
|
122
|
+
right: (s.columnPinning.right ?? []).filter((id) => id !== columnId)
|
|
123
|
+
}
|
|
124
|
+
})),
|
|
111
125
|
setPage: (p) => set({ page: p }),
|
|
112
126
|
setRowsPerPage: (n) => set({ rowsPerPage: n, page: 1 }),
|
|
113
127
|
setDensity: (v) => set({ density: v }),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useState, useRef, useMemo, useCallback, useLayoutEffect, useEffect } from "react";
|
|
2
2
|
import { useStore } from "zustand";
|
|
3
3
|
import { useColumnResize } from "../components/data-table/hooks/use-column-resize.js";
|
|
4
|
+
import { applyColumnPinningToMeta } from "../components/data-table/sticky-utils.js";
|
|
4
5
|
import { getVisiblePageNumbers } from "../components/data-table/hooks/use-table-pagination.js";
|
|
5
6
|
import { createTableOrchestrationStore } from "./table-orchestration-store.js";
|
|
6
7
|
import { useColumnFilterStats } from "./table-orchestration/use-column-filter-stats.js";
|
|
@@ -8,6 +9,26 @@ import { useColumnGaps } from "./table-orchestration/use-column-gaps.js";
|
|
|
8
9
|
import { useFilteredRows } from "./table-orchestration/use-filtered-rows.js";
|
|
9
10
|
import { useOrchestrationActions } from "./table-orchestration/use-orchestration-actions.js";
|
|
10
11
|
import { useResponsiveColumns } from "./table-orchestration/use-responsive-columns.js";
|
|
12
|
+
import { gapColumnId } from "../lib/column-gaps.js";
|
|
13
|
+
function computeVisibleColumnOrder(input) {
|
|
14
|
+
const { columnMeta, toggleableColumnIds, columnVisibility, columnGaps } = input;
|
|
15
|
+
const order = [];
|
|
16
|
+
if (columnMeta.rowControl) order.push("rowControl");
|
|
17
|
+
for (const id of toggleableColumnIds) {
|
|
18
|
+
if (columnVisibility[id] !== false) order.push(id);
|
|
19
|
+
}
|
|
20
|
+
for (const gap of columnGaps) {
|
|
21
|
+
const gapId = gapColumnId(gap.afterColumnId);
|
|
22
|
+
if (gap.afterColumnId === null) {
|
|
23
|
+
order.unshift(gapId);
|
|
24
|
+
} else {
|
|
25
|
+
const afterIdx = order.indexOf(gap.afterColumnId);
|
|
26
|
+
if (afterIdx >= 0) order.splice(afterIdx + 1, 0, gapId);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (columnMeta.actions) order.push("actions");
|
|
30
|
+
return order;
|
|
31
|
+
}
|
|
11
32
|
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
12
33
|
function useTableOrchestration(config) {
|
|
13
34
|
const {
|
|
@@ -40,6 +61,9 @@ function useTableOrchestration(config) {
|
|
|
40
61
|
const requestOpenFilterId = useStore(store, (s) => s.requestOpenFilterId);
|
|
41
62
|
const currentSort = useStore(store, (s) => s.currentSort);
|
|
42
63
|
const columnVisibility = useStore(store, (s) => s.columnVisibility);
|
|
64
|
+
const columnPinning = useStore(store, (s) => s.columnPinning);
|
|
65
|
+
const pinColumn = useStore(store, (s) => s.pinColumn);
|
|
66
|
+
const unpinColumn = useStore(store, (s) => s.unpinColumn);
|
|
43
67
|
const storedPage = useStore(store, (s) => s.page);
|
|
44
68
|
const rowsPerPage = useStore(store, (s) => s.rowsPerPage);
|
|
45
69
|
const density = useStore(store, (s) => s.density);
|
|
@@ -120,13 +144,29 @@ function useTableOrchestration(config) {
|
|
|
120
144
|
);
|
|
121
145
|
const allOnPageSelected = pageIds.size > 0 && selectedOnPage === pageIds.size;
|
|
122
146
|
const headerCheckState = allOnPageSelected ? true : selectedOnPage > 0 ? "indeterminate" : false;
|
|
123
|
-
const { columnGaps, extendedColumnMeta, extendedWidths } = useColumnGaps({
|
|
147
|
+
const { columnGaps, extendedColumnMeta: gapExtendedColumnMeta, extendedWidths } = useColumnGaps({
|
|
124
148
|
columnGroups,
|
|
125
149
|
toggleableColumnIds,
|
|
126
150
|
columnVisibility,
|
|
127
151
|
columnMeta,
|
|
128
152
|
widths
|
|
129
153
|
});
|
|
154
|
+
const visibleColumnOrder = useMemo(
|
|
155
|
+
() => computeVisibleColumnOrder({
|
|
156
|
+
columnMeta,
|
|
157
|
+
toggleableColumnIds,
|
|
158
|
+
columnVisibility,
|
|
159
|
+
columnGaps
|
|
160
|
+
}),
|
|
161
|
+
[columnGaps, columnMeta, columnVisibility, toggleableColumnIds]
|
|
162
|
+
);
|
|
163
|
+
const extendedColumnMeta = useMemo(
|
|
164
|
+
() => applyColumnPinningToMeta(gapExtendedColumnMeta, columnPinning, {
|
|
165
|
+
columnOrder: visibleColumnOrder,
|
|
166
|
+
columnWidths: extendedWidths
|
|
167
|
+
}),
|
|
168
|
+
[columnPinning, extendedWidths, gapExtendedColumnMeta, visibleColumnOrder]
|
|
169
|
+
);
|
|
130
170
|
const hiddenColumnsCount = useMemo(() => {
|
|
131
171
|
return toggleableColumnIds.filter((id) => columnVisibility[id] === false).length;
|
|
132
172
|
}, [toggleableColumnIds, columnVisibility]);
|
|
@@ -185,6 +225,9 @@ function useTableOrchestration(config) {
|
|
|
185
225
|
currentSort,
|
|
186
226
|
columnVisibility,
|
|
187
227
|
setColumnVisibility,
|
|
228
|
+
columnPinning,
|
|
229
|
+
pinColumn,
|
|
230
|
+
unpinColumn,
|
|
188
231
|
page,
|
|
189
232
|
rowsPerPage,
|
|
190
233
|
density,
|
|
@@ -249,5 +292,6 @@ function useTableOrchestration(config) {
|
|
|
249
292
|
};
|
|
250
293
|
}
|
|
251
294
|
export {
|
|
295
|
+
computeVisibleColumnOrder,
|
|
252
296
|
useTableOrchestration
|
|
253
297
|
};
|
package/dist/es/index.js
CHANGED
|
@@ -67,6 +67,7 @@ import { useTableOrchestration } from "./hooks/useTableOrchestration.js";
|
|
|
67
67
|
import { createTableOrchestrationStore, defaultValueForFilter } from "./hooks/table-orchestration-store.js";
|
|
68
68
|
import { useRowDragOverride } from "./hooks/useRowDragOverride.js";
|
|
69
69
|
import { downloadCsvFile, exportTableToCsv } from "./lib/export-table-csv.js";
|
|
70
|
+
import { applyColumnPinningToMeta } from "./components/data-table/sticky-utils.js";
|
|
70
71
|
import { computeColumnGaps, gapColumnId } from "./lib/column-gaps.js";
|
|
71
72
|
import { computeColumnStats } from "./lib/filter-stats.js";
|
|
72
73
|
import { formatEnumLabel } from "./lib/format-enum.js";
|
|
@@ -176,6 +177,7 @@ export {
|
|
|
176
177
|
TopBar,
|
|
177
178
|
TwoPanelMenuBase,
|
|
178
179
|
ViewChip,
|
|
180
|
+
applyColumnPinningToMeta,
|
|
179
181
|
applyManagedChanges,
|
|
180
182
|
badgeVariants,
|
|
181
183
|
buttonVariants,
|
package/dist/styles.css
CHANGED
package/dist/tablewright.cjs
CHANGED
|
@@ -931,6 +931,49 @@ function ScrollArea({ children, className }) {
|
|
|
931
931
|
);
|
|
932
932
|
}
|
|
933
933
|
TableLayout.ScrollArea = ScrollArea;
|
|
934
|
+
function columnWidthPx(columnId, meta, columnWidths) {
|
|
935
|
+
return columnWidths?.[columnId] ?? meta[columnId]?.minW ?? 0;
|
|
936
|
+
}
|
|
937
|
+
function applyColumnPinningToMeta(baseMeta, pinning, options) {
|
|
938
|
+
const order = options?.columnOrder ?? Object.keys(baseMeta);
|
|
939
|
+
const pinnedLeft = new Set(pinning.left ?? []);
|
|
940
|
+
const pinnedRight = new Set(pinning.right ?? []);
|
|
941
|
+
const result = {};
|
|
942
|
+
for (const [id, meta] of Object.entries(baseMeta)) {
|
|
943
|
+
if (pinnedLeft.has(id)) {
|
|
944
|
+
result[id] = { ...meta, sticky: "left" };
|
|
945
|
+
} else if (pinnedRight.has(id)) {
|
|
946
|
+
result[id] = { ...meta, sticky: "right" };
|
|
947
|
+
} else {
|
|
948
|
+
result[id] = { ...meta };
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
let leftOffset = 0;
|
|
952
|
+
for (const id of order) {
|
|
953
|
+
const meta = result[id];
|
|
954
|
+
if (meta?.sticky !== "left") continue;
|
|
955
|
+
const width = columnWidthPx(id, baseMeta, options?.columnWidths);
|
|
956
|
+
if (pinnedLeft.has(id)) {
|
|
957
|
+
result[id] = { ...meta, stickyOffset: leftOffset };
|
|
958
|
+
leftOffset += width;
|
|
959
|
+
} else {
|
|
960
|
+
leftOffset = (meta.stickyOffset ?? 0) + width;
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
let rightOffset = 0;
|
|
964
|
+
for (const id of [...order].reverse()) {
|
|
965
|
+
const meta = result[id];
|
|
966
|
+
if (meta?.sticky !== "right") continue;
|
|
967
|
+
const width = columnWidthPx(id, baseMeta, options?.columnWidths);
|
|
968
|
+
if (pinnedRight.has(id)) {
|
|
969
|
+
result[id] = { ...meta, stickyOffset: rightOffset };
|
|
970
|
+
rightOffset += width;
|
|
971
|
+
} else {
|
|
972
|
+
rightOffset = (meta.stickyOffset ?? 0) + width;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
return result;
|
|
976
|
+
}
|
|
934
977
|
function stickyStyle(meta, isHeader) {
|
|
935
978
|
if (isHeader) {
|
|
936
979
|
return {
|
|
@@ -4868,6 +4911,7 @@ function createTableOrchestrationStore({
|
|
|
4868
4911
|
requestOpenFilterId: null,
|
|
4869
4912
|
currentSort: null,
|
|
4870
4913
|
columnVisibility: initialColumnVisibility ?? {},
|
|
4914
|
+
columnPinning: { left: [], right: [] },
|
|
4871
4915
|
page: 1,
|
|
4872
4916
|
rowsPerPage: initialRowsPerPage,
|
|
4873
4917
|
density: "normal",
|
|
@@ -4948,6 +4992,19 @@ function createTableOrchestrationStore({
|
|
|
4948
4992
|
set({ columnVisibility: {} });
|
|
4949
4993
|
goCustom();
|
|
4950
4994
|
},
|
|
4995
|
+
pinColumn: (columnId, side) => set((s) => {
|
|
4996
|
+
const left = (s.columnPinning.left ?? []).filter((id) => id !== columnId);
|
|
4997
|
+
const right = (s.columnPinning.right ?? []).filter((id) => id !== columnId);
|
|
4998
|
+
if (side === "left") left.push(columnId);
|
|
4999
|
+
else right.push(columnId);
|
|
5000
|
+
return { columnPinning: { left, right } };
|
|
5001
|
+
}),
|
|
5002
|
+
unpinColumn: (columnId) => set((s) => ({
|
|
5003
|
+
columnPinning: {
|
|
5004
|
+
left: (s.columnPinning.left ?? []).filter((id) => id !== columnId),
|
|
5005
|
+
right: (s.columnPinning.right ?? []).filter((id) => id !== columnId)
|
|
5006
|
+
}
|
|
5007
|
+
})),
|
|
4951
5008
|
setPage: (p) => set({ page: p }),
|
|
4952
5009
|
setRowsPerPage: (n) => set({ rowsPerPage: n, page: 1 }),
|
|
4953
5010
|
setDensity: (v) => set({ density: v }),
|
|
@@ -5372,6 +5429,25 @@ function useResponsiveColumns(columnPriorities, wideBreakpoint, compactBreakpoin
|
|
|
5372
5429
|
}, [isWide, columnPriorities]);
|
|
5373
5430
|
return { responsiveHiddenColumnIds, isCompact };
|
|
5374
5431
|
}
|
|
5432
|
+
function computeVisibleColumnOrder(input) {
|
|
5433
|
+
const { columnMeta, toggleableColumnIds, columnVisibility, columnGaps } = input;
|
|
5434
|
+
const order = [];
|
|
5435
|
+
if (columnMeta.rowControl) order.push("rowControl");
|
|
5436
|
+
for (const id of toggleableColumnIds) {
|
|
5437
|
+
if (columnVisibility[id] !== false) order.push(id);
|
|
5438
|
+
}
|
|
5439
|
+
for (const gap of columnGaps) {
|
|
5440
|
+
const gapId = gapColumnId(gap.afterColumnId);
|
|
5441
|
+
if (gap.afterColumnId === null) {
|
|
5442
|
+
order.unshift(gapId);
|
|
5443
|
+
} else {
|
|
5444
|
+
const afterIdx = order.indexOf(gap.afterColumnId);
|
|
5445
|
+
if (afterIdx >= 0) order.splice(afterIdx + 1, 0, gapId);
|
|
5446
|
+
}
|
|
5447
|
+
}
|
|
5448
|
+
if (columnMeta.actions) order.push("actions");
|
|
5449
|
+
return order;
|
|
5450
|
+
}
|
|
5375
5451
|
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect;
|
|
5376
5452
|
function useTableOrchestration(config) {
|
|
5377
5453
|
const {
|
|
@@ -5404,6 +5480,9 @@ function useTableOrchestration(config) {
|
|
|
5404
5480
|
const requestOpenFilterId = zustand.useStore(store, (s) => s.requestOpenFilterId);
|
|
5405
5481
|
const currentSort = zustand.useStore(store, (s) => s.currentSort);
|
|
5406
5482
|
const columnVisibility = zustand.useStore(store, (s) => s.columnVisibility);
|
|
5483
|
+
const columnPinning = zustand.useStore(store, (s) => s.columnPinning);
|
|
5484
|
+
const pinColumn = zustand.useStore(store, (s) => s.pinColumn);
|
|
5485
|
+
const unpinColumn = zustand.useStore(store, (s) => s.unpinColumn);
|
|
5407
5486
|
const storedPage = zustand.useStore(store, (s) => s.page);
|
|
5408
5487
|
const rowsPerPage = zustand.useStore(store, (s) => s.rowsPerPage);
|
|
5409
5488
|
const density = zustand.useStore(store, (s) => s.density);
|
|
@@ -5484,13 +5563,29 @@ function useTableOrchestration(config) {
|
|
|
5484
5563
|
);
|
|
5485
5564
|
const allOnPageSelected = pageIds.size > 0 && selectedOnPage === pageIds.size;
|
|
5486
5565
|
const headerCheckState = allOnPageSelected ? true : selectedOnPage > 0 ? "indeterminate" : false;
|
|
5487
|
-
const { columnGaps, extendedColumnMeta, extendedWidths } = useColumnGaps({
|
|
5566
|
+
const { columnGaps, extendedColumnMeta: gapExtendedColumnMeta, extendedWidths } = useColumnGaps({
|
|
5488
5567
|
columnGroups,
|
|
5489
5568
|
toggleableColumnIds,
|
|
5490
5569
|
columnVisibility,
|
|
5491
5570
|
columnMeta,
|
|
5492
5571
|
widths
|
|
5493
5572
|
});
|
|
5573
|
+
const visibleColumnOrder = React.useMemo(
|
|
5574
|
+
() => computeVisibleColumnOrder({
|
|
5575
|
+
columnMeta,
|
|
5576
|
+
toggleableColumnIds,
|
|
5577
|
+
columnVisibility,
|
|
5578
|
+
columnGaps
|
|
5579
|
+
}),
|
|
5580
|
+
[columnGaps, columnMeta, columnVisibility, toggleableColumnIds]
|
|
5581
|
+
);
|
|
5582
|
+
const extendedColumnMeta = React.useMemo(
|
|
5583
|
+
() => applyColumnPinningToMeta(gapExtendedColumnMeta, columnPinning, {
|
|
5584
|
+
columnOrder: visibleColumnOrder,
|
|
5585
|
+
columnWidths: extendedWidths
|
|
5586
|
+
}),
|
|
5587
|
+
[columnPinning, extendedWidths, gapExtendedColumnMeta, visibleColumnOrder]
|
|
5588
|
+
);
|
|
5494
5589
|
const hiddenColumnsCount = React.useMemo(() => {
|
|
5495
5590
|
return toggleableColumnIds.filter((id) => columnVisibility[id] === false).length;
|
|
5496
5591
|
}, [toggleableColumnIds, columnVisibility]);
|
|
@@ -5549,6 +5644,9 @@ function useTableOrchestration(config) {
|
|
|
5549
5644
|
currentSort,
|
|
5550
5645
|
columnVisibility,
|
|
5551
5646
|
setColumnVisibility,
|
|
5647
|
+
columnPinning,
|
|
5648
|
+
pinColumn,
|
|
5649
|
+
unpinColumn,
|
|
5552
5650
|
page,
|
|
5553
5651
|
rowsPerPage,
|
|
5554
5652
|
density,
|
|
@@ -6089,6 +6187,7 @@ exports.TimestampCell = TimestampCell;
|
|
|
6089
6187
|
exports.TopBar = TopBar;
|
|
6090
6188
|
exports.TwoPanelMenuBase = TwoPanelMenuBase;
|
|
6091
6189
|
exports.ViewChip = ViewChip;
|
|
6190
|
+
exports.applyColumnPinningToMeta = applyColumnPinningToMeta;
|
|
6092
6191
|
exports.applyManagedChanges = applyManagedChanges;
|
|
6093
6192
|
exports.badgeVariants = badgeVariants;
|
|
6094
6193
|
exports.buttonVariants = buttonVariants;
|
package/dist/tablewright.css
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
|
+
import type { ColumnPinningState } from "@tanstack/react-table";
|
|
1
2
|
import type { CSSProperties } from "react";
|
|
2
3
|
import type { ColumnMetaDef } from "./types.js";
|
|
4
|
+
export interface ApplyColumnPinningToMetaOptions {
|
|
5
|
+
/** Visible columns in left-to-right display order (include gap columns when present). */
|
|
6
|
+
columnOrder: readonly string[];
|
|
7
|
+
/** Resolved widths in px; falls back to `meta.minW`. */
|
|
8
|
+
columnWidths?: Record<string, number>;
|
|
9
|
+
}
|
|
10
|
+
/** @internal Exported for unit tests (not re-exported from package entry). */
|
|
11
|
+
export declare function columnWidthPx(columnId: string, meta: Record<string, ColumnMetaDef>, columnWidths?: Record<string, number>): number;
|
|
12
|
+
/** Merges TanStack `ColumnPinningState` into column meta sticky fields for rendering. */
|
|
13
|
+
export declare function applyColumnPinningToMeta(baseMeta: Record<string, ColumnMetaDef>, pinning: ColumnPinningState, options?: ApplyColumnPinningToMetaOptions): Record<string, ColumnMetaDef>;
|
|
3
14
|
export declare function stickyStyle(meta: ColumnMetaDef | undefined, isHeader: boolean): CSSProperties | undefined;
|
|
4
15
|
export declare function stickyBorderClass(meta: ColumnMetaDef | undefined): string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { VisibilityState } from "@tanstack/react-table";
|
|
1
|
+
import type { ColumnPinningState, VisibilityState } from "@tanstack/react-table";
|
|
2
2
|
import type { ActiveFilter, ActiveFilterValue, ColumnFilterConfig } from "../components/data-table/filter-types.js";
|
|
3
3
|
export interface TableOrchestrationState<TViewKey extends string = string> {
|
|
4
4
|
searchInput: string;
|
|
@@ -11,6 +11,7 @@ export interface TableOrchestrationState<TViewKey extends string = string> {
|
|
|
11
11
|
direction: "asc" | "desc";
|
|
12
12
|
} | null;
|
|
13
13
|
columnVisibility: VisibilityState;
|
|
14
|
+
columnPinning: ColumnPinningState;
|
|
14
15
|
page: number;
|
|
15
16
|
rowsPerPage: number;
|
|
16
17
|
density: "normal" | "dense";
|
|
@@ -39,6 +40,8 @@ export interface TableOrchestrationActions<TViewKey extends string = string> {
|
|
|
39
40
|
hideColumn: (columnId: string) => void;
|
|
40
41
|
showColumns: (columnIds: string[]) => void;
|
|
41
42
|
resetColumns: () => void;
|
|
43
|
+
pinColumn: (columnId: string, side: "left" | "right") => void;
|
|
44
|
+
unpinColumn: (columnId: string) => void;
|
|
42
45
|
setPage: (p: number) => void;
|
|
43
46
|
setRowsPerPage: (n: number) => void;
|
|
44
47
|
setDensity: (v: "normal" | "dense") => void;
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
import type { VisibilityState } from "@tanstack/react-table";
|
|
1
|
+
import type { ColumnPinningState, VisibilityState } from "@tanstack/react-table";
|
|
2
2
|
import type { ColumnMetaDef, SortDirection } from "../components/data-table/types.js";
|
|
3
3
|
import type { ActiveFilter, ActiveFilterValue, ColumnFilterConfig, ColumnGap, ColumnGroup, FilterStatsSlice, ViewPreset } from "../components/data-table/filter-types.js";
|
|
4
4
|
import { type TableOrchestrationStoreApi } from "./table-orchestration-store.js";
|
|
5
|
+
/** @internal Exported for unit tests (not re-exported from package entry). */
|
|
6
|
+
export declare function computeVisibleColumnOrder(input: {
|
|
7
|
+
columnMeta: Record<string, ColumnMetaDef>;
|
|
8
|
+
toggleableColumnIds: readonly string[];
|
|
9
|
+
columnVisibility: VisibilityState;
|
|
10
|
+
columnGaps: ColumnGap[];
|
|
11
|
+
}): string[];
|
|
5
12
|
export interface TableOrchestrationConfig<TRow extends object, TViewKey extends string> {
|
|
6
13
|
rows: TRow[];
|
|
7
14
|
getRowId: (row: TRow) => string;
|
|
@@ -49,6 +56,9 @@ export interface TableOrchestrationReturn<TRow extends object, TViewKey extends
|
|
|
49
56
|
} | null;
|
|
50
57
|
columnVisibility: VisibilityState;
|
|
51
58
|
setColumnVisibility: React.Dispatch<React.SetStateAction<VisibilityState>>;
|
|
59
|
+
columnPinning: ColumnPinningState;
|
|
60
|
+
pinColumn: (columnId: string, side: "left" | "right") => void;
|
|
61
|
+
unpinColumn: (columnId: string) => void;
|
|
52
62
|
page: number;
|
|
53
63
|
rowsPerPage: number;
|
|
54
64
|
density: "normal" | "dense";
|
package/dist/types/index.d.ts
CHANGED
|
@@ -104,6 +104,8 @@ export { useRowDragOverride } from "./hooks/useRowDragOverride.js";
|
|
|
104
104
|
export type { UseRowDragOverrideResult } from "./hooks/useRowDragOverride.js";
|
|
105
105
|
export { downloadCsvFile, exportTableToCsv, } from "./lib/export-table-csv.js";
|
|
106
106
|
export type { DownloadCsvFileOptions, ExportTableToCsvOptions, } from "./lib/export-table-csv.js";
|
|
107
|
+
export { applyColumnPinningToMeta } from "./components/data-table/sticky-utils.js";
|
|
108
|
+
export type { ApplyColumnPinningToMetaOptions } from "./components/data-table/sticky-utils.js";
|
|
107
109
|
export { computeColumnGaps, gapColumnId } from "./lib/column-gaps.js";
|
|
108
110
|
export { computeColumnStats } from "./lib/filter-stats.js";
|
|
109
111
|
export { formatEnumLabel } from "./lib/format-enum.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@undevy-org/tablewright",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "React data-table and application-shell components: filters, drawers, row controls, sortable and resizable columns, built on Radix UI and TanStack Table.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|