@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.cjs
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var yableCore = require('@zvndev/yable-core');
|
|
4
|
-
var
|
|
4
|
+
var React4 = 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 }; }
|
|
9
10
|
|
|
10
|
-
var
|
|
11
|
+
var React4__default = /*#__PURE__*/_interopDefault(React4);
|
|
11
12
|
|
|
12
13
|
// src/index.ts
|
|
13
|
-
var YableContext =
|
|
14
|
+
var YableContext = React4.createContext({});
|
|
14
15
|
function useYableDefaults() {
|
|
15
|
-
return
|
|
16
|
+
return React4.useContext(YableContext);
|
|
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;
|
|
@@ -54,17 +131,32 @@ function shallowEqual(a, b) {
|
|
|
54
131
|
}
|
|
55
132
|
function useTable(options) {
|
|
56
133
|
const providerDefaults = useYableDefaults();
|
|
57
|
-
const optionsWithDefaults =
|
|
58
|
-
|
|
134
|
+
const optionsWithDefaults = React4.useMemo(() => {
|
|
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
|
-
}, [
|
|
67
|
-
|
|
153
|
+
}, [
|
|
154
|
+
options,
|
|
155
|
+
providerDefaults.config,
|
|
156
|
+
providerDefaults.defaultColumnDef,
|
|
157
|
+
providerDefaults.tableProfile
|
|
158
|
+
]);
|
|
159
|
+
const [state, setState] = React4.useState(() => ({
|
|
68
160
|
sorting: [],
|
|
69
161
|
columnFilters: [],
|
|
70
162
|
globalFilter: "",
|
|
@@ -101,26 +193,26 @@ function useTable(options) {
|
|
|
101
193
|
...options.initialState,
|
|
102
194
|
...options.state
|
|
103
195
|
}));
|
|
104
|
-
const stateRef =
|
|
196
|
+
const stateRef = React4.useRef(state);
|
|
105
197
|
stateRef.current = state;
|
|
106
|
-
const prevOptionsRef =
|
|
107
|
-
const stableOptions =
|
|
198
|
+
const prevOptionsRef = React4.useRef(optionsWithDefaults);
|
|
199
|
+
const stableOptions = React4.useMemo(() => {
|
|
108
200
|
if (shallowEqual(prevOptionsRef.current, optionsWithDefaults)) {
|
|
109
201
|
return prevOptionsRef.current;
|
|
110
202
|
}
|
|
111
203
|
prevOptionsRef.current = optionsWithDefaults;
|
|
112
204
|
return optionsWithDefaults;
|
|
113
205
|
}, [optionsWithDefaults]);
|
|
114
|
-
const onStateChangeRef =
|
|
206
|
+
const onStateChangeRef = React4.useRef(options.onStateChange);
|
|
115
207
|
onStateChangeRef.current = options.onStateChange;
|
|
116
|
-
const resolvedState =
|
|
208
|
+
const resolvedState = React4.useMemo(
|
|
117
209
|
() => ({
|
|
118
210
|
...state,
|
|
119
211
|
...stableOptions.state
|
|
120
212
|
}),
|
|
121
213
|
[state, stableOptions.state]
|
|
122
214
|
);
|
|
123
|
-
const onStateChange =
|
|
215
|
+
const onStateChange = React4.useCallback((updater) => {
|
|
124
216
|
const latest = onStateChangeRef.current;
|
|
125
217
|
if (latest) {
|
|
126
218
|
latest(updater);
|
|
@@ -128,7 +220,7 @@ function useTable(options) {
|
|
|
128
220
|
setState((prev) => yableCore.functionalUpdate(updater, prev));
|
|
129
221
|
}
|
|
130
222
|
}, []);
|
|
131
|
-
const resolvedOptions =
|
|
223
|
+
const resolvedOptions = React4.useMemo(
|
|
132
224
|
() => ({
|
|
133
225
|
...stableOptions,
|
|
134
226
|
state: resolvedState,
|
|
@@ -136,7 +228,7 @@ function useTable(options) {
|
|
|
136
228
|
}),
|
|
137
229
|
[stableOptions, resolvedState, onStateChange]
|
|
138
230
|
);
|
|
139
|
-
const tableRef =
|
|
231
|
+
const tableRef = React4.useRef(null);
|
|
140
232
|
if (!tableRef.current) {
|
|
141
233
|
tableRef.current = yableCore.createTable(resolvedOptions);
|
|
142
234
|
} else {
|
|
@@ -149,7 +241,33 @@ function useTable(options) {
|
|
|
149
241
|
})
|
|
150
242
|
);
|
|
151
243
|
}
|
|
152
|
-
|
|
244
|
+
React4.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
|
+
]);
|
|
270
|
+
React4.useEffect(() => {
|
|
153
271
|
return () => {
|
|
154
272
|
if (tableRef.current) {
|
|
155
273
|
tableRef.current.events.removeAllListeners();
|
|
@@ -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] = React4.useState(initialRows);
|
|
296
|
+
const [cursor, setCursor] = React4.useState(initialCursor);
|
|
297
|
+
const [hasMore, setHasMore] = React4.useState(initialHasMore);
|
|
298
|
+
const [rowCount, setRowCount] = React4.useState(initialRowCount);
|
|
299
|
+
const [pageCount, setPageCount] = React4.useState(initialPageCount);
|
|
300
|
+
const [sorting, setSorting] = React4.useState(initialSorting);
|
|
301
|
+
const [columnFilters, setColumnFilters] = React4.useState(initialColumnFilters);
|
|
302
|
+
const [globalFilter, setGlobalFilter] = React4.useState(initialGlobalFilter);
|
|
303
|
+
const [pagination, setPagination] = React4.useState(initialPagination);
|
|
304
|
+
const [loading, setLoading] = React4.useState(false);
|
|
305
|
+
const [error, setError] = React4.useState(null);
|
|
306
|
+
const abortRef = React4.useRef(null);
|
|
307
|
+
const cursorRef = React4.useRef(cursor);
|
|
308
|
+
const fetchDataRef = React4.useRef(fetchData);
|
|
309
|
+
const updateRowRef = React4.useRef(updateRow);
|
|
310
|
+
const resolveRowId = React4.useCallback(
|
|
311
|
+
(row, index) => getRowId?.(row, index) ?? String(row.id ?? index),
|
|
312
|
+
[getRowId]
|
|
313
|
+
);
|
|
314
|
+
const runFetch = React4.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 = React4.useCallback(() => runFetch("replace"), [runFetch]);
|
|
345
|
+
const loadMore = React4.useCallback(async () => {
|
|
346
|
+
if (!hasMore || loading) return;
|
|
347
|
+
await runFetch("append");
|
|
348
|
+
}, [hasMore, loading, runFetch]);
|
|
349
|
+
const patchRow = React4.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
|
+
React4.useEffect(() => {
|
|
382
|
+
fetchDataRef.current = fetchData;
|
|
383
|
+
}, [fetchData]);
|
|
384
|
+
React4.useEffect(() => {
|
|
385
|
+
updateRowRef.current = updateRow;
|
|
386
|
+
}, [updateRow]);
|
|
387
|
+
React4.useEffect(() => {
|
|
388
|
+
if (!autoLoad) return;
|
|
389
|
+
void refresh();
|
|
390
|
+
}, [autoLoad, refresh]);
|
|
391
|
+
React4.useEffect(() => {
|
|
392
|
+
cursorRef.current = cursor;
|
|
393
|
+
}, [cursor]);
|
|
394
|
+
React4.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 React4.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",
|
|
@@ -221,25 +528,25 @@ function useTablePersistence(options) {
|
|
|
221
528
|
version = 0,
|
|
222
529
|
storage: customStorage
|
|
223
530
|
} = options;
|
|
224
|
-
const storage =
|
|
225
|
-
const initialState =
|
|
531
|
+
const storage = React4.useMemo(() => resolveStorage(customStorage), [customStorage]);
|
|
532
|
+
const initialState = React4.useMemo(
|
|
226
533
|
() => readState(storage, key, version, persistedKeys),
|
|
227
534
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- intentionally read only on mount
|
|
228
535
|
[]
|
|
229
536
|
);
|
|
230
|
-
const [state, setState] =
|
|
231
|
-
const timerRef =
|
|
232
|
-
const keyRef =
|
|
537
|
+
const [state, setState] = React4.useState(initialState);
|
|
538
|
+
const timerRef = React4.useRef(null);
|
|
539
|
+
const keyRef = React4.useRef(key);
|
|
233
540
|
keyRef.current = key;
|
|
234
|
-
const versionRef =
|
|
541
|
+
const versionRef = React4.useRef(version);
|
|
235
542
|
versionRef.current = version;
|
|
236
|
-
const persistedKeysRef =
|
|
543
|
+
const persistedKeysRef = React4.useRef(persistedKeys);
|
|
237
544
|
persistedKeysRef.current = persistedKeys;
|
|
238
|
-
const debounceRef =
|
|
545
|
+
const debounceRef = React4.useRef(debounceMs);
|
|
239
546
|
debounceRef.current = debounceMs;
|
|
240
|
-
const storageRef =
|
|
547
|
+
const storageRef = React4.useRef(storage);
|
|
241
548
|
storageRef.current = storage;
|
|
242
|
-
const onStateChange =
|
|
549
|
+
const onStateChange = React4.useCallback((updater) => {
|
|
243
550
|
setState((prev) => {
|
|
244
551
|
const next = yableCore.functionalUpdate(updater, prev);
|
|
245
552
|
if (timerRef.current !== null) {
|
|
@@ -256,14 +563,14 @@ function useTablePersistence(options) {
|
|
|
256
563
|
return next;
|
|
257
564
|
});
|
|
258
565
|
}, []);
|
|
259
|
-
|
|
566
|
+
React4.useEffect(() => {
|
|
260
567
|
return () => {
|
|
261
568
|
if (timerRef.current !== null) {
|
|
262
569
|
clearTimeout(timerRef.current);
|
|
263
570
|
}
|
|
264
571
|
};
|
|
265
572
|
}, []);
|
|
266
|
-
const clearPersistedState =
|
|
573
|
+
const clearPersistedState = React4.useCallback(() => {
|
|
267
574
|
const s = storageRef.current;
|
|
268
575
|
if (s) {
|
|
269
576
|
try {
|
|
@@ -292,10 +599,10 @@ function useVirtualization({
|
|
|
292
599
|
}) {
|
|
293
600
|
const hasPretextHeights = !!(pretextHeights && pretextPrefixSums && pretextHeights.length >= totalRows);
|
|
294
601
|
const isFixedHeight = typeof rowHeight === "number" && !hasPretextHeights;
|
|
295
|
-
const heightCacheRef =
|
|
296
|
-
const heightCacheVersionRef =
|
|
297
|
-
const [heightCacheVersion, setHeightCacheVersion] =
|
|
298
|
-
const getRowHeight =
|
|
602
|
+
const heightCacheRef = React4.useRef(/* @__PURE__ */ new Map());
|
|
603
|
+
const heightCacheVersionRef = React4.useRef(0);
|
|
604
|
+
const [heightCacheVersion, setHeightCacheVersion] = React4.useState(0);
|
|
605
|
+
const getRowHeight = React4.useCallback(
|
|
299
606
|
(index) => {
|
|
300
607
|
if (hasPretextHeights) return pretextHeights[index];
|
|
301
608
|
if (isFixedHeight) return rowHeight;
|
|
@@ -309,9 +616,9 @@ function useVirtualization({
|
|
|
309
616
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
310
617
|
[rowHeight, isFixedHeight, hasPretextHeights, pretextHeights, heightCacheVersion]
|
|
311
618
|
);
|
|
312
|
-
const [scrollState, setScrollState] =
|
|
313
|
-
const rafRef =
|
|
314
|
-
|
|
619
|
+
const [scrollState, setScrollState] = React4.useState({ scrollTop: 0, containerHeight: 0 });
|
|
620
|
+
const rafRef = React4.useRef(null);
|
|
621
|
+
React4.useEffect(() => {
|
|
315
622
|
const container = containerRef.current;
|
|
316
623
|
if (!container) return;
|
|
317
624
|
setScrollState({
|
|
@@ -354,25 +661,25 @@ function useVirtualization({
|
|
|
354
661
|
resizeObserver.disconnect();
|
|
355
662
|
}
|
|
356
663
|
};
|
|
357
|
-
}, [containerRef]);
|
|
358
|
-
|
|
664
|
+
}, [containerRef, totalRows]);
|
|
665
|
+
React4.useEffect(() => {
|
|
359
666
|
if (!isFixedHeight) {
|
|
360
667
|
heightCacheRef.current.clear();
|
|
361
668
|
}
|
|
362
669
|
}, [totalRows, isFixedHeight]);
|
|
363
|
-
|
|
670
|
+
React4.useEffect(() => {
|
|
364
671
|
if (!isFixedHeight && columnSizingHash !== void 0) {
|
|
365
672
|
heightCacheRef.current.clear();
|
|
366
673
|
heightCacheVersionRef.current += 1;
|
|
367
674
|
setHeightCacheVersion(heightCacheVersionRef.current);
|
|
368
675
|
}
|
|
369
676
|
}, [columnSizingHash]);
|
|
370
|
-
const invalidateRowHeights =
|
|
677
|
+
const invalidateRowHeights = React4.useCallback(() => {
|
|
371
678
|
heightCacheRef.current.clear();
|
|
372
679
|
heightCacheVersionRef.current += 1;
|
|
373
680
|
setHeightCacheVersion(heightCacheVersionRef.current);
|
|
374
681
|
}, []);
|
|
375
|
-
const scrollTo =
|
|
682
|
+
const scrollTo = React4.useCallback(
|
|
376
683
|
(index) => {
|
|
377
684
|
const container = containerRef.current;
|
|
378
685
|
if (!container || totalRows === 0) return;
|
|
@@ -399,7 +706,7 @@ function useVirtualization({
|
|
|
399
706
|
pretextPrefixSums
|
|
400
707
|
]
|
|
401
708
|
);
|
|
402
|
-
const totalHeight =
|
|
709
|
+
const totalHeight = React4.useMemo(() => {
|
|
403
710
|
if (totalRows === 0) return 0;
|
|
404
711
|
if (hasPretextHeights && pretextPrefixSums) return pretextPrefixSums[totalRows];
|
|
405
712
|
if (isFixedHeight) return totalRows * rowHeight;
|
|
@@ -545,15 +852,21 @@ function useColumnVirtualization({
|
|
|
545
852
|
containerRef,
|
|
546
853
|
columns,
|
|
547
854
|
overscan = 2,
|
|
548
|
-
enabled = true
|
|
855
|
+
enabled = true,
|
|
856
|
+
sizingKey
|
|
549
857
|
}) {
|
|
550
|
-
const [scrollState, setScrollState] =
|
|
858
|
+
const [scrollState, setScrollState] = React4.useState({
|
|
551
859
|
scrollLeft: 0,
|
|
552
860
|
containerWidth: 0
|
|
553
861
|
});
|
|
554
|
-
const rafRef =
|
|
555
|
-
const sizes =
|
|
556
|
-
|
|
862
|
+
const rafRef = React4.useRef(null);
|
|
863
|
+
const sizes = React4.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
|
+
);
|
|
869
|
+
const offsets = React4.useMemo(() => {
|
|
557
870
|
const next = new Array(columns.length + 1);
|
|
558
871
|
next[0] = 0;
|
|
559
872
|
for (let i = 0; i < columns.length; i++) {
|
|
@@ -562,7 +875,7 @@ function useColumnVirtualization({
|
|
|
562
875
|
return next;
|
|
563
876
|
}, [columns.length, sizes]);
|
|
564
877
|
const totalWidth = offsets[offsets.length - 1] ?? 0;
|
|
565
|
-
|
|
878
|
+
React4.useEffect(() => {
|
|
566
879
|
const container = containerRef.current;
|
|
567
880
|
if (!container) return;
|
|
568
881
|
setScrollState({
|
|
@@ -609,7 +922,7 @@ function useColumnVirtualization({
|
|
|
609
922
|
resizeObserver?.disconnect();
|
|
610
923
|
};
|
|
611
924
|
}, [containerRef]);
|
|
612
|
-
const scrollToIndex =
|
|
925
|
+
const scrollToIndex = React4.useCallback(
|
|
613
926
|
(index) => {
|
|
614
927
|
const container = containerRef.current;
|
|
615
928
|
if (!container || columns.length === 0) return;
|
|
@@ -697,12 +1010,12 @@ function usePretextMeasurement({
|
|
|
697
1010
|
minRowHeight = 32,
|
|
698
1011
|
enabled = true
|
|
699
1012
|
}) {
|
|
700
|
-
const [pretext, setPretext] =
|
|
701
|
-
const [ready, setReady] =
|
|
702
|
-
const prepareTimeRef =
|
|
703
|
-
const layoutTimeRef =
|
|
1013
|
+
const [pretext, setPretext] = React4.useState(null);
|
|
1014
|
+
const [ready, setReady] = React4.useState(false);
|
|
1015
|
+
const prepareTimeRef = React4.useRef(0);
|
|
1016
|
+
const layoutTimeRef = React4.useRef(0);
|
|
704
1017
|
const columnWidthsKey = columns.map((c) => `${c.columnId}:${c.width}`).join("|");
|
|
705
|
-
|
|
1018
|
+
React4.useEffect(() => {
|
|
706
1019
|
if (!enabled) return;
|
|
707
1020
|
let cancelled = false;
|
|
708
1021
|
loadPretext().then((mod) => {
|
|
@@ -712,8 +1025,8 @@ function usePretextMeasurement({
|
|
|
712
1025
|
cancelled = true;
|
|
713
1026
|
};
|
|
714
1027
|
}, [enabled]);
|
|
715
|
-
const preparedCacheRef =
|
|
716
|
-
const preparedCells =
|
|
1028
|
+
const preparedCacheRef = React4.useRef(/* @__PURE__ */ new Map());
|
|
1029
|
+
const preparedCells = React4.useMemo(() => {
|
|
717
1030
|
if (!pretext || !enabled || data.length === 0 || columns.length === 0) return null;
|
|
718
1031
|
const cache = preparedCacheRef.current;
|
|
719
1032
|
const start = performance.now();
|
|
@@ -740,7 +1053,7 @@ function usePretextMeasurement({
|
|
|
740
1053
|
data,
|
|
741
1054
|
columns.map((c) => `${c.columnId}:${c.font}:${c.fixedHeight ? "F" : "T"}`).join("|")
|
|
742
1055
|
]);
|
|
743
|
-
const measurement =
|
|
1056
|
+
const measurement = React4.useMemo(() => {
|
|
744
1057
|
if (!pretext || !preparedCells) {
|
|
745
1058
|
return { rowHeights: null, prefixSums: null, totalHeight: 0 };
|
|
746
1059
|
}
|
|
@@ -781,7 +1094,7 @@ function usePretextMeasurement({
|
|
|
781
1094
|
totalHeight: prefixSums[data.length]
|
|
782
1095
|
};
|
|
783
1096
|
}, [pretext, preparedCells, columnWidthsKey, minRowHeight, data.length]);
|
|
784
|
-
|
|
1097
|
+
React4.useEffect(() => {
|
|
785
1098
|
if (measurement.rowHeights) setReady(true);
|
|
786
1099
|
}, [measurement.rowHeights]);
|
|
787
1100
|
return {
|
|
@@ -830,7 +1143,7 @@ function CellCurrency({
|
|
|
830
1143
|
}) {
|
|
831
1144
|
const raw = context.getValue();
|
|
832
1145
|
const num = typeof raw === "number" ? raw : Number(raw);
|
|
833
|
-
const formatter =
|
|
1146
|
+
const formatter = React4.useMemo(
|
|
834
1147
|
() => new Intl.NumberFormat(locale, {
|
|
835
1148
|
style: "currency",
|
|
836
1149
|
currency,
|
|
@@ -907,7 +1220,7 @@ function CellNumeric({
|
|
|
907
1220
|
}) {
|
|
908
1221
|
const raw = context.getValue();
|
|
909
1222
|
const num = typeof raw === "number" ? raw : Number(raw);
|
|
910
|
-
const formatter =
|
|
1223
|
+
const formatter = React4.useMemo(
|
|
911
1224
|
() => new Intl.NumberFormat(locale, {
|
|
912
1225
|
minimumFractionDigits: decimals,
|
|
913
1226
|
maximumFractionDigits: decimals
|
|
@@ -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) => `${
|
|
1164
|
-
return
|
|
1476
|
+
const widthKey = columns.map((c) => `${getColumnId2(c) ?? "?"}:${getColumnWidth(c)}`).join("|");
|
|
1477
|
+
return React4.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);
|
|
@@ -1198,7 +1511,7 @@ function useTableRowHeights({
|
|
|
1198
1511
|
defaultRecipe,
|
|
1199
1512
|
getColumnWidth
|
|
1200
1513
|
});
|
|
1201
|
-
const accessorMap =
|
|
1514
|
+
const accessorMap = React4.useMemo(() => {
|
|
1202
1515
|
const map = /* @__PURE__ */ new Map();
|
|
1203
1516
|
for (const col of columns) {
|
|
1204
1517
|
const id = col.id ?? col.accessorKey;
|
|
@@ -1215,7 +1528,7 @@ function useTableRowHeights({
|
|
|
1215
1528
|
}
|
|
1216
1529
|
return map;
|
|
1217
1530
|
}, [columns]);
|
|
1218
|
-
const getCellText =
|
|
1531
|
+
const getCellText = React4.useMemo(
|
|
1219
1532
|
() => (row, columnId) => {
|
|
1220
1533
|
const get = accessorMap.get(columnId);
|
|
1221
1534
|
if (!get) return "";
|
|
@@ -1234,10 +1547,10 @@ function useTableRowHeights({
|
|
|
1234
1547
|
});
|
|
1235
1548
|
return { ...result, measurements };
|
|
1236
1549
|
}
|
|
1237
|
-
var TableContext =
|
|
1550
|
+
var TableContext = React4.createContext(null);
|
|
1238
1551
|
var TableProvider = TableContext.Provider;
|
|
1239
1552
|
function useTableContext() {
|
|
1240
|
-
const ctx =
|
|
1553
|
+
const ctx = React4.useContext(TableContext);
|
|
1241
1554
|
if (!ctx) {
|
|
1242
1555
|
throw new Error(
|
|
1243
1556
|
"[yable E001] useTableContext must be used within a <Table> component. Did you forget to pass the `table` prop?"
|
|
@@ -1298,7 +1611,7 @@ function formatValue(value) {
|
|
|
1298
1611
|
return JSON.stringify(value);
|
|
1299
1612
|
}
|
|
1300
1613
|
function SetFilter({ column, className }) {
|
|
1301
|
-
const [open, setOpen] =
|
|
1614
|
+
const [open, setOpen] = React4.useState(false);
|
|
1302
1615
|
const filterValue = column.getFilterValue();
|
|
1303
1616
|
const selectedValues = Array.isArray(filterValue) ? filterValue : filterValue == null || filterValue === "" ? [] : [filterValue];
|
|
1304
1617
|
const facetedUniqueValues = column.getFacetedUniqueValues();
|
|
@@ -1483,22 +1796,176 @@ 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 = React4.useRef(null);
|
|
1812
|
+
const reorderEndRef = React4.useRef(0);
|
|
1813
|
+
const [drag, setDrag] = React4.useState(null);
|
|
1814
|
+
const commitReorder = React4.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 = React4.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 = React4.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({
|
|
1499
1966
|
column
|
|
1500
1967
|
}) {
|
|
1501
|
-
const style =
|
|
1968
|
+
const style = React4.useMemo(() => {
|
|
1502
1969
|
const next = {
|
|
1503
1970
|
width: column.getSize(),
|
|
1504
1971
|
minWidth: column.columnDef.minSize,
|
|
@@ -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,27 +2001,29 @@ 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
|
-
const style =
|
|
2006
|
+
const style = React4.useMemo(() => {
|
|
1534
2007
|
const s = {
|
|
1535
2008
|
width: header.getSize(),
|
|
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
|
|
1551
|
-
const
|
|
1552
|
-
const startResize = React3.useCallback(
|
|
2024
|
+
}, [header, column, pinned, isDragSource, dragTransform]);
|
|
2025
|
+
const lastResizeEndRef = React4.useRef(0);
|
|
2026
|
+
const startResize = React4.useCallback(
|
|
1553
2027
|
(e) => {
|
|
1554
2028
|
e.stopPropagation();
|
|
1555
2029
|
const onEnd = () => {
|
|
@@ -1564,125 +2038,63 @@ function HeaderCell({
|
|
|
1564
2038
|
},
|
|
1565
2039
|
[header]
|
|
1566
2040
|
);
|
|
1567
|
-
const handleResizeClick =
|
|
2041
|
+
const handleResizeClick = React4.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(
|
|
2044
|
+
const handleContentPointerDown = React4.useCallback(
|
|
1586
2045
|
(e) => {
|
|
1587
|
-
if (!canReorder) return;
|
|
1588
|
-
|
|
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");
|
|
2046
|
+
if (!canReorder || pinned) return;
|
|
2047
|
+
onReorderPointerDown(e, column.id);
|
|
1602
2048
|
},
|
|
1603
|
-
[canReorder]
|
|
2049
|
+
[canReorder, pinned, onReorderPointerDown, column.id]
|
|
1604
2050
|
);
|
|
1605
|
-
const
|
|
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(
|
|
1615
|
-
(e) => {
|
|
1616
|
-
if (!canReorder) return;
|
|
1617
|
-
e.preventDefault();
|
|
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);
|
|
1650
|
-
},
|
|
1651
|
-
[canReorder, column.id, table]
|
|
1652
|
-
);
|
|
1653
|
-
const handleHeaderClick = React3.useCallback(
|
|
2051
|
+
const handleHeaderClick = React4.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 = React4.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 })
|
|
@@ -1781,19 +2193,46 @@ function CellStatusBadge(props) {
|
|
|
1781
2193
|
}
|
|
1782
2194
|
);
|
|
1783
2195
|
}
|
|
2196
|
+
function FillHandle({
|
|
2197
|
+
rowIndex,
|
|
2198
|
+
columnIndex,
|
|
2199
|
+
onMouseDown
|
|
2200
|
+
}) {
|
|
2201
|
+
const handleMouseDown = React4.useCallback(
|
|
2202
|
+
(e) => {
|
|
2203
|
+
e.preventDefault();
|
|
2204
|
+
e.stopPropagation();
|
|
2205
|
+
onMouseDown(rowIndex, columnIndex, e);
|
|
2206
|
+
},
|
|
2207
|
+
[rowIndex, columnIndex, onMouseDown]
|
|
2208
|
+
);
|
|
2209
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2210
|
+
"div",
|
|
2211
|
+
{
|
|
2212
|
+
className: "yable-fill-handle",
|
|
2213
|
+
onMouseDown: handleMouseDown,
|
|
2214
|
+
role: "presentation",
|
|
2215
|
+
"aria-hidden": "true",
|
|
2216
|
+
title: "Drag to fill",
|
|
2217
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "yable-fill-handle-dot" })
|
|
2218
|
+
}
|
|
2219
|
+
);
|
|
2220
|
+
}
|
|
1784
2221
|
function TableCell({
|
|
1785
2222
|
cell,
|
|
1786
2223
|
table,
|
|
1787
2224
|
rowIndex,
|
|
1788
2225
|
columnIndex,
|
|
1789
2226
|
isFocused,
|
|
1790
|
-
isTabStop
|
|
2227
|
+
isTabStop,
|
|
2228
|
+
onFillHandleMouseDown
|
|
1791
2229
|
}) {
|
|
1792
2230
|
const column = cell.column;
|
|
1793
2231
|
const isEditing = cell.getIsEditing();
|
|
1794
2232
|
const isAlwaysEditable = cell.getIsAlwaysEditable();
|
|
1795
2233
|
const pinned = column.getIsPinned();
|
|
1796
2234
|
const keyboardNavigationEnabled = table.options.enableKeyboardNavigation !== false;
|
|
2235
|
+
const cellSelectionEnabled = table.options.enableCellSelection !== false && column.columnDef.enableCellSelection !== false;
|
|
1797
2236
|
const style = {
|
|
1798
2237
|
width: column.getSize(),
|
|
1799
2238
|
minWidth: column.columnDef.minSize,
|
|
@@ -1835,7 +2274,7 @@ function TableCell({
|
|
|
1835
2274
|
} else {
|
|
1836
2275
|
content = overrideValue !== void 0 ? overrideValue : cell.renderValue();
|
|
1837
2276
|
}
|
|
1838
|
-
const handleClick =
|
|
2277
|
+
const handleClick = React4.useCallback(
|
|
1839
2278
|
(e) => {
|
|
1840
2279
|
table.events.emit("cell:click", {
|
|
1841
2280
|
cell,
|
|
@@ -1849,7 +2288,7 @@ function TableCell({
|
|
|
1849
2288
|
},
|
|
1850
2289
|
[cell, column, isAlwaysEditable, isEditing, isMultiCellSelection, table]
|
|
1851
2290
|
);
|
|
1852
|
-
const handleDoubleClick =
|
|
2291
|
+
const handleDoubleClick = React4.useCallback(
|
|
1853
2292
|
(e) => {
|
|
1854
2293
|
table.events.emit("cell:dblclick", {
|
|
1855
2294
|
cell,
|
|
@@ -1860,7 +2299,7 @@ function TableCell({
|
|
|
1860
2299
|
},
|
|
1861
2300
|
[table, cell]
|
|
1862
2301
|
);
|
|
1863
|
-
const handleContextMenu =
|
|
2302
|
+
const handleContextMenu = React4.useCallback(
|
|
1864
2303
|
(e) => {
|
|
1865
2304
|
table.events.emit("cell:contextmenu", {
|
|
1866
2305
|
cell,
|
|
@@ -1871,13 +2310,14 @@ function TableCell({
|
|
|
1871
2310
|
},
|
|
1872
2311
|
[table, cell]
|
|
1873
2312
|
);
|
|
1874
|
-
const handleFocus =
|
|
2313
|
+
const handleFocus = React4.useCallback(() => {
|
|
1875
2314
|
if (!keyboardNavigationEnabled) return;
|
|
1876
2315
|
table.setFocusedCell({ rowIndex, columnIndex });
|
|
1877
2316
|
}, [columnIndex, keyboardNavigationEnabled, rowIndex, table]);
|
|
1878
|
-
const handleMouseDown =
|
|
2317
|
+
const handleMouseDown = React4.useCallback(
|
|
1879
2318
|
(e) => {
|
|
1880
2319
|
if (e.button !== 0) return;
|
|
2320
|
+
if (!cellSelectionEnabled) return;
|
|
1881
2321
|
const clickTarget = e.target;
|
|
1882
2322
|
if (isInteractiveClickTarget(clickTarget)) return;
|
|
1883
2323
|
e.preventDefault();
|
|
@@ -1885,13 +2325,14 @@ function TableCell({
|
|
|
1885
2325
|
table.startCellRangeSelection({ rowIndex, columnIndex }, { extend: e.shiftKey });
|
|
1886
2326
|
e.currentTarget.focus({ preventScroll: true });
|
|
1887
2327
|
},
|
|
1888
|
-
[columnIndex, rowIndex, table]
|
|
2328
|
+
[cellSelectionEnabled, columnIndex, rowIndex, table]
|
|
1889
2329
|
);
|
|
1890
|
-
const handleMouseEnter =
|
|
2330
|
+
const handleMouseEnter = React4.useCallback(() => {
|
|
2331
|
+
if (!cellSelectionEnabled) return;
|
|
1891
2332
|
if (!table.getState().cellSelection?.isDragging) return;
|
|
1892
2333
|
table.updateCellRangeSelection({ rowIndex, columnIndex });
|
|
1893
|
-
}, [columnIndex, rowIndex, table]);
|
|
1894
|
-
const handleMouseUp =
|
|
2334
|
+
}, [cellSelectionEnabled, columnIndex, rowIndex, table]);
|
|
2335
|
+
const handleMouseUp = React4.useCallback(() => {
|
|
1895
2336
|
if (!table.getState().cellSelection?.isDragging) return;
|
|
1896
2337
|
table.endCellRangeSelection();
|
|
1897
2338
|
}, [table]);
|
|
@@ -1900,6 +2341,7 @@ function TableCell({
|
|
|
1900
2341
|
const cellStyleDef = column.columnDef.cellStyle;
|
|
1901
2342
|
const userStyle = typeof cellStyleDef === "function" ? cellStyleDef(cell.getContext()) : cellStyleDef;
|
|
1902
2343
|
const mergedStyle = userStyle ? { ...style, ...userStyle } : style;
|
|
2344
|
+
const showFillHandle = isFocused && Boolean(table.options.enableFillHandle) && onFillHandleMouseDown != null;
|
|
1903
2345
|
const classNames = [
|
|
1904
2346
|
"yable-td",
|
|
1905
2347
|
isFocused && "yable-cell--focused",
|
|
@@ -1953,6 +2395,14 @@ function TableCell({
|
|
|
1953
2395
|
onRetry: () => void table.retryCommit(cell.row.id, column.id),
|
|
1954
2396
|
onDismiss: () => table.dismissCommit(cell.row.id, column.id)
|
|
1955
2397
|
}
|
|
2398
|
+
),
|
|
2399
|
+
showFillHandle && onFillHandleMouseDown && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2400
|
+
FillHandle,
|
|
2401
|
+
{
|
|
2402
|
+
rowIndex,
|
|
2403
|
+
columnIndex,
|
|
2404
|
+
onMouseDown: onFillHandleMouseDown
|
|
2405
|
+
}
|
|
1956
2406
|
)
|
|
1957
2407
|
]
|
|
1958
2408
|
}
|
|
@@ -1965,7 +2415,7 @@ function isInteractiveClickTarget(element) {
|
|
|
1965
2415
|
);
|
|
1966
2416
|
return interactive !== null;
|
|
1967
2417
|
}
|
|
1968
|
-
var ErrorBoundary = class extends
|
|
2418
|
+
var ErrorBoundary = class extends React4__default.default.Component {
|
|
1969
2419
|
constructor(props) {
|
|
1970
2420
|
super(props);
|
|
1971
2421
|
this.state = { hasError: false, error: null };
|
|
@@ -2011,7 +2461,7 @@ var ErrorBoundary = class extends React3__default.default.Component {
|
|
|
2011
2461
|
return this.props.children;
|
|
2012
2462
|
}
|
|
2013
2463
|
};
|
|
2014
|
-
var CellErrorBoundary = class extends
|
|
2464
|
+
var CellErrorBoundary = class extends React4__default.default.Component {
|
|
2015
2465
|
constructor(props) {
|
|
2016
2466
|
super(props);
|
|
2017
2467
|
this.state = { hasError: false, error: null };
|
|
@@ -2054,10 +2504,38 @@ var CellErrorBoundary = class extends React3__default.default.Component {
|
|
|
2054
2504
|
return this.props.children;
|
|
2055
2505
|
}
|
|
2056
2506
|
};
|
|
2507
|
+
function MasterDetail({
|
|
2508
|
+
row,
|
|
2509
|
+
table,
|
|
2510
|
+
colSpan,
|
|
2511
|
+
renderDetailPanel,
|
|
2512
|
+
animationClass
|
|
2513
|
+
}) {
|
|
2514
|
+
const renderer = renderDetailPanel ?? table.options.renderDetailPanel;
|
|
2515
|
+
if (!renderer) return null;
|
|
2516
|
+
const content = renderer(row);
|
|
2517
|
+
if (content == null) return null;
|
|
2518
|
+
const classes = [
|
|
2519
|
+
"yable-detail-row",
|
|
2520
|
+
"yable-detail-row--animated",
|
|
2521
|
+
animationClass
|
|
2522
|
+
].filter(Boolean).join(" ");
|
|
2523
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2524
|
+
"tr",
|
|
2525
|
+
{
|
|
2526
|
+
className: classes,
|
|
2527
|
+
"data-detail-for": row.id,
|
|
2528
|
+
role: "row",
|
|
2529
|
+
"aria-label": `Details for row ${row.id}`,
|
|
2530
|
+
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 }) }) })
|
|
2531
|
+
}
|
|
2532
|
+
);
|
|
2533
|
+
}
|
|
2057
2534
|
function TableBody({
|
|
2058
2535
|
table,
|
|
2059
2536
|
clickableRows,
|
|
2060
|
-
colgroup
|
|
2537
|
+
colgroup,
|
|
2538
|
+
onFillHandleMouseDown
|
|
2061
2539
|
}) {
|
|
2062
2540
|
const rows = table.getRowModel().rows;
|
|
2063
2541
|
const visibleColumns = table.getVisibleLeafColumns();
|
|
@@ -2067,16 +2545,17 @@ function TableBody({
|
|
|
2067
2545
|
range: null,
|
|
2068
2546
|
isDragging: false
|
|
2069
2547
|
};
|
|
2548
|
+
const pendingValues = table.getState().editing.pendingValues ?? {};
|
|
2070
2549
|
const options = table.options;
|
|
2071
2550
|
const enableVirtualization = options.enableVirtualization ?? false;
|
|
2072
|
-
const scrollContainerRef =
|
|
2551
|
+
const scrollContainerRef = React4.useRef(null);
|
|
2073
2552
|
const rowHeight = options.rowHeight ?? 40;
|
|
2074
2553
|
const overscan = options.overscan ?? 5;
|
|
2075
2554
|
const estimateRowHeight = options.estimateRowHeight;
|
|
2076
2555
|
const pretextHeights = options.pretextHeights ?? null;
|
|
2077
2556
|
const pretextPrefixSums = options.pretextPrefixSums ?? null;
|
|
2078
2557
|
const columnSizing = table.getState().columnSizing;
|
|
2079
|
-
const columnSizingHash =
|
|
2558
|
+
const columnSizingHash = React4.useMemo(() => {
|
|
2080
2559
|
const entries = Object.entries(columnSizing);
|
|
2081
2560
|
if (entries.length === 0) return 0;
|
|
2082
2561
|
let h = 0;
|
|
@@ -2099,7 +2578,7 @@ function TableBody({
|
|
|
2099
2578
|
columnSizingHash
|
|
2100
2579
|
});
|
|
2101
2580
|
const cellSelectionKey = cellSelection.range ? `${cellSelection.range.start.rowIndex}:${cellSelection.range.start.columnIndex}:${cellSelection.range.end.rowIndex}:${cellSelection.range.end.columnIndex}:${cellSelection.isDragging ? "dragging" : "idle"}` : `none:${cellSelection.isDragging ? "dragging" : "idle"}`;
|
|
2102
|
-
|
|
2581
|
+
React4.useEffect(() => {
|
|
2103
2582
|
const handleWindowMouseUp = () => {
|
|
2104
2583
|
if (table.getState().cellSelection?.isDragging) {
|
|
2105
2584
|
table.endCellRangeSelection();
|
|
@@ -2110,24 +2589,41 @@ function TableBody({
|
|
|
2110
2589
|
window.removeEventListener("mouseup", handleWindowMouseUp);
|
|
2111
2590
|
};
|
|
2112
2591
|
}, [table]);
|
|
2592
|
+
const renderRow = (row, rowIndex, pinnedPosition) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2593
|
+
MemoizedTableRow,
|
|
2594
|
+
{
|
|
2595
|
+
row,
|
|
2596
|
+
table,
|
|
2597
|
+
rowIndex,
|
|
2598
|
+
visibleColumns,
|
|
2599
|
+
isSelected: row.getIsSelected(),
|
|
2600
|
+
isExpanded: row.getIsExpanded(),
|
|
2601
|
+
activeColumnId: activeCell?.rowId === row.id ? activeCell.columnId : void 0,
|
|
2602
|
+
focusedColumnIndex: focusedCell?.rowIndex === rowIndex ? focusedCell.columnIndex : null,
|
|
2603
|
+
hasFocusedCell: focusedCell !== null,
|
|
2604
|
+
cellSelectionKey,
|
|
2605
|
+
pendingValuesKey: getPendingValuesKey(pendingValues[row.id]),
|
|
2606
|
+
clickable: clickableRows,
|
|
2607
|
+
pinnedPosition,
|
|
2608
|
+
onFillHandleMouseDown
|
|
2609
|
+
},
|
|
2610
|
+
row.id
|
|
2611
|
+
);
|
|
2113
2612
|
if (!enableVirtualization) {
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
},
|
|
2129
|
-
row.id
|
|
2130
|
-
)) });
|
|
2613
|
+
const rowPinning = table.getState().rowPinning;
|
|
2614
|
+
const hasPinnedRows = (rowPinning.top?.length ?? 0) > 0 || (rowPinning.bottom?.length ?? 0) > 0;
|
|
2615
|
+
if (hasPinnedRows) {
|
|
2616
|
+
const topRows = table.getTopRows();
|
|
2617
|
+
const centerRows = table.getCenterRows();
|
|
2618
|
+
const bottomRows = table.getBottomRows();
|
|
2619
|
+
let visualIndex = 0;
|
|
2620
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("tbody", { className: "yable-tbody", children: [
|
|
2621
|
+
topRows.map((row) => renderRow(row, visualIndex++, "top")),
|
|
2622
|
+
centerRows.map((row) => renderRow(row, visualIndex++)),
|
|
2623
|
+
bottomRows.map((row) => renderRow(row, visualIndex++, "bottom"))
|
|
2624
|
+
] });
|
|
2625
|
+
}
|
|
2626
|
+
return /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "yable-tbody", children: rows.map((row, rowIndex) => renderRow(row, rowIndex)) });
|
|
2131
2627
|
}
|
|
2132
2628
|
const hasPretextData = !!(pretextHeights && pretextPrefixSums);
|
|
2133
2629
|
const fixedRowHeight = typeof rowHeight === "number" && !hasPretextData ? rowHeight : void 0;
|
|
@@ -2176,7 +2672,9 @@ function TableBody({
|
|
|
2176
2672
|
focusedColumnIndex: focusedCell?.rowIndex === vRow.index ? focusedCell.columnIndex : null,
|
|
2177
2673
|
hasFocusedCell: focusedCell !== null,
|
|
2178
2674
|
cellSelectionKey,
|
|
2675
|
+
pendingValuesKey: getPendingValuesKey(pendingValues[row.id]),
|
|
2179
2676
|
clickable: clickableRows,
|
|
2677
|
+
onFillHandleMouseDown,
|
|
2180
2678
|
virtualStyle: {
|
|
2181
2679
|
position: "absolute",
|
|
2182
2680
|
top: 0,
|
|
@@ -2208,13 +2706,19 @@ function TableRowInner({
|
|
|
2208
2706
|
focusedColumnIndex,
|
|
2209
2707
|
hasFocusedCell,
|
|
2210
2708
|
cellSelectionKey: _cellSelectionKey,
|
|
2709
|
+
pendingValuesKey: _pendingValuesKey,
|
|
2211
2710
|
clickable,
|
|
2212
|
-
|
|
2711
|
+
pinnedPosition,
|
|
2712
|
+
virtualStyle,
|
|
2713
|
+
onFillHandleMouseDown
|
|
2213
2714
|
}) {
|
|
2214
2715
|
const allCells = row.getAllCells();
|
|
2215
2716
|
const visibleCells = visibleColumns.map((column) => allCells.find((cell) => cell.column.id === column.id)).filter((cell) => cell != null);
|
|
2216
|
-
const handleClick =
|
|
2717
|
+
const handleClick = React4.useCallback(
|
|
2217
2718
|
(e) => {
|
|
2719
|
+
if (table.options.enableRowClickSelection && row.getCanSelect() && !isInteractiveClickTarget2(e.target)) {
|
|
2720
|
+
row.toggleSelected();
|
|
2721
|
+
}
|
|
2218
2722
|
if (clickable) {
|
|
2219
2723
|
table.events.emit("row:click", {
|
|
2220
2724
|
row,
|
|
@@ -2222,9 +2726,9 @@ function TableRowInner({
|
|
|
2222
2726
|
});
|
|
2223
2727
|
}
|
|
2224
2728
|
},
|
|
2225
|
-
[clickable, table
|
|
2729
|
+
[clickable, table, row]
|
|
2226
2730
|
);
|
|
2227
|
-
const handleDoubleClick =
|
|
2731
|
+
const handleDoubleClick = React4.useCallback(
|
|
2228
2732
|
(e) => {
|
|
2229
2733
|
table.events.emit("row:dblclick", {
|
|
2230
2734
|
row,
|
|
@@ -2233,7 +2737,7 @@ function TableRowInner({
|
|
|
2233
2737
|
},
|
|
2234
2738
|
[table.events, row]
|
|
2235
2739
|
);
|
|
2236
|
-
const handleContextMenu =
|
|
2740
|
+
const handleContextMenu = React4.useCallback(
|
|
2237
2741
|
(e) => {
|
|
2238
2742
|
table.events.emit("row:contextmenu", {
|
|
2239
2743
|
row,
|
|
@@ -2244,15 +2748,26 @@ function TableRowInner({
|
|
|
2244
2748
|
);
|
|
2245
2749
|
const selectionEnabled = Boolean(table.options.enableRowSelection);
|
|
2246
2750
|
const expansionEnabled = Boolean(table.options.enableExpanding);
|
|
2751
|
+
const rowClassNameDef = table.options.rowClassName;
|
|
2752
|
+
const userRowClassName = typeof rowClassNameDef === "function" ? rowClassNameDef(row) : rowClassNameDef;
|
|
2753
|
+
const rowStyleDef = table.options.rowStyle;
|
|
2754
|
+
const userRowStyle = typeof rowStyleDef === "function" ? rowStyleDef(row) : rowStyleDef;
|
|
2755
|
+
const mergedRowStyle = userRowStyle ? { ...virtualStyle, ...userRowStyle } : virtualStyle;
|
|
2756
|
+
const rowClassName = [
|
|
2757
|
+
"yable-tr",
|
|
2758
|
+
pinnedPosition && `yable-tr--pinned-${pinnedPosition}`,
|
|
2759
|
+
userRowClassName
|
|
2760
|
+
].filter(Boolean).join(" ");
|
|
2247
2761
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2248
2762
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2249
2763
|
"tr",
|
|
2250
2764
|
{
|
|
2251
|
-
className:
|
|
2252
|
-
style:
|
|
2765
|
+
className: rowClassName,
|
|
2766
|
+
style: mergedRowStyle,
|
|
2253
2767
|
"data-selected": isSelected || void 0,
|
|
2254
2768
|
"data-expanded": isExpanded || void 0,
|
|
2255
2769
|
"data-clickable": clickable || void 0,
|
|
2770
|
+
"data-pinned-row": pinnedPosition,
|
|
2256
2771
|
"data-row-id": row.id,
|
|
2257
2772
|
"data-row-index": rowIndex,
|
|
2258
2773
|
"aria-selected": selectionEnabled ? isSelected : void 0,
|
|
@@ -2275,7 +2790,8 @@ function TableRowInner({
|
|
|
2275
2790
|
rowIndex,
|
|
2276
2791
|
columnIndex,
|
|
2277
2792
|
isFocused,
|
|
2278
|
-
isTabStop
|
|
2793
|
+
isTabStop,
|
|
2794
|
+
onFillHandleMouseDown
|
|
2279
2795
|
}
|
|
2280
2796
|
)
|
|
2281
2797
|
},
|
|
@@ -2284,7 +2800,7 @@ function TableRowInner({
|
|
|
2284
2800
|
})
|
|
2285
2801
|
}
|
|
2286
2802
|
),
|
|
2287
|
-
isExpanded && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2803
|
+
isExpanded && /* @__PURE__ */ jsxRuntime.jsx(MasterDetail, { row, table, colSpan: visibleColumns.length })
|
|
2288
2804
|
] });
|
|
2289
2805
|
}
|
|
2290
2806
|
function areRowPropsEqual(prev, next) {
|
|
@@ -2295,10 +2811,12 @@ function areRowPropsEqual(prev, next) {
|
|
|
2295
2811
|
if (prev.isSelected !== next.isSelected) return false;
|
|
2296
2812
|
if (prev.isExpanded !== next.isExpanded) return false;
|
|
2297
2813
|
if (prev.clickable !== next.clickable) return false;
|
|
2814
|
+
if (prev.pinnedPosition !== next.pinnedPosition) return false;
|
|
2298
2815
|
if (prev.activeColumnId !== next.activeColumnId) return false;
|
|
2299
2816
|
if (prev.focusedColumnIndex !== next.focusedColumnIndex) return false;
|
|
2300
2817
|
if (prev.hasFocusedCell !== next.hasFocusedCell) return false;
|
|
2301
2818
|
if (prev.cellSelectionKey !== next.cellSelectionKey) return false;
|
|
2819
|
+
if (prev.pendingValuesKey !== next.pendingValuesKey) return false;
|
|
2302
2820
|
if (prev.virtualStyle !== next.virtualStyle) {
|
|
2303
2821
|
if (!prev.virtualStyle || !next.virtualStyle) return false;
|
|
2304
2822
|
if (prev.virtualStyle.transform !== next.virtualStyle.transform) return false;
|
|
@@ -2307,7 +2825,17 @@ function areRowPropsEqual(prev, next) {
|
|
|
2307
2825
|
if (prev.table !== next.table) return false;
|
|
2308
2826
|
return true;
|
|
2309
2827
|
}
|
|
2310
|
-
var MemoizedTableRow =
|
|
2828
|
+
var MemoizedTableRow = React4__default.default.memo(TableRowInner, areRowPropsEqual);
|
|
2829
|
+
function getPendingValuesKey(values) {
|
|
2830
|
+
if (!values) return "";
|
|
2831
|
+
return Object.keys(values).sort().map((key) => `${key}:${String(values[key])}`).join("|");
|
|
2832
|
+
}
|
|
2833
|
+
function isInteractiveClickTarget2(target) {
|
|
2834
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
2835
|
+
return Boolean(
|
|
2836
|
+
target.closest('input, textarea, select, button, a[href], [contenteditable="true"]')
|
|
2837
|
+
);
|
|
2838
|
+
}
|
|
2311
2839
|
function TableFooter({ table }) {
|
|
2312
2840
|
const footerGroups = table.getFooterGroups();
|
|
2313
2841
|
if (!footerGroups.length) return null;
|
|
@@ -2515,8 +3043,8 @@ function StatusDivider() {
|
|
|
2515
3043
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "yable-status-bar-divider", "aria-hidden": "true" });
|
|
2516
3044
|
}
|
|
2517
3045
|
function PanelGroup({ children }) {
|
|
2518
|
-
const items =
|
|
2519
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: items.map((child, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3046
|
+
const items = React4__default.default.Children.toArray(children).filter(Boolean);
|
|
3047
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: items.map((child, i) => /* @__PURE__ */ jsxRuntime.jsxs(React4__default.default.Fragment, { children: [
|
|
2520
3048
|
i > 0 && /* @__PURE__ */ jsxRuntime.jsx(StatusDivider, {}),
|
|
2521
3049
|
child
|
|
2522
3050
|
] }, i)) });
|
|
@@ -2595,53 +3123,97 @@ function StatusBar({
|
|
|
2595
3123
|
] });
|
|
2596
3124
|
}
|
|
2597
3125
|
function SearchIcon() {
|
|
2598
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
3126
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3127
|
+
"svg",
|
|
3128
|
+
{
|
|
3129
|
+
className: "yable-sidebar-search-icon",
|
|
3130
|
+
width: "13",
|
|
3131
|
+
height: "13",
|
|
3132
|
+
viewBox: "0 0 14 14",
|
|
3133
|
+
fill: "none",
|
|
3134
|
+
"aria-hidden": "true",
|
|
3135
|
+
children: [
|
|
3136
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "6.25", cy: "6.25", r: "4.25", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
3137
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9.5 9.5L12.5 12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
3138
|
+
]
|
|
3139
|
+
}
|
|
3140
|
+
);
|
|
2602
3141
|
}
|
|
2603
3142
|
function VisibilityIcon({ visible }) {
|
|
2604
3143
|
if (visible) {
|
|
2605
3144
|
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": "true", children: [
|
|
2606
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3145
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3146
|
+
"path",
|
|
3147
|
+
{
|
|
3148
|
+
d: "M1 7s2.5-4 6-4 6 4 6 4-2.5 4-6 4-6-4-6-4z",
|
|
3149
|
+
stroke: "currentColor",
|
|
3150
|
+
strokeWidth: "1.2",
|
|
3151
|
+
strokeLinejoin: "round"
|
|
3152
|
+
}
|
|
3153
|
+
),
|
|
2607
3154
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "2", stroke: "currentColor", strokeWidth: "1.2" })
|
|
2608
3155
|
] });
|
|
2609
3156
|
}
|
|
2610
3157
|
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
|
-
|
|
3158
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3159
|
+
"path",
|
|
3160
|
+
{
|
|
3161
|
+
d: "M1 7s2.5-4 6-4 6 4 6 4-2.5 4-6 4-6-4-6-4z",
|
|
3162
|
+
stroke: "currentColor",
|
|
3163
|
+
strokeWidth: "1.2",
|
|
3164
|
+
strokeLinejoin: "round",
|
|
3165
|
+
opacity: "0.3"
|
|
3166
|
+
}
|
|
3167
|
+
),
|
|
3168
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3169
|
+
"line",
|
|
3170
|
+
{
|
|
3171
|
+
x1: "2",
|
|
3172
|
+
y1: "2",
|
|
3173
|
+
x2: "12",
|
|
3174
|
+
y2: "12",
|
|
3175
|
+
stroke: "currentColor",
|
|
3176
|
+
strokeWidth: "1.2",
|
|
3177
|
+
strokeLinecap: "round",
|
|
3178
|
+
opacity: "0.5"
|
|
3179
|
+
}
|
|
3180
|
+
)
|
|
2613
3181
|
] });
|
|
2614
3182
|
}
|
|
2615
|
-
function ColumnsPanel({
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
const
|
|
2619
|
-
const
|
|
2620
|
-
const columns =
|
|
3183
|
+
function ColumnsPanel({ table }) {
|
|
3184
|
+
const [search, setSearch] = React4.useState("");
|
|
3185
|
+
const [draggedId, setDraggedId] = React4.useState(null);
|
|
3186
|
+
const allColumns = table.getAllLeafColumns();
|
|
3187
|
+
const columnOrder = table.getState().columnOrder;
|
|
3188
|
+
const columns = columnOrder && columnOrder.length > 0 ? [...allColumns].sort((a, b) => {
|
|
3189
|
+
const ia = columnOrder.indexOf(a.id);
|
|
3190
|
+
const ib = columnOrder.indexOf(b.id);
|
|
3191
|
+
return (ia === -1 ? Number.MAX_SAFE_INTEGER : ia) - (ib === -1 ? Number.MAX_SAFE_INTEGER : ib);
|
|
3192
|
+
}) : allColumns;
|
|
2621
3193
|
const visibleCount = columns.filter((c) => c.getIsVisible()).length;
|
|
2622
3194
|
const filteredColumns = search ? columns.filter((col) => {
|
|
2623
3195
|
const header = typeof col.columnDef.header === "string" ? col.columnDef.header : col.id;
|
|
2624
3196
|
return header.toLowerCase().includes(search.toLowerCase());
|
|
2625
3197
|
}) : columns;
|
|
2626
|
-
const handleToggleAll =
|
|
3198
|
+
const handleToggleAll = React4.useCallback(
|
|
2627
3199
|
(visible) => {
|
|
2628
3200
|
table.toggleAllColumnsVisible(visible);
|
|
2629
3201
|
},
|
|
2630
3202
|
[table]
|
|
2631
3203
|
);
|
|
2632
|
-
const handleDragStart =
|
|
3204
|
+
const handleDragStart = React4.useCallback((e, columnId) => {
|
|
2633
3205
|
setDraggedId(columnId);
|
|
2634
3206
|
e.dataTransfer.effectAllowed = "move";
|
|
2635
3207
|
e.dataTransfer.setData("text/plain", columnId);
|
|
2636
3208
|
}, []);
|
|
2637
|
-
const handleDragOver =
|
|
3209
|
+
const handleDragOver = React4.useCallback((e) => {
|
|
2638
3210
|
e.preventDefault();
|
|
2639
3211
|
e.dataTransfer.dropEffect = "move";
|
|
2640
3212
|
}, []);
|
|
2641
|
-
const handleDragEnd =
|
|
3213
|
+
const handleDragEnd = React4.useCallback(() => {
|
|
2642
3214
|
setDraggedId(null);
|
|
2643
3215
|
}, []);
|
|
2644
|
-
const handleDrop =
|
|
3216
|
+
const handleDrop = React4.useCallback(
|
|
2645
3217
|
(e, targetId) => {
|
|
2646
3218
|
e.preventDefault();
|
|
2647
3219
|
if (!draggedId || draggedId === targetId) return;
|
|
@@ -2766,7 +3338,7 @@ function FiltersPanel({
|
|
|
2766
3338
|
const globalFilter = table.getState().globalFilter;
|
|
2767
3339
|
const hasFilters = columnFilters.length > 0 || Boolean(globalFilter);
|
|
2768
3340
|
const filterCount = columnFilters.length + (globalFilter ? 1 : 0);
|
|
2769
|
-
const handleRemoveColumnFilter =
|
|
3341
|
+
const handleRemoveColumnFilter = React4.useCallback(
|
|
2770
3342
|
(columnId) => {
|
|
2771
3343
|
table.setColumnFilters(
|
|
2772
3344
|
(prev) => prev.filter((f) => f.id !== columnId)
|
|
@@ -2774,7 +3346,7 @@ function FiltersPanel({
|
|
|
2774
3346
|
},
|
|
2775
3347
|
[table]
|
|
2776
3348
|
);
|
|
2777
|
-
const handleClearAll =
|
|
3349
|
+
const handleClearAll = React4.useCallback(() => {
|
|
2778
3350
|
table.resetColumnFilters(true);
|
|
2779
3351
|
table.resetGlobalFilter(true);
|
|
2780
3352
|
}, [table]);
|
|
@@ -2868,8 +3440,8 @@ function Sidebar({
|
|
|
2868
3440
|
activePanel,
|
|
2869
3441
|
onPanelChange
|
|
2870
3442
|
}) {
|
|
2871
|
-
const sidebarRef =
|
|
2872
|
-
const handleKeyDown =
|
|
3443
|
+
const sidebarRef = React4.useRef(null);
|
|
3444
|
+
const handleKeyDown = React4.useCallback(
|
|
2873
3445
|
(e) => {
|
|
2874
3446
|
if (e.key === "Escape" && open) {
|
|
2875
3447
|
onClose();
|
|
@@ -2877,7 +3449,7 @@ function Sidebar({
|
|
|
2877
3449
|
},
|
|
2878
3450
|
[open, onClose]
|
|
2879
3451
|
);
|
|
2880
|
-
|
|
3452
|
+
React4.useEffect(() => {
|
|
2881
3453
|
document.addEventListener("keydown", handleKeyDown);
|
|
2882
3454
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
2883
3455
|
}, [handleKeyDown]);
|
|
@@ -2959,11 +3531,11 @@ function Sidebar({
|
|
|
2959
3531
|
);
|
|
2960
3532
|
}
|
|
2961
3533
|
function ContextMenuItem({ item, onClose }) {
|
|
2962
|
-
const [submenuOpen, setSubmenuOpen] =
|
|
2963
|
-
const itemRef =
|
|
2964
|
-
const submenuRef =
|
|
2965
|
-
const timerRef =
|
|
2966
|
-
|
|
3534
|
+
const [submenuOpen, setSubmenuOpen] = React4.useState(false);
|
|
3535
|
+
const itemRef = React4.useRef(null);
|
|
3536
|
+
const submenuRef = React4.useRef(null);
|
|
3537
|
+
const timerRef = React4.useRef(void 0);
|
|
3538
|
+
React4.useEffect(() => {
|
|
2967
3539
|
return () => clearTimeout(timerRef.current);
|
|
2968
3540
|
}, []);
|
|
2969
3541
|
if (item.separator) {
|
|
@@ -3044,10 +3616,11 @@ function ContextMenu({
|
|
|
3044
3616
|
y,
|
|
3045
3617
|
onClose,
|
|
3046
3618
|
table,
|
|
3619
|
+
targetColumnId,
|
|
3047
3620
|
customItems
|
|
3048
3621
|
}) {
|
|
3049
|
-
const menuRef =
|
|
3050
|
-
|
|
3622
|
+
const menuRef = React4.useRef(null);
|
|
3623
|
+
React4.useEffect(() => {
|
|
3051
3624
|
if (!menuRef.current) return;
|
|
3052
3625
|
const rect = menuRef.current.getBoundingClientRect();
|
|
3053
3626
|
const vw = window.innerWidth;
|
|
@@ -3059,11 +3632,11 @@ function ContextMenu({
|
|
|
3059
3632
|
menuRef.current.style.top = `${y - rect.height}px`;
|
|
3060
3633
|
}
|
|
3061
3634
|
}, [x, y]);
|
|
3062
|
-
|
|
3635
|
+
React4.useEffect(() => {
|
|
3063
3636
|
const firstItem = menuRef.current?.querySelector('[role="menuitem"]');
|
|
3064
3637
|
firstItem?.focus();
|
|
3065
3638
|
}, []);
|
|
3066
|
-
const handleKeyDown =
|
|
3639
|
+
const handleKeyDown = React4.useCallback(
|
|
3067
3640
|
(e) => {
|
|
3068
3641
|
if (e.key === "Escape") {
|
|
3069
3642
|
onClose();
|
|
@@ -3087,6 +3660,17 @@ function ContextMenu({
|
|
|
3087
3660
|
},
|
|
3088
3661
|
[onClose]
|
|
3089
3662
|
);
|
|
3663
|
+
const resolveSortColumn = () => {
|
|
3664
|
+
if (targetColumnId) {
|
|
3665
|
+
const column = table.getColumn(targetColumnId);
|
|
3666
|
+
if (column) return column;
|
|
3667
|
+
}
|
|
3668
|
+
const focused = table.getFocusedCell();
|
|
3669
|
+
if (focused) {
|
|
3670
|
+
return table.getVisibleLeafColumns()[focused.columnIndex];
|
|
3671
|
+
}
|
|
3672
|
+
return void 0;
|
|
3673
|
+
};
|
|
3090
3674
|
const defaultItems = [
|
|
3091
3675
|
{
|
|
3092
3676
|
id: "copy",
|
|
@@ -3135,14 +3719,14 @@ function ContextMenu({
|
|
|
3135
3719
|
id: "sort-asc",
|
|
3136
3720
|
label: "Sort Ascending",
|
|
3137
3721
|
action: () => {
|
|
3138
|
-
|
|
3722
|
+
resolveSortColumn()?.toggleSorting(false);
|
|
3139
3723
|
}
|
|
3140
3724
|
},
|
|
3141
3725
|
{
|
|
3142
3726
|
id: "sort-desc",
|
|
3143
3727
|
label: "Sort Descending",
|
|
3144
3728
|
action: () => {
|
|
3145
|
-
|
|
3729
|
+
resolveSortColumn()?.toggleSorting(true);
|
|
3146
3730
|
}
|
|
3147
3731
|
},
|
|
3148
3732
|
{
|
|
@@ -3230,24 +3814,27 @@ function ContextMenu({
|
|
|
3230
3814
|
] });
|
|
3231
3815
|
}
|
|
3232
3816
|
function useContextMenu() {
|
|
3233
|
-
const [isOpen, setIsOpen] =
|
|
3234
|
-
const [x, setX] =
|
|
3235
|
-
const [y, setY] =
|
|
3236
|
-
const [targetTable, setTargetTable] =
|
|
3237
|
-
const
|
|
3238
|
-
|
|
3817
|
+
const [isOpen, setIsOpen] = React4.useState(false);
|
|
3818
|
+
const [x, setX] = React4.useState(0);
|
|
3819
|
+
const [y, setY] = React4.useState(0);
|
|
3820
|
+
const [targetTable, setTargetTable] = React4.useState(null);
|
|
3821
|
+
const [targetColumnId, setTargetColumnId] = React4.useState(void 0);
|
|
3822
|
+
const open = React4.useCallback(
|
|
3823
|
+
(clientX, clientY, table, columnId) => {
|
|
3239
3824
|
setX(clientX);
|
|
3240
3825
|
setY(clientY);
|
|
3241
3826
|
setTargetTable(table);
|
|
3827
|
+
setTargetColumnId(columnId);
|
|
3242
3828
|
setIsOpen(true);
|
|
3243
3829
|
},
|
|
3244
3830
|
[]
|
|
3245
3831
|
);
|
|
3246
|
-
const close =
|
|
3832
|
+
const close = React4.useCallback(() => {
|
|
3247
3833
|
setIsOpen(false);
|
|
3248
3834
|
setTargetTable(null);
|
|
3835
|
+
setTargetColumnId(void 0);
|
|
3249
3836
|
}, []);
|
|
3250
|
-
|
|
3837
|
+
React4.useEffect(() => {
|
|
3251
3838
|
if (!isOpen) return;
|
|
3252
3839
|
const handleKeyDown = (e) => {
|
|
3253
3840
|
if (e.key === "Escape") close();
|
|
@@ -3260,7 +3847,7 @@ function useContextMenu() {
|
|
|
3260
3847
|
document.removeEventListener("click", handleClick);
|
|
3261
3848
|
};
|
|
3262
3849
|
}, [isOpen, close]);
|
|
3263
|
-
return { isOpen, x, y, targetTable, open, close };
|
|
3850
|
+
return { isOpen, x, y, targetTable, targetColumnId, open, close };
|
|
3264
3851
|
}
|
|
3265
3852
|
function useKeyboardNavigation(table, options = {}) {
|
|
3266
3853
|
const {
|
|
@@ -3271,7 +3858,7 @@ function useKeyboardNavigation(table, options = {}) {
|
|
|
3271
3858
|
const activeCell = table.getState().editing.activeCell;
|
|
3272
3859
|
const focusedRowIndex = focusedCell?.rowIndex ?? null;
|
|
3273
3860
|
const focusedColumnIndex = focusedCell?.columnIndex ?? null;
|
|
3274
|
-
const focusCellElement =
|
|
3861
|
+
const focusCellElement = React4.useCallback(
|
|
3275
3862
|
(container, cell) => {
|
|
3276
3863
|
const element = getCellElement(container, cell);
|
|
3277
3864
|
if (!element) return false;
|
|
@@ -3286,7 +3873,7 @@ function useKeyboardNavigation(table, options = {}) {
|
|
|
3286
3873
|
},
|
|
3287
3874
|
[]
|
|
3288
3875
|
);
|
|
3289
|
-
const handleKeyDown =
|
|
3876
|
+
const handleKeyDown = React4.useCallback(
|
|
3290
3877
|
(event) => {
|
|
3291
3878
|
if (!enabled || table.options.enableKeyboardNavigation === false) return;
|
|
3292
3879
|
const target = event.target;
|
|
@@ -3360,7 +3947,7 @@ function useKeyboardNavigation(table, options = {}) {
|
|
|
3360
3947
|
},
|
|
3361
3948
|
[activeCell, containerRef, enabled, table]
|
|
3362
3949
|
);
|
|
3363
|
-
|
|
3950
|
+
React4.useEffect(() => {
|
|
3364
3951
|
if (!enabled || table.options.enableKeyboardNavigation === false) return;
|
|
3365
3952
|
const container = containerRef?.current;
|
|
3366
3953
|
if (!container) return;
|
|
@@ -3369,7 +3956,7 @@ function useKeyboardNavigation(table, options = {}) {
|
|
|
3369
3956
|
container.removeEventListener("keydown", handleKeyDown);
|
|
3370
3957
|
};
|
|
3371
3958
|
}, [containerRef, enabled, handleKeyDown, table.options.enableKeyboardNavigation]);
|
|
3372
|
-
|
|
3959
|
+
React4.useEffect(() => {
|
|
3373
3960
|
if (!enabled || table.options.enableKeyboardNavigation === false) return;
|
|
3374
3961
|
if (focusedRowIndex === null || focusedColumnIndex === null) return;
|
|
3375
3962
|
if (activeCell) return;
|
|
@@ -3460,6 +4047,85 @@ function isEditableTarget(element) {
|
|
|
3460
4047
|
}
|
|
3461
4048
|
return element.isContentEditable;
|
|
3462
4049
|
}
|
|
4050
|
+
function useFillHandle(table, options = {}) {
|
|
4051
|
+
const { enabled = true } = options;
|
|
4052
|
+
const [dragState, setDragState] = React4.useState({
|
|
4053
|
+
isDragging: false,
|
|
4054
|
+
sourceCell: null,
|
|
4055
|
+
currentCell: null
|
|
4056
|
+
});
|
|
4057
|
+
const dragRef = React4.useRef(dragState);
|
|
4058
|
+
dragRef.current = dragState;
|
|
4059
|
+
const onFillHandleMouseDown = React4.useCallback(
|
|
4060
|
+
(rowIndex, columnIndex, e) => {
|
|
4061
|
+
if (!enabled) return;
|
|
4062
|
+
e.preventDefault();
|
|
4063
|
+
e.stopPropagation();
|
|
4064
|
+
setDragState({
|
|
4065
|
+
isDragging: true,
|
|
4066
|
+
sourceCell: { rowIndex, columnIndex },
|
|
4067
|
+
currentCell: { rowIndex, columnIndex }
|
|
4068
|
+
});
|
|
4069
|
+
},
|
|
4070
|
+
[enabled]
|
|
4071
|
+
);
|
|
4072
|
+
React4.useEffect(() => {
|
|
4073
|
+
if (!dragState.isDragging) return;
|
|
4074
|
+
const handleMouseMove = (e) => {
|
|
4075
|
+
const target = document.elementFromPoint(e.clientX, e.clientY);
|
|
4076
|
+
if (!target) return;
|
|
4077
|
+
const td = target.closest("td[data-column-id]");
|
|
4078
|
+
const tr = target.closest("tr[data-row-id]");
|
|
4079
|
+
if (!td || !tr) return;
|
|
4080
|
+
const columnId = td.getAttribute("data-column-id");
|
|
4081
|
+
const rowId = tr.getAttribute("data-row-id");
|
|
4082
|
+
if (!columnId || !rowId) return;
|
|
4083
|
+
const rows = table.getRowModel().rows;
|
|
4084
|
+
const columns = table.getVisibleLeafColumns();
|
|
4085
|
+
const rowIndex = rows.findIndex((r) => r.id === rowId);
|
|
4086
|
+
const columnIndex = columns.findIndex((c) => c.id === columnId);
|
|
4087
|
+
if (rowIndex === -1 || columnIndex === -1) return;
|
|
4088
|
+
setDragState((prev) => ({
|
|
4089
|
+
...prev,
|
|
4090
|
+
currentCell: { rowIndex, columnIndex }
|
|
4091
|
+
}));
|
|
4092
|
+
};
|
|
4093
|
+
const handleMouseUp = () => {
|
|
4094
|
+
const current = dragRef.current;
|
|
4095
|
+
if (current.sourceCell && current.currentCell) {
|
|
4096
|
+
const source = current.sourceCell;
|
|
4097
|
+
const target = current.currentCell;
|
|
4098
|
+
if (source.rowIndex !== target.rowIndex || source.columnIndex !== target.columnIndex) {
|
|
4099
|
+
const sourceRange = {
|
|
4100
|
+
startRow: source.rowIndex,
|
|
4101
|
+
startCol: source.columnIndex,
|
|
4102
|
+
endRow: source.rowIndex,
|
|
4103
|
+
endCol: source.columnIndex
|
|
4104
|
+
};
|
|
4105
|
+
const targetRange = {
|
|
4106
|
+
startRow: Math.min(source.rowIndex, target.rowIndex),
|
|
4107
|
+
startCol: Math.min(source.columnIndex, target.columnIndex),
|
|
4108
|
+
endRow: Math.max(source.rowIndex, target.rowIndex),
|
|
4109
|
+
endCol: Math.max(source.columnIndex, target.columnIndex)
|
|
4110
|
+
};
|
|
4111
|
+
table.fillRange(sourceRange, targetRange);
|
|
4112
|
+
}
|
|
4113
|
+
}
|
|
4114
|
+
setDragState({
|
|
4115
|
+
isDragging: false,
|
|
4116
|
+
sourceCell: null,
|
|
4117
|
+
currentCell: null
|
|
4118
|
+
});
|
|
4119
|
+
};
|
|
4120
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
4121
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
4122
|
+
return () => {
|
|
4123
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
4124
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
4125
|
+
};
|
|
4126
|
+
}, [dragState.isDragging, table]);
|
|
4127
|
+
return { dragState, onFillHandleMouseDown };
|
|
4128
|
+
}
|
|
3463
4129
|
function filterHeaderGroups(groups, visibleColumnIds) {
|
|
3464
4130
|
return groups.map((group) => ({
|
|
3465
4131
|
...group,
|
|
@@ -3473,6 +4139,8 @@ function Table({
|
|
|
3473
4139
|
bordered: borderedProp,
|
|
3474
4140
|
compact: compactProp,
|
|
3475
4141
|
theme: themeProp,
|
|
4142
|
+
config,
|
|
4143
|
+
configProfile,
|
|
3476
4144
|
clickableRows,
|
|
3477
4145
|
footer,
|
|
3478
4146
|
loading,
|
|
@@ -3490,7 +4158,7 @@ function Table({
|
|
|
3490
4158
|
statusBar,
|
|
3491
4159
|
statusBarPanels,
|
|
3492
4160
|
sidebar,
|
|
3493
|
-
sidebarPanels
|
|
4161
|
+
sidebarPanels,
|
|
3494
4162
|
defaultSidebarPanel,
|
|
3495
4163
|
floatingFilters,
|
|
3496
4164
|
columnVirtualization,
|
|
@@ -3498,20 +4166,34 @@ function Table({
|
|
|
3498
4166
|
ariaLabel: ariaLabelProp,
|
|
3499
4167
|
...rest
|
|
3500
4168
|
}) {
|
|
3501
|
-
const
|
|
3502
|
-
const
|
|
3503
|
-
const
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
const
|
|
3508
|
-
const
|
|
3509
|
-
const
|
|
3510
|
-
const
|
|
3511
|
-
|
|
4169
|
+
const providerDefaults = useYableDefaults();
|
|
4170
|
+
const { tableProps: providerTableProps } = providerDefaults;
|
|
4171
|
+
const profile = resolveYableProfile(
|
|
4172
|
+
config ?? providerDefaults.config,
|
|
4173
|
+
configProfile ?? providerDefaults.tableProfile
|
|
4174
|
+
);
|
|
4175
|
+
const profileTableProps = profile.table;
|
|
4176
|
+
const stickyHeader = stickyHeaderProp ?? profileTableProps?.stickyHeader ?? providerTableProps?.stickyHeader;
|
|
4177
|
+
const striped = stripedProp ?? profileTableProps?.striped ?? providerTableProps?.striped;
|
|
4178
|
+
const bordered = borderedProp ?? profileTableProps?.bordered ?? providerTableProps?.bordered;
|
|
4179
|
+
const compact = compactProp ?? profileTableProps?.compact ?? providerTableProps?.compact;
|
|
4180
|
+
const theme = themeProp ?? profileTableProps?.theme ?? providerTableProps?.theme;
|
|
4181
|
+
const direction = directionProp ?? profileTableProps?.direction ?? providerTableProps?.direction;
|
|
4182
|
+
const ariaLabel = ariaLabelProp ?? profileTableProps?.ariaLabel ?? providerTableProps?.ariaLabel;
|
|
4183
|
+
const resolvedClickableRows = clickableRows ?? profileTableProps?.clickableRows;
|
|
4184
|
+
const resolvedStatusBar = statusBar ?? profileTableProps?.statusBar;
|
|
4185
|
+
const resolvedSidebar = sidebar ?? profileTableProps?.sidebar;
|
|
4186
|
+
const resolvedSidebarPanels = sidebarPanels ?? profileTableProps?.sidebarPanels ?? ["columns", "filters"];
|
|
4187
|
+
const resolvedDefaultSidebarPanel = defaultSidebarPanel ?? profileTableProps?.defaultSidebarPanel;
|
|
4188
|
+
const resolvedFloatingFilters = floatingFilters ?? profileTableProps?.floatingFilters;
|
|
4189
|
+
const resolvedColumnVirtualization = columnVirtualization ?? profileTableProps?.columnVirtualization;
|
|
4190
|
+
const resolvedColumnVirtualizationOverscan = columnVirtualizationOverscan ?? profileTableProps?.columnVirtualizationOverscan;
|
|
4191
|
+
const [sidebarOpen, setSidebarOpen] = React4.useState(false);
|
|
4192
|
+
const [sidebarPanel, setSidebarPanel] = React4.useState(
|
|
4193
|
+
resolvedDefaultSidebarPanel ?? "columns"
|
|
3512
4194
|
);
|
|
3513
|
-
const containerRef =
|
|
3514
|
-
const horizontalScrollRef =
|
|
4195
|
+
const containerRef = React4.useRef(null);
|
|
4196
|
+
const horizontalScrollRef = React4.useRef(null);
|
|
3515
4197
|
const isRtl = direction === "rtl";
|
|
3516
4198
|
const classNames = [
|
|
3517
4199
|
"yable",
|
|
@@ -3532,14 +4214,16 @@ function Table({
|
|
|
3532
4214
|
const allVisibleColumns = table.getVisibleLeafColumns();
|
|
3533
4215
|
const hasPinnedColumns = table.getLeftVisibleLeafColumns().length > 0 || table.getRightVisibleLeafColumns().length > 0;
|
|
3534
4216
|
const hasGroupedHeaders = table.getHeaderGroups().length > 1;
|
|
3535
|
-
const canVirtualizeColumns = Boolean(
|
|
4217
|
+
const canVirtualizeColumns = Boolean(resolvedColumnVirtualization) && !hasPinnedColumns && !hasGroupedHeaders && allVisibleColumns.length > 0;
|
|
4218
|
+
const allVisibleColumnSizeSignature = allVisibleColumns.map((column) => `${column.id}:${column.getSize()}`).join("|");
|
|
3536
4219
|
const columnVirtualState = useColumnVirtualization({
|
|
3537
4220
|
containerRef: horizontalScrollRef,
|
|
3538
4221
|
columns: allVisibleColumns,
|
|
3539
|
-
overscan:
|
|
3540
|
-
enabled: canVirtualizeColumns
|
|
4222
|
+
overscan: resolvedColumnVirtualizationOverscan ?? 2,
|
|
4223
|
+
enabled: canVirtualizeColumns,
|
|
4224
|
+
sizingKey: allVisibleColumnSizeSignature
|
|
3541
4225
|
});
|
|
3542
|
-
const renderTable =
|
|
4226
|
+
const renderTable = React4.useMemo(() => {
|
|
3543
4227
|
if (!canVirtualizeColumns || !columnVirtualState.isVirtualized) {
|
|
3544
4228
|
return table;
|
|
3545
4229
|
}
|
|
@@ -3565,13 +4249,16 @@ function Table({
|
|
|
3565
4249
|
const showColumnVirtualizationShell = canVirtualizeColumns;
|
|
3566
4250
|
const contextMenu = useContextMenu();
|
|
3567
4251
|
useKeyboardNavigation(table, { containerRef });
|
|
3568
|
-
const
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
const
|
|
3572
|
-
const
|
|
3573
|
-
const
|
|
3574
|
-
|
|
4252
|
+
const { onFillHandleMouseDown } = useFillHandle(table, {
|
|
4253
|
+
enabled: Boolean(table.options.enableFillHandle)
|
|
4254
|
+
});
|
|
4255
|
+
const [announcement, setAnnouncement] = React4.useState("");
|
|
4256
|
+
const prevSortingRef = React4.useRef(table.getState().sorting);
|
|
4257
|
+
const prevFilterCountRef = React4.useRef(rows.length);
|
|
4258
|
+
const prevHasFiltersRef = React4.useRef(isFiltered);
|
|
4259
|
+
const prevPaginationRef = React4.useRef(table.getState().pagination);
|
|
4260
|
+
const isFirstRenderRef = React4.useRef(true);
|
|
4261
|
+
React4.useEffect(() => {
|
|
3575
4262
|
if (isFirstRenderRef.current) {
|
|
3576
4263
|
isFirstRenderRef.current = false;
|
|
3577
4264
|
return;
|
|
@@ -3609,21 +4296,22 @@ function Table({
|
|
|
3609
4296
|
}
|
|
3610
4297
|
}
|
|
3611
4298
|
});
|
|
3612
|
-
const handleContextMenu =
|
|
4299
|
+
const handleContextMenu = React4.useCallback(
|
|
3613
4300
|
(e) => {
|
|
3614
4301
|
e.preventDefault();
|
|
3615
|
-
|
|
4302
|
+
const targetEl = e.target?.closest?.("[data-column-id]");
|
|
4303
|
+
const targetColumnId = targetEl?.getAttribute("data-column-id") ?? void 0;
|
|
4304
|
+
contextMenu.open(e.clientX, e.clientY, table, targetColumnId);
|
|
3616
4305
|
},
|
|
3617
4306
|
[contextMenu, table]
|
|
3618
4307
|
);
|
|
3619
|
-
const enableRowVirtualization = renderTable.options.enableVirtualization ?? false;
|
|
3620
4308
|
const visibleLeafColumns = renderTable.getVisibleLeafColumns();
|
|
3621
|
-
const
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
const outerTableStyle =
|
|
4309
|
+
const visibleColumnTotalSize = visibleLeafColumns.reduce(
|
|
4310
|
+
(sum, column) => sum + column.getSize(),
|
|
4311
|
+
0
|
|
4312
|
+
);
|
|
4313
|
+
const colgroup = visibleLeafColumns.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx("colgroup", { children: visibleLeafColumns.map((col) => /* @__PURE__ */ jsxRuntime.jsx("col", { style: { width: col.getSize() } }, col.id)) });
|
|
4314
|
+
const outerTableStyle = React4.useMemo(() => {
|
|
3627
4315
|
if (columnVirtualState.isVirtualized) {
|
|
3628
4316
|
return {
|
|
3629
4317
|
width: columnVirtualState.visibleWidth,
|
|
@@ -3632,15 +4320,15 @@ function Table({
|
|
|
3632
4320
|
tableLayout: "fixed"
|
|
3633
4321
|
};
|
|
3634
4322
|
}
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
4323
|
+
return {
|
|
4324
|
+
minWidth: visibleColumnTotalSize || void 0,
|
|
4325
|
+
tableLayout: "fixed"
|
|
4326
|
+
};
|
|
3639
4327
|
}, [
|
|
3640
4328
|
columnVirtualState.isVirtualized,
|
|
3641
4329
|
columnVirtualState.visibleWidth,
|
|
3642
4330
|
columnVirtualState.startOffset,
|
|
3643
|
-
|
|
4331
|
+
visibleColumnTotalSize
|
|
3644
4332
|
]);
|
|
3645
4333
|
const tableNode = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3646
4334
|
"table",
|
|
@@ -3649,9 +4337,17 @@ function Table({
|
|
|
3649
4337
|
style: outerTableStyle,
|
|
3650
4338
|
"data-column-virtualized": columnVirtualState.isVirtualized || void 0,
|
|
3651
4339
|
children: [
|
|
3652
|
-
|
|
3653
|
-
/* @__PURE__ */ jsxRuntime.jsx(TableHeader, { table: renderTable, floatingFilters }),
|
|
3654
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4340
|
+
colgroup,
|
|
4341
|
+
/* @__PURE__ */ jsxRuntime.jsx(TableHeader, { table: renderTable, floatingFilters: resolvedFloatingFilters }),
|
|
4342
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4343
|
+
TableBody,
|
|
4344
|
+
{
|
|
4345
|
+
table: renderTable,
|
|
4346
|
+
clickableRows: resolvedClickableRows,
|
|
4347
|
+
colgroup,
|
|
4348
|
+
onFillHandleMouseDown
|
|
4349
|
+
}
|
|
4350
|
+
),
|
|
3655
4351
|
footer && /* @__PURE__ */ jsxRuntime.jsx(TableFooter, { table: renderTable })
|
|
3656
4352
|
]
|
|
3657
4353
|
}
|
|
@@ -3717,18 +4413,43 @@ function Table({
|
|
|
3717
4413
|
}
|
|
3718
4414
|
))
|
|
3719
4415
|
] }),
|
|
3720
|
-
|
|
4416
|
+
resolvedSidebar && !sidebarOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4417
|
+
"button",
|
|
4418
|
+
{
|
|
4419
|
+
type: "button",
|
|
4420
|
+
className: "yable-sidebar-trigger",
|
|
4421
|
+
"aria-label": "Open tool panel",
|
|
4422
|
+
title: "Open tool panel",
|
|
4423
|
+
onClick: () => setSidebarOpen(true),
|
|
4424
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
|
|
4425
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4426
|
+
"rect",
|
|
4427
|
+
{
|
|
4428
|
+
x: "3",
|
|
4429
|
+
y: "4",
|
|
4430
|
+
width: "18",
|
|
4431
|
+
height: "16",
|
|
4432
|
+
rx: "2",
|
|
4433
|
+
stroke: "currentColor",
|
|
4434
|
+
strokeWidth: "2"
|
|
4435
|
+
}
|
|
4436
|
+
),
|
|
4437
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "14", y1: "4", x2: "14", y2: "20", stroke: "currentColor", strokeWidth: "2" })
|
|
4438
|
+
] })
|
|
4439
|
+
}
|
|
4440
|
+
),
|
|
4441
|
+
resolvedSidebar && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3721
4442
|
Sidebar,
|
|
3722
4443
|
{
|
|
3723
4444
|
table,
|
|
3724
4445
|
open: sidebarOpen,
|
|
3725
4446
|
onClose: () => setSidebarOpen(false),
|
|
3726
|
-
panels:
|
|
4447
|
+
panels: resolvedSidebarPanels,
|
|
3727
4448
|
activePanel: sidebarPanel,
|
|
3728
4449
|
onPanelChange: setSidebarPanel
|
|
3729
4450
|
}
|
|
3730
4451
|
),
|
|
3731
|
-
|
|
4452
|
+
resolvedStatusBar && /* @__PURE__ */ jsxRuntime.jsx(StatusBar, { table, panels: statusBarPanels }),
|
|
3732
4453
|
children,
|
|
3733
4454
|
contextMenu.isOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3734
4455
|
ContextMenu,
|
|
@@ -3736,7 +4457,8 @@ function Table({
|
|
|
3736
4457
|
x: contextMenu.x,
|
|
3737
4458
|
y: contextMenu.y,
|
|
3738
4459
|
onClose: contextMenu.close,
|
|
3739
|
-
table
|
|
4460
|
+
table,
|
|
4461
|
+
targetColumnId: contextMenu.targetColumnId
|
|
3740
4462
|
}
|
|
3741
4463
|
),
|
|
3742
4464
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3947,12 +4669,12 @@ function GlobalFilter({
|
|
|
3947
4669
|
}) {
|
|
3948
4670
|
const locale = yableCore.getDefaultLocale();
|
|
3949
4671
|
const resolvedPlaceholder = placeholder ?? locale.searchPlaceholder;
|
|
3950
|
-
const [value, setValue] =
|
|
4672
|
+
const [value, setValue] = React4.useState(
|
|
3951
4673
|
table.getState().globalFilter ?? ""
|
|
3952
4674
|
);
|
|
3953
|
-
const timerRef =
|
|
3954
|
-
const inputRef =
|
|
3955
|
-
const handleChange =
|
|
4675
|
+
const timerRef = React4.useRef(void 0);
|
|
4676
|
+
const inputRef = React4.useRef(null);
|
|
4677
|
+
const handleChange = React4.useCallback(
|
|
3956
4678
|
(e) => {
|
|
3957
4679
|
const newValue = e.target.value;
|
|
3958
4680
|
setValue(newValue);
|
|
@@ -3967,13 +4689,13 @@ function GlobalFilter({
|
|
|
3967
4689
|
},
|
|
3968
4690
|
[table, debounce]
|
|
3969
4691
|
);
|
|
3970
|
-
const handleClear =
|
|
4692
|
+
const handleClear = React4.useCallback(() => {
|
|
3971
4693
|
setValue("");
|
|
3972
4694
|
table.setGlobalFilter("");
|
|
3973
4695
|
clearTimeout(timerRef.current);
|
|
3974
4696
|
inputRef.current?.focus();
|
|
3975
4697
|
}, [table]);
|
|
3976
|
-
const handleKeyDown =
|
|
4698
|
+
const handleKeyDown = React4.useCallback(
|
|
3977
4699
|
(e) => {
|
|
3978
4700
|
if (e.key === "Escape" && value) {
|
|
3979
4701
|
e.preventDefault();
|
|
@@ -3982,10 +4704,10 @@ function GlobalFilter({
|
|
|
3982
4704
|
},
|
|
3983
4705
|
[value, handleClear]
|
|
3984
4706
|
);
|
|
3985
|
-
|
|
4707
|
+
React4.useEffect(() => {
|
|
3986
4708
|
return () => clearTimeout(timerRef.current);
|
|
3987
4709
|
}, []);
|
|
3988
|
-
|
|
4710
|
+
React4.useEffect(() => {
|
|
3989
4711
|
const externalValue = table.getState().globalFilter ?? "";
|
|
3990
4712
|
if (externalValue !== value) {
|
|
3991
4713
|
setValue(externalValue);
|
|
@@ -4030,7 +4752,7 @@ function CellInput({
|
|
|
4030
4752
|
className
|
|
4031
4753
|
}) {
|
|
4032
4754
|
const { table, row, column, cell } = context;
|
|
4033
|
-
const inputRef =
|
|
4755
|
+
const inputRef = React4.useRef(null);
|
|
4034
4756
|
const isEditing = cell.getIsEditing();
|
|
4035
4757
|
const isAlwaysEditable = cell.getIsAlwaysEditable();
|
|
4036
4758
|
const pending = table.getPendingValue(row.id, column.id);
|
|
@@ -4055,7 +4777,7 @@ function CellInput({
|
|
|
4055
4777
|
}
|
|
4056
4778
|
}
|
|
4057
4779
|
};
|
|
4058
|
-
|
|
4780
|
+
React4.useEffect(() => {
|
|
4059
4781
|
if ((isEditing || autoFocus) && inputRef.current) {
|
|
4060
4782
|
inputRef.current.focus();
|
|
4061
4783
|
inputRef.current.select();
|
|
@@ -4091,8 +4813,8 @@ function CellSelect({
|
|
|
4091
4813
|
const isAlwaysEditable = cell.getIsAlwaysEditable();
|
|
4092
4814
|
const pending = table.getPendingValue(row.id, column.id);
|
|
4093
4815
|
const currentValue = pending !== void 0 ? pending : cell.getValue();
|
|
4094
|
-
const commitTimerRef =
|
|
4095
|
-
|
|
4816
|
+
const commitTimerRef = React4.useRef(null);
|
|
4817
|
+
React4.useEffect(() => {
|
|
4096
4818
|
return () => {
|
|
4097
4819
|
if (commitTimerRef.current !== null) {
|
|
4098
4820
|
clearTimeout(commitTimerRef.current);
|
|
@@ -4173,7 +4895,7 @@ function CellDatePicker({
|
|
|
4173
4895
|
className
|
|
4174
4896
|
}) {
|
|
4175
4897
|
const { table, row, column, cell } = context;
|
|
4176
|
-
const inputRef =
|
|
4898
|
+
const inputRef = React4.useRef(null);
|
|
4177
4899
|
const isEditing = cell.getIsEditing();
|
|
4178
4900
|
const isAlwaysEditable = cell.getIsAlwaysEditable();
|
|
4179
4901
|
const pending = table.getPendingValue(row.id, column.id);
|
|
@@ -4187,7 +4909,7 @@ function CellDatePicker({
|
|
|
4187
4909
|
table.commitEdit();
|
|
4188
4910
|
}
|
|
4189
4911
|
};
|
|
4190
|
-
|
|
4912
|
+
React4.useEffect(() => {
|
|
4191
4913
|
if (isEditing && inputRef.current) {
|
|
4192
4914
|
inputRef.current.focus();
|
|
4193
4915
|
}
|
|
@@ -4222,7 +4944,7 @@ function formatDateValue(value, type) {
|
|
|
4222
4944
|
}
|
|
4223
4945
|
function useClipboard(table, options = {}) {
|
|
4224
4946
|
const { enabled = true, containerRef, onCopy, onCut, onPaste, ...clipboardOptions } = options;
|
|
4225
|
-
const handleCopy =
|
|
4947
|
+
const handleCopy = React4.useCallback(
|
|
4226
4948
|
(e) => {
|
|
4227
4949
|
if (isEditableTarget2(e.target)) return;
|
|
4228
4950
|
e.preventDefault();
|
|
@@ -4234,7 +4956,7 @@ function useClipboard(table, options = {}) {
|
|
|
4234
4956
|
},
|
|
4235
4957
|
[table, clipboardOptions, onCopy]
|
|
4236
4958
|
);
|
|
4237
|
-
const handleCut =
|
|
4959
|
+
const handleCut = React4.useCallback(
|
|
4238
4960
|
(e) => {
|
|
4239
4961
|
if (isEditableTarget2(e.target)) return;
|
|
4240
4962
|
e.preventDefault();
|
|
@@ -4246,7 +4968,7 @@ function useClipboard(table, options = {}) {
|
|
|
4246
4968
|
},
|
|
4247
4969
|
[table, clipboardOptions, onCut]
|
|
4248
4970
|
);
|
|
4249
|
-
const handlePaste =
|
|
4971
|
+
const handlePaste = React4.useCallback(
|
|
4250
4972
|
(e) => {
|
|
4251
4973
|
if (isEditableTarget2(e.target)) return;
|
|
4252
4974
|
e.preventDefault();
|
|
@@ -4291,7 +5013,7 @@ function useClipboard(table, options = {}) {
|
|
|
4291
5013
|
},
|
|
4292
5014
|
[table, clipboardOptions, onPaste]
|
|
4293
5015
|
);
|
|
4294
|
-
|
|
5016
|
+
React4.useEffect(() => {
|
|
4295
5017
|
if (!enabled) return;
|
|
4296
5018
|
const container = containerRef?.current ?? document;
|
|
4297
5019
|
container.addEventListener("copy", handleCopy);
|
|
@@ -4313,110 +5035,6 @@ function isEditableTarget2(el) {
|
|
|
4313
5035
|
if (el.isContentEditable) return true;
|
|
4314
5036
|
return false;
|
|
4315
5037
|
}
|
|
4316
|
-
function useFillHandle(table, options = {}) {
|
|
4317
|
-
const { enabled = true } = options;
|
|
4318
|
-
const [dragState, setDragState] = React3.useState({
|
|
4319
|
-
isDragging: false,
|
|
4320
|
-
sourceCell: null,
|
|
4321
|
-
currentCell: null
|
|
4322
|
-
});
|
|
4323
|
-
const dragRef = React3.useRef(dragState);
|
|
4324
|
-
dragRef.current = dragState;
|
|
4325
|
-
const onFillHandleMouseDown = React3.useCallback(
|
|
4326
|
-
(rowIndex, columnIndex, e) => {
|
|
4327
|
-
if (!enabled) return;
|
|
4328
|
-
e.preventDefault();
|
|
4329
|
-
e.stopPropagation();
|
|
4330
|
-
setDragState({
|
|
4331
|
-
isDragging: true,
|
|
4332
|
-
sourceCell: { rowIndex, columnIndex },
|
|
4333
|
-
currentCell: { rowIndex, columnIndex }
|
|
4334
|
-
});
|
|
4335
|
-
},
|
|
4336
|
-
[enabled]
|
|
4337
|
-
);
|
|
4338
|
-
React3.useEffect(() => {
|
|
4339
|
-
if (!dragState.isDragging) return;
|
|
4340
|
-
const handleMouseMove = (e) => {
|
|
4341
|
-
const target = document.elementFromPoint(e.clientX, e.clientY);
|
|
4342
|
-
if (!target) return;
|
|
4343
|
-
const td = target.closest("td[data-column-id]");
|
|
4344
|
-
const tr = target.closest("tr[data-row-id]");
|
|
4345
|
-
if (!td || !tr) return;
|
|
4346
|
-
const columnId = td.getAttribute("data-column-id");
|
|
4347
|
-
const rowId = tr.getAttribute("data-row-id");
|
|
4348
|
-
if (!columnId || !rowId) return;
|
|
4349
|
-
const rows = table.getRowModel().rows;
|
|
4350
|
-
const columns = table.getVisibleLeafColumns();
|
|
4351
|
-
const rowIndex = rows.findIndex((r) => r.id === rowId);
|
|
4352
|
-
const columnIndex = columns.findIndex((c) => c.id === columnId);
|
|
4353
|
-
if (rowIndex === -1 || columnIndex === -1) return;
|
|
4354
|
-
setDragState((prev) => ({
|
|
4355
|
-
...prev,
|
|
4356
|
-
currentCell: { rowIndex, columnIndex }
|
|
4357
|
-
}));
|
|
4358
|
-
};
|
|
4359
|
-
const handleMouseUp = () => {
|
|
4360
|
-
const current = dragRef.current;
|
|
4361
|
-
if (current.sourceCell && current.currentCell) {
|
|
4362
|
-
const source = current.sourceCell;
|
|
4363
|
-
const target = current.currentCell;
|
|
4364
|
-
if (source.rowIndex !== target.rowIndex || source.columnIndex !== target.columnIndex) {
|
|
4365
|
-
const sourceRange = {
|
|
4366
|
-
startRow: source.rowIndex,
|
|
4367
|
-
startCol: source.columnIndex,
|
|
4368
|
-
endRow: source.rowIndex,
|
|
4369
|
-
endCol: source.columnIndex
|
|
4370
|
-
};
|
|
4371
|
-
const targetRange = {
|
|
4372
|
-
startRow: Math.min(source.rowIndex, target.rowIndex),
|
|
4373
|
-
startCol: Math.min(source.columnIndex, target.columnIndex),
|
|
4374
|
-
endRow: Math.max(source.rowIndex, target.rowIndex),
|
|
4375
|
-
endCol: Math.max(source.columnIndex, target.columnIndex)
|
|
4376
|
-
};
|
|
4377
|
-
table.fillRange(sourceRange, targetRange);
|
|
4378
|
-
}
|
|
4379
|
-
}
|
|
4380
|
-
setDragState({
|
|
4381
|
-
isDragging: false,
|
|
4382
|
-
sourceCell: null,
|
|
4383
|
-
currentCell: null
|
|
4384
|
-
});
|
|
4385
|
-
};
|
|
4386
|
-
document.addEventListener("mousemove", handleMouseMove);
|
|
4387
|
-
document.addEventListener("mouseup", handleMouseUp);
|
|
4388
|
-
return () => {
|
|
4389
|
-
document.removeEventListener("mousemove", handleMouseMove);
|
|
4390
|
-
document.removeEventListener("mouseup", handleMouseUp);
|
|
4391
|
-
};
|
|
4392
|
-
}, [dragState.isDragging, table]);
|
|
4393
|
-
return { dragState, onFillHandleMouseDown };
|
|
4394
|
-
}
|
|
4395
|
-
function FillHandle({
|
|
4396
|
-
rowIndex,
|
|
4397
|
-
columnIndex,
|
|
4398
|
-
onMouseDown
|
|
4399
|
-
}) {
|
|
4400
|
-
const handleMouseDown = React3.useCallback(
|
|
4401
|
-
(e) => {
|
|
4402
|
-
e.preventDefault();
|
|
4403
|
-
e.stopPropagation();
|
|
4404
|
-
onMouseDown(rowIndex, columnIndex, e);
|
|
4405
|
-
},
|
|
4406
|
-
[rowIndex, columnIndex, onMouseDown]
|
|
4407
|
-
);
|
|
4408
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4409
|
-
"div",
|
|
4410
|
-
{
|
|
4411
|
-
className: "yable-fill-handle",
|
|
4412
|
-
onMouseDown: handleMouseDown,
|
|
4413
|
-
role: "presentation",
|
|
4414
|
-
"aria-hidden": "true",
|
|
4415
|
-
title: "Drag to fill",
|
|
4416
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "yable-fill-handle-dot" })
|
|
4417
|
-
}
|
|
4418
|
-
);
|
|
4419
|
-
}
|
|
4420
5038
|
function GripIcon() {
|
|
4421
5039
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4422
5040
|
"svg",
|
|
@@ -4449,7 +5067,7 @@ function DragHandle({
|
|
|
4449
5067
|
isDragging && "yable-row-drag-handle--dragging",
|
|
4450
5068
|
className
|
|
4451
5069
|
].filter(Boolean).join(" ");
|
|
4452
|
-
const handleDragStart =
|
|
5070
|
+
const handleDragStart = React4.useCallback(
|
|
4453
5071
|
(e) => {
|
|
4454
5072
|
if (e.dataTransfer && e.currentTarget instanceof HTMLElement) {
|
|
4455
5073
|
e.dataTransfer.effectAllowed = "move";
|
|
@@ -4478,10 +5096,10 @@ function useRowDrag({
|
|
|
4478
5096
|
onDataChange,
|
|
4479
5097
|
onReorder
|
|
4480
5098
|
}) {
|
|
4481
|
-
const [dragState, setDragState] =
|
|
4482
|
-
const dragRowIdRef =
|
|
4483
|
-
const dragRowIndexRef =
|
|
4484
|
-
const getRowDragProps =
|
|
5099
|
+
const [dragState, setDragState] = React4.useState(rowDragging.getInitialRowDragState);
|
|
5100
|
+
const dragRowIdRef = React4.useRef(null);
|
|
5101
|
+
const dragRowIndexRef = React4.useRef(-1);
|
|
5102
|
+
const getRowDragProps = React4.useCallback(
|
|
4485
5103
|
(rowId, rowIndex) => {
|
|
4486
5104
|
return {
|
|
4487
5105
|
draggable: true,
|
|
@@ -4580,7 +5198,7 @@ function useRowDrag({
|
|
|
4580
5198
|
},
|
|
4581
5199
|
[data, dragState, onDataChange, onReorder, table]
|
|
4582
5200
|
);
|
|
4583
|
-
const getDragHandleProps =
|
|
5201
|
+
const getDragHandleProps = React4.useCallback(
|
|
4584
5202
|
(rowId) => ({
|
|
4585
5203
|
onDragStart: (e) => {
|
|
4586
5204
|
e.dataTransfer.effectAllowed = "move";
|
|
@@ -4607,7 +5225,7 @@ function TreeToggle({
|
|
|
4607
5225
|
const isExpanded = row.getIsExpanded();
|
|
4608
5226
|
const canToggle = showToggle !== void 0 ? showToggle : hasChildren;
|
|
4609
5227
|
const indent = depth * indentWidth;
|
|
4610
|
-
const handleClick =
|
|
5228
|
+
const handleClick = React4.useCallback(
|
|
4611
5229
|
(e) => {
|
|
4612
5230
|
e.stopPropagation();
|
|
4613
5231
|
if (canToggle) {
|
|
@@ -4664,33 +5282,6 @@ function TreeToggle({
|
|
|
4664
5282
|
}
|
|
4665
5283
|
);
|
|
4666
5284
|
}
|
|
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
5285
|
function ExpandIcon({
|
|
4695
5286
|
isExpanded,
|
|
4696
5287
|
onClick,
|
|
@@ -4704,7 +5295,7 @@ function ExpandIcon({
|
|
|
4704
5295
|
className
|
|
4705
5296
|
].filter(Boolean).join(" ");
|
|
4706
5297
|
const label = ariaLabel ?? (isExpanded ? "Collapse details" : "Expand details");
|
|
4707
|
-
const handleClick =
|
|
5298
|
+
const handleClick = React4.useCallback(
|
|
4708
5299
|
(e) => {
|
|
4709
5300
|
e.stopPropagation();
|
|
4710
5301
|
onClick(e);
|
|
@@ -4769,20 +5360,20 @@ function PivotConfigPanel({
|
|
|
4769
5360
|
aggregationOptions = DEFAULT_AGGREGATION_OPTIONS,
|
|
4770
5361
|
className
|
|
4771
5362
|
}) {
|
|
4772
|
-
const [dragSource, setDragSource] =
|
|
5363
|
+
const [dragSource, setDragSource] = React4.useState(null);
|
|
4773
5364
|
const usedFields = /* @__PURE__ */ new Set([
|
|
4774
5365
|
...rowFields.map((f) => f.field),
|
|
4775
5366
|
...columnFields.map((f) => f.field),
|
|
4776
5367
|
...valueFields.map((f) => f.field)
|
|
4777
5368
|
]);
|
|
4778
5369
|
const unplacedFields = availableFields.filter((f) => !usedFields.has(f.field));
|
|
4779
|
-
const handleDragStart =
|
|
5370
|
+
const handleDragStart = React4.useCallback(
|
|
4780
5371
|
(field, zone) => {
|
|
4781
5372
|
setDragSource({ field, zone });
|
|
4782
5373
|
},
|
|
4783
5374
|
[]
|
|
4784
5375
|
);
|
|
4785
|
-
const handleDrop =
|
|
5376
|
+
const handleDrop = React4.useCallback(
|
|
4786
5377
|
(targetZone) => {
|
|
4787
5378
|
if (!dragSource) return;
|
|
4788
5379
|
const { field, zone: sourceZone } = dragSource;
|
|
@@ -4825,7 +5416,7 @@ function PivotConfigPanel({
|
|
|
4825
5416
|
onValueFieldsChange
|
|
4826
5417
|
]
|
|
4827
5418
|
);
|
|
4828
|
-
const handleAggregationChange =
|
|
5419
|
+
const handleAggregationChange = React4.useCallback(
|
|
4829
5420
|
(field, aggregation) => {
|
|
4830
5421
|
onValueFieldsChange(
|
|
4831
5422
|
valueFields.map(
|
|
@@ -4835,7 +5426,7 @@ function PivotConfigPanel({
|
|
|
4835
5426
|
},
|
|
4836
5427
|
[valueFields, onValueFieldsChange]
|
|
4837
5428
|
);
|
|
4838
|
-
const handleRemoveField =
|
|
5429
|
+
const handleRemoveField = React4.useCallback(
|
|
4839
5430
|
(field, zone) => {
|
|
4840
5431
|
if (zone === "rows") {
|
|
4841
5432
|
onRowFieldsChange(rowFields.filter((f) => f.field !== field));
|
|
@@ -5025,8 +5616,8 @@ function Tooltip({
|
|
|
5025
5616
|
content,
|
|
5026
5617
|
customComponent
|
|
5027
5618
|
}) {
|
|
5028
|
-
const tooltipRef =
|
|
5029
|
-
|
|
5619
|
+
const tooltipRef = React4.useRef(null);
|
|
5620
|
+
React4.useEffect(() => {
|
|
5030
5621
|
if (!visible || !tooltipRef.current) return;
|
|
5031
5622
|
const el = tooltipRef.current;
|
|
5032
5623
|
const rect = el.getBoundingClientRect();
|
|
@@ -5091,16 +5682,16 @@ function Tooltip({
|
|
|
5091
5682
|
}
|
|
5092
5683
|
function useTooltip(options = {}) {
|
|
5093
5684
|
const { delay = 500, placement = "top", enabled = true } = options;
|
|
5094
|
-
const [visible, setVisible] =
|
|
5095
|
-
const [position, setPosition] =
|
|
5685
|
+
const [visible, setVisible] = React4.useState(false);
|
|
5686
|
+
const [position, setPosition] = React4.useState({
|
|
5096
5687
|
x: 0,
|
|
5097
5688
|
y: 0,
|
|
5098
5689
|
placement
|
|
5099
5690
|
});
|
|
5100
|
-
const [content, setContent] =
|
|
5101
|
-
const timerRef =
|
|
5102
|
-
const targetRef =
|
|
5103
|
-
const show =
|
|
5691
|
+
const [content, setContent] = React4.useState("");
|
|
5692
|
+
const timerRef = React4.useRef(void 0);
|
|
5693
|
+
const targetRef = React4.useRef(null);
|
|
5694
|
+
const show = React4.useCallback(
|
|
5104
5695
|
(target, tooltipContent) => {
|
|
5105
5696
|
if (!enabled || !tooltipContent) return;
|
|
5106
5697
|
targetRef.current = target;
|
|
@@ -5147,12 +5738,12 @@ function useTooltip(options = {}) {
|
|
|
5147
5738
|
},
|
|
5148
5739
|
[delay, placement, enabled]
|
|
5149
5740
|
);
|
|
5150
|
-
const hide =
|
|
5741
|
+
const hide = React4.useCallback(() => {
|
|
5151
5742
|
clearTimeout(timerRef.current);
|
|
5152
5743
|
setVisible(false);
|
|
5153
5744
|
targetRef.current = null;
|
|
5154
5745
|
}, []);
|
|
5155
|
-
|
|
5746
|
+
React4.useEffect(() => {
|
|
5156
5747
|
return () => clearTimeout(timerRef.current);
|
|
5157
5748
|
}, []);
|
|
5158
5749
|
return {
|
|
@@ -5374,10 +5965,10 @@ function FlashCell({
|
|
|
5374
5965
|
}
|
|
5375
5966
|
function useCellFlash(table, options = {}) {
|
|
5376
5967
|
const { duration = 700 } = options;
|
|
5377
|
-
const [flashes, setFlashes] =
|
|
5378
|
-
const prevDataRef =
|
|
5379
|
-
const timersRef =
|
|
5380
|
-
const clearFlash =
|
|
5968
|
+
const [flashes, setFlashes] = React4.useState(/* @__PURE__ */ new Map());
|
|
5969
|
+
const prevDataRef = React4.useRef([]);
|
|
5970
|
+
const timersRef = React4.useRef(/* @__PURE__ */ new Map());
|
|
5971
|
+
const clearFlash = React4.useCallback((key) => {
|
|
5381
5972
|
setFlashes((prev) => {
|
|
5382
5973
|
const next = new Map(prev);
|
|
5383
5974
|
next.delete(key);
|
|
@@ -5385,7 +5976,7 @@ function useCellFlash(table, options = {}) {
|
|
|
5385
5976
|
});
|
|
5386
5977
|
timersRef.current.delete(key);
|
|
5387
5978
|
}, []);
|
|
5388
|
-
|
|
5979
|
+
React4.useEffect(() => {
|
|
5389
5980
|
const currentData = table.options.data;
|
|
5390
5981
|
const prevData = prevDataRef.current;
|
|
5391
5982
|
if (prevData.length > 0 && currentData !== prevData) {
|
|
@@ -5414,14 +6005,14 @@ function useCellFlash(table, options = {}) {
|
|
|
5414
6005
|
}
|
|
5415
6006
|
prevDataRef.current = currentData;
|
|
5416
6007
|
}, [table.options.data, table, duration, clearFlash]);
|
|
5417
|
-
|
|
6008
|
+
React4.useEffect(() => {
|
|
5418
6009
|
return () => {
|
|
5419
6010
|
for (const timer of timersRef.current.values()) {
|
|
5420
6011
|
clearTimeout(timer);
|
|
5421
6012
|
}
|
|
5422
6013
|
};
|
|
5423
6014
|
}, []);
|
|
5424
|
-
const getFlash =
|
|
6015
|
+
const getFlash = React4.useCallback(
|
|
5425
6016
|
(rowId, columnId) => {
|
|
5426
6017
|
return flashes.get(`${rowId}:${columnId}`);
|
|
5427
6018
|
},
|
|
@@ -5431,9 +6022,9 @@ function useCellFlash(table, options = {}) {
|
|
|
5431
6022
|
}
|
|
5432
6023
|
function useRowAnimation(_table, options = {}) {
|
|
5433
6024
|
const { enabled = false, duration = 250, easing = "ease" } = options;
|
|
5434
|
-
const prevPositionsRef =
|
|
5435
|
-
const animatingRef =
|
|
5436
|
-
const capturePositions =
|
|
6025
|
+
const prevPositionsRef = React4.useRef(/* @__PURE__ */ new Map());
|
|
6026
|
+
const animatingRef = React4.useRef(false);
|
|
6027
|
+
const capturePositions = React4.useCallback(
|
|
5437
6028
|
(containerEl) => {
|
|
5438
6029
|
if (!enabled || !containerEl) return;
|
|
5439
6030
|
const positions = /* @__PURE__ */ new Map();
|
|
@@ -5451,7 +6042,7 @@ function useRowAnimation(_table, options = {}) {
|
|
|
5451
6042
|
},
|
|
5452
6043
|
[enabled]
|
|
5453
6044
|
);
|
|
5454
|
-
const animateRows =
|
|
6045
|
+
const animateRows = React4.useCallback(
|
|
5455
6046
|
(containerEl) => {
|
|
5456
6047
|
if (!enabled || !containerEl || animatingRef.current) return;
|
|
5457
6048
|
const prevPositions = prevPositionsRef.current;
|
|
@@ -5573,8 +6164,8 @@ function sanitizeCSS(css) {
|
|
|
5573
6164
|
}
|
|
5574
6165
|
function usePrintLayout(_table, options = {}) {
|
|
5575
6166
|
const { title, additionalCSS } = options;
|
|
5576
|
-
const isPrintingRef =
|
|
5577
|
-
const preparePrint =
|
|
6167
|
+
const isPrintingRef = React4.useRef(false);
|
|
6168
|
+
const preparePrint = React4.useCallback(() => {
|
|
5578
6169
|
const yableEl = document.querySelector(".yable");
|
|
5579
6170
|
if (yableEl) {
|
|
5580
6171
|
yableEl.classList.add("yable-print-mode");
|
|
@@ -5616,23 +6207,23 @@ function usePrintLayout(_table, options = {}) {
|
|
|
5616
6207
|
}
|
|
5617
6208
|
function useTheme(options = {}) {
|
|
5618
6209
|
const { defaultTheme = "default", defaultColorScheme = "auto" } = options;
|
|
5619
|
-
const [theme, setThemeState] =
|
|
5620
|
-
const [colorScheme, setColorSchemeState] =
|
|
5621
|
-
const containerRef =
|
|
5622
|
-
const setTheme =
|
|
6210
|
+
const [theme, setThemeState] = React4.useState(defaultTheme);
|
|
6211
|
+
const [colorScheme, setColorSchemeState] = React4.useState(defaultColorScheme);
|
|
6212
|
+
const containerRef = React4.useRef(null);
|
|
6213
|
+
const setTheme = React4.useCallback((newTheme) => {
|
|
5623
6214
|
setThemeState(newTheme);
|
|
5624
6215
|
}, []);
|
|
5625
|
-
const setColorScheme =
|
|
6216
|
+
const setColorScheme = React4.useCallback((scheme) => {
|
|
5626
6217
|
setColorSchemeState(scheme);
|
|
5627
6218
|
}, []);
|
|
5628
|
-
const toggleColorScheme =
|
|
6219
|
+
const toggleColorScheme = React4.useCallback(() => {
|
|
5629
6220
|
setColorSchemeState((prev) => {
|
|
5630
6221
|
if (prev === "auto") return "dark";
|
|
5631
6222
|
if (prev === "dark") return "light";
|
|
5632
6223
|
return "auto";
|
|
5633
6224
|
});
|
|
5634
6225
|
}, []);
|
|
5635
|
-
|
|
6226
|
+
React4.useEffect(() => {
|
|
5636
6227
|
const target = containerRef.current ?? document.documentElement;
|
|
5637
6228
|
if (colorScheme === "auto") {
|
|
5638
6229
|
target.removeAttribute("data-yable-theme");
|
|
@@ -5640,8 +6231,8 @@ function useTheme(options = {}) {
|
|
|
5640
6231
|
target.setAttribute("data-yable-theme", colorScheme);
|
|
5641
6232
|
}
|
|
5642
6233
|
}, [colorScheme]);
|
|
5643
|
-
const [systemDark, setSystemDark] =
|
|
5644
|
-
|
|
6234
|
+
const [systemDark, setSystemDark] = React4.useState(false);
|
|
6235
|
+
React4.useEffect(() => {
|
|
5645
6236
|
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
5646
6237
|
setSystemDark(mq.matches);
|
|
5647
6238
|
const handler = (e) => setSystemDark(e.matches);
|
|
@@ -5663,10 +6254,11 @@ function selectColumn(options = {}) {
|
|
|
5663
6254
|
const { id = "_select", size = 40, headerAriaLabel = "Select all rows" } = options;
|
|
5664
6255
|
return {
|
|
5665
6256
|
id,
|
|
5666
|
-
header: ({ table }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6257
|
+
header: ({ table }) => /* @__PURE__ */ jsxRuntime.jsx("label", { className: "yable-checkbox-hitbox", onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5667
6258
|
"input",
|
|
5668
6259
|
{
|
|
5669
6260
|
type: "checkbox",
|
|
6261
|
+
className: "yable-checkbox",
|
|
5670
6262
|
checked: table.getIsAllPageRowsSelected(),
|
|
5671
6263
|
ref: (el) => {
|
|
5672
6264
|
if (el)
|
|
@@ -5675,19 +6267,21 @@ function selectColumn(options = {}) {
|
|
|
5675
6267
|
onChange: () => table.toggleAllPageRowsSelected(),
|
|
5676
6268
|
"aria-label": headerAriaLabel
|
|
5677
6269
|
}
|
|
5678
|
-
),
|
|
5679
|
-
cell: ({ row }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6270
|
+
) }),
|
|
6271
|
+
cell: ({ row }) => /* @__PURE__ */ jsxRuntime.jsx("label", { className: "yable-checkbox-hitbox", onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5680
6272
|
"input",
|
|
5681
6273
|
{
|
|
5682
6274
|
type: "checkbox",
|
|
6275
|
+
className: "yable-checkbox",
|
|
5683
6276
|
checked: row.getIsSelected(),
|
|
5684
6277
|
disabled: !row.getCanSelect(),
|
|
5685
6278
|
onChange: row.getToggleSelectedHandler(),
|
|
5686
|
-
"aria-label":
|
|
6279
|
+
"aria-label": "Select row"
|
|
5687
6280
|
}
|
|
5688
|
-
),
|
|
6281
|
+
) }),
|
|
5689
6282
|
size,
|
|
5690
|
-
enableSorting:
|
|
6283
|
+
enableSorting: true,
|
|
6284
|
+
sortingFn: (rowA, rowB) => Number(rowA.getIsSelected()) - Number(rowB.getIsSelected()),
|
|
5691
6285
|
enableColumnFilter: false,
|
|
5692
6286
|
enableResizing: false,
|
|
5693
6287
|
enableReorder: false,
|
|
@@ -6020,11 +6614,15 @@ exports.Tooltip = Tooltip;
|
|
|
6020
6614
|
exports.TreeToggle = TreeToggle;
|
|
6021
6615
|
exports.YableProvider = YableProvider;
|
|
6022
6616
|
exports.actionsColumn = actionsColumn;
|
|
6617
|
+
exports.applyYableConfigToColumns = applyYableConfigToColumns;
|
|
6618
|
+
exports.createYableConfig = createYableConfig;
|
|
6023
6619
|
exports.expandColumn = expandColumn;
|
|
6024
6620
|
exports.getMeasureRecipeForCellType = getMeasureRecipeForCellType;
|
|
6025
6621
|
exports.getRegisteredCellTypes = getRegisteredCellTypes;
|
|
6622
|
+
exports.getYableDefaultColumnDef = getYableDefaultColumnDef;
|
|
6026
6623
|
exports.mergeEditChanges = mergeEditChanges;
|
|
6027
6624
|
exports.resolveMeasureRecipe = resolveMeasureRecipe;
|
|
6625
|
+
exports.resolveYableProfile = resolveYableProfile;
|
|
6028
6626
|
exports.rowNumberColumn = rowNumberColumn;
|
|
6029
6627
|
exports.selectColumn = selectColumn;
|
|
6030
6628
|
exports.useAutoMeasurements = useAutoMeasurements;
|
|
@@ -6038,6 +6636,7 @@ exports.usePretextMeasurement = usePretextMeasurement;
|
|
|
6038
6636
|
exports.usePrintLayout = usePrintLayout;
|
|
6039
6637
|
exports.useRowAnimation = useRowAnimation;
|
|
6040
6638
|
exports.useRowDrag = useRowDrag;
|
|
6639
|
+
exports.useServerTable = useServerTable;
|
|
6041
6640
|
exports.useTable = useTable;
|
|
6042
6641
|
exports.useTableContext = useTableContext;
|
|
6043
6642
|
exports.useTablePersistence = useTablePersistence;
|