@zvndev/yable-react 0.4.0 → 0.5.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/index.cjs +1116 -517
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +123 -13
- package/dist/index.d.ts +123 -13
- package/dist/index.js +924 -330
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { canCellEnterEditMode, functionalUpdate, createTable, getDefaultLocale, getFirstKeyboardCell, getResolvedFocusedCell, detectCellChanges } from '@zvndev/yable-core';
|
|
2
2
|
export { CommitError, FormulaEngine, FormulaError, PivotEngine, UndoStack, aggregationFns, createColumnHelper, createLocale, createUndoRedoIntegration, en, filterFns, formulaFunctions, functionalUpdate, generatePivotColumnDefs, getDefaultLocale, getInitialPivotState, getPivotRowModel, resetLocale, setDefaultLocale, sortingFns } from '@zvndev/yable-core';
|
|
3
|
-
import
|
|
3
|
+
import React4, { createContext, useCallback, useMemo, useContext, useState, useRef, useEffect } from 'react';
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
|
+
import { createPortal } from 'react-dom';
|
|
5
6
|
import { getInitialRowDragState, moveRow } from '@zvndev/yable-core/features/rowDragging';
|
|
6
7
|
|
|
7
8
|
// src/index.ts
|
|
@@ -11,6 +12,8 @@ function useYableDefaults() {
|
|
|
11
12
|
}
|
|
12
13
|
function YableProvider({
|
|
13
14
|
children,
|
|
15
|
+
config,
|
|
16
|
+
tableProfile,
|
|
14
17
|
defaultColumnDef,
|
|
15
18
|
striped,
|
|
16
19
|
stickyHeader,
|
|
@@ -29,12 +32,86 @@ function YableProvider({
|
|
|
29
32
|
if (direction !== void 0) tableProps.direction = direction;
|
|
30
33
|
if (ariaLabel !== void 0) tableProps.ariaLabel = ariaLabel;
|
|
31
34
|
const value = {
|
|
35
|
+
config,
|
|
36
|
+
tableProfile,
|
|
32
37
|
tableProps: Object.keys(tableProps).length > 0 ? tableProps : void 0,
|
|
33
38
|
defaultColumnDef
|
|
34
39
|
};
|
|
35
40
|
return /* @__PURE__ */ jsx(YableContext.Provider, { value, children });
|
|
36
41
|
}
|
|
37
42
|
|
|
43
|
+
// src/config.ts
|
|
44
|
+
function createYableConfig(config) {
|
|
45
|
+
return config;
|
|
46
|
+
}
|
|
47
|
+
function resolveYableProfile(config, profileName = "default") {
|
|
48
|
+
const base = pickProfileFields(config);
|
|
49
|
+
const named = profileName === "default" ? void 0 : config?.profiles?.[profileName];
|
|
50
|
+
return {
|
|
51
|
+
name: profileName,
|
|
52
|
+
table: { ...base.table, ...named?.table },
|
|
53
|
+
columns: {
|
|
54
|
+
default: { ...base.columns?.default, ...named?.columns?.default },
|
|
55
|
+
byId: { ...base.columns?.byId, ...named?.columns?.byId }
|
|
56
|
+
},
|
|
57
|
+
rows: { ...base.rows, ...named?.rows },
|
|
58
|
+
cells: {
|
|
59
|
+
default: { ...base.cells?.default, ...named?.cells?.default },
|
|
60
|
+
named: { ...base.cells?.named, ...named?.cells?.named },
|
|
61
|
+
byColumn: { ...base.cells?.byColumn, ...named?.cells?.byColumn }
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function getYableDefaultColumnDef(profile) {
|
|
66
|
+
const next = {
|
|
67
|
+
...profile?.columns?.default
|
|
68
|
+
};
|
|
69
|
+
return Object.keys(next).length > 0 ? next : void 0;
|
|
70
|
+
}
|
|
71
|
+
function applyYableConfigToColumns(columns, profile) {
|
|
72
|
+
if (!profile) return columns;
|
|
73
|
+
return columns.map((columnDef) => applyColumnConfig(columnDef, profile));
|
|
74
|
+
}
|
|
75
|
+
function applyColumnConfig(columnDef, profile) {
|
|
76
|
+
const columnId = getColumnId(columnDef);
|
|
77
|
+
const explicit = columnDef;
|
|
78
|
+
const cellNames = normalizeCellConfigNames(explicit.cellConfig);
|
|
79
|
+
const namedCellConfig = cellNames.reduce(
|
|
80
|
+
(acc, name) => ({ ...acc, ...profile.cells?.named?.[name] }),
|
|
81
|
+
{}
|
|
82
|
+
);
|
|
83
|
+
const defaultCell = profile.cells?.default;
|
|
84
|
+
const columnCell = columnId ? profile.cells?.byColumn?.[columnId] : void 0;
|
|
85
|
+
const columnConfig = columnId ? profile.columns?.byId?.[columnId] : void 0;
|
|
86
|
+
const children = "columns" in columnDef && columnDef.columns ? { columns: columnDef.columns.map((child) => applyColumnConfig(child, profile)) } : void 0;
|
|
87
|
+
return {
|
|
88
|
+
...defaultCell,
|
|
89
|
+
...namedCellConfig,
|
|
90
|
+
...columnCell,
|
|
91
|
+
...columnConfig,
|
|
92
|
+
...columnDef,
|
|
93
|
+
...children
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function pickProfileFields(config) {
|
|
97
|
+
if (!config) return {};
|
|
98
|
+
return {
|
|
99
|
+
table: config.table,
|
|
100
|
+
columns: config.columns,
|
|
101
|
+
rows: config.rows,
|
|
102
|
+
cells: config.cells
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function getColumnId(columnDef) {
|
|
106
|
+
if ("id" in columnDef && columnDef.id) return String(columnDef.id);
|
|
107
|
+
if ("accessorKey" in columnDef && columnDef.accessorKey) return String(columnDef.accessorKey);
|
|
108
|
+
return void 0;
|
|
109
|
+
}
|
|
110
|
+
function normalizeCellConfigNames(value) {
|
|
111
|
+
if (!value) return [];
|
|
112
|
+
return Array.isArray(value) ? value : [value];
|
|
113
|
+
}
|
|
114
|
+
|
|
38
115
|
// src/useTable.ts
|
|
39
116
|
function shallowEqual(a, b) {
|
|
40
117
|
if (a === b) return true;
|
|
@@ -50,15 +127,30 @@ function shallowEqual(a, b) {
|
|
|
50
127
|
function useTable(options) {
|
|
51
128
|
const providerDefaults = useYableDefaults();
|
|
52
129
|
const optionsWithDefaults = useMemo(() => {
|
|
53
|
-
|
|
130
|
+
const profile = resolveYableProfile(
|
|
131
|
+
options.config ?? providerDefaults.config,
|
|
132
|
+
options.configProfile ?? providerDefaults.tableProfile
|
|
133
|
+
);
|
|
134
|
+
const profileDefaultColumnDef = getYableDefaultColumnDef(profile);
|
|
135
|
+
const configuredColumns = applyYableConfigToColumns(options.columns, profile);
|
|
136
|
+
const defaultColumnDef = {
|
|
137
|
+
...profileDefaultColumnDef,
|
|
138
|
+
...providerDefaults.defaultColumnDef,
|
|
139
|
+
...options.defaultColumnDef
|
|
140
|
+
};
|
|
54
141
|
return {
|
|
55
142
|
...options,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
143
|
+
columns: configuredColumns,
|
|
144
|
+
rowClassName: options.rowClassName ?? profile.rows?.className,
|
|
145
|
+
rowStyle: options.rowStyle ?? profile.rows?.style,
|
|
146
|
+
defaultColumnDef: Object.keys(defaultColumnDef).length > 0 ? defaultColumnDef : void 0
|
|
60
147
|
};
|
|
61
|
-
}, [
|
|
148
|
+
}, [
|
|
149
|
+
options,
|
|
150
|
+
providerDefaults.config,
|
|
151
|
+
providerDefaults.defaultColumnDef,
|
|
152
|
+
providerDefaults.tableProfile
|
|
153
|
+
]);
|
|
62
154
|
const [state, setState] = useState(() => ({
|
|
63
155
|
sorting: [],
|
|
64
156
|
columnFilters: [],
|
|
@@ -144,6 +236,32 @@ function useTable(options) {
|
|
|
144
236
|
})
|
|
145
237
|
);
|
|
146
238
|
}
|
|
239
|
+
useEffect(() => {
|
|
240
|
+
const table = tableRef.current;
|
|
241
|
+
if (!table) return;
|
|
242
|
+
const unsubscribers = [
|
|
243
|
+
options.onCellClick && table.events.on("cell:click", options.onCellClick),
|
|
244
|
+
options.onCellDoubleClick && table.events.on("cell:dblclick", options.onCellDoubleClick),
|
|
245
|
+
options.onCellContextMenu && table.events.on("cell:contextmenu", options.onCellContextMenu),
|
|
246
|
+
options.onRowClick && table.events.on("row:click", options.onRowClick),
|
|
247
|
+
options.onRowDoubleClick && table.events.on("row:dblclick", options.onRowDoubleClick),
|
|
248
|
+
options.onRowContextMenu && table.events.on("row:contextmenu", options.onRowContextMenu),
|
|
249
|
+
options.onHeaderClick && table.events.on("header:click", options.onHeaderClick),
|
|
250
|
+
options.onHeaderContextMenu && table.events.on("header:contextmenu", options.onHeaderContextMenu)
|
|
251
|
+
].filter((unsubscribe) => Boolean(unsubscribe));
|
|
252
|
+
return () => {
|
|
253
|
+
unsubscribers.forEach((unsubscribe) => unsubscribe());
|
|
254
|
+
};
|
|
255
|
+
}, [
|
|
256
|
+
options.onCellClick,
|
|
257
|
+
options.onCellContextMenu,
|
|
258
|
+
options.onCellDoubleClick,
|
|
259
|
+
options.onHeaderClick,
|
|
260
|
+
options.onHeaderContextMenu,
|
|
261
|
+
options.onRowClick,
|
|
262
|
+
options.onRowContextMenu,
|
|
263
|
+
options.onRowDoubleClick
|
|
264
|
+
]);
|
|
147
265
|
useEffect(() => {
|
|
148
266
|
return () => {
|
|
149
267
|
if (tableRef.current) {
|
|
@@ -153,6 +271,195 @@ function useTable(options) {
|
|
|
153
271
|
}, []);
|
|
154
272
|
return tableRef.current;
|
|
155
273
|
}
|
|
274
|
+
function useServerTable({
|
|
275
|
+
fetchData,
|
|
276
|
+
updateRow,
|
|
277
|
+
initialRows = [],
|
|
278
|
+
initialCursor = null,
|
|
279
|
+
initialHasMore = true,
|
|
280
|
+
initialRowCount,
|
|
281
|
+
initialPageCount,
|
|
282
|
+
initialSorting = [],
|
|
283
|
+
initialColumnFilters = [],
|
|
284
|
+
initialGlobalFilter = "",
|
|
285
|
+
initialPagination = { pageIndex: 0, pageSize: 50 },
|
|
286
|
+
autoLoad = true,
|
|
287
|
+
getRowId,
|
|
288
|
+
...tableOptions
|
|
289
|
+
}) {
|
|
290
|
+
const [rows, setRows] = useState(initialRows);
|
|
291
|
+
const [cursor, setCursor] = useState(initialCursor);
|
|
292
|
+
const [hasMore, setHasMore] = useState(initialHasMore);
|
|
293
|
+
const [rowCount, setRowCount] = useState(initialRowCount);
|
|
294
|
+
const [pageCount, setPageCount] = useState(initialPageCount);
|
|
295
|
+
const [sorting, setSorting] = useState(initialSorting);
|
|
296
|
+
const [columnFilters, setColumnFilters] = useState(initialColumnFilters);
|
|
297
|
+
const [globalFilter, setGlobalFilter] = useState(initialGlobalFilter);
|
|
298
|
+
const [pagination, setPagination] = useState(initialPagination);
|
|
299
|
+
const [loading, setLoading] = useState(false);
|
|
300
|
+
const [error, setError] = useState(null);
|
|
301
|
+
const abortRef = useRef(null);
|
|
302
|
+
const cursorRef = useRef(cursor);
|
|
303
|
+
const fetchDataRef = useRef(fetchData);
|
|
304
|
+
const updateRowRef = useRef(updateRow);
|
|
305
|
+
const resolveRowId = useCallback(
|
|
306
|
+
(row, index) => getRowId?.(row, index) ?? String(row.id ?? index),
|
|
307
|
+
[getRowId]
|
|
308
|
+
);
|
|
309
|
+
const runFetch = useCallback(
|
|
310
|
+
async (mode) => {
|
|
311
|
+
abortRef.current?.abort();
|
|
312
|
+
const abort = new AbortController();
|
|
313
|
+
abortRef.current = abort;
|
|
314
|
+
setLoading(true);
|
|
315
|
+
setError(null);
|
|
316
|
+
try {
|
|
317
|
+
const result = await fetchDataRef.current({
|
|
318
|
+
sorting,
|
|
319
|
+
columnFilters,
|
|
320
|
+
globalFilter,
|
|
321
|
+
pagination,
|
|
322
|
+
cursor: mode === "append" ? cursorRef.current : null,
|
|
323
|
+
signal: abort.signal
|
|
324
|
+
});
|
|
325
|
+
if (abort.signal.aborted) return;
|
|
326
|
+
setRows((prev) => mode === "append" ? [...prev, ...result.rows] : result.rows);
|
|
327
|
+
setCursor(result.cursor ?? null);
|
|
328
|
+
setHasMore((prev) => result.hasMore ?? prev);
|
|
329
|
+
setRowCount((prev) => result.rowCount ?? prev);
|
|
330
|
+
setPageCount((prev) => result.pageCount ?? prev);
|
|
331
|
+
} catch (nextError) {
|
|
332
|
+
if (!abort.signal.aborted) setError(nextError);
|
|
333
|
+
} finally {
|
|
334
|
+
if (!abort.signal.aborted) setLoading(false);
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
[columnFilters, globalFilter, pagination, sorting]
|
|
338
|
+
);
|
|
339
|
+
const refresh = useCallback(() => runFetch("replace"), [runFetch]);
|
|
340
|
+
const loadMore = useCallback(async () => {
|
|
341
|
+
if (!hasMore || loading) return;
|
|
342
|
+
await runFetch("append");
|
|
343
|
+
}, [hasMore, loading, runFetch]);
|
|
344
|
+
const patchRow = useCallback(
|
|
345
|
+
async (rowId, patch) => {
|
|
346
|
+
const previousRow = rows.find((row, index) => resolveRowId(row, index) === rowId);
|
|
347
|
+
setRows(
|
|
348
|
+
(prev) => prev.map((row, index) => resolveRowId(row, index) === rowId ? { ...row, ...patch } : row)
|
|
349
|
+
);
|
|
350
|
+
if (!updateRowRef.current) return;
|
|
351
|
+
const abort = new AbortController();
|
|
352
|
+
try {
|
|
353
|
+
const result = await updateRowRef.current({
|
|
354
|
+
rowId,
|
|
355
|
+
patch,
|
|
356
|
+
previousRow,
|
|
357
|
+
signal: abort.signal
|
|
358
|
+
});
|
|
359
|
+
if (!result) return;
|
|
360
|
+
setRows(
|
|
361
|
+
(prev) => prev.map(
|
|
362
|
+
(row, index) => resolveRowId(row, index) === rowId ? { ...row, ...result } : row
|
|
363
|
+
)
|
|
364
|
+
);
|
|
365
|
+
} catch (nextError) {
|
|
366
|
+
setError(nextError);
|
|
367
|
+
if (previousRow) {
|
|
368
|
+
setRows(
|
|
369
|
+
(prev) => prev.map((row, index) => resolveRowId(row, index) === rowId ? previousRow : row)
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
[resolveRowId, rows]
|
|
375
|
+
);
|
|
376
|
+
useEffect(() => {
|
|
377
|
+
fetchDataRef.current = fetchData;
|
|
378
|
+
}, [fetchData]);
|
|
379
|
+
useEffect(() => {
|
|
380
|
+
updateRowRef.current = updateRow;
|
|
381
|
+
}, [updateRow]);
|
|
382
|
+
useEffect(() => {
|
|
383
|
+
if (!autoLoad) return;
|
|
384
|
+
void refresh();
|
|
385
|
+
}, [autoLoad, refresh]);
|
|
386
|
+
useEffect(() => {
|
|
387
|
+
cursorRef.current = cursor;
|
|
388
|
+
}, [cursor]);
|
|
389
|
+
useEffect(() => () => abortRef.current?.abort(), []);
|
|
390
|
+
const table = useTable({
|
|
391
|
+
...tableOptions,
|
|
392
|
+
data: rows,
|
|
393
|
+
getRowId: resolveRowId,
|
|
394
|
+
manualSorting: true,
|
|
395
|
+
manualFiltering: true,
|
|
396
|
+
manualPagination: true,
|
|
397
|
+
rowCount,
|
|
398
|
+
pageCount,
|
|
399
|
+
state: {
|
|
400
|
+
sorting,
|
|
401
|
+
columnFilters,
|
|
402
|
+
globalFilter,
|
|
403
|
+
pagination
|
|
404
|
+
},
|
|
405
|
+
onSortingChange: (updater) => {
|
|
406
|
+
setSorting((prev) => functionalUpdate(updater, prev));
|
|
407
|
+
setCursor(null);
|
|
408
|
+
setHasMore(true);
|
|
409
|
+
},
|
|
410
|
+
onColumnFiltersChange: (updater) => {
|
|
411
|
+
setColumnFilters((prev) => functionalUpdate(updater, prev));
|
|
412
|
+
setCursor(null);
|
|
413
|
+
setHasMore(true);
|
|
414
|
+
},
|
|
415
|
+
onGlobalFilterChange: (updater) => {
|
|
416
|
+
setGlobalFilter((prev) => functionalUpdate(updater, prev));
|
|
417
|
+
setCursor(null);
|
|
418
|
+
setHasMore(true);
|
|
419
|
+
},
|
|
420
|
+
onPaginationChange: (updater) => {
|
|
421
|
+
setPagination((prev) => functionalUpdate(updater, prev));
|
|
422
|
+
setCursor(null);
|
|
423
|
+
setHasMore(true);
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
return useMemo(
|
|
427
|
+
() => ({
|
|
428
|
+
table,
|
|
429
|
+
rows,
|
|
430
|
+
loading,
|
|
431
|
+
error,
|
|
432
|
+
cursor,
|
|
433
|
+
hasMore,
|
|
434
|
+
rowCount,
|
|
435
|
+
pageCount,
|
|
436
|
+
sorting,
|
|
437
|
+
columnFilters,
|
|
438
|
+
globalFilter,
|
|
439
|
+
pagination,
|
|
440
|
+
refresh,
|
|
441
|
+
loadMore,
|
|
442
|
+
updateRow: patchRow
|
|
443
|
+
}),
|
|
444
|
+
[
|
|
445
|
+
table,
|
|
446
|
+
rows,
|
|
447
|
+
loading,
|
|
448
|
+
error,
|
|
449
|
+
cursor,
|
|
450
|
+
hasMore,
|
|
451
|
+
rowCount,
|
|
452
|
+
pageCount,
|
|
453
|
+
sorting,
|
|
454
|
+
columnFilters,
|
|
455
|
+
globalFilter,
|
|
456
|
+
pagination,
|
|
457
|
+
refresh,
|
|
458
|
+
loadMore,
|
|
459
|
+
patchRow
|
|
460
|
+
]
|
|
461
|
+
);
|
|
462
|
+
}
|
|
156
463
|
var DEFAULT_PERSISTED_KEYS = [
|
|
157
464
|
"columnVisibility",
|
|
158
465
|
"columnOrder",
|
|
@@ -349,7 +656,7 @@ function useVirtualization({
|
|
|
349
656
|
resizeObserver.disconnect();
|
|
350
657
|
}
|
|
351
658
|
};
|
|
352
|
-
}, [containerRef]);
|
|
659
|
+
}, [containerRef, totalRows]);
|
|
353
660
|
useEffect(() => {
|
|
354
661
|
if (!isFixedHeight) {
|
|
355
662
|
heightCacheRef.current.clear();
|
|
@@ -540,14 +847,20 @@ function useColumnVirtualization({
|
|
|
540
847
|
containerRef,
|
|
541
848
|
columns,
|
|
542
849
|
overscan = 2,
|
|
543
|
-
enabled = true
|
|
850
|
+
enabled = true,
|
|
851
|
+
sizingKey
|
|
544
852
|
}) {
|
|
545
853
|
const [scrollState, setScrollState] = useState({
|
|
546
854
|
scrollLeft: 0,
|
|
547
855
|
containerWidth: 0
|
|
548
856
|
});
|
|
549
857
|
const rafRef = useRef(null);
|
|
550
|
-
const sizes = useMemo(
|
|
858
|
+
const sizes = useMemo(
|
|
859
|
+
() => columns.map((column) => column.getSize()),
|
|
860
|
+
// `sizingKey` is an explicit invalidation hook for stable Column objects whose getSize value changed.
|
|
861
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
862
|
+
[columns, sizingKey]
|
|
863
|
+
);
|
|
551
864
|
const offsets = useMemo(() => {
|
|
552
865
|
const next = new Array(columns.length + 1);
|
|
553
866
|
next[0] = 0;
|
|
@@ -1125,12 +1438,12 @@ function getRegisteredCellTypes() {
|
|
|
1125
1438
|
|
|
1126
1439
|
// src/hooks/useAutoMeasurements.ts
|
|
1127
1440
|
var NON_DATA_COLUMN_IDS = /* @__PURE__ */ new Set(["select", "expand", "drag", "actions"]);
|
|
1128
|
-
function
|
|
1441
|
+
function getColumnId2(col) {
|
|
1129
1442
|
const id = col.id ?? col.accessorKey;
|
|
1130
1443
|
return typeof id === "string" ? id : void 0;
|
|
1131
1444
|
}
|
|
1132
1445
|
function defaultShouldMeasure(col) {
|
|
1133
|
-
const id =
|
|
1446
|
+
const id = getColumnId2(col);
|
|
1134
1447
|
if (!id) return false;
|
|
1135
1448
|
if (id.startsWith("_")) return false;
|
|
1136
1449
|
if (NON_DATA_COLUMN_IDS.has(id)) return false;
|
|
@@ -1155,11 +1468,11 @@ function useAutoMeasurements({
|
|
|
1155
1468
|
getColumnWidth = defaultGetColumnWidth,
|
|
1156
1469
|
shouldMeasureColumn = defaultShouldMeasure
|
|
1157
1470
|
}) {
|
|
1158
|
-
const widthKey = columns.map((c) => `${
|
|
1471
|
+
const widthKey = columns.map((c) => `${getColumnId2(c) ?? "?"}:${getColumnWidth(c)}`).join("|");
|
|
1159
1472
|
return useMemo(() => {
|
|
1160
1473
|
const result = [];
|
|
1161
1474
|
for (const col of columns) {
|
|
1162
|
-
const id =
|
|
1475
|
+
const id = getColumnId2(col);
|
|
1163
1476
|
if (!id) continue;
|
|
1164
1477
|
if (!shouldMeasureColumn(col)) continue;
|
|
1165
1478
|
const recipe = resolveMeasureRecipe(col, defaultRecipe);
|
|
@@ -1478,16 +1791,170 @@ function FloatingFilter({ column }) {
|
|
|
1478
1791
|
}
|
|
1479
1792
|
) });
|
|
1480
1793
|
}
|
|
1481
|
-
var
|
|
1794
|
+
var REORDER_TRANSITION = "transform 180ms cubic-bezier(0.2, 0, 0, 1)";
|
|
1795
|
+
function transformAt(i, d) {
|
|
1796
|
+
if (i === d.fromIndex) return 0;
|
|
1797
|
+
if (d.toIndex > d.fromIndex) return i > d.fromIndex && i < d.toIndex ? -d.width : 0;
|
|
1798
|
+
return i >= d.toIndex && i < d.fromIndex ? d.width : 0;
|
|
1799
|
+
}
|
|
1482
1800
|
function TableHeader({
|
|
1483
1801
|
table,
|
|
1484
1802
|
floatingFilters = false
|
|
1485
1803
|
}) {
|
|
1486
1804
|
const headerGroups = table.getHeaderGroups();
|
|
1487
1805
|
const visibleColumns = table.getVisibleLeafColumns();
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1806
|
+
const theadRef = useRef(null);
|
|
1807
|
+
const reorderEndRef = useRef(0);
|
|
1808
|
+
const [drag, setDrag] = useState(null);
|
|
1809
|
+
const commitReorder = useCallback(
|
|
1810
|
+
(d) => {
|
|
1811
|
+
if (d.toIndex === d.fromIndex || d.toIndex === d.fromIndex + 1) return;
|
|
1812
|
+
const order = table.getState().columnOrder;
|
|
1813
|
+
const base = order && order.length > 0 ? [...order] : d.layout.map((l) => l.id);
|
|
1814
|
+
const targetId = d.toIndex < d.layout.length ? d.layout[d.toIndex].id : null;
|
|
1815
|
+
const next = base.filter((id) => id !== d.columnId);
|
|
1816
|
+
let insertAt = targetId ? next.indexOf(targetId) : next.length;
|
|
1817
|
+
if (insertAt === -1) insertAt = next.length;
|
|
1818
|
+
next.splice(insertAt, 0, d.columnId);
|
|
1819
|
+
table.setColumnOrder(next);
|
|
1820
|
+
},
|
|
1821
|
+
[table]
|
|
1822
|
+
);
|
|
1823
|
+
const beginReorder = useCallback(
|
|
1824
|
+
(e, columnId) => {
|
|
1825
|
+
if (e.button !== 0) return;
|
|
1826
|
+
const thead = theadRef.current;
|
|
1827
|
+
if (!thead) return;
|
|
1828
|
+
const startX = e.clientX;
|
|
1829
|
+
const startY = e.clientY;
|
|
1830
|
+
const layout = [];
|
|
1831
|
+
let top = 0;
|
|
1832
|
+
let height = 0;
|
|
1833
|
+
for (const c of visibleColumns) {
|
|
1834
|
+
const th = thead.querySelector(`th[data-column-id="${CSS.escape(c.id)}"]`);
|
|
1835
|
+
if (!th) return;
|
|
1836
|
+
const r = th.getBoundingClientRect();
|
|
1837
|
+
layout.push({ id: c.id, left: r.left, width: r.width });
|
|
1838
|
+
if (c.id === columnId) {
|
|
1839
|
+
top = r.top;
|
|
1840
|
+
height = r.height;
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
const fromIndex = layout.findIndex((l) => l.id === columnId);
|
|
1844
|
+
if (fromIndex < 0) return;
|
|
1845
|
+
const src = layout[fromIndex];
|
|
1846
|
+
const bodyRoot = thead.closest("table");
|
|
1847
|
+
const applyBody = (d) => {
|
|
1848
|
+
if (!bodyRoot) return;
|
|
1849
|
+
visibleColumns.forEach((col, i) => {
|
|
1850
|
+
if (col.getIsPinned()) return;
|
|
1851
|
+
const tx = transformAt(i, d);
|
|
1852
|
+
bodyRoot.querySelectorAll(`td[data-column-id="${CSS.escape(col.id)}"]`).forEach((td) => {
|
|
1853
|
+
td.style.transition = REORDER_TRANSITION;
|
|
1854
|
+
td.style.opacity = i === d.fromIndex ? "0" : "";
|
|
1855
|
+
td.style.transform = i !== d.fromIndex && tx ? `translateX(${tx}px)` : "";
|
|
1856
|
+
});
|
|
1857
|
+
});
|
|
1858
|
+
};
|
|
1859
|
+
const clearBody = () => {
|
|
1860
|
+
bodyRoot?.querySelectorAll("td[data-column-id]").forEach((td) => {
|
|
1861
|
+
td.style.transform = "";
|
|
1862
|
+
td.style.transition = "";
|
|
1863
|
+
td.style.opacity = "";
|
|
1864
|
+
});
|
|
1865
|
+
};
|
|
1866
|
+
let started = false;
|
|
1867
|
+
let latest = {
|
|
1868
|
+
columnId,
|
|
1869
|
+
fromIndex,
|
|
1870
|
+
toIndex: fromIndex,
|
|
1871
|
+
pointerX: startX,
|
|
1872
|
+
grabOffsetX: startX - src.left,
|
|
1873
|
+
width: src.width,
|
|
1874
|
+
top,
|
|
1875
|
+
height,
|
|
1876
|
+
layout
|
|
1877
|
+
};
|
|
1878
|
+
const computeToIndex = (x) => {
|
|
1879
|
+
let t = layout.findIndex((l) => x < l.left + l.width / 2);
|
|
1880
|
+
if (t === -1) t = layout.length;
|
|
1881
|
+
return t;
|
|
1882
|
+
};
|
|
1883
|
+
const onMove = (ev) => {
|
|
1884
|
+
if (!started) {
|
|
1885
|
+
if (Math.abs(ev.clientX - startX) < 4 && Math.abs(ev.clientY - startY) < 4) return;
|
|
1886
|
+
started = true;
|
|
1887
|
+
table.setColumnDragActive(true);
|
|
1888
|
+
document.body.style.userSelect = "none";
|
|
1889
|
+
document.body.style.cursor = "grabbing";
|
|
1890
|
+
}
|
|
1891
|
+
latest = { ...latest, pointerX: ev.clientX, toIndex: computeToIndex(ev.clientX) };
|
|
1892
|
+
setDrag(latest);
|
|
1893
|
+
applyBody(latest);
|
|
1894
|
+
};
|
|
1895
|
+
const finish = () => {
|
|
1896
|
+
window.removeEventListener("pointermove", onMove);
|
|
1897
|
+
window.removeEventListener("pointerup", finish);
|
|
1898
|
+
window.removeEventListener("pointercancel", finish);
|
|
1899
|
+
if (started) {
|
|
1900
|
+
commitReorder(latest);
|
|
1901
|
+
reorderEndRef.current = Date.now();
|
|
1902
|
+
table.setColumnDragActive(false);
|
|
1903
|
+
document.body.style.userSelect = "";
|
|
1904
|
+
document.body.style.cursor = "";
|
|
1905
|
+
clearBody();
|
|
1906
|
+
}
|
|
1907
|
+
setDrag(null);
|
|
1908
|
+
};
|
|
1909
|
+
window.addEventListener("pointermove", onMove);
|
|
1910
|
+
window.addEventListener("pointerup", finish);
|
|
1911
|
+
window.addEventListener("pointercancel", finish);
|
|
1912
|
+
},
|
|
1913
|
+
[visibleColumns, table, commitReorder]
|
|
1914
|
+
);
|
|
1915
|
+
const transformFor = useCallback(
|
|
1916
|
+
(columnId) => {
|
|
1917
|
+
if (!drag) return 0;
|
|
1918
|
+
const i = visibleColumns.findIndex((c) => c.id === columnId);
|
|
1919
|
+
if (i < 0) return 0;
|
|
1920
|
+
return transformAt(i, drag);
|
|
1921
|
+
},
|
|
1922
|
+
[drag, visibleColumns]
|
|
1923
|
+
);
|
|
1924
|
+
const dragColumn = drag ? visibleColumns.find((c) => c.id === drag.columnId) : null;
|
|
1925
|
+
return /* @__PURE__ */ jsxs("thead", { className: "yable-thead", ref: theadRef, children: [
|
|
1926
|
+
headerGroups.map((headerGroup) => /* @__PURE__ */ jsx("tr", { className: "yable-header-row", children: headerGroup.headers.map((header) => /* @__PURE__ */ jsx(
|
|
1927
|
+
HeaderCell,
|
|
1928
|
+
{
|
|
1929
|
+
header,
|
|
1930
|
+
table,
|
|
1931
|
+
onReorderPointerDown: beginReorder,
|
|
1932
|
+
dragTransform: transformFor(header.column.id),
|
|
1933
|
+
isDragSource: drag?.columnId === header.column.id,
|
|
1934
|
+
dragActive: drag !== null,
|
|
1935
|
+
reorderEndRef
|
|
1936
|
+
},
|
|
1937
|
+
header.id
|
|
1938
|
+
)) }, headerGroup.id)),
|
|
1939
|
+
floatingFilters && visibleColumns.length > 0 && /* @__PURE__ */ jsx("tr", { className: "yable-header-row yable-header-row--filters", children: visibleColumns.map((column) => /* @__PURE__ */ jsx(FloatingFilterCell, { column }, `${column.id}-filter`)) }),
|
|
1940
|
+
drag && dragColumn && typeof document !== "undefined" && createPortal(
|
|
1941
|
+
/* @__PURE__ */ jsx(
|
|
1942
|
+
"div",
|
|
1943
|
+
{
|
|
1944
|
+
className: "yable-col-drag-ghost",
|
|
1945
|
+
"aria-hidden": "true",
|
|
1946
|
+
style: {
|
|
1947
|
+
position: "fixed",
|
|
1948
|
+
top: drag.top,
|
|
1949
|
+
left: drag.pointerX - drag.grabOffsetX,
|
|
1950
|
+
width: drag.width,
|
|
1951
|
+
height: drag.height
|
|
1952
|
+
},
|
|
1953
|
+
children: typeof dragColumn.columnDef.header === "string" ? dragColumn.columnDef.header : dragColumn.id
|
|
1954
|
+
}
|
|
1955
|
+
),
|
|
1956
|
+
document.body
|
|
1957
|
+
)
|
|
1491
1958
|
] });
|
|
1492
1959
|
}
|
|
1493
1960
|
function FloatingFilterCell({
|
|
@@ -1516,7 +1983,12 @@ function FloatingFilterCell({
|
|
|
1516
1983
|
}
|
|
1517
1984
|
function HeaderCell({
|
|
1518
1985
|
header,
|
|
1519
|
-
table
|
|
1986
|
+
table,
|
|
1987
|
+
onReorderPointerDown,
|
|
1988
|
+
dragTransform,
|
|
1989
|
+
isDragSource,
|
|
1990
|
+
dragActive,
|
|
1991
|
+
reorderEndRef
|
|
1520
1992
|
}) {
|
|
1521
1993
|
const column = header.column;
|
|
1522
1994
|
const canSort = column.getCanSort();
|
|
@@ -1524,6 +1996,7 @@ function HeaderCell({
|
|
|
1524
1996
|
const sortIndex = column.getSortIndex();
|
|
1525
1997
|
const canResize = column.getCanResize();
|
|
1526
1998
|
const canReorder = column.getCanReorder() && !header.isPlaceholder;
|
|
1999
|
+
const pinned = column.getIsPinned();
|
|
1527
2000
|
const headerContent = header.isPlaceholder ? null : typeof column.columnDef.header === "function" ? column.columnDef.header(header.getContext()) : column.columnDef.header ?? header.id;
|
|
1528
2001
|
const style = useMemo(() => {
|
|
1529
2002
|
const s = {
|
|
@@ -1531,18 +2004,19 @@ function HeaderCell({
|
|
|
1531
2004
|
minWidth: column.columnDef.minSize,
|
|
1532
2005
|
maxWidth: column.columnDef.maxSize
|
|
1533
2006
|
};
|
|
1534
|
-
|
|
1535
|
-
if (pinned2) {
|
|
2007
|
+
if (pinned) {
|
|
1536
2008
|
s.position = "sticky";
|
|
1537
|
-
if (
|
|
2009
|
+
if (pinned === "left") {
|
|
1538
2010
|
s.left = header.getStart("left");
|
|
1539
2011
|
} else {
|
|
1540
2012
|
s.right = header.getStart("right");
|
|
1541
2013
|
}
|
|
1542
2014
|
}
|
|
2015
|
+
if (!pinned && !isDragSource && dragTransform !== 0) {
|
|
2016
|
+
s.transform = `translateX(${dragTransform}px)`;
|
|
2017
|
+
}
|
|
1543
2018
|
return s;
|
|
1544
|
-
}, [header, column]);
|
|
1545
|
-
const pinned = column.getIsPinned();
|
|
2019
|
+
}, [header, column, pinned, isDragSource, dragTransform]);
|
|
1546
2020
|
const lastResizeEndRef = useRef(0);
|
|
1547
2021
|
const startResize = useCallback(
|
|
1548
2022
|
(e) => {
|
|
@@ -1562,122 +2036,60 @@ function HeaderCell({
|
|
|
1562
2036
|
const handleResizeClick = useCallback((e) => {
|
|
1563
2037
|
e.stopPropagation();
|
|
1564
2038
|
}, []);
|
|
1565
|
-
const
|
|
1566
|
-
const handleDragStart = useCallback(
|
|
1567
|
-
(e) => {
|
|
1568
|
-
if (!canReorder) return;
|
|
1569
|
-
e.stopPropagation();
|
|
1570
|
-
e.dataTransfer.effectAllowed = "move";
|
|
1571
|
-
try {
|
|
1572
|
-
e.dataTransfer.setData(DRAG_MIME, column.id);
|
|
1573
|
-
e.dataTransfer.setData("text/plain", column.id);
|
|
1574
|
-
} catch {
|
|
1575
|
-
}
|
|
1576
|
-
table.setColumnDragActive(true);
|
|
1577
|
-
},
|
|
1578
|
-
[canReorder, column.id, table]
|
|
1579
|
-
);
|
|
1580
|
-
const handleDragOver = useCallback(
|
|
1581
|
-
(e) => {
|
|
1582
|
-
if (!canReorder) return;
|
|
1583
|
-
const types = e.dataTransfer.types;
|
|
1584
|
-
let isYableDrag = false;
|
|
1585
|
-
for (let i = 0; i < types.length; i++) {
|
|
1586
|
-
if (types[i] === DRAG_MIME) {
|
|
1587
|
-
isYableDrag = true;
|
|
1588
|
-
break;
|
|
1589
|
-
}
|
|
1590
|
-
}
|
|
1591
|
-
if (!isYableDrag) return;
|
|
1592
|
-
e.preventDefault();
|
|
1593
|
-
e.dataTransfer.dropEffect = "move";
|
|
1594
|
-
const rect = e.currentTarget.getBoundingClientRect();
|
|
1595
|
-
const midpoint = rect.left + rect.width / 2;
|
|
1596
|
-
setDragOver(e.clientX < midpoint ? "left" : "right");
|
|
1597
|
-
},
|
|
1598
|
-
[canReorder]
|
|
1599
|
-
);
|
|
1600
|
-
const handleDragLeave = useCallback((e) => {
|
|
1601
|
-
const next = e.relatedTarget;
|
|
1602
|
-
if (next && e.currentTarget.contains(next)) return;
|
|
1603
|
-
setDragOver(null);
|
|
1604
|
-
}, []);
|
|
1605
|
-
const handleDragEnd = useCallback(() => {
|
|
1606
|
-
setDragOver(null);
|
|
1607
|
-
table.setColumnDragActive(false);
|
|
1608
|
-
}, [table]);
|
|
1609
|
-
const handleDrop = useCallback(
|
|
2039
|
+
const handleContentPointerDown = useCallback(
|
|
1610
2040
|
(e) => {
|
|
1611
|
-
if (!canReorder) return;
|
|
1612
|
-
e.
|
|
1613
|
-
e.stopPropagation();
|
|
1614
|
-
const sourceId = e.dataTransfer.getData(DRAG_MIME);
|
|
1615
|
-
const rect = e.currentTarget.getBoundingClientRect();
|
|
1616
|
-
const insertAfter = e.clientX >= rect.left + rect.width / 2;
|
|
1617
|
-
setDragOver(null);
|
|
1618
|
-
table.setColumnDragActive(false);
|
|
1619
|
-
if (!sourceId || sourceId === column.id) return;
|
|
1620
|
-
const state = table.getState();
|
|
1621
|
-
const allLeafs = table.getAllLeafColumns();
|
|
1622
|
-
const baseOrder = state.columnOrder && state.columnOrder.length > 0 ? state.columnOrder : allLeafs.map((c) => c.id);
|
|
1623
|
-
const next = [];
|
|
1624
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1625
|
-
for (const id of baseOrder) {
|
|
1626
|
-
if (allLeafs.some((c) => c.id === id)) {
|
|
1627
|
-
next.push(id);
|
|
1628
|
-
seen.add(id);
|
|
1629
|
-
}
|
|
1630
|
-
}
|
|
1631
|
-
for (const c of allLeafs) {
|
|
1632
|
-
if (!seen.has(c.id)) {
|
|
1633
|
-
next.push(c.id);
|
|
1634
|
-
seen.add(c.id);
|
|
1635
|
-
}
|
|
1636
|
-
}
|
|
1637
|
-
const fromIdx = next.indexOf(sourceId);
|
|
1638
|
-
if (fromIdx === -1) return;
|
|
1639
|
-
next.splice(fromIdx, 1);
|
|
1640
|
-
let toIdx = next.indexOf(column.id);
|
|
1641
|
-
if (toIdx === -1) return;
|
|
1642
|
-
if (insertAfter) toIdx += 1;
|
|
1643
|
-
next.splice(toIdx, 0, sourceId);
|
|
1644
|
-
table.setColumnOrder(next);
|
|
2041
|
+
if (!canReorder || pinned) return;
|
|
2042
|
+
onReorderPointerDown(e, column.id);
|
|
1645
2043
|
},
|
|
1646
|
-
[canReorder, column.id
|
|
2044
|
+
[canReorder, pinned, onReorderPointerDown, column.id]
|
|
1647
2045
|
);
|
|
1648
2046
|
const handleHeaderClick = useCallback(
|
|
1649
2047
|
(e) => {
|
|
2048
|
+
table.events.emit("header:click", {
|
|
2049
|
+
column,
|
|
2050
|
+
header,
|
|
2051
|
+
originalEvent: e
|
|
2052
|
+
});
|
|
1650
2053
|
if (!canSort) return;
|
|
1651
2054
|
if (Date.now() - lastResizeEndRef.current < 250) return;
|
|
2055
|
+
if (Date.now() - reorderEndRef.current < 250) return;
|
|
1652
2056
|
const handler = column.getToggleSortingHandler();
|
|
1653
2057
|
if (handler) handler(e);
|
|
1654
2058
|
},
|
|
1655
|
-
[canSort, column]
|
|
2059
|
+
[canSort, column, header, table.events, reorderEndRef]
|
|
2060
|
+
);
|
|
2061
|
+
const handleHeaderContextMenu = useCallback(
|
|
2062
|
+
(e) => {
|
|
2063
|
+
table.events.emit("header:contextmenu", {
|
|
2064
|
+
column,
|
|
2065
|
+
header,
|
|
2066
|
+
originalEvent: e
|
|
2067
|
+
});
|
|
2068
|
+
},
|
|
2069
|
+
[column, header, table.events]
|
|
1656
2070
|
);
|
|
1657
2071
|
return /* @__PURE__ */ jsxs(
|
|
1658
2072
|
"th",
|
|
1659
2073
|
{
|
|
1660
2074
|
className: "yable-th",
|
|
1661
2075
|
style,
|
|
2076
|
+
"data-column-id": column.id,
|
|
1662
2077
|
"data-sortable": canSort || void 0,
|
|
1663
2078
|
"data-pinned": pinned || void 0,
|
|
1664
|
-
"data-reorderable": canReorder || void 0,
|
|
1665
|
-
"data-
|
|
2079
|
+
"data-reorderable": canReorder && !pinned || void 0,
|
|
2080
|
+
"data-reordering": dragActive && !pinned || void 0,
|
|
2081
|
+
"data-drag-source": isDragSource || void 0,
|
|
1666
2082
|
"aria-sort": sortDirection === "asc" ? "ascending" : sortDirection === "desc" ? "descending" : canSort ? "none" : void 0,
|
|
1667
2083
|
role: "columnheader",
|
|
1668
2084
|
colSpan: header.colSpan,
|
|
1669
2085
|
onClick: handleHeaderClick,
|
|
1670
|
-
|
|
1671
|
-
onDragLeave: canReorder ? handleDragLeave : void 0,
|
|
1672
|
-
onDrop: canReorder ? handleDrop : void 0,
|
|
2086
|
+
onContextMenu: handleHeaderContextMenu,
|
|
1673
2087
|
children: [
|
|
1674
2088
|
/* @__PURE__ */ jsxs(
|
|
1675
2089
|
"div",
|
|
1676
2090
|
{
|
|
1677
2091
|
className: "yable-th-content",
|
|
1678
|
-
|
|
1679
|
-
onDragStart: canReorder ? handleDragStart : void 0,
|
|
1680
|
-
onDragEnd: canReorder ? handleDragEnd : void 0,
|
|
2092
|
+
onPointerDown: canReorder && !pinned ? handleContentPointerDown : void 0,
|
|
1681
2093
|
children: [
|
|
1682
2094
|
/* @__PURE__ */ jsx("span", { children: headerContent }),
|
|
1683
2095
|
canSort && /* @__PURE__ */ jsx(SortIndicator, { direction: sortDirection, index: sortIndex > 0 ? sortIndex : void 0 })
|
|
@@ -1776,19 +2188,46 @@ function CellStatusBadge(props) {
|
|
|
1776
2188
|
}
|
|
1777
2189
|
);
|
|
1778
2190
|
}
|
|
2191
|
+
function FillHandle({
|
|
2192
|
+
rowIndex,
|
|
2193
|
+
columnIndex,
|
|
2194
|
+
onMouseDown
|
|
2195
|
+
}) {
|
|
2196
|
+
const handleMouseDown = useCallback(
|
|
2197
|
+
(e) => {
|
|
2198
|
+
e.preventDefault();
|
|
2199
|
+
e.stopPropagation();
|
|
2200
|
+
onMouseDown(rowIndex, columnIndex, e);
|
|
2201
|
+
},
|
|
2202
|
+
[rowIndex, columnIndex, onMouseDown]
|
|
2203
|
+
);
|
|
2204
|
+
return /* @__PURE__ */ jsx(
|
|
2205
|
+
"div",
|
|
2206
|
+
{
|
|
2207
|
+
className: "yable-fill-handle",
|
|
2208
|
+
onMouseDown: handleMouseDown,
|
|
2209
|
+
role: "presentation",
|
|
2210
|
+
"aria-hidden": "true",
|
|
2211
|
+
title: "Drag to fill",
|
|
2212
|
+
children: /* @__PURE__ */ jsx("div", { className: "yable-fill-handle-dot" })
|
|
2213
|
+
}
|
|
2214
|
+
);
|
|
2215
|
+
}
|
|
1779
2216
|
function TableCell({
|
|
1780
2217
|
cell,
|
|
1781
2218
|
table,
|
|
1782
2219
|
rowIndex,
|
|
1783
2220
|
columnIndex,
|
|
1784
2221
|
isFocused,
|
|
1785
|
-
isTabStop
|
|
2222
|
+
isTabStop,
|
|
2223
|
+
onFillHandleMouseDown
|
|
1786
2224
|
}) {
|
|
1787
2225
|
const column = cell.column;
|
|
1788
2226
|
const isEditing = cell.getIsEditing();
|
|
1789
2227
|
const isAlwaysEditable = cell.getIsAlwaysEditable();
|
|
1790
2228
|
const pinned = column.getIsPinned();
|
|
1791
2229
|
const keyboardNavigationEnabled = table.options.enableKeyboardNavigation !== false;
|
|
2230
|
+
const cellSelectionEnabled = table.options.enableCellSelection !== false && column.columnDef.enableCellSelection !== false;
|
|
1792
2231
|
const style = {
|
|
1793
2232
|
width: column.getSize(),
|
|
1794
2233
|
minWidth: column.columnDef.minSize,
|
|
@@ -1873,6 +2312,7 @@ function TableCell({
|
|
|
1873
2312
|
const handleMouseDown = useCallback(
|
|
1874
2313
|
(e) => {
|
|
1875
2314
|
if (e.button !== 0) return;
|
|
2315
|
+
if (!cellSelectionEnabled) return;
|
|
1876
2316
|
const clickTarget = e.target;
|
|
1877
2317
|
if (isInteractiveClickTarget(clickTarget)) return;
|
|
1878
2318
|
e.preventDefault();
|
|
@@ -1880,12 +2320,13 @@ function TableCell({
|
|
|
1880
2320
|
table.startCellRangeSelection({ rowIndex, columnIndex }, { extend: e.shiftKey });
|
|
1881
2321
|
e.currentTarget.focus({ preventScroll: true });
|
|
1882
2322
|
},
|
|
1883
|
-
[columnIndex, rowIndex, table]
|
|
2323
|
+
[cellSelectionEnabled, columnIndex, rowIndex, table]
|
|
1884
2324
|
);
|
|
1885
2325
|
const handleMouseEnter = useCallback(() => {
|
|
2326
|
+
if (!cellSelectionEnabled) return;
|
|
1886
2327
|
if (!table.getState().cellSelection?.isDragging) return;
|
|
1887
2328
|
table.updateCellRangeSelection({ rowIndex, columnIndex });
|
|
1888
|
-
}, [columnIndex, rowIndex, table]);
|
|
2329
|
+
}, [cellSelectionEnabled, columnIndex, rowIndex, table]);
|
|
1889
2330
|
const handleMouseUp = useCallback(() => {
|
|
1890
2331
|
if (!table.getState().cellSelection?.isDragging) return;
|
|
1891
2332
|
table.endCellRangeSelection();
|
|
@@ -1895,6 +2336,7 @@ function TableCell({
|
|
|
1895
2336
|
const cellStyleDef = column.columnDef.cellStyle;
|
|
1896
2337
|
const userStyle = typeof cellStyleDef === "function" ? cellStyleDef(cell.getContext()) : cellStyleDef;
|
|
1897
2338
|
const mergedStyle = userStyle ? { ...style, ...userStyle } : style;
|
|
2339
|
+
const showFillHandle = isFocused && Boolean(table.options.enableFillHandle) && onFillHandleMouseDown != null;
|
|
1898
2340
|
const classNames = [
|
|
1899
2341
|
"yable-td",
|
|
1900
2342
|
isFocused && "yable-cell--focused",
|
|
@@ -1948,6 +2390,14 @@ function TableCell({
|
|
|
1948
2390
|
onRetry: () => void table.retryCommit(cell.row.id, column.id),
|
|
1949
2391
|
onDismiss: () => table.dismissCommit(cell.row.id, column.id)
|
|
1950
2392
|
}
|
|
2393
|
+
),
|
|
2394
|
+
showFillHandle && onFillHandleMouseDown && /* @__PURE__ */ jsx(
|
|
2395
|
+
FillHandle,
|
|
2396
|
+
{
|
|
2397
|
+
rowIndex,
|
|
2398
|
+
columnIndex,
|
|
2399
|
+
onMouseDown: onFillHandleMouseDown
|
|
2400
|
+
}
|
|
1951
2401
|
)
|
|
1952
2402
|
]
|
|
1953
2403
|
}
|
|
@@ -1960,7 +2410,7 @@ function isInteractiveClickTarget(element) {
|
|
|
1960
2410
|
);
|
|
1961
2411
|
return interactive !== null;
|
|
1962
2412
|
}
|
|
1963
|
-
var ErrorBoundary = class extends
|
|
2413
|
+
var ErrorBoundary = class extends React4.Component {
|
|
1964
2414
|
constructor(props) {
|
|
1965
2415
|
super(props);
|
|
1966
2416
|
this.state = { hasError: false, error: null };
|
|
@@ -2006,7 +2456,7 @@ var ErrorBoundary = class extends React3.Component {
|
|
|
2006
2456
|
return this.props.children;
|
|
2007
2457
|
}
|
|
2008
2458
|
};
|
|
2009
|
-
var CellErrorBoundary = class extends
|
|
2459
|
+
var CellErrorBoundary = class extends React4.Component {
|
|
2010
2460
|
constructor(props) {
|
|
2011
2461
|
super(props);
|
|
2012
2462
|
this.state = { hasError: false, error: null };
|
|
@@ -2049,10 +2499,38 @@ var CellErrorBoundary = class extends React3.Component {
|
|
|
2049
2499
|
return this.props.children;
|
|
2050
2500
|
}
|
|
2051
2501
|
};
|
|
2502
|
+
function MasterDetail({
|
|
2503
|
+
row,
|
|
2504
|
+
table,
|
|
2505
|
+
colSpan,
|
|
2506
|
+
renderDetailPanel,
|
|
2507
|
+
animationClass
|
|
2508
|
+
}) {
|
|
2509
|
+
const renderer = renderDetailPanel ?? table.options.renderDetailPanel;
|
|
2510
|
+
if (!renderer) return null;
|
|
2511
|
+
const content = renderer(row);
|
|
2512
|
+
if (content == null) return null;
|
|
2513
|
+
const classes = [
|
|
2514
|
+
"yable-detail-row",
|
|
2515
|
+
"yable-detail-row--animated",
|
|
2516
|
+
animationClass
|
|
2517
|
+
].filter(Boolean).join(" ");
|
|
2518
|
+
return /* @__PURE__ */ jsx(
|
|
2519
|
+
"tr",
|
|
2520
|
+
{
|
|
2521
|
+
className: classes,
|
|
2522
|
+
"data-detail-for": row.id,
|
|
2523
|
+
role: "row",
|
|
2524
|
+
"aria-label": `Details for row ${row.id}`,
|
|
2525
|
+
children: /* @__PURE__ */ jsx("td", { className: "yable-detail-cell", colSpan, role: "cell", children: /* @__PURE__ */ jsx("div", { className: "yable-detail-panel", children: /* @__PURE__ */ jsx("div", { className: "yable-detail-panel-inner", children: content }) }) })
|
|
2526
|
+
}
|
|
2527
|
+
);
|
|
2528
|
+
}
|
|
2052
2529
|
function TableBody({
|
|
2053
2530
|
table,
|
|
2054
2531
|
clickableRows,
|
|
2055
|
-
colgroup
|
|
2532
|
+
colgroup,
|
|
2533
|
+
onFillHandleMouseDown
|
|
2056
2534
|
}) {
|
|
2057
2535
|
const rows = table.getRowModel().rows;
|
|
2058
2536
|
const visibleColumns = table.getVisibleLeafColumns();
|
|
@@ -2062,6 +2540,7 @@ function TableBody({
|
|
|
2062
2540
|
range: null,
|
|
2063
2541
|
isDragging: false
|
|
2064
2542
|
};
|
|
2543
|
+
const pendingValues = table.getState().editing.pendingValues ?? {};
|
|
2065
2544
|
const options = table.options;
|
|
2066
2545
|
const enableVirtualization = options.enableVirtualization ?? false;
|
|
2067
2546
|
const scrollContainerRef = useRef(null);
|
|
@@ -2105,24 +2584,41 @@ function TableBody({
|
|
|
2105
2584
|
window.removeEventListener("mouseup", handleWindowMouseUp);
|
|
2106
2585
|
};
|
|
2107
2586
|
}, [table]);
|
|
2587
|
+
const renderRow = (row, rowIndex, pinnedPosition) => /* @__PURE__ */ jsx(
|
|
2588
|
+
MemoizedTableRow,
|
|
2589
|
+
{
|
|
2590
|
+
row,
|
|
2591
|
+
table,
|
|
2592
|
+
rowIndex,
|
|
2593
|
+
visibleColumns,
|
|
2594
|
+
isSelected: row.getIsSelected(),
|
|
2595
|
+
isExpanded: row.getIsExpanded(),
|
|
2596
|
+
activeColumnId: activeCell?.rowId === row.id ? activeCell.columnId : void 0,
|
|
2597
|
+
focusedColumnIndex: focusedCell?.rowIndex === rowIndex ? focusedCell.columnIndex : null,
|
|
2598
|
+
hasFocusedCell: focusedCell !== null,
|
|
2599
|
+
cellSelectionKey,
|
|
2600
|
+
pendingValuesKey: getPendingValuesKey(pendingValues[row.id]),
|
|
2601
|
+
clickable: clickableRows,
|
|
2602
|
+
pinnedPosition,
|
|
2603
|
+
onFillHandleMouseDown
|
|
2604
|
+
},
|
|
2605
|
+
row.id
|
|
2606
|
+
);
|
|
2108
2607
|
if (!enableVirtualization) {
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
},
|
|
2124
|
-
row.id
|
|
2125
|
-
)) });
|
|
2608
|
+
const rowPinning = table.getState().rowPinning;
|
|
2609
|
+
const hasPinnedRows = (rowPinning.top?.length ?? 0) > 0 || (rowPinning.bottom?.length ?? 0) > 0;
|
|
2610
|
+
if (hasPinnedRows) {
|
|
2611
|
+
const topRows = table.getTopRows();
|
|
2612
|
+
const centerRows = table.getCenterRows();
|
|
2613
|
+
const bottomRows = table.getBottomRows();
|
|
2614
|
+
let visualIndex = 0;
|
|
2615
|
+
return /* @__PURE__ */ jsxs("tbody", { className: "yable-tbody", children: [
|
|
2616
|
+
topRows.map((row) => renderRow(row, visualIndex++, "top")),
|
|
2617
|
+
centerRows.map((row) => renderRow(row, visualIndex++)),
|
|
2618
|
+
bottomRows.map((row) => renderRow(row, visualIndex++, "bottom"))
|
|
2619
|
+
] });
|
|
2620
|
+
}
|
|
2621
|
+
return /* @__PURE__ */ jsx("tbody", { className: "yable-tbody", children: rows.map((row, rowIndex) => renderRow(row, rowIndex)) });
|
|
2126
2622
|
}
|
|
2127
2623
|
const hasPretextData = !!(pretextHeights && pretextPrefixSums);
|
|
2128
2624
|
const fixedRowHeight = typeof rowHeight === "number" && !hasPretextData ? rowHeight : void 0;
|
|
@@ -2171,7 +2667,9 @@ function TableBody({
|
|
|
2171
2667
|
focusedColumnIndex: focusedCell?.rowIndex === vRow.index ? focusedCell.columnIndex : null,
|
|
2172
2668
|
hasFocusedCell: focusedCell !== null,
|
|
2173
2669
|
cellSelectionKey,
|
|
2670
|
+
pendingValuesKey: getPendingValuesKey(pendingValues[row.id]),
|
|
2174
2671
|
clickable: clickableRows,
|
|
2672
|
+
onFillHandleMouseDown,
|
|
2175
2673
|
virtualStyle: {
|
|
2176
2674
|
position: "absolute",
|
|
2177
2675
|
top: 0,
|
|
@@ -2203,13 +2701,19 @@ function TableRowInner({
|
|
|
2203
2701
|
focusedColumnIndex,
|
|
2204
2702
|
hasFocusedCell,
|
|
2205
2703
|
cellSelectionKey: _cellSelectionKey,
|
|
2704
|
+
pendingValuesKey: _pendingValuesKey,
|
|
2206
2705
|
clickable,
|
|
2207
|
-
|
|
2706
|
+
pinnedPosition,
|
|
2707
|
+
virtualStyle,
|
|
2708
|
+
onFillHandleMouseDown
|
|
2208
2709
|
}) {
|
|
2209
2710
|
const allCells = row.getAllCells();
|
|
2210
2711
|
const visibleCells = visibleColumns.map((column) => allCells.find((cell) => cell.column.id === column.id)).filter((cell) => cell != null);
|
|
2211
2712
|
const handleClick = useCallback(
|
|
2212
2713
|
(e) => {
|
|
2714
|
+
if (table.options.enableRowClickSelection && row.getCanSelect() && !isInteractiveClickTarget2(e.target)) {
|
|
2715
|
+
row.toggleSelected();
|
|
2716
|
+
}
|
|
2213
2717
|
if (clickable) {
|
|
2214
2718
|
table.events.emit("row:click", {
|
|
2215
2719
|
row,
|
|
@@ -2217,7 +2721,7 @@ function TableRowInner({
|
|
|
2217
2721
|
});
|
|
2218
2722
|
}
|
|
2219
2723
|
},
|
|
2220
|
-
[clickable, table
|
|
2724
|
+
[clickable, table, row]
|
|
2221
2725
|
);
|
|
2222
2726
|
const handleDoubleClick = useCallback(
|
|
2223
2727
|
(e) => {
|
|
@@ -2239,15 +2743,26 @@ function TableRowInner({
|
|
|
2239
2743
|
);
|
|
2240
2744
|
const selectionEnabled = Boolean(table.options.enableRowSelection);
|
|
2241
2745
|
const expansionEnabled = Boolean(table.options.enableExpanding);
|
|
2746
|
+
const rowClassNameDef = table.options.rowClassName;
|
|
2747
|
+
const userRowClassName = typeof rowClassNameDef === "function" ? rowClassNameDef(row) : rowClassNameDef;
|
|
2748
|
+
const rowStyleDef = table.options.rowStyle;
|
|
2749
|
+
const userRowStyle = typeof rowStyleDef === "function" ? rowStyleDef(row) : rowStyleDef;
|
|
2750
|
+
const mergedRowStyle = userRowStyle ? { ...virtualStyle, ...userRowStyle } : virtualStyle;
|
|
2751
|
+
const rowClassName = [
|
|
2752
|
+
"yable-tr",
|
|
2753
|
+
pinnedPosition && `yable-tr--pinned-${pinnedPosition}`,
|
|
2754
|
+
userRowClassName
|
|
2755
|
+
].filter(Boolean).join(" ");
|
|
2242
2756
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2243
2757
|
/* @__PURE__ */ jsx(
|
|
2244
2758
|
"tr",
|
|
2245
2759
|
{
|
|
2246
|
-
className:
|
|
2247
|
-
style:
|
|
2760
|
+
className: rowClassName,
|
|
2761
|
+
style: mergedRowStyle,
|
|
2248
2762
|
"data-selected": isSelected || void 0,
|
|
2249
2763
|
"data-expanded": isExpanded || void 0,
|
|
2250
2764
|
"data-clickable": clickable || void 0,
|
|
2765
|
+
"data-pinned-row": pinnedPosition,
|
|
2251
2766
|
"data-row-id": row.id,
|
|
2252
2767
|
"data-row-index": rowIndex,
|
|
2253
2768
|
"aria-selected": selectionEnabled ? isSelected : void 0,
|
|
@@ -2270,7 +2785,8 @@ function TableRowInner({
|
|
|
2270
2785
|
rowIndex,
|
|
2271
2786
|
columnIndex,
|
|
2272
2787
|
isFocused,
|
|
2273
|
-
isTabStop
|
|
2788
|
+
isTabStop,
|
|
2789
|
+
onFillHandleMouseDown
|
|
2274
2790
|
}
|
|
2275
2791
|
)
|
|
2276
2792
|
},
|
|
@@ -2279,7 +2795,7 @@ function TableRowInner({
|
|
|
2279
2795
|
})
|
|
2280
2796
|
}
|
|
2281
2797
|
),
|
|
2282
|
-
isExpanded && /* @__PURE__ */ jsx(
|
|
2798
|
+
isExpanded && /* @__PURE__ */ jsx(MasterDetail, { row, table, colSpan: visibleColumns.length })
|
|
2283
2799
|
] });
|
|
2284
2800
|
}
|
|
2285
2801
|
function areRowPropsEqual(prev, next) {
|
|
@@ -2290,10 +2806,12 @@ function areRowPropsEqual(prev, next) {
|
|
|
2290
2806
|
if (prev.isSelected !== next.isSelected) return false;
|
|
2291
2807
|
if (prev.isExpanded !== next.isExpanded) return false;
|
|
2292
2808
|
if (prev.clickable !== next.clickable) return false;
|
|
2809
|
+
if (prev.pinnedPosition !== next.pinnedPosition) return false;
|
|
2293
2810
|
if (prev.activeColumnId !== next.activeColumnId) return false;
|
|
2294
2811
|
if (prev.focusedColumnIndex !== next.focusedColumnIndex) return false;
|
|
2295
2812
|
if (prev.hasFocusedCell !== next.hasFocusedCell) return false;
|
|
2296
2813
|
if (prev.cellSelectionKey !== next.cellSelectionKey) return false;
|
|
2814
|
+
if (prev.pendingValuesKey !== next.pendingValuesKey) return false;
|
|
2297
2815
|
if (prev.virtualStyle !== next.virtualStyle) {
|
|
2298
2816
|
if (!prev.virtualStyle || !next.virtualStyle) return false;
|
|
2299
2817
|
if (prev.virtualStyle.transform !== next.virtualStyle.transform) return false;
|
|
@@ -2302,7 +2820,17 @@ function areRowPropsEqual(prev, next) {
|
|
|
2302
2820
|
if (prev.table !== next.table) return false;
|
|
2303
2821
|
return true;
|
|
2304
2822
|
}
|
|
2305
|
-
var MemoizedTableRow =
|
|
2823
|
+
var MemoizedTableRow = React4.memo(TableRowInner, areRowPropsEqual);
|
|
2824
|
+
function getPendingValuesKey(values) {
|
|
2825
|
+
if (!values) return "";
|
|
2826
|
+
return Object.keys(values).sort().map((key) => `${key}:${String(values[key])}`).join("|");
|
|
2827
|
+
}
|
|
2828
|
+
function isInteractiveClickTarget2(target) {
|
|
2829
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
2830
|
+
return Boolean(
|
|
2831
|
+
target.closest('input, textarea, select, button, a[href], [contenteditable="true"]')
|
|
2832
|
+
);
|
|
2833
|
+
}
|
|
2306
2834
|
function TableFooter({ table }) {
|
|
2307
2835
|
const footerGroups = table.getFooterGroups();
|
|
2308
2836
|
if (!footerGroups.length) return null;
|
|
@@ -2510,8 +3038,8 @@ function StatusDivider() {
|
|
|
2510
3038
|
return /* @__PURE__ */ jsx("span", { className: "yable-status-bar-divider", "aria-hidden": "true" });
|
|
2511
3039
|
}
|
|
2512
3040
|
function PanelGroup({ children }) {
|
|
2513
|
-
const items =
|
|
2514
|
-
return /* @__PURE__ */ jsx(Fragment, { children: items.map((child, i) => /* @__PURE__ */ jsxs(
|
|
3041
|
+
const items = React4.Children.toArray(children).filter(Boolean);
|
|
3042
|
+
return /* @__PURE__ */ jsx(Fragment, { children: items.map((child, i) => /* @__PURE__ */ jsxs(React4.Fragment, { children: [
|
|
2515
3043
|
i > 0 && /* @__PURE__ */ jsx(StatusDivider, {}),
|
|
2516
3044
|
child
|
|
2517
3045
|
] }, i)) });
|
|
@@ -2590,29 +3118,73 @@ function StatusBar({
|
|
|
2590
3118
|
] });
|
|
2591
3119
|
}
|
|
2592
3120
|
function SearchIcon() {
|
|
2593
|
-
return /* @__PURE__ */ jsxs(
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
3121
|
+
return /* @__PURE__ */ jsxs(
|
|
3122
|
+
"svg",
|
|
3123
|
+
{
|
|
3124
|
+
className: "yable-sidebar-search-icon",
|
|
3125
|
+
width: "13",
|
|
3126
|
+
height: "13",
|
|
3127
|
+
viewBox: "0 0 14 14",
|
|
3128
|
+
fill: "none",
|
|
3129
|
+
"aria-hidden": "true",
|
|
3130
|
+
children: [
|
|
3131
|
+
/* @__PURE__ */ jsx("circle", { cx: "6.25", cy: "6.25", r: "4.25", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
3132
|
+
/* @__PURE__ */ jsx("path", { d: "M9.5 9.5L12.5 12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
3133
|
+
]
|
|
3134
|
+
}
|
|
3135
|
+
);
|
|
2597
3136
|
}
|
|
2598
3137
|
function VisibilityIcon({ visible }) {
|
|
2599
3138
|
if (visible) {
|
|
2600
3139
|
return /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": "true", children: [
|
|
2601
|
-
/* @__PURE__ */ jsx(
|
|
3140
|
+
/* @__PURE__ */ jsx(
|
|
3141
|
+
"path",
|
|
3142
|
+
{
|
|
3143
|
+
d: "M1 7s2.5-4 6-4 6 4 6 4-2.5 4-6 4-6-4-6-4z",
|
|
3144
|
+
stroke: "currentColor",
|
|
3145
|
+
strokeWidth: "1.2",
|
|
3146
|
+
strokeLinejoin: "round"
|
|
3147
|
+
}
|
|
3148
|
+
),
|
|
2602
3149
|
/* @__PURE__ */ jsx("circle", { cx: "7", cy: "7", r: "2", stroke: "currentColor", strokeWidth: "1.2" })
|
|
2603
3150
|
] });
|
|
2604
3151
|
}
|
|
2605
3152
|
return /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": "true", children: [
|
|
2606
|
-
/* @__PURE__ */ jsx(
|
|
2607
|
-
|
|
3153
|
+
/* @__PURE__ */ jsx(
|
|
3154
|
+
"path",
|
|
3155
|
+
{
|
|
3156
|
+
d: "M1 7s2.5-4 6-4 6 4 6 4-2.5 4-6 4-6-4-6-4z",
|
|
3157
|
+
stroke: "currentColor",
|
|
3158
|
+
strokeWidth: "1.2",
|
|
3159
|
+
strokeLinejoin: "round",
|
|
3160
|
+
opacity: "0.3"
|
|
3161
|
+
}
|
|
3162
|
+
),
|
|
3163
|
+
/* @__PURE__ */ jsx(
|
|
3164
|
+
"line",
|
|
3165
|
+
{
|
|
3166
|
+
x1: "2",
|
|
3167
|
+
y1: "2",
|
|
3168
|
+
x2: "12",
|
|
3169
|
+
y2: "12",
|
|
3170
|
+
stroke: "currentColor",
|
|
3171
|
+
strokeWidth: "1.2",
|
|
3172
|
+
strokeLinecap: "round",
|
|
3173
|
+
opacity: "0.5"
|
|
3174
|
+
}
|
|
3175
|
+
)
|
|
2608
3176
|
] });
|
|
2609
3177
|
}
|
|
2610
|
-
function ColumnsPanel({
|
|
2611
|
-
table
|
|
2612
|
-
}) {
|
|
3178
|
+
function ColumnsPanel({ table }) {
|
|
2613
3179
|
const [search, setSearch] = useState("");
|
|
2614
3180
|
const [draggedId, setDraggedId] = useState(null);
|
|
2615
|
-
const
|
|
3181
|
+
const allColumns = table.getAllLeafColumns();
|
|
3182
|
+
const columnOrder = table.getState().columnOrder;
|
|
3183
|
+
const columns = columnOrder && columnOrder.length > 0 ? [...allColumns].sort((a, b) => {
|
|
3184
|
+
const ia = columnOrder.indexOf(a.id);
|
|
3185
|
+
const ib = columnOrder.indexOf(b.id);
|
|
3186
|
+
return (ia === -1 ? Number.MAX_SAFE_INTEGER : ia) - (ib === -1 ? Number.MAX_SAFE_INTEGER : ib);
|
|
3187
|
+
}) : allColumns;
|
|
2616
3188
|
const visibleCount = columns.filter((c) => c.getIsVisible()).length;
|
|
2617
3189
|
const filteredColumns = search ? columns.filter((col) => {
|
|
2618
3190
|
const header = typeof col.columnDef.header === "string" ? col.columnDef.header : col.id;
|
|
@@ -3039,6 +3611,7 @@ function ContextMenu({
|
|
|
3039
3611
|
y,
|
|
3040
3612
|
onClose,
|
|
3041
3613
|
table,
|
|
3614
|
+
targetColumnId,
|
|
3042
3615
|
customItems
|
|
3043
3616
|
}) {
|
|
3044
3617
|
const menuRef = useRef(null);
|
|
@@ -3082,6 +3655,17 @@ function ContextMenu({
|
|
|
3082
3655
|
},
|
|
3083
3656
|
[onClose]
|
|
3084
3657
|
);
|
|
3658
|
+
const resolveSortColumn = () => {
|
|
3659
|
+
if (targetColumnId) {
|
|
3660
|
+
const column = table.getColumn(targetColumnId);
|
|
3661
|
+
if (column) return column;
|
|
3662
|
+
}
|
|
3663
|
+
const focused = table.getFocusedCell();
|
|
3664
|
+
if (focused) {
|
|
3665
|
+
return table.getVisibleLeafColumns()[focused.columnIndex];
|
|
3666
|
+
}
|
|
3667
|
+
return void 0;
|
|
3668
|
+
};
|
|
3085
3669
|
const defaultItems = [
|
|
3086
3670
|
{
|
|
3087
3671
|
id: "copy",
|
|
@@ -3130,14 +3714,14 @@ function ContextMenu({
|
|
|
3130
3714
|
id: "sort-asc",
|
|
3131
3715
|
label: "Sort Ascending",
|
|
3132
3716
|
action: () => {
|
|
3133
|
-
|
|
3717
|
+
resolveSortColumn()?.toggleSorting(false);
|
|
3134
3718
|
}
|
|
3135
3719
|
},
|
|
3136
3720
|
{
|
|
3137
3721
|
id: "sort-desc",
|
|
3138
3722
|
label: "Sort Descending",
|
|
3139
3723
|
action: () => {
|
|
3140
|
-
|
|
3724
|
+
resolveSortColumn()?.toggleSorting(true);
|
|
3141
3725
|
}
|
|
3142
3726
|
},
|
|
3143
3727
|
{
|
|
@@ -3229,11 +3813,13 @@ function useContextMenu() {
|
|
|
3229
3813
|
const [x, setX] = useState(0);
|
|
3230
3814
|
const [y, setY] = useState(0);
|
|
3231
3815
|
const [targetTable, setTargetTable] = useState(null);
|
|
3816
|
+
const [targetColumnId, setTargetColumnId] = useState(void 0);
|
|
3232
3817
|
const open = useCallback(
|
|
3233
|
-
(clientX, clientY, table) => {
|
|
3818
|
+
(clientX, clientY, table, columnId) => {
|
|
3234
3819
|
setX(clientX);
|
|
3235
3820
|
setY(clientY);
|
|
3236
3821
|
setTargetTable(table);
|
|
3822
|
+
setTargetColumnId(columnId);
|
|
3237
3823
|
setIsOpen(true);
|
|
3238
3824
|
},
|
|
3239
3825
|
[]
|
|
@@ -3241,6 +3827,7 @@ function useContextMenu() {
|
|
|
3241
3827
|
const close = useCallback(() => {
|
|
3242
3828
|
setIsOpen(false);
|
|
3243
3829
|
setTargetTable(null);
|
|
3830
|
+
setTargetColumnId(void 0);
|
|
3244
3831
|
}, []);
|
|
3245
3832
|
useEffect(() => {
|
|
3246
3833
|
if (!isOpen) return;
|
|
@@ -3255,7 +3842,7 @@ function useContextMenu() {
|
|
|
3255
3842
|
document.removeEventListener("click", handleClick);
|
|
3256
3843
|
};
|
|
3257
3844
|
}, [isOpen, close]);
|
|
3258
|
-
return { isOpen, x, y, targetTable, open, close };
|
|
3845
|
+
return { isOpen, x, y, targetTable, targetColumnId, open, close };
|
|
3259
3846
|
}
|
|
3260
3847
|
function useKeyboardNavigation(table, options = {}) {
|
|
3261
3848
|
const {
|
|
@@ -3455,6 +4042,85 @@ function isEditableTarget(element) {
|
|
|
3455
4042
|
}
|
|
3456
4043
|
return element.isContentEditable;
|
|
3457
4044
|
}
|
|
4045
|
+
function useFillHandle(table, options = {}) {
|
|
4046
|
+
const { enabled = true } = options;
|
|
4047
|
+
const [dragState, setDragState] = useState({
|
|
4048
|
+
isDragging: false,
|
|
4049
|
+
sourceCell: null,
|
|
4050
|
+
currentCell: null
|
|
4051
|
+
});
|
|
4052
|
+
const dragRef = useRef(dragState);
|
|
4053
|
+
dragRef.current = dragState;
|
|
4054
|
+
const onFillHandleMouseDown = useCallback(
|
|
4055
|
+
(rowIndex, columnIndex, e) => {
|
|
4056
|
+
if (!enabled) return;
|
|
4057
|
+
e.preventDefault();
|
|
4058
|
+
e.stopPropagation();
|
|
4059
|
+
setDragState({
|
|
4060
|
+
isDragging: true,
|
|
4061
|
+
sourceCell: { rowIndex, columnIndex },
|
|
4062
|
+
currentCell: { rowIndex, columnIndex }
|
|
4063
|
+
});
|
|
4064
|
+
},
|
|
4065
|
+
[enabled]
|
|
4066
|
+
);
|
|
4067
|
+
useEffect(() => {
|
|
4068
|
+
if (!dragState.isDragging) return;
|
|
4069
|
+
const handleMouseMove = (e) => {
|
|
4070
|
+
const target = document.elementFromPoint(e.clientX, e.clientY);
|
|
4071
|
+
if (!target) return;
|
|
4072
|
+
const td = target.closest("td[data-column-id]");
|
|
4073
|
+
const tr = target.closest("tr[data-row-id]");
|
|
4074
|
+
if (!td || !tr) return;
|
|
4075
|
+
const columnId = td.getAttribute("data-column-id");
|
|
4076
|
+
const rowId = tr.getAttribute("data-row-id");
|
|
4077
|
+
if (!columnId || !rowId) return;
|
|
4078
|
+
const rows = table.getRowModel().rows;
|
|
4079
|
+
const columns = table.getVisibleLeafColumns();
|
|
4080
|
+
const rowIndex = rows.findIndex((r) => r.id === rowId);
|
|
4081
|
+
const columnIndex = columns.findIndex((c) => c.id === columnId);
|
|
4082
|
+
if (rowIndex === -1 || columnIndex === -1) return;
|
|
4083
|
+
setDragState((prev) => ({
|
|
4084
|
+
...prev,
|
|
4085
|
+
currentCell: { rowIndex, columnIndex }
|
|
4086
|
+
}));
|
|
4087
|
+
};
|
|
4088
|
+
const handleMouseUp = () => {
|
|
4089
|
+
const current = dragRef.current;
|
|
4090
|
+
if (current.sourceCell && current.currentCell) {
|
|
4091
|
+
const source = current.sourceCell;
|
|
4092
|
+
const target = current.currentCell;
|
|
4093
|
+
if (source.rowIndex !== target.rowIndex || source.columnIndex !== target.columnIndex) {
|
|
4094
|
+
const sourceRange = {
|
|
4095
|
+
startRow: source.rowIndex,
|
|
4096
|
+
startCol: source.columnIndex,
|
|
4097
|
+
endRow: source.rowIndex,
|
|
4098
|
+
endCol: source.columnIndex
|
|
4099
|
+
};
|
|
4100
|
+
const targetRange = {
|
|
4101
|
+
startRow: Math.min(source.rowIndex, target.rowIndex),
|
|
4102
|
+
startCol: Math.min(source.columnIndex, target.columnIndex),
|
|
4103
|
+
endRow: Math.max(source.rowIndex, target.rowIndex),
|
|
4104
|
+
endCol: Math.max(source.columnIndex, target.columnIndex)
|
|
4105
|
+
};
|
|
4106
|
+
table.fillRange(sourceRange, targetRange);
|
|
4107
|
+
}
|
|
4108
|
+
}
|
|
4109
|
+
setDragState({
|
|
4110
|
+
isDragging: false,
|
|
4111
|
+
sourceCell: null,
|
|
4112
|
+
currentCell: null
|
|
4113
|
+
});
|
|
4114
|
+
};
|
|
4115
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
4116
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
4117
|
+
return () => {
|
|
4118
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
4119
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
4120
|
+
};
|
|
4121
|
+
}, [dragState.isDragging, table]);
|
|
4122
|
+
return { dragState, onFillHandleMouseDown };
|
|
4123
|
+
}
|
|
3458
4124
|
function filterHeaderGroups(groups, visibleColumnIds) {
|
|
3459
4125
|
return groups.map((group) => ({
|
|
3460
4126
|
...group,
|
|
@@ -3468,6 +4134,8 @@ function Table({
|
|
|
3468
4134
|
bordered: borderedProp,
|
|
3469
4135
|
compact: compactProp,
|
|
3470
4136
|
theme: themeProp,
|
|
4137
|
+
config,
|
|
4138
|
+
configProfile,
|
|
3471
4139
|
clickableRows,
|
|
3472
4140
|
footer,
|
|
3473
4141
|
loading,
|
|
@@ -3485,7 +4153,7 @@ function Table({
|
|
|
3485
4153
|
statusBar,
|
|
3486
4154
|
statusBarPanels,
|
|
3487
4155
|
sidebar,
|
|
3488
|
-
sidebarPanels
|
|
4156
|
+
sidebarPanels,
|
|
3489
4157
|
defaultSidebarPanel,
|
|
3490
4158
|
floatingFilters,
|
|
3491
4159
|
columnVirtualization,
|
|
@@ -3493,17 +4161,31 @@ function Table({
|
|
|
3493
4161
|
ariaLabel: ariaLabelProp,
|
|
3494
4162
|
...rest
|
|
3495
4163
|
}) {
|
|
3496
|
-
const
|
|
3497
|
-
const
|
|
3498
|
-
const
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
const
|
|
3503
|
-
const
|
|
4164
|
+
const providerDefaults = useYableDefaults();
|
|
4165
|
+
const { tableProps: providerTableProps } = providerDefaults;
|
|
4166
|
+
const profile = resolveYableProfile(
|
|
4167
|
+
config ?? providerDefaults.config,
|
|
4168
|
+
configProfile ?? providerDefaults.tableProfile
|
|
4169
|
+
);
|
|
4170
|
+
const profileTableProps = profile.table;
|
|
4171
|
+
const stickyHeader = stickyHeaderProp ?? profileTableProps?.stickyHeader ?? providerTableProps?.stickyHeader;
|
|
4172
|
+
const striped = stripedProp ?? profileTableProps?.striped ?? providerTableProps?.striped;
|
|
4173
|
+
const bordered = borderedProp ?? profileTableProps?.bordered ?? providerTableProps?.bordered;
|
|
4174
|
+
const compact = compactProp ?? profileTableProps?.compact ?? providerTableProps?.compact;
|
|
4175
|
+
const theme = themeProp ?? profileTableProps?.theme ?? providerTableProps?.theme;
|
|
4176
|
+
const direction = directionProp ?? profileTableProps?.direction ?? providerTableProps?.direction;
|
|
4177
|
+
const ariaLabel = ariaLabelProp ?? profileTableProps?.ariaLabel ?? providerTableProps?.ariaLabel;
|
|
4178
|
+
const resolvedClickableRows = clickableRows ?? profileTableProps?.clickableRows;
|
|
4179
|
+
const resolvedStatusBar = statusBar ?? profileTableProps?.statusBar;
|
|
4180
|
+
const resolvedSidebar = sidebar ?? profileTableProps?.sidebar;
|
|
4181
|
+
const resolvedSidebarPanels = sidebarPanels ?? profileTableProps?.sidebarPanels ?? ["columns", "filters"];
|
|
4182
|
+
const resolvedDefaultSidebarPanel = defaultSidebarPanel ?? profileTableProps?.defaultSidebarPanel;
|
|
4183
|
+
const resolvedFloatingFilters = floatingFilters ?? profileTableProps?.floatingFilters;
|
|
4184
|
+
const resolvedColumnVirtualization = columnVirtualization ?? profileTableProps?.columnVirtualization;
|
|
4185
|
+
const resolvedColumnVirtualizationOverscan = columnVirtualizationOverscan ?? profileTableProps?.columnVirtualizationOverscan;
|
|
3504
4186
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
3505
4187
|
const [sidebarPanel, setSidebarPanel] = useState(
|
|
3506
|
-
|
|
4188
|
+
resolvedDefaultSidebarPanel ?? "columns"
|
|
3507
4189
|
);
|
|
3508
4190
|
const containerRef = useRef(null);
|
|
3509
4191
|
const horizontalScrollRef = useRef(null);
|
|
@@ -3527,12 +4209,14 @@ function Table({
|
|
|
3527
4209
|
const allVisibleColumns = table.getVisibleLeafColumns();
|
|
3528
4210
|
const hasPinnedColumns = table.getLeftVisibleLeafColumns().length > 0 || table.getRightVisibleLeafColumns().length > 0;
|
|
3529
4211
|
const hasGroupedHeaders = table.getHeaderGroups().length > 1;
|
|
3530
|
-
const canVirtualizeColumns = Boolean(
|
|
4212
|
+
const canVirtualizeColumns = Boolean(resolvedColumnVirtualization) && !hasPinnedColumns && !hasGroupedHeaders && allVisibleColumns.length > 0;
|
|
4213
|
+
const allVisibleColumnSizeSignature = allVisibleColumns.map((column) => `${column.id}:${column.getSize()}`).join("|");
|
|
3531
4214
|
const columnVirtualState = useColumnVirtualization({
|
|
3532
4215
|
containerRef: horizontalScrollRef,
|
|
3533
4216
|
columns: allVisibleColumns,
|
|
3534
|
-
overscan:
|
|
3535
|
-
enabled: canVirtualizeColumns
|
|
4217
|
+
overscan: resolvedColumnVirtualizationOverscan ?? 2,
|
|
4218
|
+
enabled: canVirtualizeColumns,
|
|
4219
|
+
sizingKey: allVisibleColumnSizeSignature
|
|
3536
4220
|
});
|
|
3537
4221
|
const renderTable = useMemo(() => {
|
|
3538
4222
|
if (!canVirtualizeColumns || !columnVirtualState.isVirtualized) {
|
|
@@ -3560,6 +4244,9 @@ function Table({
|
|
|
3560
4244
|
const showColumnVirtualizationShell = canVirtualizeColumns;
|
|
3561
4245
|
const contextMenu = useContextMenu();
|
|
3562
4246
|
useKeyboardNavigation(table, { containerRef });
|
|
4247
|
+
const { onFillHandleMouseDown } = useFillHandle(table, {
|
|
4248
|
+
enabled: Boolean(table.options.enableFillHandle)
|
|
4249
|
+
});
|
|
3563
4250
|
const [announcement, setAnnouncement] = useState("");
|
|
3564
4251
|
const prevSortingRef = useRef(table.getState().sorting);
|
|
3565
4252
|
const prevFilterCountRef = useRef(rows.length);
|
|
@@ -3607,17 +4294,18 @@ function Table({
|
|
|
3607
4294
|
const handleContextMenu = useCallback(
|
|
3608
4295
|
(e) => {
|
|
3609
4296
|
e.preventDefault();
|
|
3610
|
-
|
|
4297
|
+
const targetEl = e.target?.closest?.("[data-column-id]");
|
|
4298
|
+
const targetColumnId = targetEl?.getAttribute("data-column-id") ?? void 0;
|
|
4299
|
+
contextMenu.open(e.clientX, e.clientY, table, targetColumnId);
|
|
3611
4300
|
},
|
|
3612
4301
|
[contextMenu, table]
|
|
3613
4302
|
);
|
|
3614
|
-
const enableRowVirtualization = renderTable.options.enableVirtualization ?? false;
|
|
3615
4303
|
const visibleLeafColumns = renderTable.getVisibleLeafColumns();
|
|
3616
|
-
const
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
4304
|
+
const visibleColumnTotalSize = visibleLeafColumns.reduce(
|
|
4305
|
+
(sum, column) => sum + column.getSize(),
|
|
4306
|
+
0
|
|
4307
|
+
);
|
|
4308
|
+
const colgroup = visibleLeafColumns.length === 0 ? null : /* @__PURE__ */ jsx("colgroup", { children: visibleLeafColumns.map((col) => /* @__PURE__ */ jsx("col", { style: { width: col.getSize() } }, col.id)) });
|
|
3621
4309
|
const outerTableStyle = useMemo(() => {
|
|
3622
4310
|
if (columnVirtualState.isVirtualized) {
|
|
3623
4311
|
return {
|
|
@@ -3627,15 +4315,15 @@ function Table({
|
|
|
3627
4315
|
tableLayout: "fixed"
|
|
3628
4316
|
};
|
|
3629
4317
|
}
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
4318
|
+
return {
|
|
4319
|
+
minWidth: visibleColumnTotalSize || void 0,
|
|
4320
|
+
tableLayout: "fixed"
|
|
4321
|
+
};
|
|
3634
4322
|
}, [
|
|
3635
4323
|
columnVirtualState.isVirtualized,
|
|
3636
4324
|
columnVirtualState.visibleWidth,
|
|
3637
4325
|
columnVirtualState.startOffset,
|
|
3638
|
-
|
|
4326
|
+
visibleColumnTotalSize
|
|
3639
4327
|
]);
|
|
3640
4328
|
const tableNode = /* @__PURE__ */ jsxs(
|
|
3641
4329
|
"table",
|
|
@@ -3644,9 +4332,17 @@ function Table({
|
|
|
3644
4332
|
style: outerTableStyle,
|
|
3645
4333
|
"data-column-virtualized": columnVirtualState.isVirtualized || void 0,
|
|
3646
4334
|
children: [
|
|
3647
|
-
|
|
3648
|
-
/* @__PURE__ */ jsx(TableHeader, { table: renderTable, floatingFilters }),
|
|
3649
|
-
/* @__PURE__ */ jsx(
|
|
4335
|
+
colgroup,
|
|
4336
|
+
/* @__PURE__ */ jsx(TableHeader, { table: renderTable, floatingFilters: resolvedFloatingFilters }),
|
|
4337
|
+
/* @__PURE__ */ jsx(
|
|
4338
|
+
TableBody,
|
|
4339
|
+
{
|
|
4340
|
+
table: renderTable,
|
|
4341
|
+
clickableRows: resolvedClickableRows,
|
|
4342
|
+
colgroup,
|
|
4343
|
+
onFillHandleMouseDown
|
|
4344
|
+
}
|
|
4345
|
+
),
|
|
3650
4346
|
footer && /* @__PURE__ */ jsx(TableFooter, { table: renderTable })
|
|
3651
4347
|
]
|
|
3652
4348
|
}
|
|
@@ -3712,18 +4408,43 @@ function Table({
|
|
|
3712
4408
|
}
|
|
3713
4409
|
))
|
|
3714
4410
|
] }),
|
|
3715
|
-
|
|
4411
|
+
resolvedSidebar && !sidebarOpen && /* @__PURE__ */ jsx(
|
|
4412
|
+
"button",
|
|
4413
|
+
{
|
|
4414
|
+
type: "button",
|
|
4415
|
+
className: "yable-sidebar-trigger",
|
|
4416
|
+
"aria-label": "Open tool panel",
|
|
4417
|
+
title: "Open tool panel",
|
|
4418
|
+
onClick: () => setSidebarOpen(true),
|
|
4419
|
+
children: /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
|
|
4420
|
+
/* @__PURE__ */ jsx(
|
|
4421
|
+
"rect",
|
|
4422
|
+
{
|
|
4423
|
+
x: "3",
|
|
4424
|
+
y: "4",
|
|
4425
|
+
width: "18",
|
|
4426
|
+
height: "16",
|
|
4427
|
+
rx: "2",
|
|
4428
|
+
stroke: "currentColor",
|
|
4429
|
+
strokeWidth: "2"
|
|
4430
|
+
}
|
|
4431
|
+
),
|
|
4432
|
+
/* @__PURE__ */ jsx("line", { x1: "14", y1: "4", x2: "14", y2: "20", stroke: "currentColor", strokeWidth: "2" })
|
|
4433
|
+
] })
|
|
4434
|
+
}
|
|
4435
|
+
),
|
|
4436
|
+
resolvedSidebar && /* @__PURE__ */ jsx(
|
|
3716
4437
|
Sidebar,
|
|
3717
4438
|
{
|
|
3718
4439
|
table,
|
|
3719
4440
|
open: sidebarOpen,
|
|
3720
4441
|
onClose: () => setSidebarOpen(false),
|
|
3721
|
-
panels:
|
|
4442
|
+
panels: resolvedSidebarPanels,
|
|
3722
4443
|
activePanel: sidebarPanel,
|
|
3723
4444
|
onPanelChange: setSidebarPanel
|
|
3724
4445
|
}
|
|
3725
4446
|
),
|
|
3726
|
-
|
|
4447
|
+
resolvedStatusBar && /* @__PURE__ */ jsx(StatusBar, { table, panels: statusBarPanels }),
|
|
3727
4448
|
children,
|
|
3728
4449
|
contextMenu.isOpen && /* @__PURE__ */ jsx(
|
|
3729
4450
|
ContextMenu,
|
|
@@ -3731,7 +4452,8 @@ function Table({
|
|
|
3731
4452
|
x: contextMenu.x,
|
|
3732
4453
|
y: contextMenu.y,
|
|
3733
4454
|
onClose: contextMenu.close,
|
|
3734
|
-
table
|
|
4455
|
+
table,
|
|
4456
|
+
targetColumnId: contextMenu.targetColumnId
|
|
3735
4457
|
}
|
|
3736
4458
|
),
|
|
3737
4459
|
/* @__PURE__ */ jsx(
|
|
@@ -4308,110 +5030,6 @@ function isEditableTarget2(el) {
|
|
|
4308
5030
|
if (el.isContentEditable) return true;
|
|
4309
5031
|
return false;
|
|
4310
5032
|
}
|
|
4311
|
-
function useFillHandle(table, options = {}) {
|
|
4312
|
-
const { enabled = true } = options;
|
|
4313
|
-
const [dragState, setDragState] = useState({
|
|
4314
|
-
isDragging: false,
|
|
4315
|
-
sourceCell: null,
|
|
4316
|
-
currentCell: null
|
|
4317
|
-
});
|
|
4318
|
-
const dragRef = useRef(dragState);
|
|
4319
|
-
dragRef.current = dragState;
|
|
4320
|
-
const onFillHandleMouseDown = useCallback(
|
|
4321
|
-
(rowIndex, columnIndex, e) => {
|
|
4322
|
-
if (!enabled) return;
|
|
4323
|
-
e.preventDefault();
|
|
4324
|
-
e.stopPropagation();
|
|
4325
|
-
setDragState({
|
|
4326
|
-
isDragging: true,
|
|
4327
|
-
sourceCell: { rowIndex, columnIndex },
|
|
4328
|
-
currentCell: { rowIndex, columnIndex }
|
|
4329
|
-
});
|
|
4330
|
-
},
|
|
4331
|
-
[enabled]
|
|
4332
|
-
);
|
|
4333
|
-
useEffect(() => {
|
|
4334
|
-
if (!dragState.isDragging) return;
|
|
4335
|
-
const handleMouseMove = (e) => {
|
|
4336
|
-
const target = document.elementFromPoint(e.clientX, e.clientY);
|
|
4337
|
-
if (!target) return;
|
|
4338
|
-
const td = target.closest("td[data-column-id]");
|
|
4339
|
-
const tr = target.closest("tr[data-row-id]");
|
|
4340
|
-
if (!td || !tr) return;
|
|
4341
|
-
const columnId = td.getAttribute("data-column-id");
|
|
4342
|
-
const rowId = tr.getAttribute("data-row-id");
|
|
4343
|
-
if (!columnId || !rowId) return;
|
|
4344
|
-
const rows = table.getRowModel().rows;
|
|
4345
|
-
const columns = table.getVisibleLeafColumns();
|
|
4346
|
-
const rowIndex = rows.findIndex((r) => r.id === rowId);
|
|
4347
|
-
const columnIndex = columns.findIndex((c) => c.id === columnId);
|
|
4348
|
-
if (rowIndex === -1 || columnIndex === -1) return;
|
|
4349
|
-
setDragState((prev) => ({
|
|
4350
|
-
...prev,
|
|
4351
|
-
currentCell: { rowIndex, columnIndex }
|
|
4352
|
-
}));
|
|
4353
|
-
};
|
|
4354
|
-
const handleMouseUp = () => {
|
|
4355
|
-
const current = dragRef.current;
|
|
4356
|
-
if (current.sourceCell && current.currentCell) {
|
|
4357
|
-
const source = current.sourceCell;
|
|
4358
|
-
const target = current.currentCell;
|
|
4359
|
-
if (source.rowIndex !== target.rowIndex || source.columnIndex !== target.columnIndex) {
|
|
4360
|
-
const sourceRange = {
|
|
4361
|
-
startRow: source.rowIndex,
|
|
4362
|
-
startCol: source.columnIndex,
|
|
4363
|
-
endRow: source.rowIndex,
|
|
4364
|
-
endCol: source.columnIndex
|
|
4365
|
-
};
|
|
4366
|
-
const targetRange = {
|
|
4367
|
-
startRow: Math.min(source.rowIndex, target.rowIndex),
|
|
4368
|
-
startCol: Math.min(source.columnIndex, target.columnIndex),
|
|
4369
|
-
endRow: Math.max(source.rowIndex, target.rowIndex),
|
|
4370
|
-
endCol: Math.max(source.columnIndex, target.columnIndex)
|
|
4371
|
-
};
|
|
4372
|
-
table.fillRange(sourceRange, targetRange);
|
|
4373
|
-
}
|
|
4374
|
-
}
|
|
4375
|
-
setDragState({
|
|
4376
|
-
isDragging: false,
|
|
4377
|
-
sourceCell: null,
|
|
4378
|
-
currentCell: null
|
|
4379
|
-
});
|
|
4380
|
-
};
|
|
4381
|
-
document.addEventListener("mousemove", handleMouseMove);
|
|
4382
|
-
document.addEventListener("mouseup", handleMouseUp);
|
|
4383
|
-
return () => {
|
|
4384
|
-
document.removeEventListener("mousemove", handleMouseMove);
|
|
4385
|
-
document.removeEventListener("mouseup", handleMouseUp);
|
|
4386
|
-
};
|
|
4387
|
-
}, [dragState.isDragging, table]);
|
|
4388
|
-
return { dragState, onFillHandleMouseDown };
|
|
4389
|
-
}
|
|
4390
|
-
function FillHandle({
|
|
4391
|
-
rowIndex,
|
|
4392
|
-
columnIndex,
|
|
4393
|
-
onMouseDown
|
|
4394
|
-
}) {
|
|
4395
|
-
const handleMouseDown = useCallback(
|
|
4396
|
-
(e) => {
|
|
4397
|
-
e.preventDefault();
|
|
4398
|
-
e.stopPropagation();
|
|
4399
|
-
onMouseDown(rowIndex, columnIndex, e);
|
|
4400
|
-
},
|
|
4401
|
-
[rowIndex, columnIndex, onMouseDown]
|
|
4402
|
-
);
|
|
4403
|
-
return /* @__PURE__ */ jsx(
|
|
4404
|
-
"div",
|
|
4405
|
-
{
|
|
4406
|
-
className: "yable-fill-handle",
|
|
4407
|
-
onMouseDown: handleMouseDown,
|
|
4408
|
-
role: "presentation",
|
|
4409
|
-
"aria-hidden": "true",
|
|
4410
|
-
title: "Drag to fill",
|
|
4411
|
-
children: /* @__PURE__ */ jsx("div", { className: "yable-fill-handle-dot" })
|
|
4412
|
-
}
|
|
4413
|
-
);
|
|
4414
|
-
}
|
|
4415
5033
|
function GripIcon() {
|
|
4416
5034
|
return /* @__PURE__ */ jsxs(
|
|
4417
5035
|
"svg",
|
|
@@ -4659,33 +5277,6 @@ function TreeToggle({
|
|
|
4659
5277
|
}
|
|
4660
5278
|
);
|
|
4661
5279
|
}
|
|
4662
|
-
function MasterDetail({
|
|
4663
|
-
row,
|
|
4664
|
-
table,
|
|
4665
|
-
colSpan,
|
|
4666
|
-
renderDetailPanel,
|
|
4667
|
-
animationClass
|
|
4668
|
-
}) {
|
|
4669
|
-
const renderer = renderDetailPanel ?? table.options.renderDetailPanel;
|
|
4670
|
-
if (!renderer) return null;
|
|
4671
|
-
const content = renderer(row);
|
|
4672
|
-
if (content == null) return null;
|
|
4673
|
-
const classes = [
|
|
4674
|
-
"yable-detail-row",
|
|
4675
|
-
"yable-detail-row--animated",
|
|
4676
|
-
animationClass
|
|
4677
|
-
].filter(Boolean).join(" ");
|
|
4678
|
-
return /* @__PURE__ */ jsx(
|
|
4679
|
-
"tr",
|
|
4680
|
-
{
|
|
4681
|
-
className: classes,
|
|
4682
|
-
"data-detail-for": row.id,
|
|
4683
|
-
role: "row",
|
|
4684
|
-
"aria-label": `Details for row ${row.id}`,
|
|
4685
|
-
children: /* @__PURE__ */ jsx("td", { className: "yable-detail-cell", colSpan, role: "cell", children: /* @__PURE__ */ jsx("div", { className: "yable-detail-panel", children: /* @__PURE__ */ jsx("div", { className: "yable-detail-panel-inner", children: content }) }) })
|
|
4686
|
-
}
|
|
4687
|
-
);
|
|
4688
|
-
}
|
|
4689
5280
|
function ExpandIcon({
|
|
4690
5281
|
isExpanded,
|
|
4691
5282
|
onClick,
|
|
@@ -5658,10 +6249,11 @@ function selectColumn(options = {}) {
|
|
|
5658
6249
|
const { id = "_select", size = 40, headerAriaLabel = "Select all rows" } = options;
|
|
5659
6250
|
return {
|
|
5660
6251
|
id,
|
|
5661
|
-
header: ({ table }) => /* @__PURE__ */ jsx(
|
|
6252
|
+
header: ({ table }) => /* @__PURE__ */ jsx("label", { className: "yable-checkbox-hitbox", onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsx(
|
|
5662
6253
|
"input",
|
|
5663
6254
|
{
|
|
5664
6255
|
type: "checkbox",
|
|
6256
|
+
className: "yable-checkbox",
|
|
5665
6257
|
checked: table.getIsAllPageRowsSelected(),
|
|
5666
6258
|
ref: (el) => {
|
|
5667
6259
|
if (el)
|
|
@@ -5670,19 +6262,21 @@ function selectColumn(options = {}) {
|
|
|
5670
6262
|
onChange: () => table.toggleAllPageRowsSelected(),
|
|
5671
6263
|
"aria-label": headerAriaLabel
|
|
5672
6264
|
}
|
|
5673
|
-
),
|
|
5674
|
-
cell: ({ row }) => /* @__PURE__ */ jsx(
|
|
6265
|
+
) }),
|
|
6266
|
+
cell: ({ row }) => /* @__PURE__ */ jsx("label", { className: "yable-checkbox-hitbox", onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsx(
|
|
5675
6267
|
"input",
|
|
5676
6268
|
{
|
|
5677
6269
|
type: "checkbox",
|
|
6270
|
+
className: "yable-checkbox",
|
|
5678
6271
|
checked: row.getIsSelected(),
|
|
5679
6272
|
disabled: !row.getCanSelect(),
|
|
5680
6273
|
onChange: row.getToggleSelectedHandler(),
|
|
5681
|
-
"aria-label":
|
|
6274
|
+
"aria-label": "Select row"
|
|
5682
6275
|
}
|
|
5683
|
-
),
|
|
6276
|
+
) }),
|
|
5684
6277
|
size,
|
|
5685
|
-
enableSorting:
|
|
6278
|
+
enableSorting: true,
|
|
6279
|
+
sortingFn: (rowA, rowB) => Number(rowA.getIsSelected()) - Number(rowB.getIsSelected()),
|
|
5686
6280
|
enableColumnFilter: false,
|
|
5687
6281
|
enableResizing: false,
|
|
5688
6282
|
enableReorder: false,
|
|
@@ -5882,6 +6476,6 @@ function mergeEditChanges(data, changes, getRowId = (_, i) => String(i)) {
|
|
|
5882
6476
|
});
|
|
5883
6477
|
}
|
|
5884
6478
|
|
|
5885
|
-
export { CellBadge, CellBoolean, CellCheckbox, CellCurrency, CellDate, CellDatePicker, CellErrorBoundary, CellInput, CellLink, CellNumeric, CellProgress, CellRating, CellRow, CellSelect, CellStack, CellStatus, CellStatusBadge, CellText, CellToggle, CellWithIcon, ColumnsPanel, ContextMenu, ContextMenuItem, DEFAULT_TEXT_RECIPE, DragHandle, ErrorBoundary, ExpandIcon, FillHandle, FiltersPanel, FlashCell, FloatingFilter, GlobalFilter, LoadingOverlay, MasterDetail, NoRowsOverlay, Pagination, PivotConfigPanel, PrintLayout, SetFilter, Sidebar, SortIndicator, StatusBar, StatusBarPanelComponent, Table, TableBody, TableCell, TableFooter, TableHeader, TableProvider, Tooltip, TreeToggle, YableProvider, actionsColumn, expandColumn, getMeasureRecipeForCellType, getRegisteredCellTypes, mergeEditChanges, resolveMeasureRecipe, rowNumberColumn, selectColumn, useAutoMeasurements, useCellFlash, useClipboard, useColumnVirtualization, useContextMenu, useFillHandle, useKeyboardNavigation, usePretextMeasurement, usePrintLayout, useRowAnimation, useRowDrag, useTable, useTableContext, useTablePersistence, useTableRowHeights, useTheme, useTooltip, useVirtualization, useYableDefaults };
|
|
6479
|
+
export { CellBadge, CellBoolean, CellCheckbox, CellCurrency, CellDate, CellDatePicker, CellErrorBoundary, CellInput, CellLink, CellNumeric, CellProgress, CellRating, CellRow, CellSelect, CellStack, CellStatus, CellStatusBadge, CellText, CellToggle, CellWithIcon, ColumnsPanel, ContextMenu, ContextMenuItem, DEFAULT_TEXT_RECIPE, DragHandle, ErrorBoundary, ExpandIcon, FillHandle, FiltersPanel, FlashCell, FloatingFilter, GlobalFilter, LoadingOverlay, MasterDetail, NoRowsOverlay, Pagination, PivotConfigPanel, PrintLayout, SetFilter, Sidebar, SortIndicator, StatusBar, StatusBarPanelComponent, Table, TableBody, TableCell, TableFooter, TableHeader, TableProvider, Tooltip, TreeToggle, YableProvider, actionsColumn, applyYableConfigToColumns, createYableConfig, expandColumn, getMeasureRecipeForCellType, getRegisteredCellTypes, getYableDefaultColumnDef, mergeEditChanges, resolveMeasureRecipe, resolveYableProfile, rowNumberColumn, selectColumn, useAutoMeasurements, useCellFlash, useClipboard, useColumnVirtualization, useContextMenu, useFillHandle, useKeyboardNavigation, usePretextMeasurement, usePrintLayout, useRowAnimation, useRowDrag, useServerTable, useTable, useTableContext, useTablePersistence, useTableRowHeights, useTheme, useTooltip, useVirtualization, useYableDefaults };
|
|
5886
6480
|
//# sourceMappingURL=index.js.map
|
|
5887
6481
|
//# sourceMappingURL=index.js.map
|