@zvndev/yable-react 0.4.0 → 0.5.0
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/index.cjs +788 -215
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +116 -11
- package/dist/index.d.ts +116 -11
- package/dist/index.js +784 -216
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var yableCore = require('@zvndev/yable-core');
|
|
4
4
|
var React3 = require('react');
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
var reactDom = require('react-dom');
|
|
6
7
|
var rowDragging = require('@zvndev/yable-core/features/rowDragging');
|
|
7
8
|
|
|
8
9
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -16,6 +17,8 @@ function useYableDefaults() {
|
|
|
16
17
|
}
|
|
17
18
|
function YableProvider({
|
|
18
19
|
children,
|
|
20
|
+
config,
|
|
21
|
+
tableProfile,
|
|
19
22
|
defaultColumnDef,
|
|
20
23
|
striped,
|
|
21
24
|
stickyHeader,
|
|
@@ -34,12 +37,86 @@ function YableProvider({
|
|
|
34
37
|
if (direction !== void 0) tableProps.direction = direction;
|
|
35
38
|
if (ariaLabel !== void 0) tableProps.ariaLabel = ariaLabel;
|
|
36
39
|
const value = {
|
|
40
|
+
config,
|
|
41
|
+
tableProfile,
|
|
37
42
|
tableProps: Object.keys(tableProps).length > 0 ? tableProps : void 0,
|
|
38
43
|
defaultColumnDef
|
|
39
44
|
};
|
|
40
45
|
return /* @__PURE__ */ jsxRuntime.jsx(YableContext.Provider, { value, children });
|
|
41
46
|
}
|
|
42
47
|
|
|
48
|
+
// src/config.ts
|
|
49
|
+
function createYableConfig(config) {
|
|
50
|
+
return config;
|
|
51
|
+
}
|
|
52
|
+
function resolveYableProfile(config, profileName = "default") {
|
|
53
|
+
const base = pickProfileFields(config);
|
|
54
|
+
const named = profileName === "default" ? void 0 : config?.profiles?.[profileName];
|
|
55
|
+
return {
|
|
56
|
+
name: profileName,
|
|
57
|
+
table: { ...base.table, ...named?.table },
|
|
58
|
+
columns: {
|
|
59
|
+
default: { ...base.columns?.default, ...named?.columns?.default },
|
|
60
|
+
byId: { ...base.columns?.byId, ...named?.columns?.byId }
|
|
61
|
+
},
|
|
62
|
+
rows: { ...base.rows, ...named?.rows },
|
|
63
|
+
cells: {
|
|
64
|
+
default: { ...base.cells?.default, ...named?.cells?.default },
|
|
65
|
+
named: { ...base.cells?.named, ...named?.cells?.named },
|
|
66
|
+
byColumn: { ...base.cells?.byColumn, ...named?.cells?.byColumn }
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function getYableDefaultColumnDef(profile) {
|
|
71
|
+
const next = {
|
|
72
|
+
...profile?.columns?.default
|
|
73
|
+
};
|
|
74
|
+
return Object.keys(next).length > 0 ? next : void 0;
|
|
75
|
+
}
|
|
76
|
+
function applyYableConfigToColumns(columns, profile) {
|
|
77
|
+
if (!profile) return columns;
|
|
78
|
+
return columns.map((columnDef) => applyColumnConfig(columnDef, profile));
|
|
79
|
+
}
|
|
80
|
+
function applyColumnConfig(columnDef, profile) {
|
|
81
|
+
const columnId = getColumnId(columnDef);
|
|
82
|
+
const explicit = columnDef;
|
|
83
|
+
const cellNames = normalizeCellConfigNames(explicit.cellConfig);
|
|
84
|
+
const namedCellConfig = cellNames.reduce(
|
|
85
|
+
(acc, name) => ({ ...acc, ...profile.cells?.named?.[name] }),
|
|
86
|
+
{}
|
|
87
|
+
);
|
|
88
|
+
const defaultCell = profile.cells?.default;
|
|
89
|
+
const columnCell = columnId ? profile.cells?.byColumn?.[columnId] : void 0;
|
|
90
|
+
const columnConfig = columnId ? profile.columns?.byId?.[columnId] : void 0;
|
|
91
|
+
const children = "columns" in columnDef && columnDef.columns ? { columns: columnDef.columns.map((child) => applyColumnConfig(child, profile)) } : void 0;
|
|
92
|
+
return {
|
|
93
|
+
...defaultCell,
|
|
94
|
+
...namedCellConfig,
|
|
95
|
+
...columnCell,
|
|
96
|
+
...columnConfig,
|
|
97
|
+
...columnDef,
|
|
98
|
+
...children
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function pickProfileFields(config) {
|
|
102
|
+
if (!config) return {};
|
|
103
|
+
return {
|
|
104
|
+
table: config.table,
|
|
105
|
+
columns: config.columns,
|
|
106
|
+
rows: config.rows,
|
|
107
|
+
cells: config.cells
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function getColumnId(columnDef) {
|
|
111
|
+
if ("id" in columnDef && columnDef.id) return String(columnDef.id);
|
|
112
|
+
if ("accessorKey" in columnDef && columnDef.accessorKey) return String(columnDef.accessorKey);
|
|
113
|
+
return void 0;
|
|
114
|
+
}
|
|
115
|
+
function normalizeCellConfigNames(value) {
|
|
116
|
+
if (!value) return [];
|
|
117
|
+
return Array.isArray(value) ? value : [value];
|
|
118
|
+
}
|
|
119
|
+
|
|
43
120
|
// src/useTable.ts
|
|
44
121
|
function shallowEqual(a, b) {
|
|
45
122
|
if (a === b) return true;
|
|
@@ -55,15 +132,30 @@ function shallowEqual(a, b) {
|
|
|
55
132
|
function useTable(options) {
|
|
56
133
|
const providerDefaults = useYableDefaults();
|
|
57
134
|
const optionsWithDefaults = React3.useMemo(() => {
|
|
58
|
-
|
|
135
|
+
const profile = resolveYableProfile(
|
|
136
|
+
options.config ?? providerDefaults.config,
|
|
137
|
+
options.configProfile ?? providerDefaults.tableProfile
|
|
138
|
+
);
|
|
139
|
+
const profileDefaultColumnDef = getYableDefaultColumnDef(profile);
|
|
140
|
+
const configuredColumns = applyYableConfigToColumns(options.columns, profile);
|
|
141
|
+
const defaultColumnDef = {
|
|
142
|
+
...profileDefaultColumnDef,
|
|
143
|
+
...providerDefaults.defaultColumnDef,
|
|
144
|
+
...options.defaultColumnDef
|
|
145
|
+
};
|
|
59
146
|
return {
|
|
60
147
|
...options,
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
148
|
+
columns: configuredColumns,
|
|
149
|
+
rowClassName: options.rowClassName ?? profile.rows?.className,
|
|
150
|
+
rowStyle: options.rowStyle ?? profile.rows?.style,
|
|
151
|
+
defaultColumnDef: Object.keys(defaultColumnDef).length > 0 ? defaultColumnDef : void 0
|
|
65
152
|
};
|
|
66
|
-
}, [
|
|
153
|
+
}, [
|
|
154
|
+
options,
|
|
155
|
+
providerDefaults.config,
|
|
156
|
+
providerDefaults.defaultColumnDef,
|
|
157
|
+
providerDefaults.tableProfile
|
|
158
|
+
]);
|
|
67
159
|
const [state, setState] = React3.useState(() => ({
|
|
68
160
|
sorting: [],
|
|
69
161
|
columnFilters: [],
|
|
@@ -149,6 +241,32 @@ function useTable(options) {
|
|
|
149
241
|
})
|
|
150
242
|
);
|
|
151
243
|
}
|
|
244
|
+
React3.useEffect(() => {
|
|
245
|
+
const table = tableRef.current;
|
|
246
|
+
if (!table) return;
|
|
247
|
+
const unsubscribers = [
|
|
248
|
+
options.onCellClick && table.events.on("cell:click", options.onCellClick),
|
|
249
|
+
options.onCellDoubleClick && table.events.on("cell:dblclick", options.onCellDoubleClick),
|
|
250
|
+
options.onCellContextMenu && table.events.on("cell:contextmenu", options.onCellContextMenu),
|
|
251
|
+
options.onRowClick && table.events.on("row:click", options.onRowClick),
|
|
252
|
+
options.onRowDoubleClick && table.events.on("row:dblclick", options.onRowDoubleClick),
|
|
253
|
+
options.onRowContextMenu && table.events.on("row:contextmenu", options.onRowContextMenu),
|
|
254
|
+
options.onHeaderClick && table.events.on("header:click", options.onHeaderClick),
|
|
255
|
+
options.onHeaderContextMenu && table.events.on("header:contextmenu", options.onHeaderContextMenu)
|
|
256
|
+
].filter((unsubscribe) => Boolean(unsubscribe));
|
|
257
|
+
return () => {
|
|
258
|
+
unsubscribers.forEach((unsubscribe) => unsubscribe());
|
|
259
|
+
};
|
|
260
|
+
}, [
|
|
261
|
+
options.onCellClick,
|
|
262
|
+
options.onCellContextMenu,
|
|
263
|
+
options.onCellDoubleClick,
|
|
264
|
+
options.onHeaderClick,
|
|
265
|
+
options.onHeaderContextMenu,
|
|
266
|
+
options.onRowClick,
|
|
267
|
+
options.onRowContextMenu,
|
|
268
|
+
options.onRowDoubleClick
|
|
269
|
+
]);
|
|
152
270
|
React3.useEffect(() => {
|
|
153
271
|
return () => {
|
|
154
272
|
if (tableRef.current) {
|
|
@@ -158,6 +276,195 @@ function useTable(options) {
|
|
|
158
276
|
}, []);
|
|
159
277
|
return tableRef.current;
|
|
160
278
|
}
|
|
279
|
+
function useServerTable({
|
|
280
|
+
fetchData,
|
|
281
|
+
updateRow,
|
|
282
|
+
initialRows = [],
|
|
283
|
+
initialCursor = null,
|
|
284
|
+
initialHasMore = true,
|
|
285
|
+
initialRowCount,
|
|
286
|
+
initialPageCount,
|
|
287
|
+
initialSorting = [],
|
|
288
|
+
initialColumnFilters = [],
|
|
289
|
+
initialGlobalFilter = "",
|
|
290
|
+
initialPagination = { pageIndex: 0, pageSize: 50 },
|
|
291
|
+
autoLoad = true,
|
|
292
|
+
getRowId,
|
|
293
|
+
...tableOptions
|
|
294
|
+
}) {
|
|
295
|
+
const [rows, setRows] = React3.useState(initialRows);
|
|
296
|
+
const [cursor, setCursor] = React3.useState(initialCursor);
|
|
297
|
+
const [hasMore, setHasMore] = React3.useState(initialHasMore);
|
|
298
|
+
const [rowCount, setRowCount] = React3.useState(initialRowCount);
|
|
299
|
+
const [pageCount, setPageCount] = React3.useState(initialPageCount);
|
|
300
|
+
const [sorting, setSorting] = React3.useState(initialSorting);
|
|
301
|
+
const [columnFilters, setColumnFilters] = React3.useState(initialColumnFilters);
|
|
302
|
+
const [globalFilter, setGlobalFilter] = React3.useState(initialGlobalFilter);
|
|
303
|
+
const [pagination, setPagination] = React3.useState(initialPagination);
|
|
304
|
+
const [loading, setLoading] = React3.useState(false);
|
|
305
|
+
const [error, setError] = React3.useState(null);
|
|
306
|
+
const abortRef = React3.useRef(null);
|
|
307
|
+
const cursorRef = React3.useRef(cursor);
|
|
308
|
+
const fetchDataRef = React3.useRef(fetchData);
|
|
309
|
+
const updateRowRef = React3.useRef(updateRow);
|
|
310
|
+
const resolveRowId = React3.useCallback(
|
|
311
|
+
(row, index) => getRowId?.(row, index) ?? String(row.id ?? index),
|
|
312
|
+
[getRowId]
|
|
313
|
+
);
|
|
314
|
+
const runFetch = React3.useCallback(
|
|
315
|
+
async (mode) => {
|
|
316
|
+
abortRef.current?.abort();
|
|
317
|
+
const abort = new AbortController();
|
|
318
|
+
abortRef.current = abort;
|
|
319
|
+
setLoading(true);
|
|
320
|
+
setError(null);
|
|
321
|
+
try {
|
|
322
|
+
const result = await fetchDataRef.current({
|
|
323
|
+
sorting,
|
|
324
|
+
columnFilters,
|
|
325
|
+
globalFilter,
|
|
326
|
+
pagination,
|
|
327
|
+
cursor: mode === "append" ? cursorRef.current : null,
|
|
328
|
+
signal: abort.signal
|
|
329
|
+
});
|
|
330
|
+
if (abort.signal.aborted) return;
|
|
331
|
+
setRows((prev) => mode === "append" ? [...prev, ...result.rows] : result.rows);
|
|
332
|
+
setCursor(result.cursor ?? null);
|
|
333
|
+
setHasMore((prev) => result.hasMore ?? prev);
|
|
334
|
+
setRowCount((prev) => result.rowCount ?? prev);
|
|
335
|
+
setPageCount((prev) => result.pageCount ?? prev);
|
|
336
|
+
} catch (nextError) {
|
|
337
|
+
if (!abort.signal.aborted) setError(nextError);
|
|
338
|
+
} finally {
|
|
339
|
+
if (!abort.signal.aborted) setLoading(false);
|
|
340
|
+
}
|
|
341
|
+
},
|
|
342
|
+
[columnFilters, globalFilter, pagination, sorting]
|
|
343
|
+
);
|
|
344
|
+
const refresh = React3.useCallback(() => runFetch("replace"), [runFetch]);
|
|
345
|
+
const loadMore = React3.useCallback(async () => {
|
|
346
|
+
if (!hasMore || loading) return;
|
|
347
|
+
await runFetch("append");
|
|
348
|
+
}, [hasMore, loading, runFetch]);
|
|
349
|
+
const patchRow = React3.useCallback(
|
|
350
|
+
async (rowId, patch) => {
|
|
351
|
+
const previousRow = rows.find((row, index) => resolveRowId(row, index) === rowId);
|
|
352
|
+
setRows(
|
|
353
|
+
(prev) => prev.map((row, index) => resolveRowId(row, index) === rowId ? { ...row, ...patch } : row)
|
|
354
|
+
);
|
|
355
|
+
if (!updateRowRef.current) return;
|
|
356
|
+
const abort = new AbortController();
|
|
357
|
+
try {
|
|
358
|
+
const result = await updateRowRef.current({
|
|
359
|
+
rowId,
|
|
360
|
+
patch,
|
|
361
|
+
previousRow,
|
|
362
|
+
signal: abort.signal
|
|
363
|
+
});
|
|
364
|
+
if (!result) return;
|
|
365
|
+
setRows(
|
|
366
|
+
(prev) => prev.map(
|
|
367
|
+
(row, index) => resolveRowId(row, index) === rowId ? { ...row, ...result } : row
|
|
368
|
+
)
|
|
369
|
+
);
|
|
370
|
+
} catch (nextError) {
|
|
371
|
+
setError(nextError);
|
|
372
|
+
if (previousRow) {
|
|
373
|
+
setRows(
|
|
374
|
+
(prev) => prev.map((row, index) => resolveRowId(row, index) === rowId ? previousRow : row)
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
},
|
|
379
|
+
[resolveRowId, rows]
|
|
380
|
+
);
|
|
381
|
+
React3.useEffect(() => {
|
|
382
|
+
fetchDataRef.current = fetchData;
|
|
383
|
+
}, [fetchData]);
|
|
384
|
+
React3.useEffect(() => {
|
|
385
|
+
updateRowRef.current = updateRow;
|
|
386
|
+
}, [updateRow]);
|
|
387
|
+
React3.useEffect(() => {
|
|
388
|
+
if (!autoLoad) return;
|
|
389
|
+
void refresh();
|
|
390
|
+
}, [autoLoad, refresh]);
|
|
391
|
+
React3.useEffect(() => {
|
|
392
|
+
cursorRef.current = cursor;
|
|
393
|
+
}, [cursor]);
|
|
394
|
+
React3.useEffect(() => () => abortRef.current?.abort(), []);
|
|
395
|
+
const table = useTable({
|
|
396
|
+
...tableOptions,
|
|
397
|
+
data: rows,
|
|
398
|
+
getRowId: resolveRowId,
|
|
399
|
+
manualSorting: true,
|
|
400
|
+
manualFiltering: true,
|
|
401
|
+
manualPagination: true,
|
|
402
|
+
rowCount,
|
|
403
|
+
pageCount,
|
|
404
|
+
state: {
|
|
405
|
+
sorting,
|
|
406
|
+
columnFilters,
|
|
407
|
+
globalFilter,
|
|
408
|
+
pagination
|
|
409
|
+
},
|
|
410
|
+
onSortingChange: (updater) => {
|
|
411
|
+
setSorting((prev) => yableCore.functionalUpdate(updater, prev));
|
|
412
|
+
setCursor(null);
|
|
413
|
+
setHasMore(true);
|
|
414
|
+
},
|
|
415
|
+
onColumnFiltersChange: (updater) => {
|
|
416
|
+
setColumnFilters((prev) => yableCore.functionalUpdate(updater, prev));
|
|
417
|
+
setCursor(null);
|
|
418
|
+
setHasMore(true);
|
|
419
|
+
},
|
|
420
|
+
onGlobalFilterChange: (updater) => {
|
|
421
|
+
setGlobalFilter((prev) => yableCore.functionalUpdate(updater, prev));
|
|
422
|
+
setCursor(null);
|
|
423
|
+
setHasMore(true);
|
|
424
|
+
},
|
|
425
|
+
onPaginationChange: (updater) => {
|
|
426
|
+
setPagination((prev) => yableCore.functionalUpdate(updater, prev));
|
|
427
|
+
setCursor(null);
|
|
428
|
+
setHasMore(true);
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
return React3.useMemo(
|
|
432
|
+
() => ({
|
|
433
|
+
table,
|
|
434
|
+
rows,
|
|
435
|
+
loading,
|
|
436
|
+
error,
|
|
437
|
+
cursor,
|
|
438
|
+
hasMore,
|
|
439
|
+
rowCount,
|
|
440
|
+
pageCount,
|
|
441
|
+
sorting,
|
|
442
|
+
columnFilters,
|
|
443
|
+
globalFilter,
|
|
444
|
+
pagination,
|
|
445
|
+
refresh,
|
|
446
|
+
loadMore,
|
|
447
|
+
updateRow: patchRow
|
|
448
|
+
}),
|
|
449
|
+
[
|
|
450
|
+
table,
|
|
451
|
+
rows,
|
|
452
|
+
loading,
|
|
453
|
+
error,
|
|
454
|
+
cursor,
|
|
455
|
+
hasMore,
|
|
456
|
+
rowCount,
|
|
457
|
+
pageCount,
|
|
458
|
+
sorting,
|
|
459
|
+
columnFilters,
|
|
460
|
+
globalFilter,
|
|
461
|
+
pagination,
|
|
462
|
+
refresh,
|
|
463
|
+
loadMore,
|
|
464
|
+
patchRow
|
|
465
|
+
]
|
|
466
|
+
);
|
|
467
|
+
}
|
|
161
468
|
var DEFAULT_PERSISTED_KEYS = [
|
|
162
469
|
"columnVisibility",
|
|
163
470
|
"columnOrder",
|
|
@@ -354,7 +661,7 @@ function useVirtualization({
|
|
|
354
661
|
resizeObserver.disconnect();
|
|
355
662
|
}
|
|
356
663
|
};
|
|
357
|
-
}, [containerRef]);
|
|
664
|
+
}, [containerRef, totalRows]);
|
|
358
665
|
React3.useEffect(() => {
|
|
359
666
|
if (!isFixedHeight) {
|
|
360
667
|
heightCacheRef.current.clear();
|
|
@@ -545,14 +852,20 @@ function useColumnVirtualization({
|
|
|
545
852
|
containerRef,
|
|
546
853
|
columns,
|
|
547
854
|
overscan = 2,
|
|
548
|
-
enabled = true
|
|
855
|
+
enabled = true,
|
|
856
|
+
sizingKey
|
|
549
857
|
}) {
|
|
550
858
|
const [scrollState, setScrollState] = React3.useState({
|
|
551
859
|
scrollLeft: 0,
|
|
552
860
|
containerWidth: 0
|
|
553
861
|
});
|
|
554
862
|
const rafRef = React3.useRef(null);
|
|
555
|
-
const sizes = React3.useMemo(
|
|
863
|
+
const sizes = React3.useMemo(
|
|
864
|
+
() => columns.map((column) => column.getSize()),
|
|
865
|
+
// `sizingKey` is an explicit invalidation hook for stable Column objects whose getSize value changed.
|
|
866
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
867
|
+
[columns, sizingKey]
|
|
868
|
+
);
|
|
556
869
|
const offsets = React3.useMemo(() => {
|
|
557
870
|
const next = new Array(columns.length + 1);
|
|
558
871
|
next[0] = 0;
|
|
@@ -1130,12 +1443,12 @@ function getRegisteredCellTypes() {
|
|
|
1130
1443
|
|
|
1131
1444
|
// src/hooks/useAutoMeasurements.ts
|
|
1132
1445
|
var NON_DATA_COLUMN_IDS = /* @__PURE__ */ new Set(["select", "expand", "drag", "actions"]);
|
|
1133
|
-
function
|
|
1446
|
+
function getColumnId2(col) {
|
|
1134
1447
|
const id = col.id ?? col.accessorKey;
|
|
1135
1448
|
return typeof id === "string" ? id : void 0;
|
|
1136
1449
|
}
|
|
1137
1450
|
function defaultShouldMeasure(col) {
|
|
1138
|
-
const id =
|
|
1451
|
+
const id = getColumnId2(col);
|
|
1139
1452
|
if (!id) return false;
|
|
1140
1453
|
if (id.startsWith("_")) return false;
|
|
1141
1454
|
if (NON_DATA_COLUMN_IDS.has(id)) return false;
|
|
@@ -1160,11 +1473,11 @@ function useAutoMeasurements({
|
|
|
1160
1473
|
getColumnWidth = defaultGetColumnWidth,
|
|
1161
1474
|
shouldMeasureColumn = defaultShouldMeasure
|
|
1162
1475
|
}) {
|
|
1163
|
-
const widthKey = columns.map((c) => `${
|
|
1476
|
+
const widthKey = columns.map((c) => `${getColumnId2(c) ?? "?"}:${getColumnWidth(c)}`).join("|");
|
|
1164
1477
|
return React3.useMemo(() => {
|
|
1165
1478
|
const result = [];
|
|
1166
1479
|
for (const col of columns) {
|
|
1167
|
-
const id =
|
|
1480
|
+
const id = getColumnId2(col);
|
|
1168
1481
|
if (!id) continue;
|
|
1169
1482
|
if (!shouldMeasureColumn(col)) continue;
|
|
1170
1483
|
const recipe = resolveMeasureRecipe(col, defaultRecipe);
|
|
@@ -1483,16 +1796,170 @@ function FloatingFilter({ column }) {
|
|
|
1483
1796
|
}
|
|
1484
1797
|
) });
|
|
1485
1798
|
}
|
|
1486
|
-
var
|
|
1799
|
+
var REORDER_TRANSITION = "transform 180ms cubic-bezier(0.2, 0, 0, 1)";
|
|
1800
|
+
function transformAt(i, d) {
|
|
1801
|
+
if (i === d.fromIndex) return 0;
|
|
1802
|
+
if (d.toIndex > d.fromIndex) return i > d.fromIndex && i < d.toIndex ? -d.width : 0;
|
|
1803
|
+
return i >= d.toIndex && i < d.fromIndex ? d.width : 0;
|
|
1804
|
+
}
|
|
1487
1805
|
function TableHeader({
|
|
1488
1806
|
table,
|
|
1489
1807
|
floatingFilters = false
|
|
1490
1808
|
}) {
|
|
1491
1809
|
const headerGroups = table.getHeaderGroups();
|
|
1492
1810
|
const visibleColumns = table.getVisibleLeafColumns();
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1811
|
+
const theadRef = React3.useRef(null);
|
|
1812
|
+
const reorderEndRef = React3.useRef(0);
|
|
1813
|
+
const [drag, setDrag] = React3.useState(null);
|
|
1814
|
+
const commitReorder = React3.useCallback(
|
|
1815
|
+
(d) => {
|
|
1816
|
+
if (d.toIndex === d.fromIndex || d.toIndex === d.fromIndex + 1) return;
|
|
1817
|
+
const order = table.getState().columnOrder;
|
|
1818
|
+
const base = order && order.length > 0 ? [...order] : d.layout.map((l) => l.id);
|
|
1819
|
+
const targetId = d.toIndex < d.layout.length ? d.layout[d.toIndex].id : null;
|
|
1820
|
+
const next = base.filter((id) => id !== d.columnId);
|
|
1821
|
+
let insertAt = targetId ? next.indexOf(targetId) : next.length;
|
|
1822
|
+
if (insertAt === -1) insertAt = next.length;
|
|
1823
|
+
next.splice(insertAt, 0, d.columnId);
|
|
1824
|
+
table.setColumnOrder(next);
|
|
1825
|
+
},
|
|
1826
|
+
[table]
|
|
1827
|
+
);
|
|
1828
|
+
const beginReorder = React3.useCallback(
|
|
1829
|
+
(e, columnId) => {
|
|
1830
|
+
if (e.button !== 0) return;
|
|
1831
|
+
const thead = theadRef.current;
|
|
1832
|
+
if (!thead) return;
|
|
1833
|
+
const startX = e.clientX;
|
|
1834
|
+
const startY = e.clientY;
|
|
1835
|
+
const layout = [];
|
|
1836
|
+
let top = 0;
|
|
1837
|
+
let height = 0;
|
|
1838
|
+
for (const c of visibleColumns) {
|
|
1839
|
+
const th = thead.querySelector(`th[data-column-id="${CSS.escape(c.id)}"]`);
|
|
1840
|
+
if (!th) return;
|
|
1841
|
+
const r = th.getBoundingClientRect();
|
|
1842
|
+
layout.push({ id: c.id, left: r.left, width: r.width });
|
|
1843
|
+
if (c.id === columnId) {
|
|
1844
|
+
top = r.top;
|
|
1845
|
+
height = r.height;
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
const fromIndex = layout.findIndex((l) => l.id === columnId);
|
|
1849
|
+
if (fromIndex < 0) return;
|
|
1850
|
+
const src = layout[fromIndex];
|
|
1851
|
+
const bodyRoot = thead.closest("table");
|
|
1852
|
+
const applyBody = (d) => {
|
|
1853
|
+
if (!bodyRoot) return;
|
|
1854
|
+
visibleColumns.forEach((col, i) => {
|
|
1855
|
+
if (col.getIsPinned()) return;
|
|
1856
|
+
const tx = transformAt(i, d);
|
|
1857
|
+
bodyRoot.querySelectorAll(`td[data-column-id="${CSS.escape(col.id)}"]`).forEach((td) => {
|
|
1858
|
+
td.style.transition = REORDER_TRANSITION;
|
|
1859
|
+
td.style.opacity = i === d.fromIndex ? "0" : "";
|
|
1860
|
+
td.style.transform = i !== d.fromIndex && tx ? `translateX(${tx}px)` : "";
|
|
1861
|
+
});
|
|
1862
|
+
});
|
|
1863
|
+
};
|
|
1864
|
+
const clearBody = () => {
|
|
1865
|
+
bodyRoot?.querySelectorAll("td[data-column-id]").forEach((td) => {
|
|
1866
|
+
td.style.transform = "";
|
|
1867
|
+
td.style.transition = "";
|
|
1868
|
+
td.style.opacity = "";
|
|
1869
|
+
});
|
|
1870
|
+
};
|
|
1871
|
+
let started = false;
|
|
1872
|
+
let latest = {
|
|
1873
|
+
columnId,
|
|
1874
|
+
fromIndex,
|
|
1875
|
+
toIndex: fromIndex,
|
|
1876
|
+
pointerX: startX,
|
|
1877
|
+
grabOffsetX: startX - src.left,
|
|
1878
|
+
width: src.width,
|
|
1879
|
+
top,
|
|
1880
|
+
height,
|
|
1881
|
+
layout
|
|
1882
|
+
};
|
|
1883
|
+
const computeToIndex = (x) => {
|
|
1884
|
+
let t = layout.findIndex((l) => x < l.left + l.width / 2);
|
|
1885
|
+
if (t === -1) t = layout.length;
|
|
1886
|
+
return t;
|
|
1887
|
+
};
|
|
1888
|
+
const onMove = (ev) => {
|
|
1889
|
+
if (!started) {
|
|
1890
|
+
if (Math.abs(ev.clientX - startX) < 4 && Math.abs(ev.clientY - startY) < 4) return;
|
|
1891
|
+
started = true;
|
|
1892
|
+
table.setColumnDragActive(true);
|
|
1893
|
+
document.body.style.userSelect = "none";
|
|
1894
|
+
document.body.style.cursor = "grabbing";
|
|
1895
|
+
}
|
|
1896
|
+
latest = { ...latest, pointerX: ev.clientX, toIndex: computeToIndex(ev.clientX) };
|
|
1897
|
+
setDrag(latest);
|
|
1898
|
+
applyBody(latest);
|
|
1899
|
+
};
|
|
1900
|
+
const finish = () => {
|
|
1901
|
+
window.removeEventListener("pointermove", onMove);
|
|
1902
|
+
window.removeEventListener("pointerup", finish);
|
|
1903
|
+
window.removeEventListener("pointercancel", finish);
|
|
1904
|
+
if (started) {
|
|
1905
|
+
commitReorder(latest);
|
|
1906
|
+
reorderEndRef.current = Date.now();
|
|
1907
|
+
table.setColumnDragActive(false);
|
|
1908
|
+
document.body.style.userSelect = "";
|
|
1909
|
+
document.body.style.cursor = "";
|
|
1910
|
+
clearBody();
|
|
1911
|
+
}
|
|
1912
|
+
setDrag(null);
|
|
1913
|
+
};
|
|
1914
|
+
window.addEventListener("pointermove", onMove);
|
|
1915
|
+
window.addEventListener("pointerup", finish);
|
|
1916
|
+
window.addEventListener("pointercancel", finish);
|
|
1917
|
+
},
|
|
1918
|
+
[visibleColumns, table, commitReorder]
|
|
1919
|
+
);
|
|
1920
|
+
const transformFor = React3.useCallback(
|
|
1921
|
+
(columnId) => {
|
|
1922
|
+
if (!drag) return 0;
|
|
1923
|
+
const i = visibleColumns.findIndex((c) => c.id === columnId);
|
|
1924
|
+
if (i < 0) return 0;
|
|
1925
|
+
return transformAt(i, drag);
|
|
1926
|
+
},
|
|
1927
|
+
[drag, visibleColumns]
|
|
1928
|
+
);
|
|
1929
|
+
const dragColumn = drag ? visibleColumns.find((c) => c.id === drag.columnId) : null;
|
|
1930
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("thead", { className: "yable-thead", ref: theadRef, children: [
|
|
1931
|
+
headerGroups.map((headerGroup) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "yable-header-row", children: headerGroup.headers.map((header) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1932
|
+
HeaderCell,
|
|
1933
|
+
{
|
|
1934
|
+
header,
|
|
1935
|
+
table,
|
|
1936
|
+
onReorderPointerDown: beginReorder,
|
|
1937
|
+
dragTransform: transformFor(header.column.id),
|
|
1938
|
+
isDragSource: drag?.columnId === header.column.id,
|
|
1939
|
+
dragActive: drag !== null,
|
|
1940
|
+
reorderEndRef
|
|
1941
|
+
},
|
|
1942
|
+
header.id
|
|
1943
|
+
)) }, headerGroup.id)),
|
|
1944
|
+
floatingFilters && visibleColumns.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "yable-header-row yable-header-row--filters", children: visibleColumns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(FloatingFilterCell, { column }, `${column.id}-filter`)) }),
|
|
1945
|
+
drag && dragColumn && typeof document !== "undefined" && reactDom.createPortal(
|
|
1946
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1947
|
+
"div",
|
|
1948
|
+
{
|
|
1949
|
+
className: "yable-col-drag-ghost",
|
|
1950
|
+
"aria-hidden": "true",
|
|
1951
|
+
style: {
|
|
1952
|
+
position: "fixed",
|
|
1953
|
+
top: drag.top,
|
|
1954
|
+
left: drag.pointerX - drag.grabOffsetX,
|
|
1955
|
+
width: drag.width,
|
|
1956
|
+
height: drag.height
|
|
1957
|
+
},
|
|
1958
|
+
children: typeof dragColumn.columnDef.header === "string" ? dragColumn.columnDef.header : dragColumn.id
|
|
1959
|
+
}
|
|
1960
|
+
),
|
|
1961
|
+
document.body
|
|
1962
|
+
)
|
|
1496
1963
|
] });
|
|
1497
1964
|
}
|
|
1498
1965
|
function FloatingFilterCell({
|
|
@@ -1521,7 +1988,12 @@ function FloatingFilterCell({
|
|
|
1521
1988
|
}
|
|
1522
1989
|
function HeaderCell({
|
|
1523
1990
|
header,
|
|
1524
|
-
table
|
|
1991
|
+
table,
|
|
1992
|
+
onReorderPointerDown,
|
|
1993
|
+
dragTransform,
|
|
1994
|
+
isDragSource,
|
|
1995
|
+
dragActive,
|
|
1996
|
+
reorderEndRef
|
|
1525
1997
|
}) {
|
|
1526
1998
|
const column = header.column;
|
|
1527
1999
|
const canSort = column.getCanSort();
|
|
@@ -1529,6 +2001,7 @@ function HeaderCell({
|
|
|
1529
2001
|
const sortIndex = column.getSortIndex();
|
|
1530
2002
|
const canResize = column.getCanResize();
|
|
1531
2003
|
const canReorder = column.getCanReorder() && !header.isPlaceholder;
|
|
2004
|
+
const pinned = column.getIsPinned();
|
|
1532
2005
|
const headerContent = header.isPlaceholder ? null : typeof column.columnDef.header === "function" ? column.columnDef.header(header.getContext()) : column.columnDef.header ?? header.id;
|
|
1533
2006
|
const style = React3.useMemo(() => {
|
|
1534
2007
|
const s = {
|
|
@@ -1536,18 +2009,19 @@ function HeaderCell({
|
|
|
1536
2009
|
minWidth: column.columnDef.minSize,
|
|
1537
2010
|
maxWidth: column.columnDef.maxSize
|
|
1538
2011
|
};
|
|
1539
|
-
|
|
1540
|
-
if (pinned2) {
|
|
2012
|
+
if (pinned) {
|
|
1541
2013
|
s.position = "sticky";
|
|
1542
|
-
if (
|
|
2014
|
+
if (pinned === "left") {
|
|
1543
2015
|
s.left = header.getStart("left");
|
|
1544
2016
|
} else {
|
|
1545
2017
|
s.right = header.getStart("right");
|
|
1546
2018
|
}
|
|
1547
2019
|
}
|
|
2020
|
+
if (!pinned && !isDragSource && dragTransform !== 0) {
|
|
2021
|
+
s.transform = `translateX(${dragTransform}px)`;
|
|
2022
|
+
}
|
|
1548
2023
|
return s;
|
|
1549
|
-
}, [header, column]);
|
|
1550
|
-
const pinned = column.getIsPinned();
|
|
2024
|
+
}, [header, column, pinned, isDragSource, dragTransform]);
|
|
1551
2025
|
const lastResizeEndRef = React3.useRef(0);
|
|
1552
2026
|
const startResize = React3.useCallback(
|
|
1553
2027
|
(e) => {
|
|
@@ -1567,122 +2041,60 @@ function HeaderCell({
|
|
|
1567
2041
|
const handleResizeClick = React3.useCallback((e) => {
|
|
1568
2042
|
e.stopPropagation();
|
|
1569
2043
|
}, []);
|
|
1570
|
-
const
|
|
1571
|
-
const handleDragStart = React3.useCallback(
|
|
1572
|
-
(e) => {
|
|
1573
|
-
if (!canReorder) return;
|
|
1574
|
-
e.stopPropagation();
|
|
1575
|
-
e.dataTransfer.effectAllowed = "move";
|
|
1576
|
-
try {
|
|
1577
|
-
e.dataTransfer.setData(DRAG_MIME, column.id);
|
|
1578
|
-
e.dataTransfer.setData("text/plain", column.id);
|
|
1579
|
-
} catch {
|
|
1580
|
-
}
|
|
1581
|
-
table.setColumnDragActive(true);
|
|
1582
|
-
},
|
|
1583
|
-
[canReorder, column.id, table]
|
|
1584
|
-
);
|
|
1585
|
-
const handleDragOver = React3.useCallback(
|
|
1586
|
-
(e) => {
|
|
1587
|
-
if (!canReorder) return;
|
|
1588
|
-
const types = e.dataTransfer.types;
|
|
1589
|
-
let isYableDrag = false;
|
|
1590
|
-
for (let i = 0; i < types.length; i++) {
|
|
1591
|
-
if (types[i] === DRAG_MIME) {
|
|
1592
|
-
isYableDrag = true;
|
|
1593
|
-
break;
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
if (!isYableDrag) return;
|
|
1597
|
-
e.preventDefault();
|
|
1598
|
-
e.dataTransfer.dropEffect = "move";
|
|
1599
|
-
const rect = e.currentTarget.getBoundingClientRect();
|
|
1600
|
-
const midpoint = rect.left + rect.width / 2;
|
|
1601
|
-
setDragOver(e.clientX < midpoint ? "left" : "right");
|
|
1602
|
-
},
|
|
1603
|
-
[canReorder]
|
|
1604
|
-
);
|
|
1605
|
-
const handleDragLeave = React3.useCallback((e) => {
|
|
1606
|
-
const next = e.relatedTarget;
|
|
1607
|
-
if (next && e.currentTarget.contains(next)) return;
|
|
1608
|
-
setDragOver(null);
|
|
1609
|
-
}, []);
|
|
1610
|
-
const handleDragEnd = React3.useCallback(() => {
|
|
1611
|
-
setDragOver(null);
|
|
1612
|
-
table.setColumnDragActive(false);
|
|
1613
|
-
}, [table]);
|
|
1614
|
-
const handleDrop = React3.useCallback(
|
|
2044
|
+
const handleContentPointerDown = React3.useCallback(
|
|
1615
2045
|
(e) => {
|
|
1616
|
-
if (!canReorder) return;
|
|
1617
|
-
e.
|
|
1618
|
-
e.stopPropagation();
|
|
1619
|
-
const sourceId = e.dataTransfer.getData(DRAG_MIME);
|
|
1620
|
-
const rect = e.currentTarget.getBoundingClientRect();
|
|
1621
|
-
const insertAfter = e.clientX >= rect.left + rect.width / 2;
|
|
1622
|
-
setDragOver(null);
|
|
1623
|
-
table.setColumnDragActive(false);
|
|
1624
|
-
if (!sourceId || sourceId === column.id) return;
|
|
1625
|
-
const state = table.getState();
|
|
1626
|
-
const allLeafs = table.getAllLeafColumns();
|
|
1627
|
-
const baseOrder = state.columnOrder && state.columnOrder.length > 0 ? state.columnOrder : allLeafs.map((c) => c.id);
|
|
1628
|
-
const next = [];
|
|
1629
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1630
|
-
for (const id of baseOrder) {
|
|
1631
|
-
if (allLeafs.some((c) => c.id === id)) {
|
|
1632
|
-
next.push(id);
|
|
1633
|
-
seen.add(id);
|
|
1634
|
-
}
|
|
1635
|
-
}
|
|
1636
|
-
for (const c of allLeafs) {
|
|
1637
|
-
if (!seen.has(c.id)) {
|
|
1638
|
-
next.push(c.id);
|
|
1639
|
-
seen.add(c.id);
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
const fromIdx = next.indexOf(sourceId);
|
|
1643
|
-
if (fromIdx === -1) return;
|
|
1644
|
-
next.splice(fromIdx, 1);
|
|
1645
|
-
let toIdx = next.indexOf(column.id);
|
|
1646
|
-
if (toIdx === -1) return;
|
|
1647
|
-
if (insertAfter) toIdx += 1;
|
|
1648
|
-
next.splice(toIdx, 0, sourceId);
|
|
1649
|
-
table.setColumnOrder(next);
|
|
2046
|
+
if (!canReorder || pinned) return;
|
|
2047
|
+
onReorderPointerDown(e, column.id);
|
|
1650
2048
|
},
|
|
1651
|
-
[canReorder, column.id
|
|
2049
|
+
[canReorder, pinned, onReorderPointerDown, column.id]
|
|
1652
2050
|
);
|
|
1653
2051
|
const handleHeaderClick = React3.useCallback(
|
|
1654
2052
|
(e) => {
|
|
2053
|
+
table.events.emit("header:click", {
|
|
2054
|
+
column,
|
|
2055
|
+
header,
|
|
2056
|
+
originalEvent: e
|
|
2057
|
+
});
|
|
1655
2058
|
if (!canSort) return;
|
|
1656
2059
|
if (Date.now() - lastResizeEndRef.current < 250) return;
|
|
2060
|
+
if (Date.now() - reorderEndRef.current < 250) return;
|
|
1657
2061
|
const handler = column.getToggleSortingHandler();
|
|
1658
2062
|
if (handler) handler(e);
|
|
1659
2063
|
},
|
|
1660
|
-
[canSort, column]
|
|
2064
|
+
[canSort, column, header, table.events, reorderEndRef]
|
|
2065
|
+
);
|
|
2066
|
+
const handleHeaderContextMenu = React3.useCallback(
|
|
2067
|
+
(e) => {
|
|
2068
|
+
table.events.emit("header:contextmenu", {
|
|
2069
|
+
column,
|
|
2070
|
+
header,
|
|
2071
|
+
originalEvent: e
|
|
2072
|
+
});
|
|
2073
|
+
},
|
|
2074
|
+
[column, header, table.events]
|
|
1661
2075
|
);
|
|
1662
2076
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1663
2077
|
"th",
|
|
1664
2078
|
{
|
|
1665
2079
|
className: "yable-th",
|
|
1666
2080
|
style,
|
|
2081
|
+
"data-column-id": column.id,
|
|
1667
2082
|
"data-sortable": canSort || void 0,
|
|
1668
2083
|
"data-pinned": pinned || void 0,
|
|
1669
|
-
"data-reorderable": canReorder || void 0,
|
|
1670
|
-
"data-
|
|
2084
|
+
"data-reorderable": canReorder && !pinned || void 0,
|
|
2085
|
+
"data-reordering": dragActive && !pinned || void 0,
|
|
2086
|
+
"data-drag-source": isDragSource || void 0,
|
|
1671
2087
|
"aria-sort": sortDirection === "asc" ? "ascending" : sortDirection === "desc" ? "descending" : canSort ? "none" : void 0,
|
|
1672
2088
|
role: "columnheader",
|
|
1673
2089
|
colSpan: header.colSpan,
|
|
1674
2090
|
onClick: handleHeaderClick,
|
|
1675
|
-
|
|
1676
|
-
onDragLeave: canReorder ? handleDragLeave : void 0,
|
|
1677
|
-
onDrop: canReorder ? handleDrop : void 0,
|
|
2091
|
+
onContextMenu: handleHeaderContextMenu,
|
|
1678
2092
|
children: [
|
|
1679
2093
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1680
2094
|
"div",
|
|
1681
2095
|
{
|
|
1682
2096
|
className: "yable-th-content",
|
|
1683
|
-
|
|
1684
|
-
onDragStart: canReorder ? handleDragStart : void 0,
|
|
1685
|
-
onDragEnd: canReorder ? handleDragEnd : void 0,
|
|
2097
|
+
onPointerDown: canReorder && !pinned ? handleContentPointerDown : void 0,
|
|
1686
2098
|
children: [
|
|
1687
2099
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: headerContent }),
|
|
1688
2100
|
canSort && /* @__PURE__ */ jsxRuntime.jsx(SortIndicator, { direction: sortDirection, index: sortIndex > 0 ? sortIndex : void 0 })
|
|
@@ -1794,6 +2206,7 @@ function TableCell({
|
|
|
1794
2206
|
const isAlwaysEditable = cell.getIsAlwaysEditable();
|
|
1795
2207
|
const pinned = column.getIsPinned();
|
|
1796
2208
|
const keyboardNavigationEnabled = table.options.enableKeyboardNavigation !== false;
|
|
2209
|
+
const cellSelectionEnabled = table.options.enableCellSelection !== false && column.columnDef.enableCellSelection !== false;
|
|
1797
2210
|
const style = {
|
|
1798
2211
|
width: column.getSize(),
|
|
1799
2212
|
minWidth: column.columnDef.minSize,
|
|
@@ -1878,6 +2291,7 @@ function TableCell({
|
|
|
1878
2291
|
const handleMouseDown = React3.useCallback(
|
|
1879
2292
|
(e) => {
|
|
1880
2293
|
if (e.button !== 0) return;
|
|
2294
|
+
if (!cellSelectionEnabled) return;
|
|
1881
2295
|
const clickTarget = e.target;
|
|
1882
2296
|
if (isInteractiveClickTarget(clickTarget)) return;
|
|
1883
2297
|
e.preventDefault();
|
|
@@ -1885,12 +2299,13 @@ function TableCell({
|
|
|
1885
2299
|
table.startCellRangeSelection({ rowIndex, columnIndex }, { extend: e.shiftKey });
|
|
1886
2300
|
e.currentTarget.focus({ preventScroll: true });
|
|
1887
2301
|
},
|
|
1888
|
-
[columnIndex, rowIndex, table]
|
|
2302
|
+
[cellSelectionEnabled, columnIndex, rowIndex, table]
|
|
1889
2303
|
);
|
|
1890
2304
|
const handleMouseEnter = React3.useCallback(() => {
|
|
2305
|
+
if (!cellSelectionEnabled) return;
|
|
1891
2306
|
if (!table.getState().cellSelection?.isDragging) return;
|
|
1892
2307
|
table.updateCellRangeSelection({ rowIndex, columnIndex });
|
|
1893
|
-
}, [columnIndex, rowIndex, table]);
|
|
2308
|
+
}, [cellSelectionEnabled, columnIndex, rowIndex, table]);
|
|
1894
2309
|
const handleMouseUp = React3.useCallback(() => {
|
|
1895
2310
|
if (!table.getState().cellSelection?.isDragging) return;
|
|
1896
2311
|
table.endCellRangeSelection();
|
|
@@ -2054,6 +2469,33 @@ var CellErrorBoundary = class extends React3__default.default.Component {
|
|
|
2054
2469
|
return this.props.children;
|
|
2055
2470
|
}
|
|
2056
2471
|
};
|
|
2472
|
+
function MasterDetail({
|
|
2473
|
+
row,
|
|
2474
|
+
table,
|
|
2475
|
+
colSpan,
|
|
2476
|
+
renderDetailPanel,
|
|
2477
|
+
animationClass
|
|
2478
|
+
}) {
|
|
2479
|
+
const renderer = renderDetailPanel ?? table.options.renderDetailPanel;
|
|
2480
|
+
if (!renderer) return null;
|
|
2481
|
+
const content = renderer(row);
|
|
2482
|
+
if (content == null) return null;
|
|
2483
|
+
const classes = [
|
|
2484
|
+
"yable-detail-row",
|
|
2485
|
+
"yable-detail-row--animated",
|
|
2486
|
+
animationClass
|
|
2487
|
+
].filter(Boolean).join(" ");
|
|
2488
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2489
|
+
"tr",
|
|
2490
|
+
{
|
|
2491
|
+
className: classes,
|
|
2492
|
+
"data-detail-for": row.id,
|
|
2493
|
+
role: "row",
|
|
2494
|
+
"aria-label": `Details for row ${row.id}`,
|
|
2495
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("td", { className: "yable-detail-cell", colSpan, role: "cell", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "yable-detail-panel", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "yable-detail-panel-inner", children: content }) }) })
|
|
2496
|
+
}
|
|
2497
|
+
);
|
|
2498
|
+
}
|
|
2057
2499
|
function TableBody({
|
|
2058
2500
|
table,
|
|
2059
2501
|
clickableRows,
|
|
@@ -2067,6 +2509,7 @@ function TableBody({
|
|
|
2067
2509
|
range: null,
|
|
2068
2510
|
isDragging: false
|
|
2069
2511
|
};
|
|
2512
|
+
const pendingValues = table.getState().editing.pendingValues ?? {};
|
|
2070
2513
|
const options = table.options;
|
|
2071
2514
|
const enableVirtualization = options.enableVirtualization ?? false;
|
|
2072
2515
|
const scrollContainerRef = React3.useRef(null);
|
|
@@ -2110,24 +2553,40 @@ function TableBody({
|
|
|
2110
2553
|
window.removeEventListener("mouseup", handleWindowMouseUp);
|
|
2111
2554
|
};
|
|
2112
2555
|
}, [table]);
|
|
2556
|
+
const renderRow = (row, rowIndex, pinnedPosition) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2557
|
+
MemoizedTableRow,
|
|
2558
|
+
{
|
|
2559
|
+
row,
|
|
2560
|
+
table,
|
|
2561
|
+
rowIndex,
|
|
2562
|
+
visibleColumns,
|
|
2563
|
+
isSelected: row.getIsSelected(),
|
|
2564
|
+
isExpanded: row.getIsExpanded(),
|
|
2565
|
+
activeColumnId: activeCell?.rowId === row.id ? activeCell.columnId : void 0,
|
|
2566
|
+
focusedColumnIndex: focusedCell?.rowIndex === rowIndex ? focusedCell.columnIndex : null,
|
|
2567
|
+
hasFocusedCell: focusedCell !== null,
|
|
2568
|
+
cellSelectionKey,
|
|
2569
|
+
pendingValuesKey: getPendingValuesKey(pendingValues[row.id]),
|
|
2570
|
+
clickable: clickableRows,
|
|
2571
|
+
pinnedPosition
|
|
2572
|
+
},
|
|
2573
|
+
row.id
|
|
2574
|
+
);
|
|
2113
2575
|
if (!enableVirtualization) {
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
},
|
|
2129
|
-
row.id
|
|
2130
|
-
)) });
|
|
2576
|
+
const rowPinning = table.getState().rowPinning;
|
|
2577
|
+
const hasPinnedRows = (rowPinning.top?.length ?? 0) > 0 || (rowPinning.bottom?.length ?? 0) > 0;
|
|
2578
|
+
if (hasPinnedRows) {
|
|
2579
|
+
const topRows = table.getTopRows();
|
|
2580
|
+
const centerRows = table.getCenterRows();
|
|
2581
|
+
const bottomRows = table.getBottomRows();
|
|
2582
|
+
let visualIndex = 0;
|
|
2583
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("tbody", { className: "yable-tbody", children: [
|
|
2584
|
+
topRows.map((row) => renderRow(row, visualIndex++, "top")),
|
|
2585
|
+
centerRows.map((row) => renderRow(row, visualIndex++)),
|
|
2586
|
+
bottomRows.map((row) => renderRow(row, visualIndex++, "bottom"))
|
|
2587
|
+
] });
|
|
2588
|
+
}
|
|
2589
|
+
return /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "yable-tbody", children: rows.map((row, rowIndex) => renderRow(row, rowIndex)) });
|
|
2131
2590
|
}
|
|
2132
2591
|
const hasPretextData = !!(pretextHeights && pretextPrefixSums);
|
|
2133
2592
|
const fixedRowHeight = typeof rowHeight === "number" && !hasPretextData ? rowHeight : void 0;
|
|
@@ -2176,6 +2635,7 @@ function TableBody({
|
|
|
2176
2635
|
focusedColumnIndex: focusedCell?.rowIndex === vRow.index ? focusedCell.columnIndex : null,
|
|
2177
2636
|
hasFocusedCell: focusedCell !== null,
|
|
2178
2637
|
cellSelectionKey,
|
|
2638
|
+
pendingValuesKey: getPendingValuesKey(pendingValues[row.id]),
|
|
2179
2639
|
clickable: clickableRows,
|
|
2180
2640
|
virtualStyle: {
|
|
2181
2641
|
position: "absolute",
|
|
@@ -2208,13 +2668,18 @@ function TableRowInner({
|
|
|
2208
2668
|
focusedColumnIndex,
|
|
2209
2669
|
hasFocusedCell,
|
|
2210
2670
|
cellSelectionKey: _cellSelectionKey,
|
|
2671
|
+
pendingValuesKey: _pendingValuesKey,
|
|
2211
2672
|
clickable,
|
|
2673
|
+
pinnedPosition,
|
|
2212
2674
|
virtualStyle
|
|
2213
2675
|
}) {
|
|
2214
2676
|
const allCells = row.getAllCells();
|
|
2215
2677
|
const visibleCells = visibleColumns.map((column) => allCells.find((cell) => cell.column.id === column.id)).filter((cell) => cell != null);
|
|
2216
2678
|
const handleClick = React3.useCallback(
|
|
2217
2679
|
(e) => {
|
|
2680
|
+
if (table.options.enableRowClickSelection && row.getCanSelect() && !isInteractiveClickTarget2(e.target)) {
|
|
2681
|
+
row.toggleSelected();
|
|
2682
|
+
}
|
|
2218
2683
|
if (clickable) {
|
|
2219
2684
|
table.events.emit("row:click", {
|
|
2220
2685
|
row,
|
|
@@ -2222,7 +2687,7 @@ function TableRowInner({
|
|
|
2222
2687
|
});
|
|
2223
2688
|
}
|
|
2224
2689
|
},
|
|
2225
|
-
[clickable, table
|
|
2690
|
+
[clickable, table, row]
|
|
2226
2691
|
);
|
|
2227
2692
|
const handleDoubleClick = React3.useCallback(
|
|
2228
2693
|
(e) => {
|
|
@@ -2244,15 +2709,26 @@ function TableRowInner({
|
|
|
2244
2709
|
);
|
|
2245
2710
|
const selectionEnabled = Boolean(table.options.enableRowSelection);
|
|
2246
2711
|
const expansionEnabled = Boolean(table.options.enableExpanding);
|
|
2712
|
+
const rowClassNameDef = table.options.rowClassName;
|
|
2713
|
+
const userRowClassName = typeof rowClassNameDef === "function" ? rowClassNameDef(row) : rowClassNameDef;
|
|
2714
|
+
const rowStyleDef = table.options.rowStyle;
|
|
2715
|
+
const userRowStyle = typeof rowStyleDef === "function" ? rowStyleDef(row) : rowStyleDef;
|
|
2716
|
+
const mergedRowStyle = userRowStyle ? { ...virtualStyle, ...userRowStyle } : virtualStyle;
|
|
2717
|
+
const rowClassName = [
|
|
2718
|
+
"yable-tr",
|
|
2719
|
+
pinnedPosition && `yable-tr--pinned-${pinnedPosition}`,
|
|
2720
|
+
userRowClassName
|
|
2721
|
+
].filter(Boolean).join(" ");
|
|
2247
2722
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2248
2723
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2249
2724
|
"tr",
|
|
2250
2725
|
{
|
|
2251
|
-
className:
|
|
2252
|
-
style:
|
|
2726
|
+
className: rowClassName,
|
|
2727
|
+
style: mergedRowStyle,
|
|
2253
2728
|
"data-selected": isSelected || void 0,
|
|
2254
2729
|
"data-expanded": isExpanded || void 0,
|
|
2255
2730
|
"data-clickable": clickable || void 0,
|
|
2731
|
+
"data-pinned-row": pinnedPosition,
|
|
2256
2732
|
"data-row-id": row.id,
|
|
2257
2733
|
"data-row-index": rowIndex,
|
|
2258
2734
|
"aria-selected": selectionEnabled ? isSelected : void 0,
|
|
@@ -2284,7 +2760,7 @@ function TableRowInner({
|
|
|
2284
2760
|
})
|
|
2285
2761
|
}
|
|
2286
2762
|
),
|
|
2287
|
-
isExpanded && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2763
|
+
isExpanded && /* @__PURE__ */ jsxRuntime.jsx(MasterDetail, { row, table, colSpan: visibleColumns.length })
|
|
2288
2764
|
] });
|
|
2289
2765
|
}
|
|
2290
2766
|
function areRowPropsEqual(prev, next) {
|
|
@@ -2295,10 +2771,12 @@ function areRowPropsEqual(prev, next) {
|
|
|
2295
2771
|
if (prev.isSelected !== next.isSelected) return false;
|
|
2296
2772
|
if (prev.isExpanded !== next.isExpanded) return false;
|
|
2297
2773
|
if (prev.clickable !== next.clickable) return false;
|
|
2774
|
+
if (prev.pinnedPosition !== next.pinnedPosition) return false;
|
|
2298
2775
|
if (prev.activeColumnId !== next.activeColumnId) return false;
|
|
2299
2776
|
if (prev.focusedColumnIndex !== next.focusedColumnIndex) return false;
|
|
2300
2777
|
if (prev.hasFocusedCell !== next.hasFocusedCell) return false;
|
|
2301
2778
|
if (prev.cellSelectionKey !== next.cellSelectionKey) return false;
|
|
2779
|
+
if (prev.pendingValuesKey !== next.pendingValuesKey) return false;
|
|
2302
2780
|
if (prev.virtualStyle !== next.virtualStyle) {
|
|
2303
2781
|
if (!prev.virtualStyle || !next.virtualStyle) return false;
|
|
2304
2782
|
if (prev.virtualStyle.transform !== next.virtualStyle.transform) return false;
|
|
@@ -2308,6 +2786,16 @@ function areRowPropsEqual(prev, next) {
|
|
|
2308
2786
|
return true;
|
|
2309
2787
|
}
|
|
2310
2788
|
var MemoizedTableRow = React3__default.default.memo(TableRowInner, areRowPropsEqual);
|
|
2789
|
+
function getPendingValuesKey(values) {
|
|
2790
|
+
if (!values) return "";
|
|
2791
|
+
return Object.keys(values).sort().map((key) => `${key}:${String(values[key])}`).join("|");
|
|
2792
|
+
}
|
|
2793
|
+
function isInteractiveClickTarget2(target) {
|
|
2794
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
2795
|
+
return Boolean(
|
|
2796
|
+
target.closest('input, textarea, select, button, a[href], [contenteditable="true"]')
|
|
2797
|
+
);
|
|
2798
|
+
}
|
|
2311
2799
|
function TableFooter({ table }) {
|
|
2312
2800
|
const footerGroups = table.getFooterGroups();
|
|
2313
2801
|
if (!footerGroups.length) return null;
|
|
@@ -2595,29 +3083,73 @@ function StatusBar({
|
|
|
2595
3083
|
] });
|
|
2596
3084
|
}
|
|
2597
3085
|
function SearchIcon() {
|
|
2598
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
3086
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3087
|
+
"svg",
|
|
3088
|
+
{
|
|
3089
|
+
className: "yable-sidebar-search-icon",
|
|
3090
|
+
width: "13",
|
|
3091
|
+
height: "13",
|
|
3092
|
+
viewBox: "0 0 14 14",
|
|
3093
|
+
fill: "none",
|
|
3094
|
+
"aria-hidden": "true",
|
|
3095
|
+
children: [
|
|
3096
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "6.25", cy: "6.25", r: "4.25", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
3097
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9.5 9.5L12.5 12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
3098
|
+
]
|
|
3099
|
+
}
|
|
3100
|
+
);
|
|
2602
3101
|
}
|
|
2603
3102
|
function VisibilityIcon({ visible }) {
|
|
2604
3103
|
if (visible) {
|
|
2605
3104
|
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": "true", children: [
|
|
2606
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3105
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3106
|
+
"path",
|
|
3107
|
+
{
|
|
3108
|
+
d: "M1 7s2.5-4 6-4 6 4 6 4-2.5 4-6 4-6-4-6-4z",
|
|
3109
|
+
stroke: "currentColor",
|
|
3110
|
+
strokeWidth: "1.2",
|
|
3111
|
+
strokeLinejoin: "round"
|
|
3112
|
+
}
|
|
3113
|
+
),
|
|
2607
3114
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "2", stroke: "currentColor", strokeWidth: "1.2" })
|
|
2608
3115
|
] });
|
|
2609
3116
|
}
|
|
2610
3117
|
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": "true", children: [
|
|
2611
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2612
|
-
|
|
3118
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3119
|
+
"path",
|
|
3120
|
+
{
|
|
3121
|
+
d: "M1 7s2.5-4 6-4 6 4 6 4-2.5 4-6 4-6-4-6-4z",
|
|
3122
|
+
stroke: "currentColor",
|
|
3123
|
+
strokeWidth: "1.2",
|
|
3124
|
+
strokeLinejoin: "round",
|
|
3125
|
+
opacity: "0.3"
|
|
3126
|
+
}
|
|
3127
|
+
),
|
|
3128
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3129
|
+
"line",
|
|
3130
|
+
{
|
|
3131
|
+
x1: "2",
|
|
3132
|
+
y1: "2",
|
|
3133
|
+
x2: "12",
|
|
3134
|
+
y2: "12",
|
|
3135
|
+
stroke: "currentColor",
|
|
3136
|
+
strokeWidth: "1.2",
|
|
3137
|
+
strokeLinecap: "round",
|
|
3138
|
+
opacity: "0.5"
|
|
3139
|
+
}
|
|
3140
|
+
)
|
|
2613
3141
|
] });
|
|
2614
3142
|
}
|
|
2615
|
-
function ColumnsPanel({
|
|
2616
|
-
table
|
|
2617
|
-
}) {
|
|
3143
|
+
function ColumnsPanel({ table }) {
|
|
2618
3144
|
const [search, setSearch] = React3.useState("");
|
|
2619
3145
|
const [draggedId, setDraggedId] = React3.useState(null);
|
|
2620
|
-
const
|
|
3146
|
+
const allColumns = table.getAllLeafColumns();
|
|
3147
|
+
const columnOrder = table.getState().columnOrder;
|
|
3148
|
+
const columns = columnOrder && columnOrder.length > 0 ? [...allColumns].sort((a, b) => {
|
|
3149
|
+
const ia = columnOrder.indexOf(a.id);
|
|
3150
|
+
const ib = columnOrder.indexOf(b.id);
|
|
3151
|
+
return (ia === -1 ? Number.MAX_SAFE_INTEGER : ia) - (ib === -1 ? Number.MAX_SAFE_INTEGER : ib);
|
|
3152
|
+
}) : allColumns;
|
|
2621
3153
|
const visibleCount = columns.filter((c) => c.getIsVisible()).length;
|
|
2622
3154
|
const filteredColumns = search ? columns.filter((col) => {
|
|
2623
3155
|
const header = typeof col.columnDef.header === "string" ? col.columnDef.header : col.id;
|
|
@@ -3044,6 +3576,7 @@ function ContextMenu({
|
|
|
3044
3576
|
y,
|
|
3045
3577
|
onClose,
|
|
3046
3578
|
table,
|
|
3579
|
+
targetColumnId,
|
|
3047
3580
|
customItems
|
|
3048
3581
|
}) {
|
|
3049
3582
|
const menuRef = React3.useRef(null);
|
|
@@ -3087,6 +3620,17 @@ function ContextMenu({
|
|
|
3087
3620
|
},
|
|
3088
3621
|
[onClose]
|
|
3089
3622
|
);
|
|
3623
|
+
const resolveSortColumn = () => {
|
|
3624
|
+
if (targetColumnId) {
|
|
3625
|
+
const column = table.getColumn(targetColumnId);
|
|
3626
|
+
if (column) return column;
|
|
3627
|
+
}
|
|
3628
|
+
const focused = table.getFocusedCell();
|
|
3629
|
+
if (focused) {
|
|
3630
|
+
return table.getVisibleLeafColumns()[focused.columnIndex];
|
|
3631
|
+
}
|
|
3632
|
+
return void 0;
|
|
3633
|
+
};
|
|
3090
3634
|
const defaultItems = [
|
|
3091
3635
|
{
|
|
3092
3636
|
id: "copy",
|
|
@@ -3135,14 +3679,14 @@ function ContextMenu({
|
|
|
3135
3679
|
id: "sort-asc",
|
|
3136
3680
|
label: "Sort Ascending",
|
|
3137
3681
|
action: () => {
|
|
3138
|
-
|
|
3682
|
+
resolveSortColumn()?.toggleSorting(false);
|
|
3139
3683
|
}
|
|
3140
3684
|
},
|
|
3141
3685
|
{
|
|
3142
3686
|
id: "sort-desc",
|
|
3143
3687
|
label: "Sort Descending",
|
|
3144
3688
|
action: () => {
|
|
3145
|
-
|
|
3689
|
+
resolveSortColumn()?.toggleSorting(true);
|
|
3146
3690
|
}
|
|
3147
3691
|
},
|
|
3148
3692
|
{
|
|
@@ -3234,11 +3778,13 @@ function useContextMenu() {
|
|
|
3234
3778
|
const [x, setX] = React3.useState(0);
|
|
3235
3779
|
const [y, setY] = React3.useState(0);
|
|
3236
3780
|
const [targetTable, setTargetTable] = React3.useState(null);
|
|
3781
|
+
const [targetColumnId, setTargetColumnId] = React3.useState(void 0);
|
|
3237
3782
|
const open = React3.useCallback(
|
|
3238
|
-
(clientX, clientY, table) => {
|
|
3783
|
+
(clientX, clientY, table, columnId) => {
|
|
3239
3784
|
setX(clientX);
|
|
3240
3785
|
setY(clientY);
|
|
3241
3786
|
setTargetTable(table);
|
|
3787
|
+
setTargetColumnId(columnId);
|
|
3242
3788
|
setIsOpen(true);
|
|
3243
3789
|
},
|
|
3244
3790
|
[]
|
|
@@ -3246,6 +3792,7 @@ function useContextMenu() {
|
|
|
3246
3792
|
const close = React3.useCallback(() => {
|
|
3247
3793
|
setIsOpen(false);
|
|
3248
3794
|
setTargetTable(null);
|
|
3795
|
+
setTargetColumnId(void 0);
|
|
3249
3796
|
}, []);
|
|
3250
3797
|
React3.useEffect(() => {
|
|
3251
3798
|
if (!isOpen) return;
|
|
@@ -3260,7 +3807,7 @@ function useContextMenu() {
|
|
|
3260
3807
|
document.removeEventListener("click", handleClick);
|
|
3261
3808
|
};
|
|
3262
3809
|
}, [isOpen, close]);
|
|
3263
|
-
return { isOpen, x, y, targetTable, open, close };
|
|
3810
|
+
return { isOpen, x, y, targetTable, targetColumnId, open, close };
|
|
3264
3811
|
}
|
|
3265
3812
|
function useKeyboardNavigation(table, options = {}) {
|
|
3266
3813
|
const {
|
|
@@ -3473,6 +4020,8 @@ function Table({
|
|
|
3473
4020
|
bordered: borderedProp,
|
|
3474
4021
|
compact: compactProp,
|
|
3475
4022
|
theme: themeProp,
|
|
4023
|
+
config,
|
|
4024
|
+
configProfile,
|
|
3476
4025
|
clickableRows,
|
|
3477
4026
|
footer,
|
|
3478
4027
|
loading,
|
|
@@ -3490,7 +4039,7 @@ function Table({
|
|
|
3490
4039
|
statusBar,
|
|
3491
4040
|
statusBarPanels,
|
|
3492
4041
|
sidebar,
|
|
3493
|
-
sidebarPanels
|
|
4042
|
+
sidebarPanels,
|
|
3494
4043
|
defaultSidebarPanel,
|
|
3495
4044
|
floatingFilters,
|
|
3496
4045
|
columnVirtualization,
|
|
@@ -3498,17 +4047,31 @@ function Table({
|
|
|
3498
4047
|
ariaLabel: ariaLabelProp,
|
|
3499
4048
|
...rest
|
|
3500
4049
|
}) {
|
|
3501
|
-
const
|
|
3502
|
-
const
|
|
3503
|
-
const
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
const
|
|
3508
|
-
const
|
|
4050
|
+
const providerDefaults = useYableDefaults();
|
|
4051
|
+
const { tableProps: providerTableProps } = providerDefaults;
|
|
4052
|
+
const profile = resolveYableProfile(
|
|
4053
|
+
config ?? providerDefaults.config,
|
|
4054
|
+
configProfile ?? providerDefaults.tableProfile
|
|
4055
|
+
);
|
|
4056
|
+
const profileTableProps = profile.table;
|
|
4057
|
+
const stickyHeader = stickyHeaderProp ?? profileTableProps?.stickyHeader ?? providerTableProps?.stickyHeader;
|
|
4058
|
+
const striped = stripedProp ?? profileTableProps?.striped ?? providerTableProps?.striped;
|
|
4059
|
+
const bordered = borderedProp ?? profileTableProps?.bordered ?? providerTableProps?.bordered;
|
|
4060
|
+
const compact = compactProp ?? profileTableProps?.compact ?? providerTableProps?.compact;
|
|
4061
|
+
const theme = themeProp ?? profileTableProps?.theme ?? providerTableProps?.theme;
|
|
4062
|
+
const direction = directionProp ?? profileTableProps?.direction ?? providerTableProps?.direction;
|
|
4063
|
+
const ariaLabel = ariaLabelProp ?? profileTableProps?.ariaLabel ?? providerTableProps?.ariaLabel;
|
|
4064
|
+
const resolvedClickableRows = clickableRows ?? profileTableProps?.clickableRows;
|
|
4065
|
+
const resolvedStatusBar = statusBar ?? profileTableProps?.statusBar;
|
|
4066
|
+
const resolvedSidebar = sidebar ?? profileTableProps?.sidebar;
|
|
4067
|
+
const resolvedSidebarPanels = sidebarPanels ?? profileTableProps?.sidebarPanels ?? ["columns", "filters"];
|
|
4068
|
+
const resolvedDefaultSidebarPanel = defaultSidebarPanel ?? profileTableProps?.defaultSidebarPanel;
|
|
4069
|
+
const resolvedFloatingFilters = floatingFilters ?? profileTableProps?.floatingFilters;
|
|
4070
|
+
const resolvedColumnVirtualization = columnVirtualization ?? profileTableProps?.columnVirtualization;
|
|
4071
|
+
const resolvedColumnVirtualizationOverscan = columnVirtualizationOverscan ?? profileTableProps?.columnVirtualizationOverscan;
|
|
3509
4072
|
const [sidebarOpen, setSidebarOpen] = React3.useState(false);
|
|
3510
4073
|
const [sidebarPanel, setSidebarPanel] = React3.useState(
|
|
3511
|
-
|
|
4074
|
+
resolvedDefaultSidebarPanel ?? "columns"
|
|
3512
4075
|
);
|
|
3513
4076
|
const containerRef = React3.useRef(null);
|
|
3514
4077
|
const horizontalScrollRef = React3.useRef(null);
|
|
@@ -3532,12 +4095,14 @@ function Table({
|
|
|
3532
4095
|
const allVisibleColumns = table.getVisibleLeafColumns();
|
|
3533
4096
|
const hasPinnedColumns = table.getLeftVisibleLeafColumns().length > 0 || table.getRightVisibleLeafColumns().length > 0;
|
|
3534
4097
|
const hasGroupedHeaders = table.getHeaderGroups().length > 1;
|
|
3535
|
-
const canVirtualizeColumns = Boolean(
|
|
4098
|
+
const canVirtualizeColumns = Boolean(resolvedColumnVirtualization) && !hasPinnedColumns && !hasGroupedHeaders && allVisibleColumns.length > 0;
|
|
4099
|
+
const allVisibleColumnSizeSignature = allVisibleColumns.map((column) => `${column.id}:${column.getSize()}`).join("|");
|
|
3536
4100
|
const columnVirtualState = useColumnVirtualization({
|
|
3537
4101
|
containerRef: horizontalScrollRef,
|
|
3538
4102
|
columns: allVisibleColumns,
|
|
3539
|
-
overscan:
|
|
3540
|
-
enabled: canVirtualizeColumns
|
|
4103
|
+
overscan: resolvedColumnVirtualizationOverscan ?? 2,
|
|
4104
|
+
enabled: canVirtualizeColumns,
|
|
4105
|
+
sizingKey: allVisibleColumnSizeSignature
|
|
3541
4106
|
});
|
|
3542
4107
|
const renderTable = React3.useMemo(() => {
|
|
3543
4108
|
if (!canVirtualizeColumns || !columnVirtualState.isVirtualized) {
|
|
@@ -3612,17 +4177,18 @@ function Table({
|
|
|
3612
4177
|
const handleContextMenu = React3.useCallback(
|
|
3613
4178
|
(e) => {
|
|
3614
4179
|
e.preventDefault();
|
|
3615
|
-
|
|
4180
|
+
const targetEl = e.target?.closest?.("[data-column-id]");
|
|
4181
|
+
const targetColumnId = targetEl?.getAttribute("data-column-id") ?? void 0;
|
|
4182
|
+
contextMenu.open(e.clientX, e.clientY, table, targetColumnId);
|
|
3616
4183
|
},
|
|
3617
4184
|
[contextMenu, table]
|
|
3618
4185
|
);
|
|
3619
|
-
const enableRowVirtualization = renderTable.options.enableVirtualization ?? false;
|
|
3620
4186
|
const visibleLeafColumns = renderTable.getVisibleLeafColumns();
|
|
3621
|
-
const
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
4187
|
+
const visibleColumnTotalSize = visibleLeafColumns.reduce(
|
|
4188
|
+
(sum, column) => sum + column.getSize(),
|
|
4189
|
+
0
|
|
4190
|
+
);
|
|
4191
|
+
const colgroup = visibleLeafColumns.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx("colgroup", { children: visibleLeafColumns.map((col) => /* @__PURE__ */ jsxRuntime.jsx("col", { style: { width: col.getSize() } }, col.id)) });
|
|
3626
4192
|
const outerTableStyle = React3.useMemo(() => {
|
|
3627
4193
|
if (columnVirtualState.isVirtualized) {
|
|
3628
4194
|
return {
|
|
@@ -3632,15 +4198,15 @@ function Table({
|
|
|
3632
4198
|
tableLayout: "fixed"
|
|
3633
4199
|
};
|
|
3634
4200
|
}
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
4201
|
+
return {
|
|
4202
|
+
minWidth: visibleColumnTotalSize || void 0,
|
|
4203
|
+
tableLayout: "fixed"
|
|
4204
|
+
};
|
|
3639
4205
|
}, [
|
|
3640
4206
|
columnVirtualState.isVirtualized,
|
|
3641
4207
|
columnVirtualState.visibleWidth,
|
|
3642
4208
|
columnVirtualState.startOffset,
|
|
3643
|
-
|
|
4209
|
+
visibleColumnTotalSize
|
|
3644
4210
|
]);
|
|
3645
4211
|
const tableNode = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3646
4212
|
"table",
|
|
@@ -3649,9 +4215,9 @@ function Table({
|
|
|
3649
4215
|
style: outerTableStyle,
|
|
3650
4216
|
"data-column-virtualized": columnVirtualState.isVirtualized || void 0,
|
|
3651
4217
|
children: [
|
|
3652
|
-
|
|
3653
|
-
/* @__PURE__ */ jsxRuntime.jsx(TableHeader, { table: renderTable, floatingFilters }),
|
|
3654
|
-
/* @__PURE__ */ jsxRuntime.jsx(TableBody, { table: renderTable, clickableRows, colgroup }),
|
|
4218
|
+
colgroup,
|
|
4219
|
+
/* @__PURE__ */ jsxRuntime.jsx(TableHeader, { table: renderTable, floatingFilters: resolvedFloatingFilters }),
|
|
4220
|
+
/* @__PURE__ */ jsxRuntime.jsx(TableBody, { table: renderTable, clickableRows: resolvedClickableRows, colgroup }),
|
|
3655
4221
|
footer && /* @__PURE__ */ jsxRuntime.jsx(TableFooter, { table: renderTable })
|
|
3656
4222
|
]
|
|
3657
4223
|
}
|
|
@@ -3717,18 +4283,43 @@ function Table({
|
|
|
3717
4283
|
}
|
|
3718
4284
|
))
|
|
3719
4285
|
] }),
|
|
3720
|
-
|
|
4286
|
+
resolvedSidebar && !sidebarOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4287
|
+
"button",
|
|
4288
|
+
{
|
|
4289
|
+
type: "button",
|
|
4290
|
+
className: "yable-sidebar-trigger",
|
|
4291
|
+
"aria-label": "Open tool panel",
|
|
4292
|
+
title: "Open tool panel",
|
|
4293
|
+
onClick: () => setSidebarOpen(true),
|
|
4294
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
|
|
4295
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4296
|
+
"rect",
|
|
4297
|
+
{
|
|
4298
|
+
x: "3",
|
|
4299
|
+
y: "4",
|
|
4300
|
+
width: "18",
|
|
4301
|
+
height: "16",
|
|
4302
|
+
rx: "2",
|
|
4303
|
+
stroke: "currentColor",
|
|
4304
|
+
strokeWidth: "2"
|
|
4305
|
+
}
|
|
4306
|
+
),
|
|
4307
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "14", y1: "4", x2: "14", y2: "20", stroke: "currentColor", strokeWidth: "2" })
|
|
4308
|
+
] })
|
|
4309
|
+
}
|
|
4310
|
+
),
|
|
4311
|
+
resolvedSidebar && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3721
4312
|
Sidebar,
|
|
3722
4313
|
{
|
|
3723
4314
|
table,
|
|
3724
4315
|
open: sidebarOpen,
|
|
3725
4316
|
onClose: () => setSidebarOpen(false),
|
|
3726
|
-
panels:
|
|
4317
|
+
panels: resolvedSidebarPanels,
|
|
3727
4318
|
activePanel: sidebarPanel,
|
|
3728
4319
|
onPanelChange: setSidebarPanel
|
|
3729
4320
|
}
|
|
3730
4321
|
),
|
|
3731
|
-
|
|
4322
|
+
resolvedStatusBar && /* @__PURE__ */ jsxRuntime.jsx(StatusBar, { table, panels: statusBarPanels }),
|
|
3732
4323
|
children,
|
|
3733
4324
|
contextMenu.isOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3734
4325
|
ContextMenu,
|
|
@@ -3736,7 +4327,8 @@ function Table({
|
|
|
3736
4327
|
x: contextMenu.x,
|
|
3737
4328
|
y: contextMenu.y,
|
|
3738
4329
|
onClose: contextMenu.close,
|
|
3739
|
-
table
|
|
4330
|
+
table,
|
|
4331
|
+
targetColumnId: contextMenu.targetColumnId
|
|
3740
4332
|
}
|
|
3741
4333
|
),
|
|
3742
4334
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4664,33 +5256,6 @@ function TreeToggle({
|
|
|
4664
5256
|
}
|
|
4665
5257
|
);
|
|
4666
5258
|
}
|
|
4667
|
-
function MasterDetail({
|
|
4668
|
-
row,
|
|
4669
|
-
table,
|
|
4670
|
-
colSpan,
|
|
4671
|
-
renderDetailPanel,
|
|
4672
|
-
animationClass
|
|
4673
|
-
}) {
|
|
4674
|
-
const renderer = renderDetailPanel ?? table.options.renderDetailPanel;
|
|
4675
|
-
if (!renderer) return null;
|
|
4676
|
-
const content = renderer(row);
|
|
4677
|
-
if (content == null) return null;
|
|
4678
|
-
const classes = [
|
|
4679
|
-
"yable-detail-row",
|
|
4680
|
-
"yable-detail-row--animated",
|
|
4681
|
-
animationClass
|
|
4682
|
-
].filter(Boolean).join(" ");
|
|
4683
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4684
|
-
"tr",
|
|
4685
|
-
{
|
|
4686
|
-
className: classes,
|
|
4687
|
-
"data-detail-for": row.id,
|
|
4688
|
-
role: "row",
|
|
4689
|
-
"aria-label": `Details for row ${row.id}`,
|
|
4690
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("td", { className: "yable-detail-cell", colSpan, role: "cell", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "yable-detail-panel", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "yable-detail-panel-inner", children: content }) }) })
|
|
4691
|
-
}
|
|
4692
|
-
);
|
|
4693
|
-
}
|
|
4694
5259
|
function ExpandIcon({
|
|
4695
5260
|
isExpanded,
|
|
4696
5261
|
onClick,
|
|
@@ -5663,10 +6228,11 @@ function selectColumn(options = {}) {
|
|
|
5663
6228
|
const { id = "_select", size = 40, headerAriaLabel = "Select all rows" } = options;
|
|
5664
6229
|
return {
|
|
5665
6230
|
id,
|
|
5666
|
-
header: ({ table }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6231
|
+
header: ({ table }) => /* @__PURE__ */ jsxRuntime.jsx("label", { className: "yable-checkbox-hitbox", onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5667
6232
|
"input",
|
|
5668
6233
|
{
|
|
5669
6234
|
type: "checkbox",
|
|
6235
|
+
className: "yable-checkbox",
|
|
5670
6236
|
checked: table.getIsAllPageRowsSelected(),
|
|
5671
6237
|
ref: (el) => {
|
|
5672
6238
|
if (el)
|
|
@@ -5675,19 +6241,21 @@ function selectColumn(options = {}) {
|
|
|
5675
6241
|
onChange: () => table.toggleAllPageRowsSelected(),
|
|
5676
6242
|
"aria-label": headerAriaLabel
|
|
5677
6243
|
}
|
|
5678
|
-
),
|
|
5679
|
-
cell: ({ row }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6244
|
+
) }),
|
|
6245
|
+
cell: ({ row }) => /* @__PURE__ */ jsxRuntime.jsx("label", { className: "yable-checkbox-hitbox", onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5680
6246
|
"input",
|
|
5681
6247
|
{
|
|
5682
6248
|
type: "checkbox",
|
|
6249
|
+
className: "yable-checkbox",
|
|
5683
6250
|
checked: row.getIsSelected(),
|
|
5684
6251
|
disabled: !row.getCanSelect(),
|
|
5685
6252
|
onChange: row.getToggleSelectedHandler(),
|
|
5686
|
-
"aria-label":
|
|
6253
|
+
"aria-label": "Select row"
|
|
5687
6254
|
}
|
|
5688
|
-
),
|
|
6255
|
+
) }),
|
|
5689
6256
|
size,
|
|
5690
|
-
enableSorting:
|
|
6257
|
+
enableSorting: true,
|
|
6258
|
+
sortingFn: (rowA, rowB) => Number(rowA.getIsSelected()) - Number(rowB.getIsSelected()),
|
|
5691
6259
|
enableColumnFilter: false,
|
|
5692
6260
|
enableResizing: false,
|
|
5693
6261
|
enableReorder: false,
|
|
@@ -6020,11 +6588,15 @@ exports.Tooltip = Tooltip;
|
|
|
6020
6588
|
exports.TreeToggle = TreeToggle;
|
|
6021
6589
|
exports.YableProvider = YableProvider;
|
|
6022
6590
|
exports.actionsColumn = actionsColumn;
|
|
6591
|
+
exports.applyYableConfigToColumns = applyYableConfigToColumns;
|
|
6592
|
+
exports.createYableConfig = createYableConfig;
|
|
6023
6593
|
exports.expandColumn = expandColumn;
|
|
6024
6594
|
exports.getMeasureRecipeForCellType = getMeasureRecipeForCellType;
|
|
6025
6595
|
exports.getRegisteredCellTypes = getRegisteredCellTypes;
|
|
6596
|
+
exports.getYableDefaultColumnDef = getYableDefaultColumnDef;
|
|
6026
6597
|
exports.mergeEditChanges = mergeEditChanges;
|
|
6027
6598
|
exports.resolveMeasureRecipe = resolveMeasureRecipe;
|
|
6599
|
+
exports.resolveYableProfile = resolveYableProfile;
|
|
6028
6600
|
exports.rowNumberColumn = rowNumberColumn;
|
|
6029
6601
|
exports.selectColumn = selectColumn;
|
|
6030
6602
|
exports.useAutoMeasurements = useAutoMeasurements;
|
|
@@ -6038,6 +6610,7 @@ exports.usePretextMeasurement = usePretextMeasurement;
|
|
|
6038
6610
|
exports.usePrintLayout = usePrintLayout;
|
|
6039
6611
|
exports.useRowAnimation = useRowAnimation;
|
|
6040
6612
|
exports.useRowDrag = useRowDrag;
|
|
6613
|
+
exports.useServerTable = useServerTable;
|
|
6041
6614
|
exports.useTable = useTable;
|
|
6042
6615
|
exports.useTableContext = useTableContext;
|
|
6043
6616
|
exports.useTablePersistence = useTablePersistence;
|