@zvndev/yable-react 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +796 -175
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +81 -13
- package/dist/index.d.ts +81 -13
- package/dist/index.js +760 -178
- package/dist/index.js.map +1 -1
- package/package.json +14 -5
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { canCellEnterEditMode, functionalUpdate, createTable, getFirstKeyboardCell, getResolvedFocusedCell, detectCellChanges } from '@zvndev/yable-core';
|
|
2
|
-
export { CommitError, aggregationFns, createColumnHelper, createLocale, en, filterFns, functionalUpdate, getDefaultLocale, resetLocale, setDefaultLocale, sortingFns } from '@zvndev/yable-core';
|
|
1
|
+
import { canCellEnterEditMode, functionalUpdate, createTable, getDefaultLocale, getFirstKeyboardCell, getResolvedFocusedCell, detectCellChanges } from '@zvndev/yable-core';
|
|
2
|
+
export { CommitError, FormulaEngine, FormulaError, PivotEngine, UndoStack, aggregationFns, createColumnHelper, createLocale, createUndoRedoIntegration, en, filterFns, formulaFunctions, functionalUpdate, generatePivotColumnDefs, getDefaultLocale, getInitialPivotState, getPivotRowModel, resetLocale, setDefaultLocale, sortingFns } from '@zvndev/yable-core';
|
|
3
3
|
import React3, { createContext, useCallback, useMemo, useState, useRef, useEffect, useContext } from 'react';
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
import { getInitialRowDragState, moveRow } from '@zvndev/yable-core/features/rowDragging';
|
|
@@ -64,6 +64,8 @@ function useTable(options) {
|
|
|
64
64
|
prevOptionsRef.current = options;
|
|
65
65
|
return options;
|
|
66
66
|
}, [options]);
|
|
67
|
+
const onStateChangeRef = useRef(options.onStateChange);
|
|
68
|
+
onStateChangeRef.current = options.onStateChange;
|
|
67
69
|
const resolvedState = useMemo(
|
|
68
70
|
() => ({
|
|
69
71
|
...state,
|
|
@@ -73,13 +75,14 @@ function useTable(options) {
|
|
|
73
75
|
);
|
|
74
76
|
const onStateChange = useCallback(
|
|
75
77
|
(updater) => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
const latest = onStateChangeRef.current;
|
|
79
|
+
if (latest) {
|
|
80
|
+
latest(updater);
|
|
78
81
|
} else {
|
|
79
82
|
setState((prev) => functionalUpdate(updater, prev));
|
|
80
83
|
}
|
|
81
84
|
},
|
|
82
|
-
[
|
|
85
|
+
[]
|
|
83
86
|
);
|
|
84
87
|
const resolvedOptions = useMemo(
|
|
85
88
|
() => ({
|
|
@@ -207,7 +210,15 @@ function useVirtualization({
|
|
|
207
210
|
container.scrollTop = offset;
|
|
208
211
|
}
|
|
209
212
|
},
|
|
210
|
-
[
|
|
213
|
+
[
|
|
214
|
+
containerRef,
|
|
215
|
+
totalRows,
|
|
216
|
+
rowHeight,
|
|
217
|
+
isFixedHeight,
|
|
218
|
+
getRowHeight,
|
|
219
|
+
hasPretextHeights,
|
|
220
|
+
pretextPrefixSums
|
|
221
|
+
]
|
|
211
222
|
);
|
|
212
223
|
const totalHeight = useMemo(() => {
|
|
213
224
|
if (totalRows === 0) return 0;
|
|
@@ -261,10 +272,7 @@ function useVirtualization({
|
|
|
261
272
|
} else if (isFixedHeight) {
|
|
262
273
|
const fixedH = rowHeight;
|
|
263
274
|
startIndex = Math.floor(scrollTop / fixedH);
|
|
264
|
-
endIndex = Math.min(
|
|
265
|
-
totalRows - 1,
|
|
266
|
-
Math.ceil((scrollTop + containerHeight) / fixedH) - 1
|
|
267
|
-
);
|
|
275
|
+
endIndex = Math.min(totalRows - 1, Math.ceil((scrollTop + containerHeight) / fixedH) - 1);
|
|
268
276
|
} else {
|
|
269
277
|
let accum = 0;
|
|
270
278
|
let foundStart = false;
|
|
@@ -331,6 +339,162 @@ function useVirtualization({
|
|
|
331
339
|
scrollTo
|
|
332
340
|
};
|
|
333
341
|
}
|
|
342
|
+
function binarySearchOffsets(offsets, target) {
|
|
343
|
+
let low = 0;
|
|
344
|
+
let high = offsets.length - 1;
|
|
345
|
+
while (low < high) {
|
|
346
|
+
const mid = low + high >>> 1;
|
|
347
|
+
if (offsets[mid + 1] <= target) {
|
|
348
|
+
low = mid + 1;
|
|
349
|
+
} else {
|
|
350
|
+
high = mid;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return low;
|
|
354
|
+
}
|
|
355
|
+
function useColumnVirtualization({
|
|
356
|
+
containerRef,
|
|
357
|
+
columns,
|
|
358
|
+
overscan = 2,
|
|
359
|
+
enabled = true
|
|
360
|
+
}) {
|
|
361
|
+
const [scrollState, setScrollState] = useState({
|
|
362
|
+
scrollLeft: 0,
|
|
363
|
+
containerWidth: 0
|
|
364
|
+
});
|
|
365
|
+
const rafRef = useRef(null);
|
|
366
|
+
const sizes = useMemo(() => columns.map((column) => column.getSize()), [columns]);
|
|
367
|
+
const offsets = useMemo(() => {
|
|
368
|
+
const next = new Array(columns.length + 1);
|
|
369
|
+
next[0] = 0;
|
|
370
|
+
for (let i = 0; i < columns.length; i++) {
|
|
371
|
+
next[i + 1] = next[i] + (sizes[i] ?? 0);
|
|
372
|
+
}
|
|
373
|
+
return next;
|
|
374
|
+
}, [columns.length, sizes]);
|
|
375
|
+
const totalWidth = offsets[offsets.length - 1] ?? 0;
|
|
376
|
+
useEffect(() => {
|
|
377
|
+
const container = containerRef.current;
|
|
378
|
+
if (!container) return;
|
|
379
|
+
setScrollState({
|
|
380
|
+
scrollLeft: container.scrollLeft,
|
|
381
|
+
containerWidth: container.clientWidth
|
|
382
|
+
});
|
|
383
|
+
const handleScroll = () => {
|
|
384
|
+
if (rafRef.current !== null) return;
|
|
385
|
+
rafRef.current = requestAnimationFrame(() => {
|
|
386
|
+
rafRef.current = null;
|
|
387
|
+
const el = containerRef.current;
|
|
388
|
+
if (!el) return;
|
|
389
|
+
setScrollState({
|
|
390
|
+
scrollLeft: el.scrollLeft,
|
|
391
|
+
containerWidth: el.clientWidth
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
};
|
|
395
|
+
container.addEventListener("scroll", handleScroll, { passive: true });
|
|
396
|
+
let resizeObserver;
|
|
397
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
398
|
+
resizeObserver = new ResizeObserver(() => {
|
|
399
|
+
const el = containerRef.current;
|
|
400
|
+
if (!el) return;
|
|
401
|
+
setScrollState((prev) => {
|
|
402
|
+
const nextWidth = el.clientWidth;
|
|
403
|
+
if (prev.containerWidth === nextWidth && prev.scrollLeft === el.scrollLeft) {
|
|
404
|
+
return prev;
|
|
405
|
+
}
|
|
406
|
+
return {
|
|
407
|
+
scrollLeft: el.scrollLeft,
|
|
408
|
+
containerWidth: nextWidth
|
|
409
|
+
};
|
|
410
|
+
});
|
|
411
|
+
});
|
|
412
|
+
resizeObserver.observe(container);
|
|
413
|
+
}
|
|
414
|
+
return () => {
|
|
415
|
+
container.removeEventListener("scroll", handleScroll);
|
|
416
|
+
if (rafRef.current !== null) {
|
|
417
|
+
cancelAnimationFrame(rafRef.current);
|
|
418
|
+
rafRef.current = null;
|
|
419
|
+
}
|
|
420
|
+
resizeObserver?.disconnect();
|
|
421
|
+
};
|
|
422
|
+
}, [containerRef]);
|
|
423
|
+
const scrollToIndex = useCallback(
|
|
424
|
+
(index) => {
|
|
425
|
+
const container = containerRef.current;
|
|
426
|
+
if (!container || columns.length === 0) return;
|
|
427
|
+
const clampedIndex = Math.max(0, Math.min(index, columns.length - 1));
|
|
428
|
+
container.scrollLeft = offsets[clampedIndex] ?? 0;
|
|
429
|
+
},
|
|
430
|
+
[columns.length, containerRef, offsets]
|
|
431
|
+
);
|
|
432
|
+
if (!enabled || columns.length === 0) {
|
|
433
|
+
return {
|
|
434
|
+
virtualColumns: columns.map((column, index) => ({
|
|
435
|
+
column,
|
|
436
|
+
index,
|
|
437
|
+
start: offsets[index] ?? 0,
|
|
438
|
+
size: sizes[index] ?? 0
|
|
439
|
+
})),
|
|
440
|
+
startOffset: 0,
|
|
441
|
+
endOffset: 0,
|
|
442
|
+
totalWidth,
|
|
443
|
+
visibleWidth: totalWidth,
|
|
444
|
+
startIndex: 0,
|
|
445
|
+
endIndex: Math.max(columns.length - 1, 0),
|
|
446
|
+
isVirtualized: false,
|
|
447
|
+
scrollToIndex
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
const { scrollLeft, containerWidth } = scrollState;
|
|
451
|
+
if (containerWidth <= 0 || totalWidth <= containerWidth) {
|
|
452
|
+
return {
|
|
453
|
+
virtualColumns: columns.map((column, index) => ({
|
|
454
|
+
column,
|
|
455
|
+
index,
|
|
456
|
+
start: offsets[index] ?? 0,
|
|
457
|
+
size: sizes[index] ?? 0
|
|
458
|
+
})),
|
|
459
|
+
startOffset: 0,
|
|
460
|
+
endOffset: 0,
|
|
461
|
+
totalWidth,
|
|
462
|
+
visibleWidth: totalWidth,
|
|
463
|
+
startIndex: 0,
|
|
464
|
+
endIndex: Math.max(columns.length - 1, 0),
|
|
465
|
+
isVirtualized: false,
|
|
466
|
+
scrollToIndex
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
const startIndex = binarySearchOffsets(offsets, scrollLeft);
|
|
470
|
+
const endBoundary = scrollLeft + containerWidth;
|
|
471
|
+
const endIndex = binarySearchOffsets(offsets, Math.max(scrollLeft, endBoundary - 1));
|
|
472
|
+
const overscanStart = Math.max(0, startIndex - overscan);
|
|
473
|
+
const overscanEnd = Math.min(columns.length - 1, endIndex + overscan);
|
|
474
|
+
const virtualColumns = [];
|
|
475
|
+
for (let i = overscanStart; i <= overscanEnd; i++) {
|
|
476
|
+
virtualColumns.push({
|
|
477
|
+
column: columns[i],
|
|
478
|
+
index: i,
|
|
479
|
+
start: offsets[i] ?? 0,
|
|
480
|
+
size: sizes[i] ?? 0
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
const startOffset = offsets[overscanStart] ?? 0;
|
|
484
|
+
const visibleWidth = (offsets[overscanEnd + 1] ?? totalWidth) - startOffset;
|
|
485
|
+
const endOffset = totalWidth - (offsets[overscanEnd + 1] ?? totalWidth);
|
|
486
|
+
return {
|
|
487
|
+
virtualColumns,
|
|
488
|
+
startOffset,
|
|
489
|
+
endOffset,
|
|
490
|
+
totalWidth,
|
|
491
|
+
visibleWidth,
|
|
492
|
+
startIndex: overscanStart,
|
|
493
|
+
endIndex: overscanEnd,
|
|
494
|
+
isVirtualized: true,
|
|
495
|
+
scrollToIndex
|
|
496
|
+
};
|
|
497
|
+
}
|
|
334
498
|
var pretextPromise = null;
|
|
335
499
|
function loadPretext() {
|
|
336
500
|
if (pretextPromise) return pretextPromise;
|
|
@@ -381,7 +545,12 @@ function usePretextMeasurement({
|
|
|
381
545
|
}
|
|
382
546
|
prepareTimeRef.current = performance.now() - start;
|
|
383
547
|
return result;
|
|
384
|
-
}, [
|
|
548
|
+
}, [
|
|
549
|
+
pretext,
|
|
550
|
+
enabled,
|
|
551
|
+
data,
|
|
552
|
+
columns.map((c) => `${c.columnId}:${c.font}:${c.fixedHeight ? "F" : "T"}`).join("|")
|
|
553
|
+
]);
|
|
385
554
|
const measurement = useMemo(() => {
|
|
386
555
|
if (!pretext || !preparedCells) {
|
|
387
556
|
return { rowHeights: null, prefixSums: null, totalHeight: 0 };
|
|
@@ -419,6 +588,7 @@ function usePretextMeasurement({
|
|
|
419
588
|
return {
|
|
420
589
|
rowHeights,
|
|
421
590
|
prefixSums,
|
|
591
|
+
// Safe: prefixSums has length data.length + 1, so [data.length] always exists
|
|
422
592
|
totalHeight: prefixSums[data.length]
|
|
423
593
|
};
|
|
424
594
|
}, [pretext, preparedCells, columnWidthsKey, minRowHeight, data.length]);
|
|
@@ -683,18 +853,10 @@ function CellDate({
|
|
|
683
853
|
if (raw == null) return null;
|
|
684
854
|
const date = raw instanceof Date ? raw : new Date(String(raw));
|
|
685
855
|
if (isNaN(date.getTime())) return /* @__PURE__ */ jsx("span", { className: "yable-cell-date", children: String(raw) });
|
|
686
|
-
const formatter =
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
timeZone: "UTC"
|
|
691
|
-
});
|
|
692
|
-
}
|
|
693
|
-
if (typeof format === "object") {
|
|
694
|
-
return new Intl.DateTimeFormat(locale, { ...format, timeZone: "UTC" });
|
|
695
|
-
}
|
|
696
|
-
return null;
|
|
697
|
-
}, [format, locale]);
|
|
856
|
+
const formatter = typeof format === "string" && format !== "relative" ? new Intl.DateTimeFormat(locale, {
|
|
857
|
+
...PRESETS[format],
|
|
858
|
+
timeZone: "UTC"
|
|
859
|
+
}) : typeof format === "object" ? new Intl.DateTimeFormat(locale, { ...format, timeZone: "UTC" }) : null;
|
|
698
860
|
const formatted = format === "relative" ? formatRelative(date) : formatter ? formatter.format(date) : date.toLocaleDateString(locale);
|
|
699
861
|
return /* @__PURE__ */ jsx("span", { className: `yable-cell-date ${className ?? ""}`, title: date.toISOString(), children: formatted });
|
|
700
862
|
}
|
|
@@ -705,8 +867,14 @@ var measureRecipe9 = {
|
|
|
705
867
|
padding: 20
|
|
706
868
|
};
|
|
707
869
|
function isSafeUrl(url) {
|
|
708
|
-
const normalized = String(url).
|
|
709
|
-
|
|
870
|
+
const normalized = String(url).trim();
|
|
871
|
+
if (/^[/#?]/.test(normalized)) return true;
|
|
872
|
+
try {
|
|
873
|
+
const parsed = new URL(normalized, "https://placeholder.invalid");
|
|
874
|
+
return ["http:", "https:", "mailto:", "tel:"].includes(parsed.protocol);
|
|
875
|
+
} catch {
|
|
876
|
+
return false;
|
|
877
|
+
}
|
|
710
878
|
}
|
|
711
879
|
function CellLink({
|
|
712
880
|
context,
|
|
@@ -883,7 +1051,7 @@ function useTableContext() {
|
|
|
883
1051
|
const ctx = useContext(TableContext);
|
|
884
1052
|
if (!ctx) {
|
|
885
1053
|
throw new Error(
|
|
886
|
-
"[yable] useTableContext must be used within a <Table> component. Did you forget to pass the `table` prop?"
|
|
1054
|
+
"[yable E001] useTableContext must be used within a <Table> component. Did you forget to pass the `table` prop?"
|
|
887
1055
|
);
|
|
888
1056
|
}
|
|
889
1057
|
return ctx;
|
|
@@ -933,12 +1101,234 @@ function SortIndicator({ direction, index }) {
|
|
|
933
1101
|
}
|
|
934
1102
|
);
|
|
935
1103
|
}
|
|
1104
|
+
function formatValue(value) {
|
|
1105
|
+
if (value == null || value === "") return "(empty)";
|
|
1106
|
+
if (typeof value === "string") return value;
|
|
1107
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
1108
|
+
if (value instanceof Date) return value.toISOString();
|
|
1109
|
+
return JSON.stringify(value);
|
|
1110
|
+
}
|
|
1111
|
+
function SetFilter({ column, className }) {
|
|
1112
|
+
const [open, setOpen] = useState(false);
|
|
1113
|
+
const filterValue = column.getFilterValue();
|
|
1114
|
+
const selectedValues = Array.isArray(filterValue) ? filterValue : filterValue == null || filterValue === "" ? [] : [filterValue];
|
|
1115
|
+
const facetedUniqueValues = column.getFacetedUniqueValues();
|
|
1116
|
+
const options = Array.from(facetedUniqueValues.entries()).map(([value, count]) => ({
|
|
1117
|
+
value,
|
|
1118
|
+
count,
|
|
1119
|
+
label: formatValue(value)
|
|
1120
|
+
})).sort((a, b) => a.label.localeCompare(b.label));
|
|
1121
|
+
const selectedSet = new Set(selectedValues);
|
|
1122
|
+
const toggleValue = (value) => {
|
|
1123
|
+
const next = new Set(selectedSet);
|
|
1124
|
+
if (next.has(value)) {
|
|
1125
|
+
next.delete(value);
|
|
1126
|
+
} else {
|
|
1127
|
+
next.add(value);
|
|
1128
|
+
}
|
|
1129
|
+
const nextValues = Array.from(next);
|
|
1130
|
+
column.setFilterValue(nextValues.length > 0 ? nextValues : void 0);
|
|
1131
|
+
};
|
|
1132
|
+
const headerLabel = typeof column.columnDef.header === "string" ? column.columnDef.header : column.id;
|
|
1133
|
+
return /* @__PURE__ */ jsxs(
|
|
1134
|
+
"div",
|
|
1135
|
+
{
|
|
1136
|
+
className: ["yable-set-filter", className].filter(Boolean).join(" "),
|
|
1137
|
+
style: { position: "relative" },
|
|
1138
|
+
children: [
|
|
1139
|
+
/* @__PURE__ */ jsx(
|
|
1140
|
+
"button",
|
|
1141
|
+
{
|
|
1142
|
+
type: "button",
|
|
1143
|
+
className: "yable-set-filter-trigger",
|
|
1144
|
+
"aria-haspopup": "dialog",
|
|
1145
|
+
"aria-expanded": open,
|
|
1146
|
+
onClick: () => setOpen((prev) => !prev),
|
|
1147
|
+
style: {
|
|
1148
|
+
width: "100%",
|
|
1149
|
+
minHeight: 28,
|
|
1150
|
+
padding: "4px 8px",
|
|
1151
|
+
border: "1px solid rgba(127, 127, 127, 0.35)",
|
|
1152
|
+
borderRadius: 6,
|
|
1153
|
+
background: "transparent",
|
|
1154
|
+
font: "inherit",
|
|
1155
|
+
textAlign: "left",
|
|
1156
|
+
cursor: "pointer"
|
|
1157
|
+
},
|
|
1158
|
+
children: selectedValues.length > 0 ? `${selectedValues.length} selected` : `Filter ${headerLabel}`
|
|
1159
|
+
}
|
|
1160
|
+
),
|
|
1161
|
+
open && /* @__PURE__ */ jsxs(
|
|
1162
|
+
"div",
|
|
1163
|
+
{
|
|
1164
|
+
role: "dialog",
|
|
1165
|
+
"aria-label": `${headerLabel} set filter`,
|
|
1166
|
+
className: "yable-set-filter-popover",
|
|
1167
|
+
style: {
|
|
1168
|
+
position: "absolute",
|
|
1169
|
+
insetInlineStart: 0,
|
|
1170
|
+
top: "calc(100% + 4px)",
|
|
1171
|
+
zIndex: 20,
|
|
1172
|
+
width: 220,
|
|
1173
|
+
maxHeight: 240,
|
|
1174
|
+
overflow: "auto",
|
|
1175
|
+
padding: 8,
|
|
1176
|
+
border: "1px solid rgba(127, 127, 127, 0.35)",
|
|
1177
|
+
borderRadius: 8,
|
|
1178
|
+
background: "var(--yable-color-bg, #fff)",
|
|
1179
|
+
boxShadow: "0 10px 30px rgba(0, 0, 0, 0.12)"
|
|
1180
|
+
},
|
|
1181
|
+
children: [
|
|
1182
|
+
/* @__PURE__ */ jsxs(
|
|
1183
|
+
"div",
|
|
1184
|
+
{
|
|
1185
|
+
style: {
|
|
1186
|
+
display: "flex",
|
|
1187
|
+
alignItems: "center",
|
|
1188
|
+
justifyContent: "space-between",
|
|
1189
|
+
gap: 8,
|
|
1190
|
+
marginBottom: 8
|
|
1191
|
+
},
|
|
1192
|
+
children: [
|
|
1193
|
+
/* @__PURE__ */ jsx("strong", { style: { fontSize: 12 }, children: headerLabel }),
|
|
1194
|
+
selectedValues.length > 0 && /* @__PURE__ */ jsx(
|
|
1195
|
+
"button",
|
|
1196
|
+
{
|
|
1197
|
+
type: "button",
|
|
1198
|
+
onClick: () => column.setFilterValue(void 0),
|
|
1199
|
+
style: {
|
|
1200
|
+
border: "none",
|
|
1201
|
+
background: "transparent",
|
|
1202
|
+
padding: 0,
|
|
1203
|
+
cursor: "pointer",
|
|
1204
|
+
fontSize: 12
|
|
1205
|
+
},
|
|
1206
|
+
children: "Clear"
|
|
1207
|
+
}
|
|
1208
|
+
)
|
|
1209
|
+
]
|
|
1210
|
+
}
|
|
1211
|
+
),
|
|
1212
|
+
/* @__PURE__ */ jsxs("div", { role: "group", "aria-label": `${headerLabel} options`, children: [
|
|
1213
|
+
options.length === 0 && /* @__PURE__ */ jsx("div", { style: { fontSize: 12, opacity: 0.75 }, children: "No values" }),
|
|
1214
|
+
options.map((option) => {
|
|
1215
|
+
const checked = selectedSet.has(option.value);
|
|
1216
|
+
return /* @__PURE__ */ jsxs(
|
|
1217
|
+
"label",
|
|
1218
|
+
{
|
|
1219
|
+
style: {
|
|
1220
|
+
display: "flex",
|
|
1221
|
+
alignItems: "center",
|
|
1222
|
+
gap: 8,
|
|
1223
|
+
padding: "4px 0",
|
|
1224
|
+
fontSize: 12
|
|
1225
|
+
},
|
|
1226
|
+
children: [
|
|
1227
|
+
/* @__PURE__ */ jsx(
|
|
1228
|
+
"input",
|
|
1229
|
+
{
|
|
1230
|
+
type: "checkbox",
|
|
1231
|
+
checked,
|
|
1232
|
+
onChange: () => toggleValue(option.value)
|
|
1233
|
+
}
|
|
1234
|
+
),
|
|
1235
|
+
/* @__PURE__ */ jsx("span", { style: { flex: 1 }, children: option.label }),
|
|
1236
|
+
/* @__PURE__ */ jsx("span", { style: { opacity: 0.6 }, children: option.count })
|
|
1237
|
+
]
|
|
1238
|
+
},
|
|
1239
|
+
`${option.label}-${option.count}`
|
|
1240
|
+
);
|
|
1241
|
+
})
|
|
1242
|
+
] })
|
|
1243
|
+
]
|
|
1244
|
+
}
|
|
1245
|
+
)
|
|
1246
|
+
]
|
|
1247
|
+
}
|
|
1248
|
+
);
|
|
1249
|
+
}
|
|
1250
|
+
function isSetCompatibleValue(value) {
|
|
1251
|
+
return value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
1252
|
+
}
|
|
1253
|
+
function inferFilterVariant(column) {
|
|
1254
|
+
const meta = column.columnDef.meta ?? {};
|
|
1255
|
+
if (meta.filterVariant) return meta.filterVariant;
|
|
1256
|
+
const uniqueValues = column.getFacetedUniqueValues();
|
|
1257
|
+
if (uniqueValues.size > 0 && uniqueValues.size <= 12) {
|
|
1258
|
+
const allValuesSupported = Array.from(uniqueValues.keys()).every(isSetCompatibleValue);
|
|
1259
|
+
if (allValuesSupported) return "set";
|
|
1260
|
+
}
|
|
1261
|
+
return "text";
|
|
1262
|
+
}
|
|
1263
|
+
function FloatingFilter({ column }) {
|
|
1264
|
+
const variant = inferFilterVariant(column);
|
|
1265
|
+
if (!column.getCanFilter()) {
|
|
1266
|
+
return /* @__PURE__ */ jsx("div", { style: { minHeight: 28 }, "aria-hidden": "true" });
|
|
1267
|
+
}
|
|
1268
|
+
if (variant === "set") {
|
|
1269
|
+
return /* @__PURE__ */ jsx(SetFilter, { column });
|
|
1270
|
+
}
|
|
1271
|
+
const filterValue = column.getFilterValue();
|
|
1272
|
+
const normalizedValue = typeof filterValue === "string" || typeof filterValue === "number" ? String(filterValue) : "";
|
|
1273
|
+
const label = typeof column.columnDef.header === "string" ? column.columnDef.header : column.id;
|
|
1274
|
+
return /* @__PURE__ */ jsx("label", { style: { display: "block" }, children: /* @__PURE__ */ jsx(
|
|
1275
|
+
"input",
|
|
1276
|
+
{
|
|
1277
|
+
"aria-label": `Filter ${label}`,
|
|
1278
|
+
className: "yable-floating-filter-input",
|
|
1279
|
+
value: normalizedValue,
|
|
1280
|
+
onChange: (event) => {
|
|
1281
|
+
const nextValue = event.target.value;
|
|
1282
|
+
column.setFilterValue(nextValue === "" ? void 0 : nextValue);
|
|
1283
|
+
},
|
|
1284
|
+
placeholder: `Filter ${label}`,
|
|
1285
|
+
style: {
|
|
1286
|
+
width: "100%",
|
|
1287
|
+
minHeight: 28,
|
|
1288
|
+
padding: "4px 8px",
|
|
1289
|
+
border: "1px solid rgba(127, 127, 127, 0.35)",
|
|
1290
|
+
borderRadius: 6,
|
|
1291
|
+
background: "transparent",
|
|
1292
|
+
font: "inherit"
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
) });
|
|
1296
|
+
}
|
|
936
1297
|
var DRAG_MIME = "application/yable-column";
|
|
937
1298
|
function TableHeader({
|
|
938
|
-
table
|
|
1299
|
+
table,
|
|
1300
|
+
floatingFilters = false
|
|
939
1301
|
}) {
|
|
940
1302
|
const headerGroups = table.getHeaderGroups();
|
|
941
|
-
|
|
1303
|
+
const visibleColumns = table.getVisibleLeafColumns();
|
|
1304
|
+
return /* @__PURE__ */ jsxs("thead", { className: "yable-thead", children: [
|
|
1305
|
+
headerGroups.map((headerGroup) => /* @__PURE__ */ jsx("tr", { className: "yable-header-row", children: headerGroup.headers.map((header) => /* @__PURE__ */ jsx(HeaderCell, { header, table }, header.id)) }, headerGroup.id)),
|
|
1306
|
+
floatingFilters && visibleColumns.length > 0 && /* @__PURE__ */ jsx("tr", { className: "yable-header-row yable-header-row--filters", children: visibleColumns.map((column) => /* @__PURE__ */ jsx(FloatingFilterCell, { column }, `${column.id}-filter`)) })
|
|
1307
|
+
] });
|
|
1308
|
+
}
|
|
1309
|
+
function FloatingFilterCell({
|
|
1310
|
+
column
|
|
1311
|
+
}) {
|
|
1312
|
+
const style = useMemo(() => {
|
|
1313
|
+
const next = {
|
|
1314
|
+
width: column.getSize(),
|
|
1315
|
+
minWidth: column.columnDef.minSize,
|
|
1316
|
+
maxWidth: column.columnDef.maxSize,
|
|
1317
|
+
padding: 6,
|
|
1318
|
+
verticalAlign: "top"
|
|
1319
|
+
};
|
|
1320
|
+
const pinned = column.getIsPinned();
|
|
1321
|
+
if (pinned) {
|
|
1322
|
+
next.position = "sticky";
|
|
1323
|
+
if (pinned === "left") {
|
|
1324
|
+
next.left = column.getStart("left");
|
|
1325
|
+
} else {
|
|
1326
|
+
next.right = column.getStart("right");
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
return next;
|
|
1330
|
+
}, [column]);
|
|
1331
|
+
return /* @__PURE__ */ jsx("th", { className: "yable-th yable-th--filter", role: "columnheader", style, children: /* @__PURE__ */ jsx(FloatingFilter, { column }) });
|
|
942
1332
|
}
|
|
943
1333
|
function HeaderCell({
|
|
944
1334
|
header,
|
|
@@ -1027,14 +1417,11 @@ function HeaderCell({
|
|
|
1027
1417
|
},
|
|
1028
1418
|
[canReorder]
|
|
1029
1419
|
);
|
|
1030
|
-
const handleDragLeave = useCallback(
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
},
|
|
1036
|
-
[]
|
|
1037
|
-
);
|
|
1420
|
+
const handleDragLeave = useCallback((e) => {
|
|
1421
|
+
const next = e.relatedTarget;
|
|
1422
|
+
if (next && e.currentTarget.contains(next)) return;
|
|
1423
|
+
setDragOver(null);
|
|
1424
|
+
}, []);
|
|
1038
1425
|
const handleDragEnd = useCallback(() => {
|
|
1039
1426
|
setDragOver(null);
|
|
1040
1427
|
}, []);
|
|
@@ -1107,13 +1494,7 @@ function HeaderCell({
|
|
|
1107
1494
|
children: [
|
|
1108
1495
|
/* @__PURE__ */ jsxs("div", { className: "yable-th-content", children: [
|
|
1109
1496
|
/* @__PURE__ */ jsx("span", { children: headerContent }),
|
|
1110
|
-
canSort && /* @__PURE__ */ jsx(
|
|
1111
|
-
SortIndicator,
|
|
1112
|
-
{
|
|
1113
|
-
direction: sortDirection,
|
|
1114
|
-
index: sortIndex > 0 ? sortIndex : void 0
|
|
1115
|
-
}
|
|
1116
|
-
)
|
|
1497
|
+
canSort && /* @__PURE__ */ jsx(SortIndicator, { direction: sortDirection, index: sortIndex > 0 ? sortIndex : void 0 })
|
|
1117
1498
|
] }),
|
|
1118
1499
|
canResize && /* @__PURE__ */ jsx(
|
|
1119
1500
|
"div",
|
|
@@ -1238,6 +1619,10 @@ function TableCell({
|
|
|
1238
1619
|
const cellStatus = table.getCellStatus(cell.row.id, column.id);
|
|
1239
1620
|
const cellErrorMessage = table.getCellErrorMessage(cell.row.id, column.id);
|
|
1240
1621
|
const cellConflictWith = table.getCellConflictWith(cell.row.id, column.id);
|
|
1622
|
+
const selectionRange = table.getCellSelectionRange();
|
|
1623
|
+
const selectionEdges = table.getCellSelectionEdges(rowIndex, columnIndex);
|
|
1624
|
+
const isCellSelected = selectionEdges !== null;
|
|
1625
|
+
const isMultiCellSelection = selectionRange !== null && (selectionRange.start.rowIndex !== selectionRange.end.rowIndex || selectionRange.start.columnIndex !== selectionRange.end.columnIndex);
|
|
1241
1626
|
const overrideValue = cellStatus !== "idle" ? table.getCellRenderValue(cell.row.id, column.id) : void 0;
|
|
1242
1627
|
let content;
|
|
1243
1628
|
const cellDef = column.columnDef.cell;
|
|
@@ -1261,23 +1646,17 @@ function TableCell({
|
|
|
1261
1646
|
}
|
|
1262
1647
|
const handleClick = useCallback(
|
|
1263
1648
|
(e) => {
|
|
1264
|
-
table.setFocusedCell({ rowIndex, columnIndex });
|
|
1265
|
-
const clickTarget = e.target;
|
|
1266
|
-
if (!isInteractiveClickTarget(clickTarget)) {
|
|
1267
|
-
const currentTarget = e.currentTarget;
|
|
1268
|
-
currentTarget.focus({ preventScroll: true });
|
|
1269
|
-
}
|
|
1270
1649
|
table.events.emit("cell:click", {
|
|
1271
1650
|
cell,
|
|
1272
1651
|
row: cell.row,
|
|
1273
1652
|
column: cell.column,
|
|
1274
1653
|
event: e.nativeEvent
|
|
1275
1654
|
});
|
|
1276
|
-
if (canCellEnterEditMode(table, cell.row, column) && !isAlwaysEditable && !isEditing) {
|
|
1655
|
+
if (canCellEnterEditMode(table, cell.row, column) && !isAlwaysEditable && !isEditing && !isMultiCellSelection && !e.shiftKey && !e.metaKey && !e.ctrlKey) {
|
|
1277
1656
|
table.startEditing(cell.row.id, column.id);
|
|
1278
1657
|
}
|
|
1279
1658
|
},
|
|
1280
|
-
[cell, column,
|
|
1659
|
+
[cell, column, isAlwaysEditable, isEditing, isMultiCellSelection, table]
|
|
1281
1660
|
);
|
|
1282
1661
|
const handleDoubleClick = useCallback(
|
|
1283
1662
|
(e) => {
|
|
@@ -1305,9 +1684,34 @@ function TableCell({
|
|
|
1305
1684
|
if (!keyboardNavigationEnabled) return;
|
|
1306
1685
|
table.setFocusedCell({ rowIndex, columnIndex });
|
|
1307
1686
|
}, [columnIndex, keyboardNavigationEnabled, rowIndex, table]);
|
|
1687
|
+
const handleMouseDown = useCallback(
|
|
1688
|
+
(e) => {
|
|
1689
|
+
if (e.button !== 0) return;
|
|
1690
|
+
const clickTarget = e.target;
|
|
1691
|
+
if (isInteractiveClickTarget(clickTarget)) return;
|
|
1692
|
+
e.preventDefault();
|
|
1693
|
+
table.setFocusedCell({ rowIndex, columnIndex });
|
|
1694
|
+
table.startCellRangeSelection({ rowIndex, columnIndex }, { extend: e.shiftKey });
|
|
1695
|
+
e.currentTarget.focus({ preventScroll: true });
|
|
1696
|
+
},
|
|
1697
|
+
[columnIndex, rowIndex, table]
|
|
1698
|
+
);
|
|
1699
|
+
const handleMouseEnter = useCallback(() => {
|
|
1700
|
+
if (!table.getState().cellSelection?.isDragging) return;
|
|
1701
|
+
table.updateCellRangeSelection({ rowIndex, columnIndex });
|
|
1702
|
+
}, [columnIndex, rowIndex, table]);
|
|
1703
|
+
const handleMouseUp = useCallback(() => {
|
|
1704
|
+
if (!table.getState().cellSelection?.isDragging) return;
|
|
1705
|
+
table.endCellRangeSelection();
|
|
1706
|
+
}, [table]);
|
|
1308
1707
|
const classNames = [
|
|
1309
1708
|
"yable-td",
|
|
1310
|
-
isFocused && "yable-cell--focused"
|
|
1709
|
+
isFocused && "yable-cell--focused",
|
|
1710
|
+
isCellSelected && "yable-cell--selected",
|
|
1711
|
+
selectionEdges?.top && "yable-cell--selection-top",
|
|
1712
|
+
selectionEdges?.right && "yable-cell--selection-right",
|
|
1713
|
+
selectionEdges?.bottom && "yable-cell--selection-bottom",
|
|
1714
|
+
selectionEdges?.left && "yable-cell--selection-left"
|
|
1311
1715
|
].filter(Boolean).join(" ");
|
|
1312
1716
|
return /* @__PURE__ */ jsxs(
|
|
1313
1717
|
"td",
|
|
@@ -1321,10 +1725,14 @@ function TableCell({
|
|
|
1321
1725
|
"data-column-id": column.id,
|
|
1322
1726
|
"data-row-index": rowIndex,
|
|
1323
1727
|
"data-column-index": columnIndex,
|
|
1728
|
+
"data-cell-selected": isCellSelected || void 0,
|
|
1324
1729
|
"aria-rowindex": rowIndex + 1,
|
|
1325
1730
|
"aria-colindex": columnIndex + 1,
|
|
1326
1731
|
role: "gridcell",
|
|
1327
1732
|
tabIndex: keyboardNavigationEnabled ? isTabStop ? 0 : -1 : void 0,
|
|
1733
|
+
onMouseDown: handleMouseDown,
|
|
1734
|
+
onMouseEnter: handleMouseEnter,
|
|
1735
|
+
onMouseUp: handleMouseUp,
|
|
1328
1736
|
onClick: handleClick,
|
|
1329
1737
|
onDoubleClick: handleDoubleClick,
|
|
1330
1738
|
onContextMenu: handleContextMenu,
|
|
@@ -1449,14 +1857,15 @@ var CellErrorBoundary = class extends React3.Component {
|
|
|
1449
1857
|
return this.props.children;
|
|
1450
1858
|
}
|
|
1451
1859
|
};
|
|
1452
|
-
function TableBody({
|
|
1453
|
-
table,
|
|
1454
|
-
clickableRows
|
|
1455
|
-
}) {
|
|
1860
|
+
function TableBody({ table, clickableRows }) {
|
|
1456
1861
|
const rows = table.getRowModel().rows;
|
|
1457
1862
|
const visibleColumns = table.getVisibleLeafColumns();
|
|
1458
1863
|
const activeCell = table.getState().editing.activeCell;
|
|
1459
1864
|
const focusedCell = table.getFocusedCell();
|
|
1865
|
+
const cellSelection = table.getState().cellSelection ?? {
|
|
1866
|
+
range: null,
|
|
1867
|
+
isDragging: false
|
|
1868
|
+
};
|
|
1460
1869
|
const options = table.options;
|
|
1461
1870
|
const enableVirtualization = options.enableVirtualization ?? false;
|
|
1462
1871
|
const scrollContainerRef = useRef(null);
|
|
@@ -1474,6 +1883,18 @@ function TableBody({
|
|
|
1474
1883
|
pretextHeights,
|
|
1475
1884
|
pretextPrefixSums
|
|
1476
1885
|
});
|
|
1886
|
+
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"}`;
|
|
1887
|
+
useEffect(() => {
|
|
1888
|
+
const handleWindowMouseUp = () => {
|
|
1889
|
+
if (table.getState().cellSelection?.isDragging) {
|
|
1890
|
+
table.endCellRangeSelection();
|
|
1891
|
+
}
|
|
1892
|
+
};
|
|
1893
|
+
window.addEventListener("mouseup", handleWindowMouseUp);
|
|
1894
|
+
return () => {
|
|
1895
|
+
window.removeEventListener("mouseup", handleWindowMouseUp);
|
|
1896
|
+
};
|
|
1897
|
+
}, [table]);
|
|
1477
1898
|
if (!enableVirtualization) {
|
|
1478
1899
|
return /* @__PURE__ */ jsx("tbody", { className: "yable-tbody", children: rows.map((row, rowIndex) => /* @__PURE__ */ jsx(
|
|
1479
1900
|
MemoizedTableRow,
|
|
@@ -1487,6 +1908,7 @@ function TableBody({
|
|
|
1487
1908
|
activeColumnId: activeCell?.rowId === row.id ? activeCell.columnId : void 0,
|
|
1488
1909
|
focusedColumnIndex: focusedCell?.rowIndex === rowIndex ? focusedCell.columnIndex : null,
|
|
1489
1910
|
hasFocusedCell: focusedCell !== null,
|
|
1911
|
+
cellSelectionKey,
|
|
1490
1912
|
clickable: clickableRows
|
|
1491
1913
|
},
|
|
1492
1914
|
row.id
|
|
@@ -1495,73 +1917,67 @@ function TableBody({
|
|
|
1495
1917
|
const hasPretextData = !!(pretextHeights && pretextPrefixSums);
|
|
1496
1918
|
const fixedRowHeight = typeof rowHeight === "number" && !hasPretextData ? rowHeight : void 0;
|
|
1497
1919
|
const containerHeight = hasPretextData ? Math.min(totalHeight, 800) : fixedRowHeight ? Math.min(totalHeight, fixedRowHeight * 20) : 600;
|
|
1498
|
-
return /* @__PURE__ */ jsx("tbody", { className: "yable-tbody", children: /* @__PURE__ */ jsx("tr", { style: { height: 0, padding: 0, border: "none" }, children: /* @__PURE__ */ jsx(
|
|
1499
|
-
"
|
|
1920
|
+
return /* @__PURE__ */ jsx("tbody", { className: "yable-tbody", children: /* @__PURE__ */ jsx("tr", { style: { height: 0, padding: 0, border: "none" }, children: /* @__PURE__ */ jsx("td", { style: { height: 0, padding: 0, border: "none" }, colSpan: visibleColumns.length, children: /* @__PURE__ */ jsx(
|
|
1921
|
+
"div",
|
|
1500
1922
|
{
|
|
1501
|
-
|
|
1502
|
-
|
|
1923
|
+
ref: scrollContainerRef,
|
|
1924
|
+
className: "yable-virtual-scroll-container",
|
|
1925
|
+
style: {
|
|
1926
|
+
overflowY: "auto",
|
|
1927
|
+
height: containerHeight,
|
|
1928
|
+
position: "relative"
|
|
1929
|
+
},
|
|
1503
1930
|
children: /* @__PURE__ */ jsx(
|
|
1504
1931
|
"div",
|
|
1505
1932
|
{
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
style: {
|
|
1509
|
-
overflowY: "auto",
|
|
1510
|
-
height: containerHeight,
|
|
1511
|
-
position: "relative"
|
|
1512
|
-
},
|
|
1933
|
+
className: "yable-virtual-spacer",
|
|
1934
|
+
style: { height: totalHeight, position: "relative" },
|
|
1513
1935
|
children: /* @__PURE__ */ jsx(
|
|
1514
|
-
"
|
|
1936
|
+
"table",
|
|
1515
1937
|
{
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1938
|
+
style: {
|
|
1939
|
+
position: "absolute",
|
|
1940
|
+
top: 0,
|
|
1941
|
+
left: 0,
|
|
1942
|
+
width: "100%",
|
|
1943
|
+
tableLayout: "fixed",
|
|
1944
|
+
borderCollapse: "collapse"
|
|
1945
|
+
},
|
|
1946
|
+
children: /* @__PURE__ */ jsx("tbody", { children: virtualRows.map((vRow) => {
|
|
1947
|
+
const row = rows[vRow.index];
|
|
1948
|
+
if (!row) return null;
|
|
1949
|
+
return /* @__PURE__ */ jsx(
|
|
1950
|
+
MemoizedTableRow,
|
|
1951
|
+
{
|
|
1952
|
+
row,
|
|
1953
|
+
table,
|
|
1954
|
+
rowIndex: vRow.index,
|
|
1955
|
+
visibleColumns,
|
|
1956
|
+
isSelected: row.getIsSelected(),
|
|
1957
|
+
isExpanded: row.getIsExpanded(),
|
|
1958
|
+
activeColumnId: activeCell?.rowId === row.id ? activeCell.columnId : void 0,
|
|
1959
|
+
focusedColumnIndex: focusedCell?.rowIndex === vRow.index ? focusedCell.columnIndex : null,
|
|
1960
|
+
hasFocusedCell: focusedCell !== null,
|
|
1961
|
+
cellSelectionKey,
|
|
1962
|
+
clickable: clickableRows,
|
|
1963
|
+
virtualStyle: {
|
|
1964
|
+
position: "absolute",
|
|
1965
|
+
top: 0,
|
|
1966
|
+
left: 0,
|
|
1967
|
+
width: "100%",
|
|
1968
|
+
height: vRow.size,
|
|
1969
|
+
transform: `translateY(${vRow.start}px)`
|
|
1970
|
+
}
|
|
1528
1971
|
},
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
return /* @__PURE__ */ jsx(
|
|
1533
|
-
MemoizedTableRow,
|
|
1534
|
-
{
|
|
1535
|
-
row,
|
|
1536
|
-
table,
|
|
1537
|
-
rowIndex: vRow.index,
|
|
1538
|
-
visibleColumns,
|
|
1539
|
-
isSelected: row.getIsSelected(),
|
|
1540
|
-
isExpanded: row.getIsExpanded(),
|
|
1541
|
-
activeColumnId: activeCell?.rowId === row.id ? activeCell.columnId : void 0,
|
|
1542
|
-
focusedColumnIndex: focusedCell?.rowIndex === vRow.index ? focusedCell.columnIndex : null,
|
|
1543
|
-
hasFocusedCell: focusedCell !== null,
|
|
1544
|
-
clickable: clickableRows,
|
|
1545
|
-
virtualStyle: {
|
|
1546
|
-
position: "absolute",
|
|
1547
|
-
top: 0,
|
|
1548
|
-
left: 0,
|
|
1549
|
-
width: "100%",
|
|
1550
|
-
height: vRow.size,
|
|
1551
|
-
transform: `translateY(${vRow.start}px)`
|
|
1552
|
-
}
|
|
1553
|
-
},
|
|
1554
|
-
row.id
|
|
1555
|
-
);
|
|
1556
|
-
}) })
|
|
1557
|
-
}
|
|
1558
|
-
)
|
|
1972
|
+
row.id
|
|
1973
|
+
);
|
|
1974
|
+
}) })
|
|
1559
1975
|
}
|
|
1560
1976
|
)
|
|
1561
1977
|
}
|
|
1562
1978
|
)
|
|
1563
1979
|
}
|
|
1564
|
-
) }) });
|
|
1980
|
+
) }) }) });
|
|
1565
1981
|
}
|
|
1566
1982
|
function TableRowInner({
|
|
1567
1983
|
row,
|
|
@@ -1573,10 +1989,12 @@ function TableRowInner({
|
|
|
1573
1989
|
activeColumnId,
|
|
1574
1990
|
focusedColumnIndex,
|
|
1575
1991
|
hasFocusedCell,
|
|
1992
|
+
cellSelectionKey: _cellSelectionKey,
|
|
1576
1993
|
clickable,
|
|
1577
1994
|
virtualStyle
|
|
1578
1995
|
}) {
|
|
1579
|
-
const
|
|
1996
|
+
const allCells = row.getAllCells();
|
|
1997
|
+
const visibleCells = visibleColumns.map((column) => allCells.find((cell) => cell.column.id === column.id)).filter((cell) => cell != null);
|
|
1580
1998
|
const handleClick = useCallback(
|
|
1581
1999
|
(e) => {
|
|
1582
2000
|
if (clickable) {
|
|
@@ -1606,6 +2024,8 @@ function TableRowInner({
|
|
|
1606
2024
|
},
|
|
1607
2025
|
[table.events, row]
|
|
1608
2026
|
);
|
|
2027
|
+
const selectionEnabled = Boolean(table.options.enableRowSelection);
|
|
2028
|
+
const expansionEnabled = Boolean(table.options.enableExpanding);
|
|
1609
2029
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1610
2030
|
/* @__PURE__ */ jsx(
|
|
1611
2031
|
"tr",
|
|
@@ -1617,6 +2037,8 @@ function TableRowInner({
|
|
|
1617
2037
|
"data-clickable": clickable || void 0,
|
|
1618
2038
|
"data-row-id": row.id,
|
|
1619
2039
|
"data-row-index": rowIndex,
|
|
2040
|
+
"aria-selected": selectionEnabled ? isSelected : void 0,
|
|
2041
|
+
"aria-expanded": expansionEnabled ? isExpanded : void 0,
|
|
1620
2042
|
onClick: handleClick,
|
|
1621
2043
|
onDoubleClick: handleDoubleClick,
|
|
1622
2044
|
onContextMenu: handleContextMenu,
|
|
@@ -1658,6 +2080,7 @@ function areRowPropsEqual(prev, next) {
|
|
|
1658
2080
|
if (prev.activeColumnId !== next.activeColumnId) return false;
|
|
1659
2081
|
if (prev.focusedColumnIndex !== next.focusedColumnIndex) return false;
|
|
1660
2082
|
if (prev.hasFocusedCell !== next.hasFocusedCell) return false;
|
|
2083
|
+
if (prev.cellSelectionKey !== next.cellSelectionKey) return false;
|
|
1661
2084
|
if (prev.virtualStyle !== next.virtualStyle) {
|
|
1662
2085
|
if (!prev.virtualStyle || !next.virtualStyle) return false;
|
|
1663
2086
|
if (prev.virtualStyle.transform !== next.virtualStyle.transform) return false;
|
|
@@ -1667,9 +2090,7 @@ function areRowPropsEqual(prev, next) {
|
|
|
1667
2090
|
return true;
|
|
1668
2091
|
}
|
|
1669
2092
|
var MemoizedTableRow = React3.memo(TableRowInner, areRowPropsEqual);
|
|
1670
|
-
function TableFooter({
|
|
1671
|
-
table
|
|
1672
|
-
}) {
|
|
2093
|
+
function TableFooter({ table }) {
|
|
1673
2094
|
const footerGroups = table.getFooterGroups();
|
|
1674
2095
|
if (!footerGroups.length) return null;
|
|
1675
2096
|
return /* @__PURE__ */ jsx("tfoot", { className: "yable-tfoot", children: footerGroups.map((footerGroup) => /* @__PURE__ */ jsx("tr", { className: "yable-tr", children: footerGroup.headers.map((header) => {
|
|
@@ -1715,19 +2136,20 @@ function Spinner() {
|
|
|
1715
2136
|
function LoadingOverlay({
|
|
1716
2137
|
loading,
|
|
1717
2138
|
loadingComponent,
|
|
1718
|
-
loadingText
|
|
2139
|
+
loadingText
|
|
1719
2140
|
}) {
|
|
1720
2141
|
if (!loading) return null;
|
|
2142
|
+
const resolvedText = loadingText ?? getDefaultLocale().loadingText;
|
|
1721
2143
|
return /* @__PURE__ */ jsx(
|
|
1722
2144
|
"div",
|
|
1723
2145
|
{
|
|
1724
2146
|
className: "yable-overlay-loading",
|
|
1725
2147
|
role: "alert",
|
|
1726
2148
|
"aria-busy": "true",
|
|
1727
|
-
"aria-label":
|
|
2149
|
+
"aria-label": resolvedText,
|
|
1728
2150
|
children: /* @__PURE__ */ jsx("div", { className: "yable-overlay-loading-content", children: loadingComponent ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1729
2151
|
/* @__PURE__ */ jsx(Spinner, {}),
|
|
1730
|
-
|
|
2152
|
+
resolvedText && /* @__PURE__ */ jsx("span", { className: "yable-overlay-loading-text", children: resolvedText })
|
|
1731
2153
|
] }) })
|
|
1732
2154
|
}
|
|
1733
2155
|
);
|
|
@@ -1845,8 +2267,9 @@ function NoRowsOverlay({
|
|
|
1845
2267
|
if (emptyComponent) {
|
|
1846
2268
|
return /* @__PURE__ */ jsx("div", { className: "yable-overlay-empty", children: emptyComponent });
|
|
1847
2269
|
}
|
|
1848
|
-
const
|
|
1849
|
-
const
|
|
2270
|
+
const locale = getDefaultLocale();
|
|
2271
|
+
const defaultMessage = isFiltered ? locale.emptyNoResults : locale.emptyNoData;
|
|
2272
|
+
const defaultDetail = isFiltered ? locale.emptyNoResultsDetail : locale.emptyNoDataDetail;
|
|
1850
2273
|
const icon = emptyIcon ?? (isFiltered ? /* @__PURE__ */ jsx(DefaultFilteredIcon, {}) : /* @__PURE__ */ jsx(DefaultEmptyIcon, {}));
|
|
1851
2274
|
return /* @__PURE__ */ jsxs("div", { className: "yable-overlay-empty", role: "status", children: [
|
|
1852
2275
|
/* @__PURE__ */ jsx("div", { className: "yable-overlay-empty-icon-wrapper", children: icon }),
|
|
@@ -2430,11 +2853,11 @@ function ContextMenu({
|
|
|
2430
2853
|
}
|
|
2431
2854
|
if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
2432
2855
|
e.preventDefault();
|
|
2433
|
-
const items2 = menuRef.current?.querySelectorAll(
|
|
2434
|
-
|
|
2435
|
-
const currentIndex = Array.from(items2).findIndex(
|
|
2436
|
-
(el) => el === document.activeElement
|
|
2856
|
+
const items2 = menuRef.current?.querySelectorAll(
|
|
2857
|
+
'[role="menuitem"]:not([aria-disabled="true"])'
|
|
2437
2858
|
);
|
|
2859
|
+
if (!items2 || items2.length === 0) return;
|
|
2860
|
+
const currentIndex = Array.from(items2).findIndex((el) => el === document.activeElement);
|
|
2438
2861
|
let nextIndex;
|
|
2439
2862
|
if (e.key === "ArrowDown") {
|
|
2440
2863
|
nextIndex = currentIndex < items2.length - 1 ? currentIndex + 1 : 0;
|
|
@@ -2479,11 +2902,7 @@ function ContextMenu({
|
|
|
2479
2902
|
navigator.clipboard?.readText().then((text) => {
|
|
2480
2903
|
const editing = table.getState().editing;
|
|
2481
2904
|
if (editing?.activeCell) {
|
|
2482
|
-
table.pasteFromClipboard(
|
|
2483
|
-
text,
|
|
2484
|
-
editing.activeCell.rowId,
|
|
2485
|
-
editing.activeCell.columnId
|
|
2486
|
-
);
|
|
2905
|
+
table.pasteFromClipboard(text, editing.activeCell.rowId, editing.activeCell.columnId);
|
|
2487
2906
|
}
|
|
2488
2907
|
}).catch(() => {
|
|
2489
2908
|
});
|
|
@@ -2823,6 +3242,12 @@ function isEditableTarget(element) {
|
|
|
2823
3242
|
}
|
|
2824
3243
|
return element.isContentEditable;
|
|
2825
3244
|
}
|
|
3245
|
+
function filterHeaderGroups(groups, visibleColumnIds) {
|
|
3246
|
+
return groups.map((group) => ({
|
|
3247
|
+
...group,
|
|
3248
|
+
headers: group.headers.filter((header) => visibleColumnIds.has(header.column.id))
|
|
3249
|
+
})).filter((group) => group.headers.length > 0);
|
|
3250
|
+
}
|
|
2826
3251
|
function Table({
|
|
2827
3252
|
table,
|
|
2828
3253
|
stickyHeader,
|
|
@@ -2835,7 +3260,7 @@ function Table({
|
|
|
2835
3260
|
loading,
|
|
2836
3261
|
loadingComponent,
|
|
2837
3262
|
loadingText,
|
|
2838
|
-
emptyMessage
|
|
3263
|
+
emptyMessage,
|
|
2839
3264
|
emptyComponent,
|
|
2840
3265
|
emptyIcon,
|
|
2841
3266
|
emptyDetail,
|
|
@@ -2849,6 +3274,10 @@ function Table({
|
|
|
2849
3274
|
sidebar,
|
|
2850
3275
|
sidebarPanels = ["columns", "filters"],
|
|
2851
3276
|
defaultSidebarPanel,
|
|
3277
|
+
floatingFilters,
|
|
3278
|
+
columnVirtualization,
|
|
3279
|
+
columnVirtualizationOverscan,
|
|
3280
|
+
ariaLabel,
|
|
2852
3281
|
...rest
|
|
2853
3282
|
}) {
|
|
2854
3283
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
@@ -2856,6 +3285,7 @@ function Table({
|
|
|
2856
3285
|
defaultSidebarPanel ?? "columns"
|
|
2857
3286
|
);
|
|
2858
3287
|
const containerRef = useRef(null);
|
|
3288
|
+
const horizontalScrollRef = useRef(null);
|
|
2859
3289
|
const isRtl = direction === "rtl";
|
|
2860
3290
|
const classNames = [
|
|
2861
3291
|
"yable",
|
|
@@ -2873,8 +3303,86 @@ function Table({
|
|
|
2873
3303
|
const hasGlobalFilter = Boolean(table.getState().globalFilter);
|
|
2874
3304
|
const hasColumnFilters = table.getState().columnFilters.length > 0;
|
|
2875
3305
|
const isFiltered = hasGlobalFilter || hasColumnFilters;
|
|
3306
|
+
const allVisibleColumns = table.getVisibleLeafColumns();
|
|
3307
|
+
const hasPinnedColumns = table.getLeftVisibleLeafColumns().length > 0 || table.getRightVisibleLeafColumns().length > 0;
|
|
3308
|
+
const hasGroupedHeaders = table.getHeaderGroups().length > 1;
|
|
3309
|
+
const canVirtualizeColumns = Boolean(columnVirtualization) && !hasPinnedColumns && !hasGroupedHeaders && allVisibleColumns.length > 0;
|
|
3310
|
+
const columnVirtualState = useColumnVirtualization({
|
|
3311
|
+
containerRef: horizontalScrollRef,
|
|
3312
|
+
columns: allVisibleColumns,
|
|
3313
|
+
overscan: columnVirtualizationOverscan ?? 2,
|
|
3314
|
+
enabled: canVirtualizeColumns
|
|
3315
|
+
});
|
|
3316
|
+
const renderTable = useMemo(() => {
|
|
3317
|
+
if (!canVirtualizeColumns || !columnVirtualState.isVirtualized) {
|
|
3318
|
+
return table;
|
|
3319
|
+
}
|
|
3320
|
+
const virtualColumns = columnVirtualState.virtualColumns.map((entry) => entry.column);
|
|
3321
|
+
const visibleColumnIds = new Set(virtualColumns.map((column) => column.id));
|
|
3322
|
+
const next = Object.create(table);
|
|
3323
|
+
next.getVisibleFlatColumns = () => virtualColumns;
|
|
3324
|
+
next.getVisibleLeafColumns = () => virtualColumns;
|
|
3325
|
+
next.getCenterVisibleLeafColumns = () => virtualColumns;
|
|
3326
|
+
next.getLeftVisibleLeafColumns = () => [];
|
|
3327
|
+
next.getRightVisibleLeafColumns = () => [];
|
|
3328
|
+
next.getHeaderGroups = () => filterHeaderGroups(table.getHeaderGroups(), visibleColumnIds);
|
|
3329
|
+
next.getCenterHeaderGroups = () => filterHeaderGroups(table.getCenterHeaderGroups(), visibleColumnIds);
|
|
3330
|
+
next.getFooterGroups = () => filterHeaderGroups(table.getFooterGroups(), visibleColumnIds);
|
|
3331
|
+
next.getCenterFooterGroups = () => filterHeaderGroups(table.getCenterFooterGroups(), visibleColumnIds);
|
|
3332
|
+
return next;
|
|
3333
|
+
}, [
|
|
3334
|
+
canVirtualizeColumns,
|
|
3335
|
+
columnVirtualState.isVirtualized,
|
|
3336
|
+
columnVirtualState.virtualColumns,
|
|
3337
|
+
table
|
|
3338
|
+
]);
|
|
3339
|
+
const showColumnVirtualizationShell = canVirtualizeColumns;
|
|
2876
3340
|
const contextMenu = useContextMenu();
|
|
2877
3341
|
useKeyboardNavigation(table, { containerRef });
|
|
3342
|
+
const [announcement, setAnnouncement] = useState("");
|
|
3343
|
+
const prevSortingRef = useRef(table.getState().sorting);
|
|
3344
|
+
const prevFilterCountRef = useRef(rows.length);
|
|
3345
|
+
const prevHasFiltersRef = useRef(isFiltered);
|
|
3346
|
+
const prevPaginationRef = useRef(table.getState().pagination);
|
|
3347
|
+
const isFirstRenderRef = useRef(true);
|
|
3348
|
+
useEffect(() => {
|
|
3349
|
+
if (isFirstRenderRef.current) {
|
|
3350
|
+
isFirstRenderRef.current = false;
|
|
3351
|
+
return;
|
|
3352
|
+
}
|
|
3353
|
+
const currentSorting = table.getState().sorting;
|
|
3354
|
+
const currentPagination = table.getState().pagination;
|
|
3355
|
+
const currentRowCount = rows.length;
|
|
3356
|
+
const currentIsFiltered = isFiltered;
|
|
3357
|
+
if (JSON.stringify(currentSorting) !== JSON.stringify(prevSortingRef.current)) {
|
|
3358
|
+
prevSortingRef.current = currentSorting;
|
|
3359
|
+
const firstSort = currentSorting[0];
|
|
3360
|
+
if (firstSort) {
|
|
3361
|
+
const column = table.getColumn(firstSort.id);
|
|
3362
|
+
const headerDef = column?.columnDef.header;
|
|
3363
|
+
const columnName = typeof headerDef === "string" ? headerDef : firstSort.id;
|
|
3364
|
+
const direction2 = firstSort.desc ? "descending" : "ascending";
|
|
3365
|
+
setAnnouncement(`Sorted by ${columnName} ${direction2}`);
|
|
3366
|
+
return;
|
|
3367
|
+
}
|
|
3368
|
+
}
|
|
3369
|
+
if (currentRowCount !== prevFilterCountRef.current || currentIsFiltered !== prevHasFiltersRef.current) {
|
|
3370
|
+
prevFilterCountRef.current = currentRowCount;
|
|
3371
|
+
prevHasFiltersRef.current = currentIsFiltered;
|
|
3372
|
+
if (currentIsFiltered) {
|
|
3373
|
+
setAnnouncement(`${currentRowCount} rows after filtering`);
|
|
3374
|
+
return;
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
3377
|
+
if (JSON.stringify(currentPagination) !== JSON.stringify(prevPaginationRef.current)) {
|
|
3378
|
+
prevPaginationRef.current = currentPagination;
|
|
3379
|
+
const pageCount = table.getPageCount();
|
|
3380
|
+
if (pageCount > 0) {
|
|
3381
|
+
setAnnouncement(`Page ${currentPagination.pageIndex + 1} of ${pageCount}`);
|
|
3382
|
+
return;
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
3385
|
+
});
|
|
2878
3386
|
const handleContextMenu = useCallback(
|
|
2879
3387
|
(e) => {
|
|
2880
3388
|
e.preventDefault();
|
|
@@ -2882,6 +3390,24 @@ function Table({
|
|
|
2882
3390
|
},
|
|
2883
3391
|
[contextMenu, table]
|
|
2884
3392
|
);
|
|
3393
|
+
const tableNode = /* @__PURE__ */ jsxs(
|
|
3394
|
+
"table",
|
|
3395
|
+
{
|
|
3396
|
+
className: "yable-table",
|
|
3397
|
+
style: columnVirtualState.isVirtualized ? {
|
|
3398
|
+
width: columnVirtualState.visibleWidth,
|
|
3399
|
+
minWidth: columnVirtualState.visibleWidth,
|
|
3400
|
+
marginLeft: columnVirtualState.startOffset,
|
|
3401
|
+
tableLayout: "fixed"
|
|
3402
|
+
} : void 0,
|
|
3403
|
+
"data-column-virtualized": columnVirtualState.isVirtualized || void 0,
|
|
3404
|
+
children: [
|
|
3405
|
+
/* @__PURE__ */ jsx(TableHeader, { table: renderTable, floatingFilters }),
|
|
3406
|
+
/* @__PURE__ */ jsx(TableBody, { table: renderTable, clickableRows }),
|
|
3407
|
+
footer && /* @__PURE__ */ jsx(TableFooter, { table: renderTable })
|
|
3408
|
+
]
|
|
3409
|
+
}
|
|
3410
|
+
);
|
|
2885
3411
|
return /* @__PURE__ */ jsx(TableProvider, { value: table, children: /* @__PURE__ */ jsxs(
|
|
2886
3412
|
"div",
|
|
2887
3413
|
{
|
|
@@ -2890,23 +3416,40 @@ function Table({
|
|
|
2890
3416
|
"data-theme": theme,
|
|
2891
3417
|
dir: direction,
|
|
2892
3418
|
role: "grid",
|
|
3419
|
+
"aria-label": ariaLabel ?? "Data table",
|
|
2893
3420
|
"aria-rowcount": table.getRowModel().rows.length,
|
|
2894
3421
|
"aria-colcount": table.getVisibleLeafColumns().length,
|
|
2895
3422
|
onContextMenu: handleContextMenu,
|
|
2896
3423
|
...rest,
|
|
2897
3424
|
children: [
|
|
2898
3425
|
/* @__PURE__ */ jsxs("div", { className: "yable-main", children: [
|
|
2899
|
-
/* @__PURE__ */
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
3426
|
+
showColumnVirtualizationShell ? /* @__PURE__ */ jsx(
|
|
3427
|
+
"div",
|
|
3428
|
+
{
|
|
3429
|
+
ref: horizontalScrollRef,
|
|
3430
|
+
className: "yable-horizontal-scroll-container",
|
|
3431
|
+
style: {
|
|
3432
|
+
overflowX: "auto",
|
|
3433
|
+
overflowY: "visible",
|
|
3434
|
+
maxWidth: "100%",
|
|
3435
|
+
position: "relative"
|
|
3436
|
+
},
|
|
3437
|
+
children: /* @__PURE__ */ jsx(
|
|
3438
|
+
"div",
|
|
3439
|
+
{
|
|
3440
|
+
className: "yable-horizontal-scroll-inner",
|
|
3441
|
+
style: {
|
|
3442
|
+
width: Math.max(columnVirtualState.totalWidth, columnVirtualState.visibleWidth),
|
|
3443
|
+
minWidth: Math.max(
|
|
3444
|
+
columnVirtualState.totalWidth,
|
|
3445
|
+
columnVirtualState.visibleWidth
|
|
3446
|
+
)
|
|
3447
|
+
},
|
|
3448
|
+
children: tableNode
|
|
3449
|
+
}
|
|
3450
|
+
)
|
|
3451
|
+
}
|
|
3452
|
+
) : tableNode,
|
|
2910
3453
|
/* @__PURE__ */ jsx(
|
|
2911
3454
|
LoadingOverlay,
|
|
2912
3455
|
{
|
|
@@ -2947,6 +3490,24 @@ function Table({
|
|
|
2947
3490
|
onClose: contextMenu.close,
|
|
2948
3491
|
table
|
|
2949
3492
|
}
|
|
3493
|
+
),
|
|
3494
|
+
/* @__PURE__ */ jsx(
|
|
3495
|
+
"div",
|
|
3496
|
+
{
|
|
3497
|
+
role: "status",
|
|
3498
|
+
"aria-live": "polite",
|
|
3499
|
+
"aria-atomic": "true",
|
|
3500
|
+
style: {
|
|
3501
|
+
position: "absolute",
|
|
3502
|
+
width: "1px",
|
|
3503
|
+
height: "1px",
|
|
3504
|
+
overflow: "hidden",
|
|
3505
|
+
clip: "rect(0,0,0,0)",
|
|
3506
|
+
whiteSpace: "nowrap",
|
|
3507
|
+
border: 0
|
|
3508
|
+
},
|
|
3509
|
+
children: announcement
|
|
3510
|
+
}
|
|
2950
3511
|
)
|
|
2951
3512
|
]
|
|
2952
3513
|
}
|
|
@@ -2987,9 +3548,10 @@ function Pagination({
|
|
|
2987
3548
|
const to = Math.min((pageIndex + 1) * pageSize, totalRows);
|
|
2988
3549
|
const canPrev = table.getCanPreviousPage();
|
|
2989
3550
|
const canNext = table.getCanNextPage();
|
|
3551
|
+
const locale = getDefaultLocale();
|
|
2990
3552
|
return /* @__PURE__ */ jsxs("nav", { className: "yable-pagination", role: "navigation", "aria-label": "Table pagination", children: [
|
|
2991
3553
|
showInfo && /* @__PURE__ */ jsxs("div", { className: "yable-pagination-info", children: [
|
|
2992
|
-
/* @__PURE__ */ jsx("span", { className: "yable-pagination-info-text", children: totalRows > 0 ? `${from}\u2013${to}
|
|
3554
|
+
/* @__PURE__ */ jsx("span", { className: "yable-pagination-info-text", children: totalRows > 0 ? `${from}\u2013${to} ${locale.paginationOf} ${totalRows}` : locale.paginationNoResults }),
|
|
2993
3555
|
showPageSize && /* @__PURE__ */ jsxs("div", { className: "yable-pagination-select-wrapper", children: [
|
|
2994
3556
|
/* @__PURE__ */ jsx(
|
|
2995
3557
|
"select",
|
|
@@ -3002,7 +3564,8 @@ function Pagination({
|
|
|
3002
3564
|
"aria-label": "Rows per page",
|
|
3003
3565
|
children: pageSizes.map((size) => /* @__PURE__ */ jsxs("option", { value: size, children: [
|
|
3004
3566
|
size,
|
|
3005
|
-
"
|
|
3567
|
+
" ",
|
|
3568
|
+
locale.paginationRows
|
|
3006
3569
|
] }, size))
|
|
3007
3570
|
}
|
|
3008
3571
|
),
|
|
@@ -3017,8 +3580,8 @@ function Pagination({
|
|
|
3017
3580
|
className: "yable-pagination-btn yable-pagination-btn--nav",
|
|
3018
3581
|
onClick: () => table.setPageIndex(0),
|
|
3019
3582
|
disabled: !canPrev,
|
|
3020
|
-
"aria-label":
|
|
3021
|
-
title:
|
|
3583
|
+
"aria-label": locale.paginationFirstPage,
|
|
3584
|
+
title: locale.paginationFirstPage,
|
|
3022
3585
|
children: /* @__PURE__ */ jsx(ChevronFirstIcon, {})
|
|
3023
3586
|
}
|
|
3024
3587
|
),
|
|
@@ -3029,8 +3592,8 @@ function Pagination({
|
|
|
3029
3592
|
className: "yable-pagination-btn yable-pagination-btn--nav",
|
|
3030
3593
|
onClick: () => table.previousPage(),
|
|
3031
3594
|
disabled: !canPrev,
|
|
3032
|
-
"aria-label":
|
|
3033
|
-
title:
|
|
3595
|
+
"aria-label": locale.paginationPreviousPage,
|
|
3596
|
+
title: locale.paginationPreviousPage,
|
|
3034
3597
|
children: /* @__PURE__ */ jsx(ChevronLeftIcon, {})
|
|
3035
3598
|
}
|
|
3036
3599
|
),
|
|
@@ -3054,7 +3617,7 @@ function Pagination({
|
|
|
3054
3617
|
className: `yable-pagination-btn yable-pagination-btn--page${page === pageIndex ? " yable-pagination-btn--active" : ""}`,
|
|
3055
3618
|
"data-active": page === pageIndex ? "true" : void 0,
|
|
3056
3619
|
onClick: () => table.setPageIndex(page),
|
|
3057
|
-
"aria-label":
|
|
3620
|
+
"aria-label": `${locale.paginationPage} ${page + 1}`,
|
|
3058
3621
|
"aria-current": page === pageIndex ? "page" : void 0,
|
|
3059
3622
|
children: page + 1
|
|
3060
3623
|
},
|
|
@@ -3068,8 +3631,8 @@ function Pagination({
|
|
|
3068
3631
|
className: "yable-pagination-btn yable-pagination-btn--nav",
|
|
3069
3632
|
onClick: () => table.nextPage(),
|
|
3070
3633
|
disabled: !canNext,
|
|
3071
|
-
"aria-label":
|
|
3072
|
-
title:
|
|
3634
|
+
"aria-label": locale.paginationNextPage,
|
|
3635
|
+
title: locale.paginationNextPage,
|
|
3073
3636
|
children: /* @__PURE__ */ jsx(ChevronRightIcon, {})
|
|
3074
3637
|
}
|
|
3075
3638
|
),
|
|
@@ -3080,8 +3643,8 @@ function Pagination({
|
|
|
3080
3643
|
className: "yable-pagination-btn yable-pagination-btn--nav",
|
|
3081
3644
|
onClick: () => table.setPageIndex(pageCount - 1),
|
|
3082
3645
|
disabled: !canNext,
|
|
3083
|
-
"aria-label":
|
|
3084
|
-
title:
|
|
3646
|
+
"aria-label": locale.paginationLastPage,
|
|
3647
|
+
title: locale.paginationLastPage,
|
|
3085
3648
|
children: /* @__PURE__ */ jsx(ChevronLastIcon, {})
|
|
3086
3649
|
}
|
|
3087
3650
|
)
|
|
@@ -3130,10 +3693,12 @@ function ClearIcon() {
|
|
|
3130
3693
|
}
|
|
3131
3694
|
function GlobalFilter({
|
|
3132
3695
|
table,
|
|
3133
|
-
placeholder
|
|
3696
|
+
placeholder,
|
|
3134
3697
|
debounce = 300,
|
|
3135
3698
|
className
|
|
3136
3699
|
}) {
|
|
3700
|
+
const locale = getDefaultLocale();
|
|
3701
|
+
const resolvedPlaceholder = placeholder ?? locale.searchPlaceholder;
|
|
3137
3702
|
const [value, setValue] = useState(
|
|
3138
3703
|
table.getState().globalFilter ?? ""
|
|
3139
3704
|
);
|
|
@@ -3190,8 +3755,8 @@ function GlobalFilter({
|
|
|
3190
3755
|
value,
|
|
3191
3756
|
onChange: handleChange,
|
|
3192
3757
|
onKeyDown: handleKeyDown,
|
|
3193
|
-
placeholder,
|
|
3194
|
-
"aria-label":
|
|
3758
|
+
placeholder: resolvedPlaceholder,
|
|
3759
|
+
"aria-label": locale.searchAriaLabel,
|
|
3195
3760
|
role: "searchbox"
|
|
3196
3761
|
}
|
|
3197
3762
|
),
|
|
@@ -3278,10 +3843,25 @@ function CellSelect({
|
|
|
3278
3843
|
const isAlwaysEditable = cell.getIsAlwaysEditable();
|
|
3279
3844
|
const pending = table.getPendingValue(row.id, column.id);
|
|
3280
3845
|
const currentValue = pending !== void 0 ? pending : cell.getValue();
|
|
3846
|
+
const commitTimerRef = useRef(null);
|
|
3847
|
+
useEffect(() => {
|
|
3848
|
+
return () => {
|
|
3849
|
+
if (commitTimerRef.current !== null) {
|
|
3850
|
+
clearTimeout(commitTimerRef.current);
|
|
3851
|
+
commitTimerRef.current = null;
|
|
3852
|
+
}
|
|
3853
|
+
};
|
|
3854
|
+
}, []);
|
|
3281
3855
|
const handleChange = (e) => {
|
|
3282
3856
|
table.setPendingValue(row.id, column.id, e.target.value);
|
|
3283
3857
|
if (isEditing && !isAlwaysEditable) {
|
|
3284
|
-
|
|
3858
|
+
if (commitTimerRef.current !== null) {
|
|
3859
|
+
clearTimeout(commitTimerRef.current);
|
|
3860
|
+
}
|
|
3861
|
+
commitTimerRef.current = setTimeout(() => {
|
|
3862
|
+
commitTimerRef.current = null;
|
|
3863
|
+
table.commitEdit();
|
|
3864
|
+
}, 0);
|
|
3285
3865
|
}
|
|
3286
3866
|
};
|
|
3287
3867
|
return /* @__PURE__ */ jsxs(
|
|
@@ -3393,14 +3973,7 @@ function formatDateValue(value, type) {
|
|
|
3393
3973
|
return String(value);
|
|
3394
3974
|
}
|
|
3395
3975
|
function useClipboard(table, options = {}) {
|
|
3396
|
-
const {
|
|
3397
|
-
enabled = true,
|
|
3398
|
-
containerRef,
|
|
3399
|
-
onCopy,
|
|
3400
|
-
onCut,
|
|
3401
|
-
onPaste,
|
|
3402
|
-
...clipboardOptions
|
|
3403
|
-
} = options;
|
|
3976
|
+
const { enabled = true, containerRef, onCopy, onCut, onPaste, ...clipboardOptions } = options;
|
|
3404
3977
|
const handleCopy = useCallback(
|
|
3405
3978
|
(e) => {
|
|
3406
3979
|
if (isEditableTarget2(e.target)) return;
|
|
@@ -3438,20 +4011,29 @@ function useClipboard(table, options = {}) {
|
|
|
3438
4011
|
targetRowId = state.editing.activeCell.rowId;
|
|
3439
4012
|
targetColumnId = state.editing.activeCell.columnId;
|
|
3440
4013
|
} else {
|
|
3441
|
-
const
|
|
3442
|
-
|
|
3443
|
-
);
|
|
3444
|
-
if (
|
|
3445
|
-
|
|
4014
|
+
const selectedRange = table.getCellSelectionRange();
|
|
4015
|
+
const rows = table.getRowModel().rows;
|
|
4016
|
+
const columns = table.getVisibleLeafColumns();
|
|
4017
|
+
if (selectedRange) {
|
|
4018
|
+
const startRowIndex = Math.min(selectedRange.start.rowIndex, selectedRange.end.rowIndex);
|
|
4019
|
+
const startColumnIndex = Math.min(
|
|
4020
|
+
selectedRange.start.columnIndex,
|
|
4021
|
+
selectedRange.end.columnIndex
|
|
4022
|
+
);
|
|
4023
|
+
targetRowId = rows[startRowIndex]?.id;
|
|
4024
|
+
targetColumnId = columns[startColumnIndex]?.id;
|
|
3446
4025
|
} else {
|
|
3447
|
-
const
|
|
3448
|
-
|
|
4026
|
+
const selectedRowIds = Object.keys(state.rowSelection || {}).filter(
|
|
4027
|
+
(id) => state.rowSelection[id]
|
|
4028
|
+
);
|
|
4029
|
+
if (selectedRowIds.length > 0) {
|
|
4030
|
+
targetRowId = selectedRowIds[0];
|
|
4031
|
+
} else if (rows.length > 0) {
|
|
3449
4032
|
targetRowId = rows[0].id;
|
|
3450
4033
|
}
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
targetColumnId = columns[0].id;
|
|
4034
|
+
if (columns.length > 0) {
|
|
4035
|
+
targetColumnId = columns[0].id;
|
|
4036
|
+
}
|
|
3455
4037
|
}
|
|
3456
4038
|
}
|
|
3457
4039
|
if (targetRowId && targetColumnId) {
|
|
@@ -4741,7 +5323,7 @@ function sanitizeCSS(css) {
|
|
|
4741
5323
|
sanitized = sanitized.replace(/javascript\s*:/gi, "/* javascript: removed */");
|
|
4742
5324
|
return sanitized;
|
|
4743
5325
|
}
|
|
4744
|
-
function usePrintLayout(
|
|
5326
|
+
function usePrintLayout(_table, options = {}) {
|
|
4745
5327
|
const { title, additionalCSS } = options;
|
|
4746
5328
|
const isPrintingRef = useRef(false);
|
|
4747
5329
|
const preparePrint = useCallback(() => {
|
|
@@ -4778,7 +5360,7 @@ function usePrintLayout(table, options = {}) {
|
|
|
4778
5360
|
requestAnimationFrame(() => {
|
|
4779
5361
|
window.print();
|
|
4780
5362
|
});
|
|
4781
|
-
}, [
|
|
5363
|
+
}, [title, additionalCSS]);
|
|
4782
5364
|
return {
|
|
4783
5365
|
preparePrint,
|
|
4784
5366
|
isPrinting: isPrintingRef.current
|
|
@@ -4830,6 +5412,6 @@ function useTheme(options = {}) {
|
|
|
4830
5412
|
};
|
|
4831
5413
|
}
|
|
4832
5414
|
|
|
4833
|
-
export { CellBadge, CellBoolean, CellCheckbox, CellCurrency, CellDate, CellDatePicker, CellErrorBoundary, CellInput, CellLink, CellNumeric, CellProgress, CellRating, CellSelect, CellStatus, CellStatusBadge, CellToggle, ColumnsPanel, ContextMenu, ContextMenuItem, DEFAULT_TEXT_RECIPE, DragHandle, ErrorBoundary, ExpandIcon, FillHandle, FiltersPanel, FlashCell, GlobalFilter, LoadingOverlay, MasterDetail, NoRowsOverlay, Pagination, PivotConfigPanel, PrintLayout, Sidebar, SortIndicator, StatusBar, StatusBarPanelComponent, Table, TableBody, TableCell, TableFooter, TableHeader, TableProvider, Tooltip, TreeToggle, getMeasureRecipeForCellType, getRegisteredCellTypes, resolveMeasureRecipe, useAutoMeasurements, useCellFlash, useClipboard, useContextMenu, useFillHandle, useKeyboardNavigation, usePretextMeasurement, usePrintLayout, useRowAnimation, useRowDrag, useTable, useTableContext, useTableRowHeights, useTheme, useTooltip, useVirtualization };
|
|
5415
|
+
export { CellBadge, CellBoolean, CellCheckbox, CellCurrency, CellDate, CellDatePicker, CellErrorBoundary, CellInput, CellLink, CellNumeric, CellProgress, CellRating, CellSelect, CellStatus, CellStatusBadge, CellToggle, ColumnsPanel, ContextMenu, ContextMenuItem, DEFAULT_TEXT_RECIPE, DragHandle, ErrorBoundary, ExpandIcon, FillHandle, FiltersPanel, FlashCell, FloatingFilter, GlobalFilter, LoadingOverlay, MasterDetail, NoRowsOverlay, Pagination, PivotConfigPanel, PrintLayout, SetFilter, Sidebar, SortIndicator, StatusBar, StatusBarPanelComponent, Table, TableBody, TableCell, TableFooter, TableHeader, TableProvider, Tooltip, TreeToggle, getMeasureRecipeForCellType, getRegisteredCellTypes, resolveMeasureRecipe, useAutoMeasurements, useCellFlash, useClipboard, useColumnVirtualization, useContextMenu, useFillHandle, useKeyboardNavigation, usePretextMeasurement, usePrintLayout, useRowAnimation, useRowDrag, useTable, useTableContext, useTableRowHeights, useTheme, useTooltip, useVirtualization };
|
|
4834
5416
|
//# sourceMappingURL=index.js.map
|
|
4835
5417
|
//# sourceMappingURL=index.js.map
|