@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.cjs
CHANGED
|
@@ -69,6 +69,8 @@ function useTable(options) {
|
|
|
69
69
|
prevOptionsRef.current = options;
|
|
70
70
|
return options;
|
|
71
71
|
}, [options]);
|
|
72
|
+
const onStateChangeRef = React3.useRef(options.onStateChange);
|
|
73
|
+
onStateChangeRef.current = options.onStateChange;
|
|
72
74
|
const resolvedState = React3.useMemo(
|
|
73
75
|
() => ({
|
|
74
76
|
...state,
|
|
@@ -78,13 +80,14 @@ function useTable(options) {
|
|
|
78
80
|
);
|
|
79
81
|
const onStateChange = React3.useCallback(
|
|
80
82
|
(updater) => {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
const latest = onStateChangeRef.current;
|
|
84
|
+
if (latest) {
|
|
85
|
+
latest(updater);
|
|
83
86
|
} else {
|
|
84
87
|
setState((prev) => yableCore.functionalUpdate(updater, prev));
|
|
85
88
|
}
|
|
86
89
|
},
|
|
87
|
-
[
|
|
90
|
+
[]
|
|
88
91
|
);
|
|
89
92
|
const resolvedOptions = React3.useMemo(
|
|
90
93
|
() => ({
|
|
@@ -212,7 +215,15 @@ function useVirtualization({
|
|
|
212
215
|
container.scrollTop = offset;
|
|
213
216
|
}
|
|
214
217
|
},
|
|
215
|
-
[
|
|
218
|
+
[
|
|
219
|
+
containerRef,
|
|
220
|
+
totalRows,
|
|
221
|
+
rowHeight,
|
|
222
|
+
isFixedHeight,
|
|
223
|
+
getRowHeight,
|
|
224
|
+
hasPretextHeights,
|
|
225
|
+
pretextPrefixSums
|
|
226
|
+
]
|
|
216
227
|
);
|
|
217
228
|
const totalHeight = React3.useMemo(() => {
|
|
218
229
|
if (totalRows === 0) return 0;
|
|
@@ -266,10 +277,7 @@ function useVirtualization({
|
|
|
266
277
|
} else if (isFixedHeight) {
|
|
267
278
|
const fixedH = rowHeight;
|
|
268
279
|
startIndex = Math.floor(scrollTop / fixedH);
|
|
269
|
-
endIndex = Math.min(
|
|
270
|
-
totalRows - 1,
|
|
271
|
-
Math.ceil((scrollTop + containerHeight) / fixedH) - 1
|
|
272
|
-
);
|
|
280
|
+
endIndex = Math.min(totalRows - 1, Math.ceil((scrollTop + containerHeight) / fixedH) - 1);
|
|
273
281
|
} else {
|
|
274
282
|
let accum = 0;
|
|
275
283
|
let foundStart = false;
|
|
@@ -336,6 +344,162 @@ function useVirtualization({
|
|
|
336
344
|
scrollTo
|
|
337
345
|
};
|
|
338
346
|
}
|
|
347
|
+
function binarySearchOffsets(offsets, target) {
|
|
348
|
+
let low = 0;
|
|
349
|
+
let high = offsets.length - 1;
|
|
350
|
+
while (low < high) {
|
|
351
|
+
const mid = low + high >>> 1;
|
|
352
|
+
if (offsets[mid + 1] <= target) {
|
|
353
|
+
low = mid + 1;
|
|
354
|
+
} else {
|
|
355
|
+
high = mid;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
return low;
|
|
359
|
+
}
|
|
360
|
+
function useColumnVirtualization({
|
|
361
|
+
containerRef,
|
|
362
|
+
columns,
|
|
363
|
+
overscan = 2,
|
|
364
|
+
enabled = true
|
|
365
|
+
}) {
|
|
366
|
+
const [scrollState, setScrollState] = React3.useState({
|
|
367
|
+
scrollLeft: 0,
|
|
368
|
+
containerWidth: 0
|
|
369
|
+
});
|
|
370
|
+
const rafRef = React3.useRef(null);
|
|
371
|
+
const sizes = React3.useMemo(() => columns.map((column) => column.getSize()), [columns]);
|
|
372
|
+
const offsets = React3.useMemo(() => {
|
|
373
|
+
const next = new Array(columns.length + 1);
|
|
374
|
+
next[0] = 0;
|
|
375
|
+
for (let i = 0; i < columns.length; i++) {
|
|
376
|
+
next[i + 1] = next[i] + (sizes[i] ?? 0);
|
|
377
|
+
}
|
|
378
|
+
return next;
|
|
379
|
+
}, [columns.length, sizes]);
|
|
380
|
+
const totalWidth = offsets[offsets.length - 1] ?? 0;
|
|
381
|
+
React3.useEffect(() => {
|
|
382
|
+
const container = containerRef.current;
|
|
383
|
+
if (!container) return;
|
|
384
|
+
setScrollState({
|
|
385
|
+
scrollLeft: container.scrollLeft,
|
|
386
|
+
containerWidth: container.clientWidth
|
|
387
|
+
});
|
|
388
|
+
const handleScroll = () => {
|
|
389
|
+
if (rafRef.current !== null) return;
|
|
390
|
+
rafRef.current = requestAnimationFrame(() => {
|
|
391
|
+
rafRef.current = null;
|
|
392
|
+
const el = containerRef.current;
|
|
393
|
+
if (!el) return;
|
|
394
|
+
setScrollState({
|
|
395
|
+
scrollLeft: el.scrollLeft,
|
|
396
|
+
containerWidth: el.clientWidth
|
|
397
|
+
});
|
|
398
|
+
});
|
|
399
|
+
};
|
|
400
|
+
container.addEventListener("scroll", handleScroll, { passive: true });
|
|
401
|
+
let resizeObserver;
|
|
402
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
403
|
+
resizeObserver = new ResizeObserver(() => {
|
|
404
|
+
const el = containerRef.current;
|
|
405
|
+
if (!el) return;
|
|
406
|
+
setScrollState((prev) => {
|
|
407
|
+
const nextWidth = el.clientWidth;
|
|
408
|
+
if (prev.containerWidth === nextWidth && prev.scrollLeft === el.scrollLeft) {
|
|
409
|
+
return prev;
|
|
410
|
+
}
|
|
411
|
+
return {
|
|
412
|
+
scrollLeft: el.scrollLeft,
|
|
413
|
+
containerWidth: nextWidth
|
|
414
|
+
};
|
|
415
|
+
});
|
|
416
|
+
});
|
|
417
|
+
resizeObserver.observe(container);
|
|
418
|
+
}
|
|
419
|
+
return () => {
|
|
420
|
+
container.removeEventListener("scroll", handleScroll);
|
|
421
|
+
if (rafRef.current !== null) {
|
|
422
|
+
cancelAnimationFrame(rafRef.current);
|
|
423
|
+
rafRef.current = null;
|
|
424
|
+
}
|
|
425
|
+
resizeObserver?.disconnect();
|
|
426
|
+
};
|
|
427
|
+
}, [containerRef]);
|
|
428
|
+
const scrollToIndex = React3.useCallback(
|
|
429
|
+
(index) => {
|
|
430
|
+
const container = containerRef.current;
|
|
431
|
+
if (!container || columns.length === 0) return;
|
|
432
|
+
const clampedIndex = Math.max(0, Math.min(index, columns.length - 1));
|
|
433
|
+
container.scrollLeft = offsets[clampedIndex] ?? 0;
|
|
434
|
+
},
|
|
435
|
+
[columns.length, containerRef, offsets]
|
|
436
|
+
);
|
|
437
|
+
if (!enabled || columns.length === 0) {
|
|
438
|
+
return {
|
|
439
|
+
virtualColumns: columns.map((column, index) => ({
|
|
440
|
+
column,
|
|
441
|
+
index,
|
|
442
|
+
start: offsets[index] ?? 0,
|
|
443
|
+
size: sizes[index] ?? 0
|
|
444
|
+
})),
|
|
445
|
+
startOffset: 0,
|
|
446
|
+
endOffset: 0,
|
|
447
|
+
totalWidth,
|
|
448
|
+
visibleWidth: totalWidth,
|
|
449
|
+
startIndex: 0,
|
|
450
|
+
endIndex: Math.max(columns.length - 1, 0),
|
|
451
|
+
isVirtualized: false,
|
|
452
|
+
scrollToIndex
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
const { scrollLeft, containerWidth } = scrollState;
|
|
456
|
+
if (containerWidth <= 0 || totalWidth <= containerWidth) {
|
|
457
|
+
return {
|
|
458
|
+
virtualColumns: columns.map((column, index) => ({
|
|
459
|
+
column,
|
|
460
|
+
index,
|
|
461
|
+
start: offsets[index] ?? 0,
|
|
462
|
+
size: sizes[index] ?? 0
|
|
463
|
+
})),
|
|
464
|
+
startOffset: 0,
|
|
465
|
+
endOffset: 0,
|
|
466
|
+
totalWidth,
|
|
467
|
+
visibleWidth: totalWidth,
|
|
468
|
+
startIndex: 0,
|
|
469
|
+
endIndex: Math.max(columns.length - 1, 0),
|
|
470
|
+
isVirtualized: false,
|
|
471
|
+
scrollToIndex
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
const startIndex = binarySearchOffsets(offsets, scrollLeft);
|
|
475
|
+
const endBoundary = scrollLeft + containerWidth;
|
|
476
|
+
const endIndex = binarySearchOffsets(offsets, Math.max(scrollLeft, endBoundary - 1));
|
|
477
|
+
const overscanStart = Math.max(0, startIndex - overscan);
|
|
478
|
+
const overscanEnd = Math.min(columns.length - 1, endIndex + overscan);
|
|
479
|
+
const virtualColumns = [];
|
|
480
|
+
for (let i = overscanStart; i <= overscanEnd; i++) {
|
|
481
|
+
virtualColumns.push({
|
|
482
|
+
column: columns[i],
|
|
483
|
+
index: i,
|
|
484
|
+
start: offsets[i] ?? 0,
|
|
485
|
+
size: sizes[i] ?? 0
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
const startOffset = offsets[overscanStart] ?? 0;
|
|
489
|
+
const visibleWidth = (offsets[overscanEnd + 1] ?? totalWidth) - startOffset;
|
|
490
|
+
const endOffset = totalWidth - (offsets[overscanEnd + 1] ?? totalWidth);
|
|
491
|
+
return {
|
|
492
|
+
virtualColumns,
|
|
493
|
+
startOffset,
|
|
494
|
+
endOffset,
|
|
495
|
+
totalWidth,
|
|
496
|
+
visibleWidth,
|
|
497
|
+
startIndex: overscanStart,
|
|
498
|
+
endIndex: overscanEnd,
|
|
499
|
+
isVirtualized: true,
|
|
500
|
+
scrollToIndex
|
|
501
|
+
};
|
|
502
|
+
}
|
|
339
503
|
var pretextPromise = null;
|
|
340
504
|
function loadPretext() {
|
|
341
505
|
if (pretextPromise) return pretextPromise;
|
|
@@ -386,7 +550,12 @@ function usePretextMeasurement({
|
|
|
386
550
|
}
|
|
387
551
|
prepareTimeRef.current = performance.now() - start;
|
|
388
552
|
return result;
|
|
389
|
-
}, [
|
|
553
|
+
}, [
|
|
554
|
+
pretext,
|
|
555
|
+
enabled,
|
|
556
|
+
data,
|
|
557
|
+
columns.map((c) => `${c.columnId}:${c.font}:${c.fixedHeight ? "F" : "T"}`).join("|")
|
|
558
|
+
]);
|
|
390
559
|
const measurement = React3.useMemo(() => {
|
|
391
560
|
if (!pretext || !preparedCells) {
|
|
392
561
|
return { rowHeights: null, prefixSums: null, totalHeight: 0 };
|
|
@@ -424,6 +593,7 @@ function usePretextMeasurement({
|
|
|
424
593
|
return {
|
|
425
594
|
rowHeights,
|
|
426
595
|
prefixSums,
|
|
596
|
+
// Safe: prefixSums has length data.length + 1, so [data.length] always exists
|
|
427
597
|
totalHeight: prefixSums[data.length]
|
|
428
598
|
};
|
|
429
599
|
}, [pretext, preparedCells, columnWidthsKey, minRowHeight, data.length]);
|
|
@@ -688,18 +858,10 @@ function CellDate({
|
|
|
688
858
|
if (raw == null) return null;
|
|
689
859
|
const date = raw instanceof Date ? raw : new Date(String(raw));
|
|
690
860
|
if (isNaN(date.getTime())) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "yable-cell-date", children: String(raw) });
|
|
691
|
-
const formatter =
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
timeZone: "UTC"
|
|
696
|
-
});
|
|
697
|
-
}
|
|
698
|
-
if (typeof format === "object") {
|
|
699
|
-
return new Intl.DateTimeFormat(locale, { ...format, timeZone: "UTC" });
|
|
700
|
-
}
|
|
701
|
-
return null;
|
|
702
|
-
}, [format, locale]);
|
|
861
|
+
const formatter = typeof format === "string" && format !== "relative" ? new Intl.DateTimeFormat(locale, {
|
|
862
|
+
...PRESETS[format],
|
|
863
|
+
timeZone: "UTC"
|
|
864
|
+
}) : typeof format === "object" ? new Intl.DateTimeFormat(locale, { ...format, timeZone: "UTC" }) : null;
|
|
703
865
|
const formatted = format === "relative" ? formatRelative(date) : formatter ? formatter.format(date) : date.toLocaleDateString(locale);
|
|
704
866
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: `yable-cell-date ${className ?? ""}`, title: date.toISOString(), children: formatted });
|
|
705
867
|
}
|
|
@@ -710,8 +872,14 @@ var measureRecipe9 = {
|
|
|
710
872
|
padding: 20
|
|
711
873
|
};
|
|
712
874
|
function isSafeUrl(url) {
|
|
713
|
-
const normalized = String(url).
|
|
714
|
-
|
|
875
|
+
const normalized = String(url).trim();
|
|
876
|
+
if (/^[/#?]/.test(normalized)) return true;
|
|
877
|
+
try {
|
|
878
|
+
const parsed = new URL(normalized, "https://placeholder.invalid");
|
|
879
|
+
return ["http:", "https:", "mailto:", "tel:"].includes(parsed.protocol);
|
|
880
|
+
} catch {
|
|
881
|
+
return false;
|
|
882
|
+
}
|
|
715
883
|
}
|
|
716
884
|
function CellLink({
|
|
717
885
|
context,
|
|
@@ -888,7 +1056,7 @@ function useTableContext() {
|
|
|
888
1056
|
const ctx = React3.useContext(TableContext);
|
|
889
1057
|
if (!ctx) {
|
|
890
1058
|
throw new Error(
|
|
891
|
-
"[yable] useTableContext must be used within a <Table> component. Did you forget to pass the `table` prop?"
|
|
1059
|
+
"[yable E001] useTableContext must be used within a <Table> component. Did you forget to pass the `table` prop?"
|
|
892
1060
|
);
|
|
893
1061
|
}
|
|
894
1062
|
return ctx;
|
|
@@ -938,12 +1106,234 @@ function SortIndicator({ direction, index }) {
|
|
|
938
1106
|
}
|
|
939
1107
|
);
|
|
940
1108
|
}
|
|
1109
|
+
function formatValue(value) {
|
|
1110
|
+
if (value == null || value === "") return "(empty)";
|
|
1111
|
+
if (typeof value === "string") return value;
|
|
1112
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
1113
|
+
if (value instanceof Date) return value.toISOString();
|
|
1114
|
+
return JSON.stringify(value);
|
|
1115
|
+
}
|
|
1116
|
+
function SetFilter({ column, className }) {
|
|
1117
|
+
const [open, setOpen] = React3.useState(false);
|
|
1118
|
+
const filterValue = column.getFilterValue();
|
|
1119
|
+
const selectedValues = Array.isArray(filterValue) ? filterValue : filterValue == null || filterValue === "" ? [] : [filterValue];
|
|
1120
|
+
const facetedUniqueValues = column.getFacetedUniqueValues();
|
|
1121
|
+
const options = Array.from(facetedUniqueValues.entries()).map(([value, count]) => ({
|
|
1122
|
+
value,
|
|
1123
|
+
count,
|
|
1124
|
+
label: formatValue(value)
|
|
1125
|
+
})).sort((a, b) => a.label.localeCompare(b.label));
|
|
1126
|
+
const selectedSet = new Set(selectedValues);
|
|
1127
|
+
const toggleValue = (value) => {
|
|
1128
|
+
const next = new Set(selectedSet);
|
|
1129
|
+
if (next.has(value)) {
|
|
1130
|
+
next.delete(value);
|
|
1131
|
+
} else {
|
|
1132
|
+
next.add(value);
|
|
1133
|
+
}
|
|
1134
|
+
const nextValues = Array.from(next);
|
|
1135
|
+
column.setFilterValue(nextValues.length > 0 ? nextValues : void 0);
|
|
1136
|
+
};
|
|
1137
|
+
const headerLabel = typeof column.columnDef.header === "string" ? column.columnDef.header : column.id;
|
|
1138
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1139
|
+
"div",
|
|
1140
|
+
{
|
|
1141
|
+
className: ["yable-set-filter", className].filter(Boolean).join(" "),
|
|
1142
|
+
style: { position: "relative" },
|
|
1143
|
+
children: [
|
|
1144
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1145
|
+
"button",
|
|
1146
|
+
{
|
|
1147
|
+
type: "button",
|
|
1148
|
+
className: "yable-set-filter-trigger",
|
|
1149
|
+
"aria-haspopup": "dialog",
|
|
1150
|
+
"aria-expanded": open,
|
|
1151
|
+
onClick: () => setOpen((prev) => !prev),
|
|
1152
|
+
style: {
|
|
1153
|
+
width: "100%",
|
|
1154
|
+
minHeight: 28,
|
|
1155
|
+
padding: "4px 8px",
|
|
1156
|
+
border: "1px solid rgba(127, 127, 127, 0.35)",
|
|
1157
|
+
borderRadius: 6,
|
|
1158
|
+
background: "transparent",
|
|
1159
|
+
font: "inherit",
|
|
1160
|
+
textAlign: "left",
|
|
1161
|
+
cursor: "pointer"
|
|
1162
|
+
},
|
|
1163
|
+
children: selectedValues.length > 0 ? `${selectedValues.length} selected` : `Filter ${headerLabel}`
|
|
1164
|
+
}
|
|
1165
|
+
),
|
|
1166
|
+
open && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1167
|
+
"div",
|
|
1168
|
+
{
|
|
1169
|
+
role: "dialog",
|
|
1170
|
+
"aria-label": `${headerLabel} set filter`,
|
|
1171
|
+
className: "yable-set-filter-popover",
|
|
1172
|
+
style: {
|
|
1173
|
+
position: "absolute",
|
|
1174
|
+
insetInlineStart: 0,
|
|
1175
|
+
top: "calc(100% + 4px)",
|
|
1176
|
+
zIndex: 20,
|
|
1177
|
+
width: 220,
|
|
1178
|
+
maxHeight: 240,
|
|
1179
|
+
overflow: "auto",
|
|
1180
|
+
padding: 8,
|
|
1181
|
+
border: "1px solid rgba(127, 127, 127, 0.35)",
|
|
1182
|
+
borderRadius: 8,
|
|
1183
|
+
background: "var(--yable-color-bg, #fff)",
|
|
1184
|
+
boxShadow: "0 10px 30px rgba(0, 0, 0, 0.12)"
|
|
1185
|
+
},
|
|
1186
|
+
children: [
|
|
1187
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1188
|
+
"div",
|
|
1189
|
+
{
|
|
1190
|
+
style: {
|
|
1191
|
+
display: "flex",
|
|
1192
|
+
alignItems: "center",
|
|
1193
|
+
justifyContent: "space-between",
|
|
1194
|
+
gap: 8,
|
|
1195
|
+
marginBottom: 8
|
|
1196
|
+
},
|
|
1197
|
+
children: [
|
|
1198
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { style: { fontSize: 12 }, children: headerLabel }),
|
|
1199
|
+
selectedValues.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1200
|
+
"button",
|
|
1201
|
+
{
|
|
1202
|
+
type: "button",
|
|
1203
|
+
onClick: () => column.setFilterValue(void 0),
|
|
1204
|
+
style: {
|
|
1205
|
+
border: "none",
|
|
1206
|
+
background: "transparent",
|
|
1207
|
+
padding: 0,
|
|
1208
|
+
cursor: "pointer",
|
|
1209
|
+
fontSize: 12
|
|
1210
|
+
},
|
|
1211
|
+
children: "Clear"
|
|
1212
|
+
}
|
|
1213
|
+
)
|
|
1214
|
+
]
|
|
1215
|
+
}
|
|
1216
|
+
),
|
|
1217
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-label": `${headerLabel} options`, children: [
|
|
1218
|
+
options.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 12, opacity: 0.75 }, children: "No values" }),
|
|
1219
|
+
options.map((option) => {
|
|
1220
|
+
const checked = selectedSet.has(option.value);
|
|
1221
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1222
|
+
"label",
|
|
1223
|
+
{
|
|
1224
|
+
style: {
|
|
1225
|
+
display: "flex",
|
|
1226
|
+
alignItems: "center",
|
|
1227
|
+
gap: 8,
|
|
1228
|
+
padding: "4px 0",
|
|
1229
|
+
fontSize: 12
|
|
1230
|
+
},
|
|
1231
|
+
children: [
|
|
1232
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1233
|
+
"input",
|
|
1234
|
+
{
|
|
1235
|
+
type: "checkbox",
|
|
1236
|
+
checked,
|
|
1237
|
+
onChange: () => toggleValue(option.value)
|
|
1238
|
+
}
|
|
1239
|
+
),
|
|
1240
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { flex: 1 }, children: option.label }),
|
|
1241
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { opacity: 0.6 }, children: option.count })
|
|
1242
|
+
]
|
|
1243
|
+
},
|
|
1244
|
+
`${option.label}-${option.count}`
|
|
1245
|
+
);
|
|
1246
|
+
})
|
|
1247
|
+
] })
|
|
1248
|
+
]
|
|
1249
|
+
}
|
|
1250
|
+
)
|
|
1251
|
+
]
|
|
1252
|
+
}
|
|
1253
|
+
);
|
|
1254
|
+
}
|
|
1255
|
+
function isSetCompatibleValue(value) {
|
|
1256
|
+
return value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
1257
|
+
}
|
|
1258
|
+
function inferFilterVariant(column) {
|
|
1259
|
+
const meta = column.columnDef.meta ?? {};
|
|
1260
|
+
if (meta.filterVariant) return meta.filterVariant;
|
|
1261
|
+
const uniqueValues = column.getFacetedUniqueValues();
|
|
1262
|
+
if (uniqueValues.size > 0 && uniqueValues.size <= 12) {
|
|
1263
|
+
const allValuesSupported = Array.from(uniqueValues.keys()).every(isSetCompatibleValue);
|
|
1264
|
+
if (allValuesSupported) return "set";
|
|
1265
|
+
}
|
|
1266
|
+
return "text";
|
|
1267
|
+
}
|
|
1268
|
+
function FloatingFilter({ column }) {
|
|
1269
|
+
const variant = inferFilterVariant(column);
|
|
1270
|
+
if (!column.getCanFilter()) {
|
|
1271
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { minHeight: 28 }, "aria-hidden": "true" });
|
|
1272
|
+
}
|
|
1273
|
+
if (variant === "set") {
|
|
1274
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SetFilter, { column });
|
|
1275
|
+
}
|
|
1276
|
+
const filterValue = column.getFilterValue();
|
|
1277
|
+
const normalizedValue = typeof filterValue === "string" || typeof filterValue === "number" ? String(filterValue) : "";
|
|
1278
|
+
const label = typeof column.columnDef.header === "string" ? column.columnDef.header : column.id;
|
|
1279
|
+
return /* @__PURE__ */ jsxRuntime.jsx("label", { style: { display: "block" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1280
|
+
"input",
|
|
1281
|
+
{
|
|
1282
|
+
"aria-label": `Filter ${label}`,
|
|
1283
|
+
className: "yable-floating-filter-input",
|
|
1284
|
+
value: normalizedValue,
|
|
1285
|
+
onChange: (event) => {
|
|
1286
|
+
const nextValue = event.target.value;
|
|
1287
|
+
column.setFilterValue(nextValue === "" ? void 0 : nextValue);
|
|
1288
|
+
},
|
|
1289
|
+
placeholder: `Filter ${label}`,
|
|
1290
|
+
style: {
|
|
1291
|
+
width: "100%",
|
|
1292
|
+
minHeight: 28,
|
|
1293
|
+
padding: "4px 8px",
|
|
1294
|
+
border: "1px solid rgba(127, 127, 127, 0.35)",
|
|
1295
|
+
borderRadius: 6,
|
|
1296
|
+
background: "transparent",
|
|
1297
|
+
font: "inherit"
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
) });
|
|
1301
|
+
}
|
|
941
1302
|
var DRAG_MIME = "application/yable-column";
|
|
942
1303
|
function TableHeader({
|
|
943
|
-
table
|
|
1304
|
+
table,
|
|
1305
|
+
floatingFilters = false
|
|
944
1306
|
}) {
|
|
945
1307
|
const headerGroups = table.getHeaderGroups();
|
|
946
|
-
|
|
1308
|
+
const visibleColumns = table.getVisibleLeafColumns();
|
|
1309
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("thead", { className: "yable-thead", children: [
|
|
1310
|
+
headerGroups.map((headerGroup) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "yable-header-row", children: headerGroup.headers.map((header) => /* @__PURE__ */ jsxRuntime.jsx(HeaderCell, { header, table }, header.id)) }, headerGroup.id)),
|
|
1311
|
+
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`)) })
|
|
1312
|
+
] });
|
|
1313
|
+
}
|
|
1314
|
+
function FloatingFilterCell({
|
|
1315
|
+
column
|
|
1316
|
+
}) {
|
|
1317
|
+
const style = React3.useMemo(() => {
|
|
1318
|
+
const next = {
|
|
1319
|
+
width: column.getSize(),
|
|
1320
|
+
minWidth: column.columnDef.minSize,
|
|
1321
|
+
maxWidth: column.columnDef.maxSize,
|
|
1322
|
+
padding: 6,
|
|
1323
|
+
verticalAlign: "top"
|
|
1324
|
+
};
|
|
1325
|
+
const pinned = column.getIsPinned();
|
|
1326
|
+
if (pinned) {
|
|
1327
|
+
next.position = "sticky";
|
|
1328
|
+
if (pinned === "left") {
|
|
1329
|
+
next.left = column.getStart("left");
|
|
1330
|
+
} else {
|
|
1331
|
+
next.right = column.getStart("right");
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
return next;
|
|
1335
|
+
}, [column]);
|
|
1336
|
+
return /* @__PURE__ */ jsxRuntime.jsx("th", { className: "yable-th yable-th--filter", role: "columnheader", style, children: /* @__PURE__ */ jsxRuntime.jsx(FloatingFilter, { column }) });
|
|
947
1337
|
}
|
|
948
1338
|
function HeaderCell({
|
|
949
1339
|
header,
|
|
@@ -1032,14 +1422,11 @@ function HeaderCell({
|
|
|
1032
1422
|
},
|
|
1033
1423
|
[canReorder]
|
|
1034
1424
|
);
|
|
1035
|
-
const handleDragLeave = React3.useCallback(
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
},
|
|
1041
|
-
[]
|
|
1042
|
-
);
|
|
1425
|
+
const handleDragLeave = React3.useCallback((e) => {
|
|
1426
|
+
const next = e.relatedTarget;
|
|
1427
|
+
if (next && e.currentTarget.contains(next)) return;
|
|
1428
|
+
setDragOver(null);
|
|
1429
|
+
}, []);
|
|
1043
1430
|
const handleDragEnd = React3.useCallback(() => {
|
|
1044
1431
|
setDragOver(null);
|
|
1045
1432
|
}, []);
|
|
@@ -1112,13 +1499,7 @@ function HeaderCell({
|
|
|
1112
1499
|
children: [
|
|
1113
1500
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "yable-th-content", children: [
|
|
1114
1501
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: headerContent }),
|
|
1115
|
-
canSort && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1116
|
-
SortIndicator,
|
|
1117
|
-
{
|
|
1118
|
-
direction: sortDirection,
|
|
1119
|
-
index: sortIndex > 0 ? sortIndex : void 0
|
|
1120
|
-
}
|
|
1121
|
-
)
|
|
1502
|
+
canSort && /* @__PURE__ */ jsxRuntime.jsx(SortIndicator, { direction: sortDirection, index: sortIndex > 0 ? sortIndex : void 0 })
|
|
1122
1503
|
] }),
|
|
1123
1504
|
canResize && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1124
1505
|
"div",
|
|
@@ -1243,6 +1624,10 @@ function TableCell({
|
|
|
1243
1624
|
const cellStatus = table.getCellStatus(cell.row.id, column.id);
|
|
1244
1625
|
const cellErrorMessage = table.getCellErrorMessage(cell.row.id, column.id);
|
|
1245
1626
|
const cellConflictWith = table.getCellConflictWith(cell.row.id, column.id);
|
|
1627
|
+
const selectionRange = table.getCellSelectionRange();
|
|
1628
|
+
const selectionEdges = table.getCellSelectionEdges(rowIndex, columnIndex);
|
|
1629
|
+
const isCellSelected = selectionEdges !== null;
|
|
1630
|
+
const isMultiCellSelection = selectionRange !== null && (selectionRange.start.rowIndex !== selectionRange.end.rowIndex || selectionRange.start.columnIndex !== selectionRange.end.columnIndex);
|
|
1246
1631
|
const overrideValue = cellStatus !== "idle" ? table.getCellRenderValue(cell.row.id, column.id) : void 0;
|
|
1247
1632
|
let content;
|
|
1248
1633
|
const cellDef = column.columnDef.cell;
|
|
@@ -1266,23 +1651,17 @@ function TableCell({
|
|
|
1266
1651
|
}
|
|
1267
1652
|
const handleClick = React3.useCallback(
|
|
1268
1653
|
(e) => {
|
|
1269
|
-
table.setFocusedCell({ rowIndex, columnIndex });
|
|
1270
|
-
const clickTarget = e.target;
|
|
1271
|
-
if (!isInteractiveClickTarget(clickTarget)) {
|
|
1272
|
-
const currentTarget = e.currentTarget;
|
|
1273
|
-
currentTarget.focus({ preventScroll: true });
|
|
1274
|
-
}
|
|
1275
1654
|
table.events.emit("cell:click", {
|
|
1276
1655
|
cell,
|
|
1277
1656
|
row: cell.row,
|
|
1278
1657
|
column: cell.column,
|
|
1279
1658
|
event: e.nativeEvent
|
|
1280
1659
|
});
|
|
1281
|
-
if (yableCore.canCellEnterEditMode(table, cell.row, column) && !isAlwaysEditable && !isEditing) {
|
|
1660
|
+
if (yableCore.canCellEnterEditMode(table, cell.row, column) && !isAlwaysEditable && !isEditing && !isMultiCellSelection && !e.shiftKey && !e.metaKey && !e.ctrlKey) {
|
|
1282
1661
|
table.startEditing(cell.row.id, column.id);
|
|
1283
1662
|
}
|
|
1284
1663
|
},
|
|
1285
|
-
[cell, column,
|
|
1664
|
+
[cell, column, isAlwaysEditable, isEditing, isMultiCellSelection, table]
|
|
1286
1665
|
);
|
|
1287
1666
|
const handleDoubleClick = React3.useCallback(
|
|
1288
1667
|
(e) => {
|
|
@@ -1310,9 +1689,34 @@ function TableCell({
|
|
|
1310
1689
|
if (!keyboardNavigationEnabled) return;
|
|
1311
1690
|
table.setFocusedCell({ rowIndex, columnIndex });
|
|
1312
1691
|
}, [columnIndex, keyboardNavigationEnabled, rowIndex, table]);
|
|
1692
|
+
const handleMouseDown = React3.useCallback(
|
|
1693
|
+
(e) => {
|
|
1694
|
+
if (e.button !== 0) return;
|
|
1695
|
+
const clickTarget = e.target;
|
|
1696
|
+
if (isInteractiveClickTarget(clickTarget)) return;
|
|
1697
|
+
e.preventDefault();
|
|
1698
|
+
table.setFocusedCell({ rowIndex, columnIndex });
|
|
1699
|
+
table.startCellRangeSelection({ rowIndex, columnIndex }, { extend: e.shiftKey });
|
|
1700
|
+
e.currentTarget.focus({ preventScroll: true });
|
|
1701
|
+
},
|
|
1702
|
+
[columnIndex, rowIndex, table]
|
|
1703
|
+
);
|
|
1704
|
+
const handleMouseEnter = React3.useCallback(() => {
|
|
1705
|
+
if (!table.getState().cellSelection?.isDragging) return;
|
|
1706
|
+
table.updateCellRangeSelection({ rowIndex, columnIndex });
|
|
1707
|
+
}, [columnIndex, rowIndex, table]);
|
|
1708
|
+
const handleMouseUp = React3.useCallback(() => {
|
|
1709
|
+
if (!table.getState().cellSelection?.isDragging) return;
|
|
1710
|
+
table.endCellRangeSelection();
|
|
1711
|
+
}, [table]);
|
|
1313
1712
|
const classNames = [
|
|
1314
1713
|
"yable-td",
|
|
1315
|
-
isFocused && "yable-cell--focused"
|
|
1714
|
+
isFocused && "yable-cell--focused",
|
|
1715
|
+
isCellSelected && "yable-cell--selected",
|
|
1716
|
+
selectionEdges?.top && "yable-cell--selection-top",
|
|
1717
|
+
selectionEdges?.right && "yable-cell--selection-right",
|
|
1718
|
+
selectionEdges?.bottom && "yable-cell--selection-bottom",
|
|
1719
|
+
selectionEdges?.left && "yable-cell--selection-left"
|
|
1316
1720
|
].filter(Boolean).join(" ");
|
|
1317
1721
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1318
1722
|
"td",
|
|
@@ -1326,10 +1730,14 @@ function TableCell({
|
|
|
1326
1730
|
"data-column-id": column.id,
|
|
1327
1731
|
"data-row-index": rowIndex,
|
|
1328
1732
|
"data-column-index": columnIndex,
|
|
1733
|
+
"data-cell-selected": isCellSelected || void 0,
|
|
1329
1734
|
"aria-rowindex": rowIndex + 1,
|
|
1330
1735
|
"aria-colindex": columnIndex + 1,
|
|
1331
1736
|
role: "gridcell",
|
|
1332
1737
|
tabIndex: keyboardNavigationEnabled ? isTabStop ? 0 : -1 : void 0,
|
|
1738
|
+
onMouseDown: handleMouseDown,
|
|
1739
|
+
onMouseEnter: handleMouseEnter,
|
|
1740
|
+
onMouseUp: handleMouseUp,
|
|
1333
1741
|
onClick: handleClick,
|
|
1334
1742
|
onDoubleClick: handleDoubleClick,
|
|
1335
1743
|
onContextMenu: handleContextMenu,
|
|
@@ -1454,14 +1862,15 @@ var CellErrorBoundary = class extends React3__default.default.Component {
|
|
|
1454
1862
|
return this.props.children;
|
|
1455
1863
|
}
|
|
1456
1864
|
};
|
|
1457
|
-
function TableBody({
|
|
1458
|
-
table,
|
|
1459
|
-
clickableRows
|
|
1460
|
-
}) {
|
|
1865
|
+
function TableBody({ table, clickableRows }) {
|
|
1461
1866
|
const rows = table.getRowModel().rows;
|
|
1462
1867
|
const visibleColumns = table.getVisibleLeafColumns();
|
|
1463
1868
|
const activeCell = table.getState().editing.activeCell;
|
|
1464
1869
|
const focusedCell = table.getFocusedCell();
|
|
1870
|
+
const cellSelection = table.getState().cellSelection ?? {
|
|
1871
|
+
range: null,
|
|
1872
|
+
isDragging: false
|
|
1873
|
+
};
|
|
1465
1874
|
const options = table.options;
|
|
1466
1875
|
const enableVirtualization = options.enableVirtualization ?? false;
|
|
1467
1876
|
const scrollContainerRef = React3.useRef(null);
|
|
@@ -1479,6 +1888,18 @@ function TableBody({
|
|
|
1479
1888
|
pretextHeights,
|
|
1480
1889
|
pretextPrefixSums
|
|
1481
1890
|
});
|
|
1891
|
+
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"}`;
|
|
1892
|
+
React3.useEffect(() => {
|
|
1893
|
+
const handleWindowMouseUp = () => {
|
|
1894
|
+
if (table.getState().cellSelection?.isDragging) {
|
|
1895
|
+
table.endCellRangeSelection();
|
|
1896
|
+
}
|
|
1897
|
+
};
|
|
1898
|
+
window.addEventListener("mouseup", handleWindowMouseUp);
|
|
1899
|
+
return () => {
|
|
1900
|
+
window.removeEventListener("mouseup", handleWindowMouseUp);
|
|
1901
|
+
};
|
|
1902
|
+
}, [table]);
|
|
1482
1903
|
if (!enableVirtualization) {
|
|
1483
1904
|
return /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "yable-tbody", children: rows.map((row, rowIndex) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1484
1905
|
MemoizedTableRow,
|
|
@@ -1492,6 +1913,7 @@ function TableBody({
|
|
|
1492
1913
|
activeColumnId: activeCell?.rowId === row.id ? activeCell.columnId : void 0,
|
|
1493
1914
|
focusedColumnIndex: focusedCell?.rowIndex === rowIndex ? focusedCell.columnIndex : null,
|
|
1494
1915
|
hasFocusedCell: focusedCell !== null,
|
|
1916
|
+
cellSelectionKey,
|
|
1495
1917
|
clickable: clickableRows
|
|
1496
1918
|
},
|
|
1497
1919
|
row.id
|
|
@@ -1500,73 +1922,67 @@ function TableBody({
|
|
|
1500
1922
|
const hasPretextData = !!(pretextHeights && pretextPrefixSums);
|
|
1501
1923
|
const fixedRowHeight = typeof rowHeight === "number" && !hasPretextData ? rowHeight : void 0;
|
|
1502
1924
|
const containerHeight = hasPretextData ? Math.min(totalHeight, 800) : fixedRowHeight ? Math.min(totalHeight, fixedRowHeight * 20) : 600;
|
|
1503
|
-
return /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "yable-tbody", children: /* @__PURE__ */ jsxRuntime.jsx("tr", { style: { height: 0, padding: 0, border: "none" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1504
|
-
"
|
|
1925
|
+
return /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "yable-tbody", children: /* @__PURE__ */ jsxRuntime.jsx("tr", { style: { height: 0, padding: 0, border: "none" }, children: /* @__PURE__ */ jsxRuntime.jsx("td", { style: { height: 0, padding: 0, border: "none" }, colSpan: visibleColumns.length, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1926
|
+
"div",
|
|
1505
1927
|
{
|
|
1506
|
-
|
|
1507
|
-
|
|
1928
|
+
ref: scrollContainerRef,
|
|
1929
|
+
className: "yable-virtual-scroll-container",
|
|
1930
|
+
style: {
|
|
1931
|
+
overflowY: "auto",
|
|
1932
|
+
height: containerHeight,
|
|
1933
|
+
position: "relative"
|
|
1934
|
+
},
|
|
1508
1935
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1509
1936
|
"div",
|
|
1510
1937
|
{
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
style: {
|
|
1514
|
-
overflowY: "auto",
|
|
1515
|
-
height: containerHeight,
|
|
1516
|
-
position: "relative"
|
|
1517
|
-
},
|
|
1938
|
+
className: "yable-virtual-spacer",
|
|
1939
|
+
style: { height: totalHeight, position: "relative" },
|
|
1518
1940
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1519
|
-
"
|
|
1941
|
+
"table",
|
|
1520
1942
|
{
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1943
|
+
style: {
|
|
1944
|
+
position: "absolute",
|
|
1945
|
+
top: 0,
|
|
1946
|
+
left: 0,
|
|
1947
|
+
width: "100%",
|
|
1948
|
+
tableLayout: "fixed",
|
|
1949
|
+
borderCollapse: "collapse"
|
|
1950
|
+
},
|
|
1951
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: virtualRows.map((vRow) => {
|
|
1952
|
+
const row = rows[vRow.index];
|
|
1953
|
+
if (!row) return null;
|
|
1954
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1955
|
+
MemoizedTableRow,
|
|
1956
|
+
{
|
|
1957
|
+
row,
|
|
1958
|
+
table,
|
|
1959
|
+
rowIndex: vRow.index,
|
|
1960
|
+
visibleColumns,
|
|
1961
|
+
isSelected: row.getIsSelected(),
|
|
1962
|
+
isExpanded: row.getIsExpanded(),
|
|
1963
|
+
activeColumnId: activeCell?.rowId === row.id ? activeCell.columnId : void 0,
|
|
1964
|
+
focusedColumnIndex: focusedCell?.rowIndex === vRow.index ? focusedCell.columnIndex : null,
|
|
1965
|
+
hasFocusedCell: focusedCell !== null,
|
|
1966
|
+
cellSelectionKey,
|
|
1967
|
+
clickable: clickableRows,
|
|
1968
|
+
virtualStyle: {
|
|
1969
|
+
position: "absolute",
|
|
1970
|
+
top: 0,
|
|
1971
|
+
left: 0,
|
|
1972
|
+
width: "100%",
|
|
1973
|
+
height: vRow.size,
|
|
1974
|
+
transform: `translateY(${vRow.start}px)`
|
|
1975
|
+
}
|
|
1533
1976
|
},
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1538
|
-
MemoizedTableRow,
|
|
1539
|
-
{
|
|
1540
|
-
row,
|
|
1541
|
-
table,
|
|
1542
|
-
rowIndex: vRow.index,
|
|
1543
|
-
visibleColumns,
|
|
1544
|
-
isSelected: row.getIsSelected(),
|
|
1545
|
-
isExpanded: row.getIsExpanded(),
|
|
1546
|
-
activeColumnId: activeCell?.rowId === row.id ? activeCell.columnId : void 0,
|
|
1547
|
-
focusedColumnIndex: focusedCell?.rowIndex === vRow.index ? focusedCell.columnIndex : null,
|
|
1548
|
-
hasFocusedCell: focusedCell !== null,
|
|
1549
|
-
clickable: clickableRows,
|
|
1550
|
-
virtualStyle: {
|
|
1551
|
-
position: "absolute",
|
|
1552
|
-
top: 0,
|
|
1553
|
-
left: 0,
|
|
1554
|
-
width: "100%",
|
|
1555
|
-
height: vRow.size,
|
|
1556
|
-
transform: `translateY(${vRow.start}px)`
|
|
1557
|
-
}
|
|
1558
|
-
},
|
|
1559
|
-
row.id
|
|
1560
|
-
);
|
|
1561
|
-
}) })
|
|
1562
|
-
}
|
|
1563
|
-
)
|
|
1977
|
+
row.id
|
|
1978
|
+
);
|
|
1979
|
+
}) })
|
|
1564
1980
|
}
|
|
1565
1981
|
)
|
|
1566
1982
|
}
|
|
1567
1983
|
)
|
|
1568
1984
|
}
|
|
1569
|
-
) }) });
|
|
1985
|
+
) }) }) });
|
|
1570
1986
|
}
|
|
1571
1987
|
function TableRowInner({
|
|
1572
1988
|
row,
|
|
@@ -1578,10 +1994,12 @@ function TableRowInner({
|
|
|
1578
1994
|
activeColumnId,
|
|
1579
1995
|
focusedColumnIndex,
|
|
1580
1996
|
hasFocusedCell,
|
|
1997
|
+
cellSelectionKey: _cellSelectionKey,
|
|
1581
1998
|
clickable,
|
|
1582
1999
|
virtualStyle
|
|
1583
2000
|
}) {
|
|
1584
|
-
const
|
|
2001
|
+
const allCells = row.getAllCells();
|
|
2002
|
+
const visibleCells = visibleColumns.map((column) => allCells.find((cell) => cell.column.id === column.id)).filter((cell) => cell != null);
|
|
1585
2003
|
const handleClick = React3.useCallback(
|
|
1586
2004
|
(e) => {
|
|
1587
2005
|
if (clickable) {
|
|
@@ -1611,6 +2029,8 @@ function TableRowInner({
|
|
|
1611
2029
|
},
|
|
1612
2030
|
[table.events, row]
|
|
1613
2031
|
);
|
|
2032
|
+
const selectionEnabled = Boolean(table.options.enableRowSelection);
|
|
2033
|
+
const expansionEnabled = Boolean(table.options.enableExpanding);
|
|
1614
2034
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1615
2035
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1616
2036
|
"tr",
|
|
@@ -1622,6 +2042,8 @@ function TableRowInner({
|
|
|
1622
2042
|
"data-clickable": clickable || void 0,
|
|
1623
2043
|
"data-row-id": row.id,
|
|
1624
2044
|
"data-row-index": rowIndex,
|
|
2045
|
+
"aria-selected": selectionEnabled ? isSelected : void 0,
|
|
2046
|
+
"aria-expanded": expansionEnabled ? isExpanded : void 0,
|
|
1625
2047
|
onClick: handleClick,
|
|
1626
2048
|
onDoubleClick: handleDoubleClick,
|
|
1627
2049
|
onContextMenu: handleContextMenu,
|
|
@@ -1663,6 +2085,7 @@ function areRowPropsEqual(prev, next) {
|
|
|
1663
2085
|
if (prev.activeColumnId !== next.activeColumnId) return false;
|
|
1664
2086
|
if (prev.focusedColumnIndex !== next.focusedColumnIndex) return false;
|
|
1665
2087
|
if (prev.hasFocusedCell !== next.hasFocusedCell) return false;
|
|
2088
|
+
if (prev.cellSelectionKey !== next.cellSelectionKey) return false;
|
|
1666
2089
|
if (prev.virtualStyle !== next.virtualStyle) {
|
|
1667
2090
|
if (!prev.virtualStyle || !next.virtualStyle) return false;
|
|
1668
2091
|
if (prev.virtualStyle.transform !== next.virtualStyle.transform) return false;
|
|
@@ -1672,9 +2095,7 @@ function areRowPropsEqual(prev, next) {
|
|
|
1672
2095
|
return true;
|
|
1673
2096
|
}
|
|
1674
2097
|
var MemoizedTableRow = React3__default.default.memo(TableRowInner, areRowPropsEqual);
|
|
1675
|
-
function TableFooter({
|
|
1676
|
-
table
|
|
1677
|
-
}) {
|
|
2098
|
+
function TableFooter({ table }) {
|
|
1678
2099
|
const footerGroups = table.getFooterGroups();
|
|
1679
2100
|
if (!footerGroups.length) return null;
|
|
1680
2101
|
return /* @__PURE__ */ jsxRuntime.jsx("tfoot", { className: "yable-tfoot", children: footerGroups.map((footerGroup) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "yable-tr", children: footerGroup.headers.map((header) => {
|
|
@@ -1720,19 +2141,20 @@ function Spinner() {
|
|
|
1720
2141
|
function LoadingOverlay({
|
|
1721
2142
|
loading,
|
|
1722
2143
|
loadingComponent,
|
|
1723
|
-
loadingText
|
|
2144
|
+
loadingText
|
|
1724
2145
|
}) {
|
|
1725
2146
|
if (!loading) return null;
|
|
2147
|
+
const resolvedText = loadingText ?? yableCore.getDefaultLocale().loadingText;
|
|
1726
2148
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1727
2149
|
"div",
|
|
1728
2150
|
{
|
|
1729
2151
|
className: "yable-overlay-loading",
|
|
1730
2152
|
role: "alert",
|
|
1731
2153
|
"aria-busy": "true",
|
|
1732
|
-
"aria-label":
|
|
2154
|
+
"aria-label": resolvedText,
|
|
1733
2155
|
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "yable-overlay-loading-content", children: loadingComponent ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1734
2156
|
/* @__PURE__ */ jsxRuntime.jsx(Spinner, {}),
|
|
1735
|
-
|
|
2157
|
+
resolvedText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "yable-overlay-loading-text", children: resolvedText })
|
|
1736
2158
|
] }) })
|
|
1737
2159
|
}
|
|
1738
2160
|
);
|
|
@@ -1850,8 +2272,9 @@ function NoRowsOverlay({
|
|
|
1850
2272
|
if (emptyComponent) {
|
|
1851
2273
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "yable-overlay-empty", children: emptyComponent });
|
|
1852
2274
|
}
|
|
1853
|
-
const
|
|
1854
|
-
const
|
|
2275
|
+
const locale = yableCore.getDefaultLocale();
|
|
2276
|
+
const defaultMessage = isFiltered ? locale.emptyNoResults : locale.emptyNoData;
|
|
2277
|
+
const defaultDetail = isFiltered ? locale.emptyNoResultsDetail : locale.emptyNoDataDetail;
|
|
1855
2278
|
const icon = emptyIcon ?? (isFiltered ? /* @__PURE__ */ jsxRuntime.jsx(DefaultFilteredIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(DefaultEmptyIcon, {}));
|
|
1856
2279
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "yable-overlay-empty", role: "status", children: [
|
|
1857
2280
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "yable-overlay-empty-icon-wrapper", children: icon }),
|
|
@@ -2435,11 +2858,11 @@ function ContextMenu({
|
|
|
2435
2858
|
}
|
|
2436
2859
|
if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
2437
2860
|
e.preventDefault();
|
|
2438
|
-
const items2 = menuRef.current?.querySelectorAll(
|
|
2439
|
-
|
|
2440
|
-
const currentIndex = Array.from(items2).findIndex(
|
|
2441
|
-
(el) => el === document.activeElement
|
|
2861
|
+
const items2 = menuRef.current?.querySelectorAll(
|
|
2862
|
+
'[role="menuitem"]:not([aria-disabled="true"])'
|
|
2442
2863
|
);
|
|
2864
|
+
if (!items2 || items2.length === 0) return;
|
|
2865
|
+
const currentIndex = Array.from(items2).findIndex((el) => el === document.activeElement);
|
|
2443
2866
|
let nextIndex;
|
|
2444
2867
|
if (e.key === "ArrowDown") {
|
|
2445
2868
|
nextIndex = currentIndex < items2.length - 1 ? currentIndex + 1 : 0;
|
|
@@ -2484,11 +2907,7 @@ function ContextMenu({
|
|
|
2484
2907
|
navigator.clipboard?.readText().then((text) => {
|
|
2485
2908
|
const editing = table.getState().editing;
|
|
2486
2909
|
if (editing?.activeCell) {
|
|
2487
|
-
table.pasteFromClipboard(
|
|
2488
|
-
text,
|
|
2489
|
-
editing.activeCell.rowId,
|
|
2490
|
-
editing.activeCell.columnId
|
|
2491
|
-
);
|
|
2910
|
+
table.pasteFromClipboard(text, editing.activeCell.rowId, editing.activeCell.columnId);
|
|
2492
2911
|
}
|
|
2493
2912
|
}).catch(() => {
|
|
2494
2913
|
});
|
|
@@ -2828,6 +3247,12 @@ function isEditableTarget(element) {
|
|
|
2828
3247
|
}
|
|
2829
3248
|
return element.isContentEditable;
|
|
2830
3249
|
}
|
|
3250
|
+
function filterHeaderGroups(groups, visibleColumnIds) {
|
|
3251
|
+
return groups.map((group) => ({
|
|
3252
|
+
...group,
|
|
3253
|
+
headers: group.headers.filter((header) => visibleColumnIds.has(header.column.id))
|
|
3254
|
+
})).filter((group) => group.headers.length > 0);
|
|
3255
|
+
}
|
|
2831
3256
|
function Table({
|
|
2832
3257
|
table,
|
|
2833
3258
|
stickyHeader,
|
|
@@ -2840,7 +3265,7 @@ function Table({
|
|
|
2840
3265
|
loading,
|
|
2841
3266
|
loadingComponent,
|
|
2842
3267
|
loadingText,
|
|
2843
|
-
emptyMessage
|
|
3268
|
+
emptyMessage,
|
|
2844
3269
|
emptyComponent,
|
|
2845
3270
|
emptyIcon,
|
|
2846
3271
|
emptyDetail,
|
|
@@ -2854,6 +3279,10 @@ function Table({
|
|
|
2854
3279
|
sidebar,
|
|
2855
3280
|
sidebarPanels = ["columns", "filters"],
|
|
2856
3281
|
defaultSidebarPanel,
|
|
3282
|
+
floatingFilters,
|
|
3283
|
+
columnVirtualization,
|
|
3284
|
+
columnVirtualizationOverscan,
|
|
3285
|
+
ariaLabel,
|
|
2857
3286
|
...rest
|
|
2858
3287
|
}) {
|
|
2859
3288
|
const [sidebarOpen, setSidebarOpen] = React3.useState(false);
|
|
@@ -2861,6 +3290,7 @@ function Table({
|
|
|
2861
3290
|
defaultSidebarPanel ?? "columns"
|
|
2862
3291
|
);
|
|
2863
3292
|
const containerRef = React3.useRef(null);
|
|
3293
|
+
const horizontalScrollRef = React3.useRef(null);
|
|
2864
3294
|
const isRtl = direction === "rtl";
|
|
2865
3295
|
const classNames = [
|
|
2866
3296
|
"yable",
|
|
@@ -2878,8 +3308,86 @@ function Table({
|
|
|
2878
3308
|
const hasGlobalFilter = Boolean(table.getState().globalFilter);
|
|
2879
3309
|
const hasColumnFilters = table.getState().columnFilters.length > 0;
|
|
2880
3310
|
const isFiltered = hasGlobalFilter || hasColumnFilters;
|
|
3311
|
+
const allVisibleColumns = table.getVisibleLeafColumns();
|
|
3312
|
+
const hasPinnedColumns = table.getLeftVisibleLeafColumns().length > 0 || table.getRightVisibleLeafColumns().length > 0;
|
|
3313
|
+
const hasGroupedHeaders = table.getHeaderGroups().length > 1;
|
|
3314
|
+
const canVirtualizeColumns = Boolean(columnVirtualization) && !hasPinnedColumns && !hasGroupedHeaders && allVisibleColumns.length > 0;
|
|
3315
|
+
const columnVirtualState = useColumnVirtualization({
|
|
3316
|
+
containerRef: horizontalScrollRef,
|
|
3317
|
+
columns: allVisibleColumns,
|
|
3318
|
+
overscan: columnVirtualizationOverscan ?? 2,
|
|
3319
|
+
enabled: canVirtualizeColumns
|
|
3320
|
+
});
|
|
3321
|
+
const renderTable = React3.useMemo(() => {
|
|
3322
|
+
if (!canVirtualizeColumns || !columnVirtualState.isVirtualized) {
|
|
3323
|
+
return table;
|
|
3324
|
+
}
|
|
3325
|
+
const virtualColumns = columnVirtualState.virtualColumns.map((entry) => entry.column);
|
|
3326
|
+
const visibleColumnIds = new Set(virtualColumns.map((column) => column.id));
|
|
3327
|
+
const next = Object.create(table);
|
|
3328
|
+
next.getVisibleFlatColumns = () => virtualColumns;
|
|
3329
|
+
next.getVisibleLeafColumns = () => virtualColumns;
|
|
3330
|
+
next.getCenterVisibleLeafColumns = () => virtualColumns;
|
|
3331
|
+
next.getLeftVisibleLeafColumns = () => [];
|
|
3332
|
+
next.getRightVisibleLeafColumns = () => [];
|
|
3333
|
+
next.getHeaderGroups = () => filterHeaderGroups(table.getHeaderGroups(), visibleColumnIds);
|
|
3334
|
+
next.getCenterHeaderGroups = () => filterHeaderGroups(table.getCenterHeaderGroups(), visibleColumnIds);
|
|
3335
|
+
next.getFooterGroups = () => filterHeaderGroups(table.getFooterGroups(), visibleColumnIds);
|
|
3336
|
+
next.getCenterFooterGroups = () => filterHeaderGroups(table.getCenterFooterGroups(), visibleColumnIds);
|
|
3337
|
+
return next;
|
|
3338
|
+
}, [
|
|
3339
|
+
canVirtualizeColumns,
|
|
3340
|
+
columnVirtualState.isVirtualized,
|
|
3341
|
+
columnVirtualState.virtualColumns,
|
|
3342
|
+
table
|
|
3343
|
+
]);
|
|
3344
|
+
const showColumnVirtualizationShell = canVirtualizeColumns;
|
|
2881
3345
|
const contextMenu = useContextMenu();
|
|
2882
3346
|
useKeyboardNavigation(table, { containerRef });
|
|
3347
|
+
const [announcement, setAnnouncement] = React3.useState("");
|
|
3348
|
+
const prevSortingRef = React3.useRef(table.getState().sorting);
|
|
3349
|
+
const prevFilterCountRef = React3.useRef(rows.length);
|
|
3350
|
+
const prevHasFiltersRef = React3.useRef(isFiltered);
|
|
3351
|
+
const prevPaginationRef = React3.useRef(table.getState().pagination);
|
|
3352
|
+
const isFirstRenderRef = React3.useRef(true);
|
|
3353
|
+
React3.useEffect(() => {
|
|
3354
|
+
if (isFirstRenderRef.current) {
|
|
3355
|
+
isFirstRenderRef.current = false;
|
|
3356
|
+
return;
|
|
3357
|
+
}
|
|
3358
|
+
const currentSorting = table.getState().sorting;
|
|
3359
|
+
const currentPagination = table.getState().pagination;
|
|
3360
|
+
const currentRowCount = rows.length;
|
|
3361
|
+
const currentIsFiltered = isFiltered;
|
|
3362
|
+
if (JSON.stringify(currentSorting) !== JSON.stringify(prevSortingRef.current)) {
|
|
3363
|
+
prevSortingRef.current = currentSorting;
|
|
3364
|
+
const firstSort = currentSorting[0];
|
|
3365
|
+
if (firstSort) {
|
|
3366
|
+
const column = table.getColumn(firstSort.id);
|
|
3367
|
+
const headerDef = column?.columnDef.header;
|
|
3368
|
+
const columnName = typeof headerDef === "string" ? headerDef : firstSort.id;
|
|
3369
|
+
const direction2 = firstSort.desc ? "descending" : "ascending";
|
|
3370
|
+
setAnnouncement(`Sorted by ${columnName} ${direction2}`);
|
|
3371
|
+
return;
|
|
3372
|
+
}
|
|
3373
|
+
}
|
|
3374
|
+
if (currentRowCount !== prevFilterCountRef.current || currentIsFiltered !== prevHasFiltersRef.current) {
|
|
3375
|
+
prevFilterCountRef.current = currentRowCount;
|
|
3376
|
+
prevHasFiltersRef.current = currentIsFiltered;
|
|
3377
|
+
if (currentIsFiltered) {
|
|
3378
|
+
setAnnouncement(`${currentRowCount} rows after filtering`);
|
|
3379
|
+
return;
|
|
3380
|
+
}
|
|
3381
|
+
}
|
|
3382
|
+
if (JSON.stringify(currentPagination) !== JSON.stringify(prevPaginationRef.current)) {
|
|
3383
|
+
prevPaginationRef.current = currentPagination;
|
|
3384
|
+
const pageCount = table.getPageCount();
|
|
3385
|
+
if (pageCount > 0) {
|
|
3386
|
+
setAnnouncement(`Page ${currentPagination.pageIndex + 1} of ${pageCount}`);
|
|
3387
|
+
return;
|
|
3388
|
+
}
|
|
3389
|
+
}
|
|
3390
|
+
});
|
|
2883
3391
|
const handleContextMenu = React3.useCallback(
|
|
2884
3392
|
(e) => {
|
|
2885
3393
|
e.preventDefault();
|
|
@@ -2887,6 +3395,24 @@ function Table({
|
|
|
2887
3395
|
},
|
|
2888
3396
|
[contextMenu, table]
|
|
2889
3397
|
);
|
|
3398
|
+
const tableNode = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3399
|
+
"table",
|
|
3400
|
+
{
|
|
3401
|
+
className: "yable-table",
|
|
3402
|
+
style: columnVirtualState.isVirtualized ? {
|
|
3403
|
+
width: columnVirtualState.visibleWidth,
|
|
3404
|
+
minWidth: columnVirtualState.visibleWidth,
|
|
3405
|
+
marginLeft: columnVirtualState.startOffset,
|
|
3406
|
+
tableLayout: "fixed"
|
|
3407
|
+
} : void 0,
|
|
3408
|
+
"data-column-virtualized": columnVirtualState.isVirtualized || void 0,
|
|
3409
|
+
children: [
|
|
3410
|
+
/* @__PURE__ */ jsxRuntime.jsx(TableHeader, { table: renderTable, floatingFilters }),
|
|
3411
|
+
/* @__PURE__ */ jsxRuntime.jsx(TableBody, { table: renderTable, clickableRows }),
|
|
3412
|
+
footer && /* @__PURE__ */ jsxRuntime.jsx(TableFooter, { table: renderTable })
|
|
3413
|
+
]
|
|
3414
|
+
}
|
|
3415
|
+
);
|
|
2890
3416
|
return /* @__PURE__ */ jsxRuntime.jsx(TableProvider, { value: table, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2891
3417
|
"div",
|
|
2892
3418
|
{
|
|
@@ -2895,23 +3421,40 @@ function Table({
|
|
|
2895
3421
|
"data-theme": theme,
|
|
2896
3422
|
dir: direction,
|
|
2897
3423
|
role: "grid",
|
|
3424
|
+
"aria-label": ariaLabel ?? "Data table",
|
|
2898
3425
|
"aria-rowcount": table.getRowModel().rows.length,
|
|
2899
3426
|
"aria-colcount": table.getVisibleLeafColumns().length,
|
|
2900
3427
|
onContextMenu: handleContextMenu,
|
|
2901
3428
|
...rest,
|
|
2902
3429
|
children: [
|
|
2903
3430
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "yable-main", children: [
|
|
2904
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
3431
|
+
showColumnVirtualizationShell ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3432
|
+
"div",
|
|
3433
|
+
{
|
|
3434
|
+
ref: horizontalScrollRef,
|
|
3435
|
+
className: "yable-horizontal-scroll-container",
|
|
3436
|
+
style: {
|
|
3437
|
+
overflowX: "auto",
|
|
3438
|
+
overflowY: "visible",
|
|
3439
|
+
maxWidth: "100%",
|
|
3440
|
+
position: "relative"
|
|
3441
|
+
},
|
|
3442
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3443
|
+
"div",
|
|
3444
|
+
{
|
|
3445
|
+
className: "yable-horizontal-scroll-inner",
|
|
3446
|
+
style: {
|
|
3447
|
+
width: Math.max(columnVirtualState.totalWidth, columnVirtualState.visibleWidth),
|
|
3448
|
+
minWidth: Math.max(
|
|
3449
|
+
columnVirtualState.totalWidth,
|
|
3450
|
+
columnVirtualState.visibleWidth
|
|
3451
|
+
)
|
|
3452
|
+
},
|
|
3453
|
+
children: tableNode
|
|
3454
|
+
}
|
|
3455
|
+
)
|
|
3456
|
+
}
|
|
3457
|
+
) : tableNode,
|
|
2915
3458
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2916
3459
|
LoadingOverlay,
|
|
2917
3460
|
{
|
|
@@ -2952,6 +3495,24 @@ function Table({
|
|
|
2952
3495
|
onClose: contextMenu.close,
|
|
2953
3496
|
table
|
|
2954
3497
|
}
|
|
3498
|
+
),
|
|
3499
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3500
|
+
"div",
|
|
3501
|
+
{
|
|
3502
|
+
role: "status",
|
|
3503
|
+
"aria-live": "polite",
|
|
3504
|
+
"aria-atomic": "true",
|
|
3505
|
+
style: {
|
|
3506
|
+
position: "absolute",
|
|
3507
|
+
width: "1px",
|
|
3508
|
+
height: "1px",
|
|
3509
|
+
overflow: "hidden",
|
|
3510
|
+
clip: "rect(0,0,0,0)",
|
|
3511
|
+
whiteSpace: "nowrap",
|
|
3512
|
+
border: 0
|
|
3513
|
+
},
|
|
3514
|
+
children: announcement
|
|
3515
|
+
}
|
|
2955
3516
|
)
|
|
2956
3517
|
]
|
|
2957
3518
|
}
|
|
@@ -2992,9 +3553,10 @@ function Pagination({
|
|
|
2992
3553
|
const to = Math.min((pageIndex + 1) * pageSize, totalRows);
|
|
2993
3554
|
const canPrev = table.getCanPreviousPage();
|
|
2994
3555
|
const canNext = table.getCanNextPage();
|
|
3556
|
+
const locale = yableCore.getDefaultLocale();
|
|
2995
3557
|
return /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "yable-pagination", role: "navigation", "aria-label": "Table pagination", children: [
|
|
2996
3558
|
showInfo && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "yable-pagination-info", children: [
|
|
2997
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "yable-pagination-info-text", children: totalRows > 0 ? `${from}\u2013${to}
|
|
3559
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "yable-pagination-info-text", children: totalRows > 0 ? `${from}\u2013${to} ${locale.paginationOf} ${totalRows}` : locale.paginationNoResults }),
|
|
2998
3560
|
showPageSize && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "yable-pagination-select-wrapper", children: [
|
|
2999
3561
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3000
3562
|
"select",
|
|
@@ -3007,7 +3569,8 @@ function Pagination({
|
|
|
3007
3569
|
"aria-label": "Rows per page",
|
|
3008
3570
|
children: pageSizes.map((size) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: size, children: [
|
|
3009
3571
|
size,
|
|
3010
|
-
"
|
|
3572
|
+
" ",
|
|
3573
|
+
locale.paginationRows
|
|
3011
3574
|
] }, size))
|
|
3012
3575
|
}
|
|
3013
3576
|
),
|
|
@@ -3022,8 +3585,8 @@ function Pagination({
|
|
|
3022
3585
|
className: "yable-pagination-btn yable-pagination-btn--nav",
|
|
3023
3586
|
onClick: () => table.setPageIndex(0),
|
|
3024
3587
|
disabled: !canPrev,
|
|
3025
|
-
"aria-label":
|
|
3026
|
-
title:
|
|
3588
|
+
"aria-label": locale.paginationFirstPage,
|
|
3589
|
+
title: locale.paginationFirstPage,
|
|
3027
3590
|
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronFirstIcon, {})
|
|
3028
3591
|
}
|
|
3029
3592
|
),
|
|
@@ -3034,8 +3597,8 @@ function Pagination({
|
|
|
3034
3597
|
className: "yable-pagination-btn yable-pagination-btn--nav",
|
|
3035
3598
|
onClick: () => table.previousPage(),
|
|
3036
3599
|
disabled: !canPrev,
|
|
3037
|
-
"aria-label":
|
|
3038
|
-
title:
|
|
3600
|
+
"aria-label": locale.paginationPreviousPage,
|
|
3601
|
+
title: locale.paginationPreviousPage,
|
|
3039
3602
|
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, {})
|
|
3040
3603
|
}
|
|
3041
3604
|
),
|
|
@@ -3059,7 +3622,7 @@ function Pagination({
|
|
|
3059
3622
|
className: `yable-pagination-btn yable-pagination-btn--page${page === pageIndex ? " yable-pagination-btn--active" : ""}`,
|
|
3060
3623
|
"data-active": page === pageIndex ? "true" : void 0,
|
|
3061
3624
|
onClick: () => table.setPageIndex(page),
|
|
3062
|
-
"aria-label":
|
|
3625
|
+
"aria-label": `${locale.paginationPage} ${page + 1}`,
|
|
3063
3626
|
"aria-current": page === pageIndex ? "page" : void 0,
|
|
3064
3627
|
children: page + 1
|
|
3065
3628
|
},
|
|
@@ -3073,8 +3636,8 @@ function Pagination({
|
|
|
3073
3636
|
className: "yable-pagination-btn yable-pagination-btn--nav",
|
|
3074
3637
|
onClick: () => table.nextPage(),
|
|
3075
3638
|
disabled: !canNext,
|
|
3076
|
-
"aria-label":
|
|
3077
|
-
title:
|
|
3639
|
+
"aria-label": locale.paginationNextPage,
|
|
3640
|
+
title: locale.paginationNextPage,
|
|
3078
3641
|
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, {})
|
|
3079
3642
|
}
|
|
3080
3643
|
),
|
|
@@ -3085,8 +3648,8 @@ function Pagination({
|
|
|
3085
3648
|
className: "yable-pagination-btn yable-pagination-btn--nav",
|
|
3086
3649
|
onClick: () => table.setPageIndex(pageCount - 1),
|
|
3087
3650
|
disabled: !canNext,
|
|
3088
|
-
"aria-label":
|
|
3089
|
-
title:
|
|
3651
|
+
"aria-label": locale.paginationLastPage,
|
|
3652
|
+
title: locale.paginationLastPage,
|
|
3090
3653
|
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLastIcon, {})
|
|
3091
3654
|
}
|
|
3092
3655
|
)
|
|
@@ -3135,10 +3698,12 @@ function ClearIcon() {
|
|
|
3135
3698
|
}
|
|
3136
3699
|
function GlobalFilter({
|
|
3137
3700
|
table,
|
|
3138
|
-
placeholder
|
|
3701
|
+
placeholder,
|
|
3139
3702
|
debounce = 300,
|
|
3140
3703
|
className
|
|
3141
3704
|
}) {
|
|
3705
|
+
const locale = yableCore.getDefaultLocale();
|
|
3706
|
+
const resolvedPlaceholder = placeholder ?? locale.searchPlaceholder;
|
|
3142
3707
|
const [value, setValue] = React3.useState(
|
|
3143
3708
|
table.getState().globalFilter ?? ""
|
|
3144
3709
|
);
|
|
@@ -3195,8 +3760,8 @@ function GlobalFilter({
|
|
|
3195
3760
|
value,
|
|
3196
3761
|
onChange: handleChange,
|
|
3197
3762
|
onKeyDown: handleKeyDown,
|
|
3198
|
-
placeholder,
|
|
3199
|
-
"aria-label":
|
|
3763
|
+
placeholder: resolvedPlaceholder,
|
|
3764
|
+
"aria-label": locale.searchAriaLabel,
|
|
3200
3765
|
role: "searchbox"
|
|
3201
3766
|
}
|
|
3202
3767
|
),
|
|
@@ -3283,10 +3848,25 @@ function CellSelect({
|
|
|
3283
3848
|
const isAlwaysEditable = cell.getIsAlwaysEditable();
|
|
3284
3849
|
const pending = table.getPendingValue(row.id, column.id);
|
|
3285
3850
|
const currentValue = pending !== void 0 ? pending : cell.getValue();
|
|
3851
|
+
const commitTimerRef = React3.useRef(null);
|
|
3852
|
+
React3.useEffect(() => {
|
|
3853
|
+
return () => {
|
|
3854
|
+
if (commitTimerRef.current !== null) {
|
|
3855
|
+
clearTimeout(commitTimerRef.current);
|
|
3856
|
+
commitTimerRef.current = null;
|
|
3857
|
+
}
|
|
3858
|
+
};
|
|
3859
|
+
}, []);
|
|
3286
3860
|
const handleChange = (e) => {
|
|
3287
3861
|
table.setPendingValue(row.id, column.id, e.target.value);
|
|
3288
3862
|
if (isEditing && !isAlwaysEditable) {
|
|
3289
|
-
|
|
3863
|
+
if (commitTimerRef.current !== null) {
|
|
3864
|
+
clearTimeout(commitTimerRef.current);
|
|
3865
|
+
}
|
|
3866
|
+
commitTimerRef.current = setTimeout(() => {
|
|
3867
|
+
commitTimerRef.current = null;
|
|
3868
|
+
table.commitEdit();
|
|
3869
|
+
}, 0);
|
|
3290
3870
|
}
|
|
3291
3871
|
};
|
|
3292
3872
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -3398,14 +3978,7 @@ function formatDateValue(value, type) {
|
|
|
3398
3978
|
return String(value);
|
|
3399
3979
|
}
|
|
3400
3980
|
function useClipboard(table, options = {}) {
|
|
3401
|
-
const {
|
|
3402
|
-
enabled = true,
|
|
3403
|
-
containerRef,
|
|
3404
|
-
onCopy,
|
|
3405
|
-
onCut,
|
|
3406
|
-
onPaste,
|
|
3407
|
-
...clipboardOptions
|
|
3408
|
-
} = options;
|
|
3981
|
+
const { enabled = true, containerRef, onCopy, onCut, onPaste, ...clipboardOptions } = options;
|
|
3409
3982
|
const handleCopy = React3.useCallback(
|
|
3410
3983
|
(e) => {
|
|
3411
3984
|
if (isEditableTarget2(e.target)) return;
|
|
@@ -3443,20 +4016,29 @@ function useClipboard(table, options = {}) {
|
|
|
3443
4016
|
targetRowId = state.editing.activeCell.rowId;
|
|
3444
4017
|
targetColumnId = state.editing.activeCell.columnId;
|
|
3445
4018
|
} else {
|
|
3446
|
-
const
|
|
3447
|
-
|
|
3448
|
-
);
|
|
3449
|
-
if (
|
|
3450
|
-
|
|
4019
|
+
const selectedRange = table.getCellSelectionRange();
|
|
4020
|
+
const rows = table.getRowModel().rows;
|
|
4021
|
+
const columns = table.getVisibleLeafColumns();
|
|
4022
|
+
if (selectedRange) {
|
|
4023
|
+
const startRowIndex = Math.min(selectedRange.start.rowIndex, selectedRange.end.rowIndex);
|
|
4024
|
+
const startColumnIndex = Math.min(
|
|
4025
|
+
selectedRange.start.columnIndex,
|
|
4026
|
+
selectedRange.end.columnIndex
|
|
4027
|
+
);
|
|
4028
|
+
targetRowId = rows[startRowIndex]?.id;
|
|
4029
|
+
targetColumnId = columns[startColumnIndex]?.id;
|
|
3451
4030
|
} else {
|
|
3452
|
-
const
|
|
3453
|
-
|
|
4031
|
+
const selectedRowIds = Object.keys(state.rowSelection || {}).filter(
|
|
4032
|
+
(id) => state.rowSelection[id]
|
|
4033
|
+
);
|
|
4034
|
+
if (selectedRowIds.length > 0) {
|
|
4035
|
+
targetRowId = selectedRowIds[0];
|
|
4036
|
+
} else if (rows.length > 0) {
|
|
3454
4037
|
targetRowId = rows[0].id;
|
|
3455
4038
|
}
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
targetColumnId = columns[0].id;
|
|
4039
|
+
if (columns.length > 0) {
|
|
4040
|
+
targetColumnId = columns[0].id;
|
|
4041
|
+
}
|
|
3460
4042
|
}
|
|
3461
4043
|
}
|
|
3462
4044
|
if (targetRowId && targetColumnId) {
|
|
@@ -4746,7 +5328,7 @@ function sanitizeCSS(css) {
|
|
|
4746
5328
|
sanitized = sanitized.replace(/javascript\s*:/gi, "/* javascript: removed */");
|
|
4747
5329
|
return sanitized;
|
|
4748
5330
|
}
|
|
4749
|
-
function usePrintLayout(
|
|
5331
|
+
function usePrintLayout(_table, options = {}) {
|
|
4750
5332
|
const { title, additionalCSS } = options;
|
|
4751
5333
|
const isPrintingRef = React3.useRef(false);
|
|
4752
5334
|
const preparePrint = React3.useCallback(() => {
|
|
@@ -4783,7 +5365,7 @@ function usePrintLayout(table, options = {}) {
|
|
|
4783
5365
|
requestAnimationFrame(() => {
|
|
4784
5366
|
window.print();
|
|
4785
5367
|
});
|
|
4786
|
-
}, [
|
|
5368
|
+
}, [title, additionalCSS]);
|
|
4787
5369
|
return {
|
|
4788
5370
|
preparePrint,
|
|
4789
5371
|
isPrinting: isPrintingRef.current
|
|
@@ -4839,6 +5421,22 @@ Object.defineProperty(exports, "CommitError", {
|
|
|
4839
5421
|
enumerable: true,
|
|
4840
5422
|
get: function () { return yableCore.CommitError; }
|
|
4841
5423
|
});
|
|
5424
|
+
Object.defineProperty(exports, "FormulaEngine", {
|
|
5425
|
+
enumerable: true,
|
|
5426
|
+
get: function () { return yableCore.FormulaEngine; }
|
|
5427
|
+
});
|
|
5428
|
+
Object.defineProperty(exports, "FormulaError", {
|
|
5429
|
+
enumerable: true,
|
|
5430
|
+
get: function () { return yableCore.FormulaError; }
|
|
5431
|
+
});
|
|
5432
|
+
Object.defineProperty(exports, "PivotEngine", {
|
|
5433
|
+
enumerable: true,
|
|
5434
|
+
get: function () { return yableCore.PivotEngine; }
|
|
5435
|
+
});
|
|
5436
|
+
Object.defineProperty(exports, "UndoStack", {
|
|
5437
|
+
enumerable: true,
|
|
5438
|
+
get: function () { return yableCore.UndoStack; }
|
|
5439
|
+
});
|
|
4842
5440
|
Object.defineProperty(exports, "aggregationFns", {
|
|
4843
5441
|
enumerable: true,
|
|
4844
5442
|
get: function () { return yableCore.aggregationFns; }
|
|
@@ -4851,6 +5449,10 @@ Object.defineProperty(exports, "createLocale", {
|
|
|
4851
5449
|
enumerable: true,
|
|
4852
5450
|
get: function () { return yableCore.createLocale; }
|
|
4853
5451
|
});
|
|
5452
|
+
Object.defineProperty(exports, "createUndoRedoIntegration", {
|
|
5453
|
+
enumerable: true,
|
|
5454
|
+
get: function () { return yableCore.createUndoRedoIntegration; }
|
|
5455
|
+
});
|
|
4854
5456
|
Object.defineProperty(exports, "en", {
|
|
4855
5457
|
enumerable: true,
|
|
4856
5458
|
get: function () { return yableCore.en; }
|
|
@@ -4859,14 +5461,30 @@ Object.defineProperty(exports, "filterFns", {
|
|
|
4859
5461
|
enumerable: true,
|
|
4860
5462
|
get: function () { return yableCore.filterFns; }
|
|
4861
5463
|
});
|
|
5464
|
+
Object.defineProperty(exports, "formulaFunctions", {
|
|
5465
|
+
enumerable: true,
|
|
5466
|
+
get: function () { return yableCore.formulaFunctions; }
|
|
5467
|
+
});
|
|
4862
5468
|
Object.defineProperty(exports, "functionalUpdate", {
|
|
4863
5469
|
enumerable: true,
|
|
4864
5470
|
get: function () { return yableCore.functionalUpdate; }
|
|
4865
5471
|
});
|
|
5472
|
+
Object.defineProperty(exports, "generatePivotColumnDefs", {
|
|
5473
|
+
enumerable: true,
|
|
5474
|
+
get: function () { return yableCore.generatePivotColumnDefs; }
|
|
5475
|
+
});
|
|
4866
5476
|
Object.defineProperty(exports, "getDefaultLocale", {
|
|
4867
5477
|
enumerable: true,
|
|
4868
5478
|
get: function () { return yableCore.getDefaultLocale; }
|
|
4869
5479
|
});
|
|
5480
|
+
Object.defineProperty(exports, "getInitialPivotState", {
|
|
5481
|
+
enumerable: true,
|
|
5482
|
+
get: function () { return yableCore.getInitialPivotState; }
|
|
5483
|
+
});
|
|
5484
|
+
Object.defineProperty(exports, "getPivotRowModel", {
|
|
5485
|
+
enumerable: true,
|
|
5486
|
+
get: function () { return yableCore.getPivotRowModel; }
|
|
5487
|
+
});
|
|
4870
5488
|
Object.defineProperty(exports, "resetLocale", {
|
|
4871
5489
|
enumerable: true,
|
|
4872
5490
|
get: function () { return yableCore.resetLocale; }
|
|
@@ -4905,6 +5523,7 @@ exports.ExpandIcon = ExpandIcon;
|
|
|
4905
5523
|
exports.FillHandle = FillHandle;
|
|
4906
5524
|
exports.FiltersPanel = FiltersPanel;
|
|
4907
5525
|
exports.FlashCell = FlashCell;
|
|
5526
|
+
exports.FloatingFilter = FloatingFilter;
|
|
4908
5527
|
exports.GlobalFilter = GlobalFilter;
|
|
4909
5528
|
exports.LoadingOverlay = LoadingOverlay;
|
|
4910
5529
|
exports.MasterDetail = MasterDetail;
|
|
@@ -4912,6 +5531,7 @@ exports.NoRowsOverlay = NoRowsOverlay;
|
|
|
4912
5531
|
exports.Pagination = Pagination;
|
|
4913
5532
|
exports.PivotConfigPanel = PivotConfigPanel;
|
|
4914
5533
|
exports.PrintLayout = PrintLayout;
|
|
5534
|
+
exports.SetFilter = SetFilter;
|
|
4915
5535
|
exports.Sidebar = Sidebar;
|
|
4916
5536
|
exports.SortIndicator = SortIndicator;
|
|
4917
5537
|
exports.StatusBar = StatusBar;
|
|
@@ -4930,6 +5550,7 @@ exports.resolveMeasureRecipe = resolveMeasureRecipe;
|
|
|
4930
5550
|
exports.useAutoMeasurements = useAutoMeasurements;
|
|
4931
5551
|
exports.useCellFlash = useCellFlash;
|
|
4932
5552
|
exports.useClipboard = useClipboard;
|
|
5553
|
+
exports.useColumnVirtualization = useColumnVirtualization;
|
|
4933
5554
|
exports.useContextMenu = useContextMenu;
|
|
4934
5555
|
exports.useFillHandle = useFillHandle;
|
|
4935
5556
|
exports.useKeyboardNavigation = useKeyboardNavigation;
|