@pretable/react 0.0.1 → 0.0.2
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/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/index.cjs +1605 -200
- package/dist/index.d.cts +316 -67
- package/dist/index.d.ts +316 -67
- package/dist/index.mjs +1603 -200
- package/package.json +23 -7
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { useMemo,
|
|
1
|
+
import { memo, useMemo, useRef, useLayoutEffect, useSyncExternalStore, useCallback, useState, useEffect, createElement } from 'react';
|
|
2
2
|
import { createGrid } from '@pretable/core';
|
|
3
|
-
import {
|
|
3
|
+
import { getDensityHeights } from '@pretable/ui';
|
|
4
|
+
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
4
5
|
|
|
5
6
|
// src/pretable-surface.tsx
|
|
6
7
|
|
|
@@ -483,23 +484,12 @@ function getEstimatedRowHeightSignature(row, columns) {
|
|
|
483
484
|
}).join("|");
|
|
484
485
|
}
|
|
485
486
|
function readCellValue(row, column) {
|
|
486
|
-
return column.
|
|
487
|
+
return column.value ? column.value(row) : row[column.id];
|
|
487
488
|
}
|
|
488
489
|
function getColumnWidth(column) {
|
|
489
490
|
return column.widthPx ?? (column.wrap ? WRAPPED_COLUMN_WIDTH : FIXED_COLUMN_WIDTH);
|
|
490
491
|
}
|
|
491
492
|
function usePretable({
|
|
492
|
-
autosize,
|
|
493
|
-
columns,
|
|
494
|
-
rows,
|
|
495
|
-
getRowId
|
|
496
|
-
}) {
|
|
497
|
-
return useMemo(
|
|
498
|
-
() => createGrid({ columns, rows, getRowId, autosize }),
|
|
499
|
-
[autosize, columns, getRowId, rows]
|
|
500
|
-
);
|
|
501
|
-
}
|
|
502
|
-
function usePretableModel({
|
|
503
493
|
autosize,
|
|
504
494
|
columns,
|
|
505
495
|
rows,
|
|
@@ -507,25 +497,79 @@ function usePretableModel({
|
|
|
507
497
|
viewportHeight,
|
|
508
498
|
viewportWidth,
|
|
509
499
|
overscan = 6,
|
|
510
|
-
|
|
511
|
-
measuredHeights
|
|
500
|
+
state,
|
|
501
|
+
measuredHeights,
|
|
502
|
+
onSelectionChange,
|
|
503
|
+
onFocusChange
|
|
512
504
|
}) {
|
|
513
|
-
const grid =
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
505
|
+
const grid = useMemo(
|
|
506
|
+
() => createGrid({ columns, rows, getRowId, autosize }),
|
|
507
|
+
[autosize, columns, getRowId, rows]
|
|
508
|
+
);
|
|
509
|
+
const lastColumnIdsRef = useRef(null);
|
|
510
|
+
useLayoutEffect(() => {
|
|
511
|
+
const currentIds = columns.map((c) => c.id);
|
|
512
|
+
const prevIds = lastColumnIdsRef.current;
|
|
513
|
+
if (prevIds === null || prevIds.length !== currentIds.length || prevIds.some((id, i) => id !== currentIds[i])) {
|
|
514
|
+
if (prevIds !== null) {
|
|
515
|
+
grid.mergeColumnsFromProps(columns);
|
|
516
|
+
}
|
|
517
|
+
lastColumnIdsRef.current = currentIds;
|
|
526
518
|
}
|
|
527
|
-
|
|
528
|
-
|
|
519
|
+
}, [columns, grid]);
|
|
520
|
+
if (state) {
|
|
521
|
+
if (state.sort !== void 0) {
|
|
522
|
+
grid.setSort(state.sort?.columnId ?? null, state.sort?.direction ?? null);
|
|
523
|
+
}
|
|
524
|
+
if (state.filters !== void 0) {
|
|
525
|
+
grid.replaceFilters(state.filters);
|
|
526
|
+
}
|
|
527
|
+
if (state.columnWidths !== void 0) {
|
|
528
|
+
const widths = state.columnWidths;
|
|
529
|
+
for (const column of grid.options.columns) {
|
|
530
|
+
const next = widths[column.id];
|
|
531
|
+
if (next !== void 0 && next !== column.widthPx) {
|
|
532
|
+
grid.setColumnWidth(column.id, next);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
if (state.columnOrder !== void 0) {
|
|
537
|
+
const targetOrder = state.columnOrder;
|
|
538
|
+
const currentIds = grid.options.columns.map((c) => c.id);
|
|
539
|
+
const targetIds = [
|
|
540
|
+
...targetOrder.filter((id) => currentIds.includes(id)),
|
|
541
|
+
...currentIds.filter((id) => !targetOrder.includes(id))
|
|
542
|
+
];
|
|
543
|
+
for (let i = 0; i < targetIds.length; i += 1) {
|
|
544
|
+
const id = targetIds[i];
|
|
545
|
+
const currentIdx = grid.options.columns.findIndex((c) => c.id === id);
|
|
546
|
+
if (currentIdx !== i && id !== "__pretable_row_select__") {
|
|
547
|
+
grid.moveColumn(id, i);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
if (state.columnPinned !== void 0) {
|
|
552
|
+
const pinned = state.columnPinned;
|
|
553
|
+
for (const [id, value] of Object.entries(pinned)) {
|
|
554
|
+
const column = grid.options.columns.find((c) => c.id === id);
|
|
555
|
+
if (!column) continue;
|
|
556
|
+
const targetPinned = value === "left" ? "left" : null;
|
|
557
|
+
const currentPinned = column.pinned ?? null;
|
|
558
|
+
if (currentPinned !== targetPinned) {
|
|
559
|
+
grid.setColumnPinned(id, targetPinned);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
if (state.selection !== void 0) {
|
|
564
|
+
grid.setSelection(state.selection);
|
|
565
|
+
}
|
|
566
|
+
if (state.focus !== void 0) {
|
|
567
|
+
const focus = state.focus;
|
|
568
|
+
if (focus.rowId !== null && focus.columnId !== null) {
|
|
569
|
+
grid.setFocus({ rowId: focus.rowId, columnId: focus.columnId });
|
|
570
|
+
} else {
|
|
571
|
+
grid.setFocus(null);
|
|
572
|
+
}
|
|
529
573
|
}
|
|
530
574
|
}
|
|
531
575
|
const snapshot = useSyncExternalStore(
|
|
@@ -584,7 +628,7 @@ function usePretableModel({
|
|
|
584
628
|
focusedRowId: snapshot.focus.rowId,
|
|
585
629
|
rowModelRowCount: snapshot.visibleRows.length,
|
|
586
630
|
renderedRowCount: renderSnapshot.rows.length,
|
|
587
|
-
selectedRowId: snapshot.selection.
|
|
631
|
+
selectedRowId: snapshot.selection.ranges[0]?.startRowId ?? null,
|
|
588
632
|
totalRowCount: snapshot.totalRowCount,
|
|
589
633
|
totalHeight: renderSnapshot.totalHeight,
|
|
590
634
|
visibleRowCount: viewportRows.length,
|
|
@@ -601,7 +645,7 @@ function usePretableModel({
|
|
|
601
645
|
renderSnapshot.totalHeight,
|
|
602
646
|
snapshot.focus.rowId,
|
|
603
647
|
snapshot.visibleRows.length,
|
|
604
|
-
snapshot.selection.
|
|
648
|
+
snapshot.selection.ranges,
|
|
605
649
|
snapshot.totalRowCount,
|
|
606
650
|
snapshot.viewport.height,
|
|
607
651
|
snapshot.viewport.scrollTop,
|
|
@@ -614,6 +658,45 @@ function usePretableModel({
|
|
|
614
658
|
telemetry
|
|
615
659
|
};
|
|
616
660
|
}
|
|
661
|
+
function subscribe(callback) {
|
|
662
|
+
if (typeof document === "undefined") return () => {
|
|
663
|
+
};
|
|
664
|
+
const observer = new MutationObserver(callback);
|
|
665
|
+
observer.observe(document.documentElement, {
|
|
666
|
+
attributes: true,
|
|
667
|
+
attributeFilter: ["data-density", "data-theme", "class", "style"]
|
|
668
|
+
});
|
|
669
|
+
return () => observer.disconnect();
|
|
670
|
+
}
|
|
671
|
+
function useResolvedHeights(rowHeightProp, headerHeightProp) {
|
|
672
|
+
const cachedClient = useRef(null);
|
|
673
|
+
const cachedServer = useRef(null);
|
|
674
|
+
const getSnapshot = useCallback(() => {
|
|
675
|
+
const css = getDensityHeights();
|
|
676
|
+
const rowHeight = rowHeightProp ?? css.rowHeight;
|
|
677
|
+
const headerHeight = headerHeightProp ?? css.headerHeight;
|
|
678
|
+
const prev = cachedClient.current;
|
|
679
|
+
if (prev !== null && prev.rowHeight === rowHeight && prev.headerHeight === headerHeight) {
|
|
680
|
+
return prev;
|
|
681
|
+
}
|
|
682
|
+
const next = { rowHeight, headerHeight };
|
|
683
|
+
cachedClient.current = next;
|
|
684
|
+
return next;
|
|
685
|
+
}, [rowHeightProp, headerHeightProp]);
|
|
686
|
+
const getServerSnapshot = useCallback(() => {
|
|
687
|
+
const css = getDensityHeights();
|
|
688
|
+
const rowHeight = rowHeightProp ?? css.rowHeight;
|
|
689
|
+
const headerHeight = headerHeightProp ?? css.headerHeight;
|
|
690
|
+
const prev = cachedServer.current;
|
|
691
|
+
if (prev !== null && prev.rowHeight === rowHeight && prev.headerHeight === headerHeight) {
|
|
692
|
+
return prev;
|
|
693
|
+
}
|
|
694
|
+
const next = { rowHeight, headerHeight };
|
|
695
|
+
cachedServer.current = next;
|
|
696
|
+
return next;
|
|
697
|
+
}, [rowHeightProp, headerHeightProp]);
|
|
698
|
+
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
699
|
+
}
|
|
617
700
|
|
|
618
701
|
// src/rendering.ts
|
|
619
702
|
var DEFAULT_ROW_HEIGHT2 = 44;
|
|
@@ -645,7 +728,7 @@ function getNextSortDirection(current) {
|
|
|
645
728
|
return null;
|
|
646
729
|
}
|
|
647
730
|
function resolveCellValue(row, column) {
|
|
648
|
-
return column.
|
|
731
|
+
return column.value ? column.value(row) : row[column.id];
|
|
649
732
|
}
|
|
650
733
|
function formatCellValue(value) {
|
|
651
734
|
if (Array.isArray(value)) {
|
|
@@ -654,69 +737,6 @@ function formatCellValue(value) {
|
|
|
654
737
|
return String(value ?? "");
|
|
655
738
|
}
|
|
656
739
|
|
|
657
|
-
// src/density.ts
|
|
658
|
-
var FALLBACK_ROW_HEIGHT = 32;
|
|
659
|
-
var FALLBACK_HEADER_HEIGHT = HEADER_HEIGHT;
|
|
660
|
-
function parsePx(value) {
|
|
661
|
-
const match = value.trim().match(/^([\d.]+)px$/);
|
|
662
|
-
return match ? parseFloat(match[1]) : null;
|
|
663
|
-
}
|
|
664
|
-
function getDensityHeights() {
|
|
665
|
-
if (typeof document === "undefined") {
|
|
666
|
-
return {
|
|
667
|
-
rowHeight: FALLBACK_ROW_HEIGHT,
|
|
668
|
-
headerHeight: FALLBACK_HEADER_HEIGHT
|
|
669
|
-
};
|
|
670
|
-
}
|
|
671
|
-
const styles = getComputedStyle(document.documentElement);
|
|
672
|
-
const read = (name) => {
|
|
673
|
-
if (typeof styles?.getPropertyValue !== "function") return "";
|
|
674
|
-
return styles.getPropertyValue(name);
|
|
675
|
-
};
|
|
676
|
-
return {
|
|
677
|
-
rowHeight: parsePx(read("--pretable-row-height")) ?? FALLBACK_ROW_HEIGHT,
|
|
678
|
-
headerHeight: parsePx(read("--pretable-header-height")) ?? FALLBACK_HEADER_HEIGHT
|
|
679
|
-
};
|
|
680
|
-
}
|
|
681
|
-
function subscribe(callback) {
|
|
682
|
-
if (typeof document === "undefined") return () => {
|
|
683
|
-
};
|
|
684
|
-
const observer = new MutationObserver(callback);
|
|
685
|
-
observer.observe(document.documentElement, {
|
|
686
|
-
attributes: true,
|
|
687
|
-
attributeFilter: ["data-density", "data-theme", "class", "style"]
|
|
688
|
-
});
|
|
689
|
-
return () => observer.disconnect();
|
|
690
|
-
}
|
|
691
|
-
function useResolvedHeights(rowHeightProp, headerHeightProp) {
|
|
692
|
-
const cachedClient = useRef(null);
|
|
693
|
-
const cachedServer = useRef(null);
|
|
694
|
-
const getSnapshot = useCallback(() => {
|
|
695
|
-
const css = getDensityHeights();
|
|
696
|
-
const rowHeight = rowHeightProp ?? css.rowHeight;
|
|
697
|
-
const headerHeight = headerHeightProp ?? css.headerHeight;
|
|
698
|
-
const prev = cachedClient.current;
|
|
699
|
-
if (prev !== null && prev.rowHeight === rowHeight && prev.headerHeight === headerHeight) {
|
|
700
|
-
return prev;
|
|
701
|
-
}
|
|
702
|
-
const next = { rowHeight, headerHeight };
|
|
703
|
-
cachedClient.current = next;
|
|
704
|
-
return next;
|
|
705
|
-
}, [rowHeightProp, headerHeightProp]);
|
|
706
|
-
const getServerSnapshot = useCallback(() => {
|
|
707
|
-
const rowHeight = rowHeightProp ?? FALLBACK_ROW_HEIGHT;
|
|
708
|
-
const headerHeight = headerHeightProp ?? FALLBACK_HEADER_HEIGHT;
|
|
709
|
-
const prev = cachedServer.current;
|
|
710
|
-
if (prev !== null && prev.rowHeight === rowHeight && prev.headerHeight === headerHeight) {
|
|
711
|
-
return prev;
|
|
712
|
-
}
|
|
713
|
-
const next = { rowHeight, headerHeight };
|
|
714
|
-
cachedServer.current = next;
|
|
715
|
-
return next;
|
|
716
|
-
}, [rowHeightProp, headerHeightProp]);
|
|
717
|
-
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
718
|
-
}
|
|
719
|
-
|
|
720
740
|
// src/styles.ts
|
|
721
741
|
function getViewportStyle(height) {
|
|
722
742
|
return {
|
|
@@ -786,6 +806,162 @@ function getPinnedCellStyle(left) {
|
|
|
786
806
|
zIndex: 1
|
|
787
807
|
};
|
|
788
808
|
}
|
|
809
|
+
|
|
810
|
+
// src/constants.ts
|
|
811
|
+
var ROW_SELECT_COLUMN_ID = "__pretable_row_select__";
|
|
812
|
+
|
|
813
|
+
// src/copy.ts
|
|
814
|
+
function defaultCoerceForCopy(value) {
|
|
815
|
+
if (value === null || value === void 0) return "";
|
|
816
|
+
if (value instanceof Date) return value.toISOString();
|
|
817
|
+
const t = typeof value;
|
|
818
|
+
if (t === "string" || t === "number" || t === "boolean" || t === "bigint") {
|
|
819
|
+
return String(value);
|
|
820
|
+
}
|
|
821
|
+
if (t === "object") {
|
|
822
|
+
try {
|
|
823
|
+
return JSON.stringify(value);
|
|
824
|
+
} catch {
|
|
825
|
+
return String(value);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
return String(value);
|
|
829
|
+
}
|
|
830
|
+
function serializeRangesAsTsv(args) {
|
|
831
|
+
const dataColumns = args.columns.filter((c) => c.id !== ROW_SELECT_COLUMN_ID);
|
|
832
|
+
if (dataColumns.length === 0) return null;
|
|
833
|
+
const colIndex = /* @__PURE__ */ new Map();
|
|
834
|
+
dataColumns.forEach((c, i) => colIndex.set(c.id, i));
|
|
835
|
+
const rowIndex = /* @__PURE__ */ new Map();
|
|
836
|
+
args.visibleRows.forEach((r, i) => rowIndex.set(r.id, i));
|
|
837
|
+
const blocks = [];
|
|
838
|
+
for (const range of args.ranges) {
|
|
839
|
+
const startRow = rowIndex.get(range.startRowId);
|
|
840
|
+
const endRow = rowIndex.get(range.endRowId);
|
|
841
|
+
const startIsSynth = range.startColumnId === ROW_SELECT_COLUMN_ID;
|
|
842
|
+
const endIsSynth = range.endColumnId === ROW_SELECT_COLUMN_ID;
|
|
843
|
+
const startCol = colIndex.get(range.startColumnId);
|
|
844
|
+
const endCol = colIndex.get(range.endColumnId);
|
|
845
|
+
const haveRows = startRow !== void 0 && endRow !== void 0;
|
|
846
|
+
const rowLo = haveRows ? Math.min(startRow, endRow) : -1;
|
|
847
|
+
const rowHi = haveRows ? Math.max(startRow, endRow) : -1;
|
|
848
|
+
let colLo;
|
|
849
|
+
let colHi;
|
|
850
|
+
if (startIsSynth && endIsSynth) {
|
|
851
|
+
continue;
|
|
852
|
+
} else if (startIsSynth && endCol !== void 0) {
|
|
853
|
+
colLo = 0;
|
|
854
|
+
colHi = endCol;
|
|
855
|
+
} else if (endIsSynth && startCol !== void 0) {
|
|
856
|
+
colLo = startCol;
|
|
857
|
+
colHi = 0;
|
|
858
|
+
} else if (startCol !== void 0 && endCol !== void 0) {
|
|
859
|
+
colLo = Math.min(startCol, endCol);
|
|
860
|
+
colHi = Math.max(startCol, endCol);
|
|
861
|
+
} else if (startCol !== void 0) {
|
|
862
|
+
colLo = colHi = startCol;
|
|
863
|
+
} else if (endCol !== void 0) {
|
|
864
|
+
colLo = colHi = endCol;
|
|
865
|
+
} else {
|
|
866
|
+
continue;
|
|
867
|
+
}
|
|
868
|
+
if (colLo > colHi) {
|
|
869
|
+
[colLo, colHi] = [colHi, colLo];
|
|
870
|
+
}
|
|
871
|
+
colLo = Math.max(colLo, 0);
|
|
872
|
+
colHi = Math.min(colHi, dataColumns.length - 1);
|
|
873
|
+
if (colLo > colHi) continue;
|
|
874
|
+
if (!haveRows || rowLo > rowHi) continue;
|
|
875
|
+
const lines = [];
|
|
876
|
+
if (args.copyWithHeaders) {
|
|
877
|
+
const headerCells = [];
|
|
878
|
+
for (let c = colLo; c <= colHi; c += 1) {
|
|
879
|
+
const col = dataColumns[c];
|
|
880
|
+
headerCells.push(col.header ?? col.id);
|
|
881
|
+
}
|
|
882
|
+
lines.push(headerCells.join(" "));
|
|
883
|
+
lines.push("");
|
|
884
|
+
}
|
|
885
|
+
for (let r = rowLo; r <= rowHi; r += 1) {
|
|
886
|
+
const row = args.visibleRows[r];
|
|
887
|
+
const cells = [];
|
|
888
|
+
for (let c = colLo; c <= colHi; c += 1) {
|
|
889
|
+
const col = dataColumns[c];
|
|
890
|
+
const raw = col.value ? col.value(row.row) : row.row[col.id];
|
|
891
|
+
const text = col.format ? col.format({ value: raw, row: row.row, column: col }) : defaultCoerceForCopy(raw);
|
|
892
|
+
cells.push(text);
|
|
893
|
+
}
|
|
894
|
+
lines.push(cells.join(" "));
|
|
895
|
+
}
|
|
896
|
+
blocks.push(lines.join("\n"));
|
|
897
|
+
}
|
|
898
|
+
if (blocks.length === 0) return null;
|
|
899
|
+
return { text: blocks.join("\n\n") };
|
|
900
|
+
}
|
|
901
|
+
async function defaultCopyToClipboard(payload) {
|
|
902
|
+
if (typeof navigator === "undefined" || !navigator.clipboard) return;
|
|
903
|
+
if (payload.html && typeof globalThis.ClipboardItem !== "undefined" && typeof navigator.clipboard.write === "function") {
|
|
904
|
+
await navigator.clipboard.write([
|
|
905
|
+
new globalThis.ClipboardItem({
|
|
906
|
+
"text/plain": new Blob([payload.text], { type: "text/plain" }),
|
|
907
|
+
"text/html": new Blob([payload.html], { type: "text/html" })
|
|
908
|
+
})
|
|
909
|
+
]);
|
|
910
|
+
} else {
|
|
911
|
+
await navigator.clipboard.writeText(payload.text);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
var defaultMessages = {
|
|
915
|
+
selectAllAnnouncement: ({ rowCount, columnCount, isAll }) => isAll ? "All rows selected" : `${rowCount} rows \xD7 ${columnCount} columns selected`,
|
|
916
|
+
copyAnnouncement: ({ rowCount, columnCount }) => `${rowCount} rows \xD7 ${columnCount} columns copied`,
|
|
917
|
+
copyFailedAnnouncement: () => "Copy failed"
|
|
918
|
+
};
|
|
919
|
+
var ANNOUNCE_DEBOUNCE_MS = 500;
|
|
920
|
+
var REORDER_THRESHOLD_PX = 5;
|
|
921
|
+
function CellContentImpl({
|
|
922
|
+
formattedValue,
|
|
923
|
+
renderRef,
|
|
924
|
+
fallbackRenderRef,
|
|
925
|
+
cellRenderInput
|
|
926
|
+
}) {
|
|
927
|
+
if (renderRef) {
|
|
928
|
+
return /* @__PURE__ */ jsx(Fragment, { children: renderRef(cellRenderInput) });
|
|
929
|
+
}
|
|
930
|
+
if (fallbackRenderRef) {
|
|
931
|
+
return /* @__PURE__ */ jsx(Fragment, { children: fallbackRenderRef(cellRenderInput) });
|
|
932
|
+
}
|
|
933
|
+
return /* @__PURE__ */ jsx(Fragment, { children: formattedValue });
|
|
934
|
+
}
|
|
935
|
+
function cellContentPropsEqual(prev, next) {
|
|
936
|
+
return prev.rowId === next.rowId && prev.columnId === next.columnId && prev.value === next.value && prev.formattedValue === next.formattedValue && prev.isFocused === next.isFocused && prev.isSelected === next.isSelected && prev.renderRef === next.renderRef && prev.fallbackRenderRef === next.fallbackRenderRef;
|
|
937
|
+
}
|
|
938
|
+
var MemoizedCellContent = memo(CellContentImpl, cellContentPropsEqual);
|
|
939
|
+
function HeaderContentImpl({
|
|
940
|
+
label,
|
|
941
|
+
sortDirection,
|
|
942
|
+
renderHeaderRef,
|
|
943
|
+
fallbackRenderHeaderRef,
|
|
944
|
+
headerRenderInput
|
|
945
|
+
}) {
|
|
946
|
+
if (renderHeaderRef) {
|
|
947
|
+
return /* @__PURE__ */ jsx(Fragment, { children: renderHeaderRef(headerRenderInput) });
|
|
948
|
+
}
|
|
949
|
+
if (fallbackRenderHeaderRef) {
|
|
950
|
+
return /* @__PURE__ */ jsx(Fragment, { children: fallbackRenderHeaderRef({
|
|
951
|
+
column: headerRenderInput.column,
|
|
952
|
+
label,
|
|
953
|
+
sortDirection
|
|
954
|
+
}) });
|
|
955
|
+
}
|
|
956
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
957
|
+
/* @__PURE__ */ jsx("span", { children: label }),
|
|
958
|
+
/* @__PURE__ */ jsx("strong", { children: sortDirection === "desc" ? "Newest" : sortDirection === "asc" ? "Oldest" : "Sort" })
|
|
959
|
+
] });
|
|
960
|
+
}
|
|
961
|
+
function headerContentPropsEqual(prev, next) {
|
|
962
|
+
return prev.columnId === next.columnId && prev.label === next.label && prev.sortDirection === next.sortDirection && prev.isSorted === next.isSorted && prev.width === next.width && prev.isSortable === next.isSortable && prev.renderHeaderRef === next.renderHeaderRef && prev.fallbackRenderHeaderRef === next.fallbackRenderHeaderRef;
|
|
963
|
+
}
|
|
964
|
+
var MemoizedHeaderContent = memo(HeaderContentImpl, headerContentPropsEqual);
|
|
789
965
|
function PretableSurface({
|
|
790
966
|
ariaLabel,
|
|
791
967
|
autosize,
|
|
@@ -797,45 +973,292 @@ function PretableSurface({
|
|
|
797
973
|
getRowClassName,
|
|
798
974
|
getRowId,
|
|
799
975
|
getRowProps,
|
|
800
|
-
|
|
976
|
+
state,
|
|
801
977
|
overscan = 6,
|
|
802
978
|
onGridReady,
|
|
803
979
|
onSelectedRowIdChange,
|
|
980
|
+
onSelectionChange,
|
|
981
|
+
onFocusChange,
|
|
804
982
|
onSortChange,
|
|
983
|
+
onColumnWidthsChange,
|
|
984
|
+
onColumnOrderChange,
|
|
985
|
+
onColumnPinnedChange,
|
|
805
986
|
onTelemetryChange,
|
|
806
987
|
renderBodyCell,
|
|
807
988
|
renderHeaderCell,
|
|
808
989
|
rows,
|
|
990
|
+
rowSelectionColumn,
|
|
809
991
|
selectFocusedRowOnArrowKey = false,
|
|
992
|
+
tabBehavior = "wrap-rows",
|
|
810
993
|
viewportStyle,
|
|
811
|
-
viewportHeight
|
|
994
|
+
viewportHeight,
|
|
995
|
+
copyWithHeaders,
|
|
996
|
+
onCopy,
|
|
997
|
+
copyToClipboard,
|
|
998
|
+
messages
|
|
812
999
|
}) {
|
|
813
1000
|
const [measuredHeights, setMeasuredHeights] = useState({});
|
|
1001
|
+
const [dragLiveWidth, setDragLiveWidth] = useState(null);
|
|
1002
|
+
const resizeStateRef = useRef(null);
|
|
1003
|
+
const wasResizingRef = useRef(false);
|
|
1004
|
+
const wasReorderingRef = useRef(false);
|
|
1005
|
+
const reorderStateRef = useRef(null);
|
|
1006
|
+
const [reorderDrag, setReorderDrag] = useState(null);
|
|
814
1007
|
const [viewportWidth, setViewportWidth] = useState(0);
|
|
1008
|
+
const [liveMessage, setLiveMessage] = useState("");
|
|
1009
|
+
const announceTimerRef = useRef(null);
|
|
1010
|
+
const pendingAnnouncementRef = useRef(null);
|
|
1011
|
+
const scheduleAnnouncement = useCallback((message) => {
|
|
1012
|
+
pendingAnnouncementRef.current = message;
|
|
1013
|
+
if (announceTimerRef.current !== null) {
|
|
1014
|
+
clearTimeout(announceTimerRef.current);
|
|
1015
|
+
}
|
|
1016
|
+
announceTimerRef.current = setTimeout(() => {
|
|
1017
|
+
if (pendingAnnouncementRef.current !== null) {
|
|
1018
|
+
setLiveMessage(pendingAnnouncementRef.current);
|
|
1019
|
+
pendingAnnouncementRef.current = null;
|
|
1020
|
+
}
|
|
1021
|
+
announceTimerRef.current = null;
|
|
1022
|
+
}, ANNOUNCE_DEBOUNCE_MS);
|
|
1023
|
+
}, []);
|
|
1024
|
+
useEffect(() => {
|
|
1025
|
+
return () => {
|
|
1026
|
+
if (announceTimerRef.current !== null) {
|
|
1027
|
+
clearTimeout(announceTimerRef.current);
|
|
1028
|
+
}
|
|
1029
|
+
};
|
|
1030
|
+
}, []);
|
|
1031
|
+
const effectiveMessages = useMemo(
|
|
1032
|
+
() => ({
|
|
1033
|
+
selectAllAnnouncement: messages?.selectAllAnnouncement ?? defaultMessages.selectAllAnnouncement,
|
|
1034
|
+
copyAnnouncement: messages?.copyAnnouncement ?? defaultMessages.copyAnnouncement,
|
|
1035
|
+
copyFailedAnnouncement: messages?.copyFailedAnnouncement ?? defaultMessages.copyFailedAnnouncement
|
|
1036
|
+
}),
|
|
1037
|
+
[messages]
|
|
1038
|
+
);
|
|
815
1039
|
const measuredHeightsRef = useRef({});
|
|
816
1040
|
const measuredRowKeysRef = useRef({});
|
|
817
1041
|
const rowNodesRef = useRef(/* @__PURE__ */ new Map());
|
|
1042
|
+
const cellNodesRef = useRef(/* @__PURE__ */ new Map());
|
|
818
1043
|
const viewportRef = useRef(null);
|
|
1044
|
+
const dragAnchorRef = useRef(null);
|
|
1045
|
+
const dragStartSelectionRef = useRef(null);
|
|
1046
|
+
const lastCheckedRowAnchorRef = useRef(null);
|
|
819
1047
|
const { headerHeight } = useResolvedHeights();
|
|
820
1048
|
const bodyViewportHeight = Math.max(viewportHeight - headerHeight, 0);
|
|
821
|
-
const
|
|
1049
|
+
const effectiveColumns = useMemo(() => {
|
|
1050
|
+
if (!rowSelectionColumn?.enabled) return columns;
|
|
1051
|
+
const synth = {
|
|
1052
|
+
id: ROW_SELECT_COLUMN_ID,
|
|
1053
|
+
header: "",
|
|
1054
|
+
widthPx: rowSelectionColumn.width ?? 36,
|
|
1055
|
+
sortable: false,
|
|
1056
|
+
filterable: false,
|
|
1057
|
+
...rowSelectionColumn.pinned ?? true ? { pinned: "left" } : {}
|
|
1058
|
+
};
|
|
1059
|
+
return [synth, ...columns];
|
|
1060
|
+
}, [columns, rowSelectionColumn]);
|
|
1061
|
+
const { grid, snapshot, renderSnapshot, telemetry } = usePretable({
|
|
822
1062
|
autosize,
|
|
823
|
-
columns,
|
|
1063
|
+
columns: effectiveColumns,
|
|
824
1064
|
getRowId,
|
|
825
|
-
|
|
1065
|
+
state: state ?? void 0,
|
|
826
1066
|
measuredHeights,
|
|
827
1067
|
overscan,
|
|
828
1068
|
rows,
|
|
829
1069
|
viewportHeight: bodyViewportHeight,
|
|
830
|
-
viewportWidth: viewportWidth || void 0
|
|
1070
|
+
viewportWidth: viewportWidth || void 0,
|
|
1071
|
+
onSelectionChange,
|
|
1072
|
+
onFocusChange
|
|
831
1073
|
});
|
|
832
|
-
const
|
|
1074
|
+
const focusedRowId = snapshot.focus.rowId;
|
|
1075
|
+
const focusedColumnId = snapshot.focus.columnId;
|
|
1076
|
+
const pinnedOffsets = useMemo(
|
|
1077
|
+
() => getPinnedLeftOffsets(effectiveColumns),
|
|
1078
|
+
[effectiveColumns]
|
|
1079
|
+
);
|
|
1080
|
+
const columnsById = useMemo(() => {
|
|
1081
|
+
const map = /* @__PURE__ */ new Map();
|
|
1082
|
+
for (const col of effectiveColumns) {
|
|
1083
|
+
map.set(col.id, col);
|
|
1084
|
+
}
|
|
1085
|
+
return map;
|
|
1086
|
+
}, [effectiveColumns]);
|
|
1087
|
+
const { columnLefts, columnWidths } = useMemo(() => {
|
|
1088
|
+
const engineColumns = grid.options.columns;
|
|
1089
|
+
const lefts = new Array(engineColumns.length).fill(0);
|
|
1090
|
+
const widths = new Array(engineColumns.length).fill(0);
|
|
1091
|
+
for (const planned of renderSnapshot.columns) {
|
|
1092
|
+
lefts[planned.index] = planned.left;
|
|
1093
|
+
widths[planned.index] = planned.width;
|
|
1094
|
+
}
|
|
1095
|
+
let acc = 0;
|
|
1096
|
+
for (let i = 0; i < engineColumns.length; i += 1) {
|
|
1097
|
+
const col = engineColumns[i];
|
|
1098
|
+
if (widths[i] === 0) {
|
|
1099
|
+
widths[i] = col.widthPx ?? 0;
|
|
1100
|
+
lefts[i] = acc;
|
|
1101
|
+
}
|
|
1102
|
+
acc = lefts[i] + widths[i];
|
|
1103
|
+
}
|
|
1104
|
+
return { columnLefts: lefts, columnWidths: widths };
|
|
1105
|
+
}, [renderSnapshot.columns, grid.options.columns]);
|
|
1106
|
+
const visibleRowIndexById = useMemo(() => {
|
|
1107
|
+
const map = /* @__PURE__ */ new Map();
|
|
1108
|
+
for (let i = 0; i < snapshot.visibleRows.length; i += 1) {
|
|
1109
|
+
const row = snapshot.visibleRows[i];
|
|
1110
|
+
if (row) {
|
|
1111
|
+
map.set(row.id, i);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
return map;
|
|
1115
|
+
}, [snapshot.visibleRows]);
|
|
1116
|
+
const dataColumnIndex = useMemo(() => {
|
|
1117
|
+
const dataColumns = effectiveColumns.filter(
|
|
1118
|
+
(c) => c.id !== ROW_SELECT_COLUMN_ID
|
|
1119
|
+
);
|
|
1120
|
+
const idxById = /* @__PURE__ */ new Map();
|
|
1121
|
+
for (let i = 0; i < dataColumns.length; i += 1) {
|
|
1122
|
+
idxById.set(dataColumns[i].id, i);
|
|
1123
|
+
}
|
|
1124
|
+
return { dataColumns, idxById };
|
|
1125
|
+
}, [effectiveColumns]);
|
|
1126
|
+
const { fullySelectedRowIds, indeterminateRowIds } = useMemo(() => {
|
|
1127
|
+
const fullyRows = /* @__PURE__ */ new Set();
|
|
1128
|
+
const indeterminateRows = /* @__PURE__ */ new Set();
|
|
1129
|
+
const ranges = snapshot.selection.ranges;
|
|
1130
|
+
const { dataColumns, idxById: dataColIdxByColId } = dataColumnIndex;
|
|
1131
|
+
if (ranges.length === 0 || dataColumns.length === 0) {
|
|
1132
|
+
return {
|
|
1133
|
+
fullySelectedRowIds: fullyRows,
|
|
1134
|
+
indeterminateRowIds: indeterminateRows
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
const visibleRows = snapshot.visibleRows;
|
|
1138
|
+
const colCount = dataColumns.length;
|
|
1139
|
+
if (colCount <= 30) {
|
|
1140
|
+
const rowMask = /* @__PURE__ */ new Map();
|
|
1141
|
+
for (const range of ranges) {
|
|
1142
|
+
const r1 = visibleRowIndexById.get(range.startRowId);
|
|
1143
|
+
const r2 = visibleRowIndexById.get(range.endRowId);
|
|
1144
|
+
if (r1 === void 0 || r2 === void 0) continue;
|
|
1145
|
+
const rowLo = Math.min(r1, r2);
|
|
1146
|
+
const rowHi = Math.max(r1, r2);
|
|
1147
|
+
const startSynth = range.startColumnId === ROW_SELECT_COLUMN_ID;
|
|
1148
|
+
const endSynth = range.endColumnId === ROW_SELECT_COLUMN_ID;
|
|
1149
|
+
let dataColLo;
|
|
1150
|
+
let dataColHi;
|
|
1151
|
+
if (startSynth && endSynth) {
|
|
1152
|
+
continue;
|
|
1153
|
+
}
|
|
1154
|
+
if (startSynth || endSynth) {
|
|
1155
|
+
dataColLo = 0;
|
|
1156
|
+
dataColHi = colCount - 1;
|
|
1157
|
+
} else {
|
|
1158
|
+
const a = dataColIdxByColId.get(range.startColumnId);
|
|
1159
|
+
const b = dataColIdxByColId.get(range.endColumnId);
|
|
1160
|
+
if (a === void 0 || b === void 0) continue;
|
|
1161
|
+
dataColLo = Math.min(a, b);
|
|
1162
|
+
dataColHi = Math.max(a, b);
|
|
1163
|
+
}
|
|
1164
|
+
const spanWidth = dataColHi - dataColLo + 1;
|
|
1165
|
+
const spanMask = (spanWidth >= 30 ? 1073741823 : (1 << spanWidth) - 1) << dataColLo >>> 0;
|
|
1166
|
+
for (let rowIdx = rowLo; rowIdx <= rowHi; rowIdx += 1) {
|
|
1167
|
+
rowMask.set(rowIdx, (rowMask.get(rowIdx) ?? 0) | spanMask);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
const fullMask = colCount >= 30 ? 1073741823 : (1 << colCount) - 1 >>> 0;
|
|
1171
|
+
for (const [rowIdx, mask] of rowMask) {
|
|
1172
|
+
if (mask === 0) continue;
|
|
1173
|
+
const row = visibleRows[rowIdx];
|
|
1174
|
+
if (!row) continue;
|
|
1175
|
+
if (mask === fullMask) fullyRows.add(row.id);
|
|
1176
|
+
else indeterminateRows.add(row.id);
|
|
1177
|
+
}
|
|
1178
|
+
} else {
|
|
1179
|
+
const rowCoverage = /* @__PURE__ */ new Map();
|
|
1180
|
+
for (const range of ranges) {
|
|
1181
|
+
const r1 = visibleRowIndexById.get(range.startRowId);
|
|
1182
|
+
const r2 = visibleRowIndexById.get(range.endRowId);
|
|
1183
|
+
if (r1 === void 0 || r2 === void 0) continue;
|
|
1184
|
+
const rowLo = Math.min(r1, r2);
|
|
1185
|
+
const rowHi = Math.max(r1, r2);
|
|
1186
|
+
const startSynth = range.startColumnId === ROW_SELECT_COLUMN_ID;
|
|
1187
|
+
const endSynth = range.endColumnId === ROW_SELECT_COLUMN_ID;
|
|
1188
|
+
let dataColLo;
|
|
1189
|
+
let dataColHi;
|
|
1190
|
+
if (startSynth && endSynth) continue;
|
|
1191
|
+
if (startSynth || endSynth) {
|
|
1192
|
+
dataColLo = 0;
|
|
1193
|
+
dataColHi = colCount - 1;
|
|
1194
|
+
} else {
|
|
1195
|
+
const a = dataColIdxByColId.get(range.startColumnId);
|
|
1196
|
+
const b = dataColIdxByColId.get(range.endColumnId);
|
|
1197
|
+
if (a === void 0 || b === void 0) continue;
|
|
1198
|
+
dataColLo = Math.min(a, b);
|
|
1199
|
+
dataColHi = Math.max(a, b);
|
|
1200
|
+
}
|
|
1201
|
+
for (let rowIdx = rowLo; rowIdx <= rowHi; rowIdx += 1) {
|
|
1202
|
+
let cov = rowCoverage.get(rowIdx);
|
|
1203
|
+
if (!cov) {
|
|
1204
|
+
cov = /* @__PURE__ */ new Set();
|
|
1205
|
+
rowCoverage.set(rowIdx, cov);
|
|
1206
|
+
}
|
|
1207
|
+
for (let colIdx = dataColLo; colIdx <= dataColHi; colIdx += 1) {
|
|
1208
|
+
cov.add(colIdx);
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
for (const [rowIdx, cov] of rowCoverage) {
|
|
1213
|
+
const row = visibleRows[rowIdx];
|
|
1214
|
+
if (!row) continue;
|
|
1215
|
+
if (cov.size === 0) continue;
|
|
1216
|
+
if (cov.size === colCount) fullyRows.add(row.id);
|
|
1217
|
+
else indeterminateRows.add(row.id);
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
return {
|
|
1221
|
+
fullySelectedRowIds: fullyRows,
|
|
1222
|
+
indeterminateRowIds: indeterminateRows
|
|
1223
|
+
};
|
|
1224
|
+
}, [
|
|
1225
|
+
snapshot.selection.ranges,
|
|
1226
|
+
snapshot.visibleRows,
|
|
1227
|
+
dataColumnIndex,
|
|
1228
|
+
visibleRowIndexById
|
|
1229
|
+
]);
|
|
1230
|
+
const isCellSelected = useCallback(
|
|
1231
|
+
(rowId, columnId) => {
|
|
1232
|
+
const ranges = snapshot.selection.ranges;
|
|
1233
|
+
if (ranges.length === 0) return false;
|
|
1234
|
+
const rIdx = visibleRowIndexById.get(rowId);
|
|
1235
|
+
if (rIdx === void 0) return false;
|
|
1236
|
+
const cIdx = dataColumnIndex.idxById.get(columnId);
|
|
1237
|
+
if (cIdx === void 0) return false;
|
|
1238
|
+
for (const range of ranges) {
|
|
1239
|
+
const r1 = visibleRowIndexById.get(range.startRowId);
|
|
1240
|
+
const r2 = visibleRowIndexById.get(range.endRowId);
|
|
1241
|
+
if (r1 === void 0 || r2 === void 0) continue;
|
|
1242
|
+
if (rIdx < Math.min(r1, r2) || rIdx > Math.max(r1, r2)) continue;
|
|
1243
|
+
const startSynth = range.startColumnId === ROW_SELECT_COLUMN_ID;
|
|
1244
|
+
const endSynth = range.endColumnId === ROW_SELECT_COLUMN_ID;
|
|
1245
|
+
if (startSynth && endSynth) continue;
|
|
1246
|
+
if (startSynth || endSynth) return true;
|
|
1247
|
+
const a = dataColumnIndex.idxById.get(range.startColumnId);
|
|
1248
|
+
const b = dataColumnIndex.idxById.get(range.endColumnId);
|
|
1249
|
+
if (a === void 0 || b === void 0) continue;
|
|
1250
|
+
if (cIdx >= Math.min(a, b) && cIdx <= Math.max(a, b)) return true;
|
|
1251
|
+
}
|
|
1252
|
+
return false;
|
|
1253
|
+
},
|
|
1254
|
+
[snapshot.selection.ranges, visibleRowIndexById, dataColumnIndex]
|
|
1255
|
+
);
|
|
833
1256
|
useLayoutEffect(() => {
|
|
834
1257
|
const el = viewportRef.current;
|
|
835
1258
|
if (el && viewportWidth === 0) {
|
|
836
1259
|
setViewportWidth(el.clientWidth);
|
|
837
1260
|
}
|
|
838
|
-
});
|
|
1261
|
+
}, [viewportWidth]);
|
|
839
1262
|
useLayoutEffect(() => {
|
|
840
1263
|
onTelemetryChange?.(telemetry);
|
|
841
1264
|
}, [onTelemetryChange, telemetry]);
|
|
@@ -843,14 +1266,26 @@ function PretableSurface({
|
|
|
843
1266
|
onGridReady?.(grid);
|
|
844
1267
|
}, [grid, onGridReady]);
|
|
845
1268
|
useLayoutEffect(() => {
|
|
846
|
-
if (!
|
|
1269
|
+
if (!focusedRowId || !focusedColumnId) {
|
|
847
1270
|
return;
|
|
848
1271
|
}
|
|
849
|
-
const
|
|
850
|
-
|
|
851
|
-
|
|
1272
|
+
const cellNode = cellNodesRef.current.get(
|
|
1273
|
+
`${focusedRowId}::${focusedColumnId}`
|
|
1274
|
+
);
|
|
1275
|
+
if (cellNode && document.activeElement !== cellNode) {
|
|
1276
|
+
cellNode.focus({ preventScroll: true });
|
|
852
1277
|
}
|
|
853
|
-
}, [
|
|
1278
|
+
}, [focusedRowId, focusedColumnId]);
|
|
1279
|
+
useLayoutEffect(() => {
|
|
1280
|
+
const injectedSelectedRowId = state?.selection?.ranges[0]?.startRowId ?? null;
|
|
1281
|
+
if (!injectedSelectedRowId) {
|
|
1282
|
+
return;
|
|
1283
|
+
}
|
|
1284
|
+
const currentSelectedRowId = snapshot.selection.ranges[0]?.startRowId ?? null;
|
|
1285
|
+
if (currentSelectedRowId !== injectedSelectedRowId) {
|
|
1286
|
+
onSelectedRowIdChange?.(injectedSelectedRowId);
|
|
1287
|
+
}
|
|
1288
|
+
}, [state, onSelectedRowIdChange, snapshot.selection.ranges]);
|
|
854
1289
|
useLayoutEffect(() => {
|
|
855
1290
|
let nextHeights = measuredHeightsRef.current;
|
|
856
1291
|
let nextKeys = measuredRowKeysRef.current;
|
|
@@ -891,35 +1326,106 @@ function PretableSurface({
|
|
|
891
1326
|
if (changed) {
|
|
892
1327
|
setMeasuredHeights(nextHeights);
|
|
893
1328
|
}
|
|
894
|
-
}, [snapshot.visibleRows,
|
|
1329
|
+
}, [snapshot.visibleRows, effectiveColumns, viewportWidth]);
|
|
895
1330
|
return /* @__PURE__ */ jsxs(
|
|
896
1331
|
"div",
|
|
897
1332
|
{
|
|
1333
|
+
"aria-colcount": effectiveColumns.length,
|
|
898
1334
|
"aria-label": ariaLabel,
|
|
1335
|
+
"aria-multiselectable": "true",
|
|
1336
|
+
"aria-rowcount": snapshot.totalRowCount + 1,
|
|
899
1337
|
"data-pretable-scroll-viewport": "",
|
|
900
1338
|
ref: viewportRef,
|
|
901
1339
|
role: "grid",
|
|
902
|
-
tabIndex:
|
|
1340
|
+
tabIndex: -1,
|
|
903
1341
|
onKeyDown: (event) => {
|
|
904
|
-
if (event.key === "
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
1342
|
+
if ((event.key === "Escape" || event.key === "Esc") && reorderStateRef.current?.dragging) {
|
|
1343
|
+
reorderStateRef.current = null;
|
|
1344
|
+
setReorderDrag(null);
|
|
1345
|
+
event.preventDefault();
|
|
1346
|
+
return;
|
|
1347
|
+
}
|
|
1348
|
+
if ((event.key === "Escape" || event.key === "Esc") && dragAnchorRef.current !== null && dragStartSelectionRef.current !== null) {
|
|
1349
|
+
const before2 = grid.getSnapshot();
|
|
1350
|
+
grid.setSelection(dragStartSelectionRef.current);
|
|
1351
|
+
dragAnchorRef.current = null;
|
|
1352
|
+
dragStartSelectionRef.current = null;
|
|
1353
|
+
const after = grid.getSnapshot();
|
|
1354
|
+
if (JSON.stringify(before2.selection) !== JSON.stringify(after.selection)) {
|
|
1355
|
+
onSelectionChange?.(after.selection);
|
|
913
1356
|
}
|
|
914
1357
|
event.preventDefault();
|
|
915
1358
|
return;
|
|
916
1359
|
}
|
|
917
|
-
if (event.key === "
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
1360
|
+
if ((event.key === "c" || event.key === "C") && (event.metaKey || event.ctrlKey) && !event.shiftKey && !event.altKey && !(event.target instanceof HTMLInputElement) && !(event.target instanceof HTMLTextAreaElement)) {
|
|
1361
|
+
event.preventDefault();
|
|
1362
|
+
const snap = grid.getSnapshot();
|
|
1363
|
+
if (snap.selection.ranges.length === 0) {
|
|
1364
|
+
return;
|
|
1365
|
+
}
|
|
1366
|
+
const args = {
|
|
1367
|
+
ranges: snap.selection.ranges,
|
|
1368
|
+
visibleRows: snap.visibleRows,
|
|
1369
|
+
columns: effectiveColumns,
|
|
1370
|
+
copyWithHeaders: copyWithHeaders ?? false
|
|
1371
|
+
};
|
|
1372
|
+
const payload = onCopy ? onCopy(args) : serializeRangesAsTsv(args);
|
|
1373
|
+
if (payload) {
|
|
1374
|
+
const extent = computeSelectionExtent(
|
|
1375
|
+
snap.selection.ranges,
|
|
1376
|
+
snap,
|
|
1377
|
+
effectiveColumns
|
|
1378
|
+
);
|
|
1379
|
+
Promise.resolve(
|
|
1380
|
+
(copyToClipboard ?? defaultCopyToClipboard)(payload)
|
|
1381
|
+
).then(() => {
|
|
1382
|
+
scheduleAnnouncement(
|
|
1383
|
+
effectiveMessages.copyAnnouncement({
|
|
1384
|
+
rowCount: extent.rowCount,
|
|
1385
|
+
columnCount: extent.columnCount
|
|
1386
|
+
})
|
|
1387
|
+
);
|
|
1388
|
+
}).catch((err) => {
|
|
1389
|
+
console.warn("[pretable] clipboard copy failed", err);
|
|
1390
|
+
scheduleAnnouncement(
|
|
1391
|
+
effectiveMessages.copyFailedAnnouncement()
|
|
1392
|
+
);
|
|
1393
|
+
});
|
|
1394
|
+
}
|
|
1395
|
+
return;
|
|
1396
|
+
}
|
|
1397
|
+
const isSelectAll = (event.metaKey || event.ctrlKey) && (event.key === "a" || event.key === "A") && !event.shiftKey && !event.altKey;
|
|
1398
|
+
const before = grid.getSnapshot();
|
|
1399
|
+
const handled = handleSurfaceKeyDown(event, {
|
|
1400
|
+
bodyViewportHeight,
|
|
1401
|
+
columns: effectiveColumns,
|
|
1402
|
+
grid,
|
|
1403
|
+
onSelectedRowIdChange,
|
|
1404
|
+
selectFocusedRowOnArrowKey,
|
|
1405
|
+
tabBehavior
|
|
1406
|
+
});
|
|
1407
|
+
if (handled) {
|
|
1408
|
+
event.preventDefault();
|
|
1409
|
+
const after = grid.getSnapshot();
|
|
1410
|
+
if (isSelectAll) {
|
|
1411
|
+
const extent = computeSelectionExtent(
|
|
1412
|
+
after.selection.ranges,
|
|
1413
|
+
after,
|
|
1414
|
+
effectiveColumns
|
|
1415
|
+
);
|
|
1416
|
+
scheduleAnnouncement(
|
|
1417
|
+
effectiveMessages.selectAllAnnouncement({
|
|
1418
|
+
rowCount: extent.rowCount,
|
|
1419
|
+
columnCount: extent.columnCount,
|
|
1420
|
+
isAll: extent.isAll
|
|
1421
|
+
})
|
|
1422
|
+
);
|
|
1423
|
+
}
|
|
1424
|
+
if (before.focus.rowId !== after.focus.rowId || before.focus.columnId !== after.focus.columnId) {
|
|
1425
|
+
onFocusChange?.(after.focus);
|
|
1426
|
+
}
|
|
1427
|
+
if (JSON.stringify(before.selection) !== JSON.stringify(after.selection)) {
|
|
1428
|
+
onSelectionChange?.(after.selection);
|
|
923
1429
|
}
|
|
924
1430
|
}
|
|
925
1431
|
},
|
|
@@ -943,12 +1449,93 @@ function PretableSurface({
|
|
|
943
1449
|
/* @__PURE__ */ jsx(
|
|
944
1450
|
"div",
|
|
945
1451
|
{
|
|
1452
|
+
"aria-atomic": "true",
|
|
1453
|
+
"aria-live": "polite",
|
|
1454
|
+
className: "pt-sr-only",
|
|
1455
|
+
"data-pretable-live-region": "",
|
|
1456
|
+
role: "status",
|
|
1457
|
+
children: liveMessage
|
|
1458
|
+
}
|
|
1459
|
+
),
|
|
1460
|
+
/* @__PURE__ */ jsx(
|
|
1461
|
+
"div",
|
|
1462
|
+
{
|
|
1463
|
+
"aria-rowindex": 1,
|
|
946
1464
|
"data-pretable-header-row": "",
|
|
1465
|
+
role: "row",
|
|
947
1466
|
style: getHeaderRowStyle(renderSnapshot.totalWidth, headerHeight),
|
|
948
|
-
children: renderSnapshot.columns.
|
|
949
|
-
const column =
|
|
1467
|
+
children: renderSnapshot.columns.flatMap((plannedCol) => {
|
|
1468
|
+
const column = columnsById.get(plannedCol.id);
|
|
950
1469
|
if (!column) {
|
|
951
|
-
return
|
|
1470
|
+
return [];
|
|
1471
|
+
}
|
|
1472
|
+
const effWidth = dragLiveWidth?.columnId === column.id ? dragLiveWidth.width : plannedCol.width;
|
|
1473
|
+
if (column.id === ROW_SELECT_COLUMN_ID) {
|
|
1474
|
+
const pinnedOffset2 = pinnedOffsets[column.id];
|
|
1475
|
+
const positionStyle2 = plannedCol.pinned === "left" && pinnedOffset2 !== void 0 ? {
|
|
1476
|
+
...getHeaderCellStyle(plannedCol.left, plannedCol.width),
|
|
1477
|
+
...getPinnedCellStyle(pinnedOffset2)
|
|
1478
|
+
} : getHeaderCellStyle(plannedCol.left, plannedCol.width);
|
|
1479
|
+
const visibleRows = snapshot.visibleRows;
|
|
1480
|
+
const allFullySelected = visibleRows.length > 0 && visibleRows.every((r) => fullySelectedRowIds.has(r.id));
|
|
1481
|
+
const anySelected = visibleRows.some(
|
|
1482
|
+
(r) => fullySelectedRowIds.has(r.id) || indeterminateRowIds.has(r.id)
|
|
1483
|
+
);
|
|
1484
|
+
const headerCheckState = allFullySelected ? "true" : anySelected ? "mixed" : "false";
|
|
1485
|
+
const showHeaderCheckbox = rowSelectionColumn?.headerCheckbox !== false;
|
|
1486
|
+
return /* @__PURE__ */ jsx(
|
|
1487
|
+
"div",
|
|
1488
|
+
{
|
|
1489
|
+
"aria-colindex": plannedCol.index + 1,
|
|
1490
|
+
"data-pretable-header-cell": "",
|
|
1491
|
+
"data-pretable-row-select-header": "",
|
|
1492
|
+
"data-pinned": plannedCol.pinned === "left" ? "left" : void 0,
|
|
1493
|
+
role: "columnheader",
|
|
1494
|
+
style: {
|
|
1495
|
+
alignItems: "center",
|
|
1496
|
+
display: "flex",
|
|
1497
|
+
justifyContent: "center",
|
|
1498
|
+
padding: 0,
|
|
1499
|
+
...positionStyle2
|
|
1500
|
+
},
|
|
1501
|
+
children: showHeaderCheckbox ? /* @__PURE__ */ jsx(
|
|
1502
|
+
"button",
|
|
1503
|
+
{
|
|
1504
|
+
"aria-checked": headerCheckState,
|
|
1505
|
+
"aria-label": "Select all rows",
|
|
1506
|
+
"data-pretable-row-select-all": "true",
|
|
1507
|
+
onClick: (event) => {
|
|
1508
|
+
event.stopPropagation();
|
|
1509
|
+
const before = grid.getSnapshot();
|
|
1510
|
+
const setting = !allFullySelected;
|
|
1511
|
+
grid.setSelectAllVisible(setting);
|
|
1512
|
+
const after = grid.getSnapshot();
|
|
1513
|
+
if (JSON.stringify(before.selection) !== JSON.stringify(after.selection)) {
|
|
1514
|
+
onSelectionChange?.(after.selection);
|
|
1515
|
+
}
|
|
1516
|
+
if (setting) {
|
|
1517
|
+
const extent = computeSelectionExtent(
|
|
1518
|
+
after.selection.ranges,
|
|
1519
|
+
after,
|
|
1520
|
+
effectiveColumns
|
|
1521
|
+
);
|
|
1522
|
+
scheduleAnnouncement(
|
|
1523
|
+
effectiveMessages.selectAllAnnouncement({
|
|
1524
|
+
rowCount: extent.rowCount,
|
|
1525
|
+
columnCount: extent.columnCount,
|
|
1526
|
+
isAll: extent.isAll
|
|
1527
|
+
})
|
|
1528
|
+
);
|
|
1529
|
+
}
|
|
1530
|
+
},
|
|
1531
|
+
role: "checkbox",
|
|
1532
|
+
type: "button",
|
|
1533
|
+
children: headerCheckState === "true" ? "\u2713" : headerCheckState === "mixed" ? "\u2013" : ""
|
|
1534
|
+
}
|
|
1535
|
+
) : null
|
|
1536
|
+
},
|
|
1537
|
+
column.id
|
|
1538
|
+
);
|
|
952
1539
|
}
|
|
953
1540
|
const label = column.header ?? column.id;
|
|
954
1541
|
const sortDirection = snapshot.sort.columnId === column.id ? snapshot.sort.direction : null;
|
|
@@ -958,54 +1545,261 @@ function PretableSurface({
|
|
|
958
1545
|
}) ?? {};
|
|
959
1546
|
const pinnedOffset = pinnedOffsets[column.id];
|
|
960
1547
|
const positionStyle = plannedCol.pinned === "left" && pinnedOffset !== void 0 ? {
|
|
961
|
-
...getHeaderCellStyle(plannedCol.left,
|
|
1548
|
+
...getHeaderCellStyle(plannedCol.left, effWidth),
|
|
962
1549
|
...getPinnedCellStyle(pinnedOffset)
|
|
963
|
-
} : getHeaderCellStyle(plannedCol.left,
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
1550
|
+
} : getHeaderCellStyle(plannedCol.left, effWidth);
|
|
1551
|
+
const ariaSort = sortDirection === "asc" ? "ascending" : sortDirection === "desc" ? "descending" : "none";
|
|
1552
|
+
const showResizeHandle = column.resizable !== false;
|
|
1553
|
+
const isDragging = dragLiveWidth?.columnId === column.id;
|
|
1554
|
+
const handleLeft = plannedCol.left + effWidth - 4;
|
|
1555
|
+
const handlePinnedStyle = plannedCol.pinned === "left" && pinnedOffset !== void 0 ? {
|
|
1556
|
+
position: "sticky",
|
|
1557
|
+
zIndex: 3,
|
|
1558
|
+
left: pinnedOffset + effWidth - 4
|
|
1559
|
+
} : null;
|
|
1560
|
+
return [
|
|
1561
|
+
/* @__PURE__ */ createElement(
|
|
1562
|
+
"button",
|
|
1563
|
+
{
|
|
1564
|
+
...headerProps,
|
|
1565
|
+
"aria-colindex": plannedCol.index + 1,
|
|
1566
|
+
"aria-label": `Sort ${label}`,
|
|
1567
|
+
"aria-sort": ariaSort,
|
|
1568
|
+
className: getHeaderCellClassName?.({
|
|
1569
|
+
column,
|
|
1570
|
+
sortDirection
|
|
1571
|
+
}),
|
|
1572
|
+
"data-pretable-header-cell": "",
|
|
1573
|
+
"data-pinned": plannedCol.pinned === "left" ? "left" : void 0,
|
|
1574
|
+
key: column.id,
|
|
1575
|
+
role: "columnheader",
|
|
1576
|
+
onClick: (event) => {
|
|
1577
|
+
if (wasReorderingRef.current) {
|
|
1578
|
+
event.preventDefault();
|
|
1579
|
+
wasReorderingRef.current = false;
|
|
1580
|
+
return;
|
|
1581
|
+
}
|
|
1582
|
+
const nextDirection = getNextSortDirection(sortDirection);
|
|
1583
|
+
grid.setSort(column.id, nextDirection);
|
|
1584
|
+
if (nextDirection) {
|
|
1585
|
+
onSortChange?.({
|
|
1586
|
+
columnId: column.id,
|
|
1587
|
+
direction: nextDirection
|
|
1588
|
+
});
|
|
1589
|
+
} else {
|
|
1590
|
+
onSortChange?.(null);
|
|
1591
|
+
}
|
|
1592
|
+
},
|
|
1593
|
+
...column.id !== ROW_SELECT_COLUMN_ID && column.reorderable !== false ? {
|
|
1594
|
+
onPointerDown: (event) => {
|
|
1595
|
+
if (event.button !== 0) return;
|
|
1596
|
+
if (event.shiftKey || event.metaKey || event.ctrlKey)
|
|
1597
|
+
return;
|
|
1598
|
+
reorderStateRef.current = {
|
|
1599
|
+
columnId: column.id,
|
|
1600
|
+
pointerId: event.pointerId,
|
|
1601
|
+
startX: event.clientX,
|
|
1602
|
+
startY: event.clientY,
|
|
1603
|
+
dragging: false
|
|
1604
|
+
};
|
|
1605
|
+
},
|
|
1606
|
+
onPointerMove: (event) => {
|
|
1607
|
+
const drag = reorderStateRef.current;
|
|
1608
|
+
if (!drag || drag.columnId !== column.id) return;
|
|
1609
|
+
if (event.pointerId !== drag.pointerId) return;
|
|
1610
|
+
const dx = event.clientX - drag.startX;
|
|
1611
|
+
const dy = event.clientY - drag.startY;
|
|
1612
|
+
const dist = Math.hypot(dx, dy);
|
|
1613
|
+
const surfaceRect = viewportRef.current?.getBoundingClientRect();
|
|
1614
|
+
const surfaceLeft = surfaceRect?.left ?? 0;
|
|
1615
|
+
if (!drag.dragging) {
|
|
1616
|
+
if (dist < REORDER_THRESHOLD_PX) return;
|
|
1617
|
+
drag.dragging = true;
|
|
1618
|
+
try {
|
|
1619
|
+
event.currentTarget.setPointerCapture(
|
|
1620
|
+
event.pointerId
|
|
1621
|
+
);
|
|
1622
|
+
} catch {
|
|
1623
|
+
}
|
|
1624
|
+
const headerEl = event.currentTarget;
|
|
1625
|
+
const rect = headerEl.getBoundingClientRect();
|
|
1626
|
+
setReorderDrag({
|
|
1627
|
+
columnId: column.id,
|
|
1628
|
+
cursorX: event.clientX,
|
|
1629
|
+
cursorY: event.clientY,
|
|
1630
|
+
dropIndex: computeDropIndex(
|
|
1631
|
+
event.clientX,
|
|
1632
|
+
effectiveColumns.length,
|
|
1633
|
+
columnLefts,
|
|
1634
|
+
columnWidths,
|
|
1635
|
+
surfaceLeft
|
|
1636
|
+
),
|
|
1637
|
+
ghostWidth: rect.width || effWidth,
|
|
1638
|
+
ghostHeight: rect.height || headerHeight,
|
|
1639
|
+
ghostHeader: String(column.header ?? column.id)
|
|
1640
|
+
});
|
|
1641
|
+
return;
|
|
1642
|
+
}
|
|
1643
|
+
setReorderDrag(
|
|
1644
|
+
(prev) => prev ? {
|
|
1645
|
+
...prev,
|
|
1646
|
+
cursorX: event.clientX,
|
|
1647
|
+
cursorY: event.clientY,
|
|
1648
|
+
dropIndex: computeDropIndex(
|
|
1649
|
+
event.clientX,
|
|
1650
|
+
effectiveColumns.length,
|
|
1651
|
+
columnLefts,
|
|
1652
|
+
columnWidths,
|
|
1653
|
+
surfaceLeft
|
|
1654
|
+
)
|
|
1655
|
+
} : null
|
|
1656
|
+
);
|
|
1657
|
+
},
|
|
1658
|
+
onPointerUp: (event) => {
|
|
1659
|
+
const drag = reorderStateRef.current;
|
|
1660
|
+
if (!drag || drag.columnId !== column.id) return;
|
|
1661
|
+
if (event.pointerId !== drag.pointerId) return;
|
|
1662
|
+
const current = reorderDrag;
|
|
1663
|
+
if (drag.dragging && current) {
|
|
1664
|
+
wasReorderingRef.current = true;
|
|
1665
|
+
const beforePinned = buildPinnedMap(grid);
|
|
1666
|
+
grid.moveColumn(column.id, current.dropIndex);
|
|
1667
|
+
const afterOrder = grid.options.columns.map((c) => c.id).filter((id) => id !== ROW_SELECT_COLUMN_ID);
|
|
1668
|
+
onColumnOrderChange?.(afterOrder);
|
|
1669
|
+
const afterPinned = buildPinnedMap(grid);
|
|
1670
|
+
if (!pinnedMapsEqual(beforePinned, afterPinned)) {
|
|
1671
|
+
onColumnPinnedChange?.(afterPinned);
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
try {
|
|
1675
|
+
event.currentTarget.releasePointerCapture(
|
|
1676
|
+
event.pointerId
|
|
1677
|
+
);
|
|
1678
|
+
} catch {
|
|
1679
|
+
}
|
|
1680
|
+
reorderStateRef.current = null;
|
|
1681
|
+
setReorderDrag(null);
|
|
1682
|
+
},
|
|
1683
|
+
onPointerCancel: () => {
|
|
1684
|
+
reorderStateRef.current = null;
|
|
1685
|
+
setReorderDrag(null);
|
|
1686
|
+
}
|
|
1687
|
+
} : {},
|
|
1688
|
+
style: {
|
|
1689
|
+
alignItems: "start",
|
|
1690
|
+
border: 0,
|
|
1691
|
+
borderRight: "1px solid rgba(255, 255, 255, 0.06)",
|
|
1692
|
+
color: "inherit",
|
|
1693
|
+
display: "grid",
|
|
1694
|
+
gap: 4,
|
|
1695
|
+
textAlign: "left",
|
|
1696
|
+
...positionStyle
|
|
1697
|
+
},
|
|
1698
|
+
type: "button"
|
|
1699
|
+
},
|
|
1700
|
+
/* @__PURE__ */ jsx(
|
|
1701
|
+
MemoizedHeaderContent,
|
|
1702
|
+
{
|
|
1703
|
+
columnId: column.id,
|
|
1704
|
+
label,
|
|
1705
|
+
sortDirection,
|
|
1706
|
+
isSorted: sortDirection !== null,
|
|
1707
|
+
width: effWidth,
|
|
1708
|
+
isSortable: column.sortable !== false,
|
|
1709
|
+
renderHeaderRef: column.renderHeader ?? null,
|
|
1710
|
+
fallbackRenderHeaderRef: renderHeaderCell ?? null,
|
|
1711
|
+
headerRenderInput: {
|
|
1712
|
+
column,
|
|
1713
|
+
label,
|
|
1714
|
+
sortDirection,
|
|
1715
|
+
isSorted: sortDirection !== null
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
)
|
|
1719
|
+
),
|
|
1720
|
+
showResizeHandle ? /* @__PURE__ */ jsx(
|
|
1721
|
+
"div",
|
|
1722
|
+
{
|
|
1723
|
+
"data-pretable-resize-handle": "",
|
|
1724
|
+
"data-column-id": column.id,
|
|
1725
|
+
"data-dragging": isDragging ? "true" : "false",
|
|
1726
|
+
style: {
|
|
1727
|
+
position: "absolute",
|
|
1728
|
+
top: 0,
|
|
1729
|
+
height: "100%",
|
|
1730
|
+
width: 4,
|
|
1731
|
+
left: handleLeft,
|
|
1732
|
+
cursor: "col-resize",
|
|
1733
|
+
zIndex: 4,
|
|
1734
|
+
touchAction: "none",
|
|
1735
|
+
userSelect: "none",
|
|
1736
|
+
...handlePinnedStyle ?? {}
|
|
1737
|
+
},
|
|
1738
|
+
onPointerDown: (event) => {
|
|
1739
|
+
if (event.button !== 0) return;
|
|
1740
|
+
event.stopPropagation();
|
|
1741
|
+
const startWidth = column.widthPx ?? plannedCol.width ?? Math.max(column.minWidthPx ?? 40, 80);
|
|
1742
|
+
resizeStateRef.current = {
|
|
981
1743
|
columnId: column.id,
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1744
|
+
startX: event.clientX,
|
|
1745
|
+
startWidth,
|
|
1746
|
+
pointerId: event.pointerId
|
|
1747
|
+
};
|
|
1748
|
+
wasResizingRef.current = false;
|
|
1749
|
+
try {
|
|
1750
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
1751
|
+
} catch {
|
|
1752
|
+
}
|
|
1753
|
+
setDragLiveWidth({ columnId: column.id, width: startWidth });
|
|
1754
|
+
},
|
|
1755
|
+
onPointerMove: (event) => {
|
|
1756
|
+
const drag = resizeStateRef.current;
|
|
1757
|
+
if (!drag || drag.columnId !== column.id) return;
|
|
1758
|
+
const min = column.minWidthPx ?? 40;
|
|
1759
|
+
const max = column.maxWidthPx ?? Infinity;
|
|
1760
|
+
const next = Math.max(
|
|
1761
|
+
min,
|
|
1762
|
+
Math.min(
|
|
1763
|
+
max,
|
|
1764
|
+
drag.startWidth + (event.clientX - drag.startX)
|
|
1765
|
+
)
|
|
1766
|
+
);
|
|
1767
|
+
if (Math.abs(next - drag.startWidth) > 0) {
|
|
1768
|
+
wasResizingRef.current = true;
|
|
1769
|
+
}
|
|
1770
|
+
setDragLiveWidth({ columnId: column.id, width: next });
|
|
1771
|
+
},
|
|
1772
|
+
onPointerUp: (event) => {
|
|
1773
|
+
const drag = resizeStateRef.current;
|
|
1774
|
+
if (!drag || drag.columnId !== column.id) return;
|
|
1775
|
+
const finalWidth = dragLiveWidth?.width ?? drag.startWidth;
|
|
1776
|
+
try {
|
|
1777
|
+
event.currentTarget.releasePointerCapture(drag.pointerId);
|
|
1778
|
+
} catch {
|
|
1779
|
+
}
|
|
1780
|
+
grid.setColumnWidth(column.id, finalWidth);
|
|
1781
|
+
onColumnWidthsChange?.(buildWidthsMap(grid));
|
|
1782
|
+
resizeStateRef.current = null;
|
|
1783
|
+
setDragLiveWidth(null);
|
|
1784
|
+
},
|
|
1785
|
+
onPointerCancel: () => {
|
|
1786
|
+
resizeStateRef.current = null;
|
|
1787
|
+
setDragLiveWidth(null);
|
|
1788
|
+
wasResizingRef.current = false;
|
|
1789
|
+
},
|
|
1790
|
+
onDoubleClick: (event) => {
|
|
1791
|
+
if (wasResizingRef.current) {
|
|
1792
|
+
event.preventDefault();
|
|
1793
|
+
wasResizingRef.current = false;
|
|
1794
|
+
return;
|
|
1795
|
+
}
|
|
1796
|
+
grid.autosizeColumn(column.id);
|
|
1797
|
+
onColumnWidthsChange?.(buildWidthsMap(grid));
|
|
986
1798
|
}
|
|
987
1799
|
},
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
borderRight: "1px solid rgba(255, 255, 255, 0.06)",
|
|
992
|
-
color: "inherit",
|
|
993
|
-
display: "grid",
|
|
994
|
-
gap: 4,
|
|
995
|
-
textAlign: "left",
|
|
996
|
-
...positionStyle
|
|
997
|
-
},
|
|
998
|
-
type: "button"
|
|
999
|
-
},
|
|
1000
|
-
renderHeaderCell ? renderHeaderCell({
|
|
1001
|
-
column,
|
|
1002
|
-
label,
|
|
1003
|
-
sortDirection
|
|
1004
|
-
}) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1005
|
-
/* @__PURE__ */ jsx("span", { children: label }),
|
|
1006
|
-
/* @__PURE__ */ jsx("strong", { children: sortDirection === "desc" ? "Newest" : sortDirection === "asc" ? "Oldest" : "Sort" })
|
|
1007
|
-
] })
|
|
1008
|
-
);
|
|
1800
|
+
`${column.id}::resize-handle`
|
|
1801
|
+
) : null
|
|
1802
|
+
];
|
|
1009
1803
|
})
|
|
1010
1804
|
}
|
|
1011
1805
|
),
|
|
@@ -1019,7 +1813,7 @@ function PretableSurface({
|
|
|
1019
1813
|
),
|
|
1020
1814
|
children: renderSnapshot.rows.map(({ height, id, row, rowIndex, top }) => {
|
|
1021
1815
|
const isFocused = snapshot.focus.rowId === id;
|
|
1022
|
-
const isSelected =
|
|
1816
|
+
const isSelected = fullySelectedRowIds.has(id);
|
|
1023
1817
|
const rowProps = getRowProps?.({
|
|
1024
1818
|
isFocused,
|
|
1025
1819
|
isSelected,
|
|
@@ -1031,8 +1825,8 @@ function PretableSurface({
|
|
|
1031
1825
|
"div",
|
|
1032
1826
|
{
|
|
1033
1827
|
...rowProps,
|
|
1034
|
-
"aria-rowindex": rowIndex +
|
|
1035
|
-
"aria-selected": isSelected,
|
|
1828
|
+
"aria-rowindex": rowIndex + 2,
|
|
1829
|
+
"aria-selected": isSelected ? "true" : void 0,
|
|
1036
1830
|
className: getRowClassName?.({
|
|
1037
1831
|
isFocused,
|
|
1038
1832
|
isSelected,
|
|
@@ -1048,11 +1842,7 @@ function PretableSurface({
|
|
|
1048
1842
|
"data-selected": isSelected ? "true" : "false",
|
|
1049
1843
|
"data-testid": "pretable-row",
|
|
1050
1844
|
key: id,
|
|
1051
|
-
|
|
1052
|
-
grid.setFocus(id, columns[0]?.id ?? null);
|
|
1053
|
-
grid.selectRow(id);
|
|
1054
|
-
onSelectedRowIdChange?.(id);
|
|
1055
|
-
},
|
|
1845
|
+
role: "row",
|
|
1056
1846
|
ref: (node) => {
|
|
1057
1847
|
if (node) {
|
|
1058
1848
|
rowNodesRef.current.set(id, node);
|
|
@@ -1063,15 +1853,20 @@ function PretableSurface({
|
|
|
1063
1853
|
style: getRowStyle(top, height)
|
|
1064
1854
|
},
|
|
1065
1855
|
renderSnapshot.columns.map((plannedCol) => {
|
|
1066
|
-
const column =
|
|
1856
|
+
const column = columnsById.get(plannedCol.id);
|
|
1067
1857
|
if (!column) {
|
|
1068
1858
|
return null;
|
|
1069
1859
|
}
|
|
1070
1860
|
const value = resolveCellValue(row, column);
|
|
1861
|
+
const cellKey = `${id}::${column.id}`;
|
|
1862
|
+
const cellIsFocused = isFocused && snapshot.focus.columnId === column.id;
|
|
1863
|
+
const cellIsSelected = isCellSelected(id, column.id);
|
|
1864
|
+
const formattedValue = column.format ? column.format({ value, row, column }) : formatCellValue(value);
|
|
1071
1865
|
const bodyInput = {
|
|
1072
1866
|
column,
|
|
1073
|
-
|
|
1074
|
-
|
|
1867
|
+
formattedValue,
|
|
1868
|
+
isFocused: cellIsFocused,
|
|
1869
|
+
isSelected: cellIsSelected,
|
|
1075
1870
|
row,
|
|
1076
1871
|
rowId: id,
|
|
1077
1872
|
rowIndex,
|
|
@@ -1079,39 +1874,310 @@ function PretableSurface({
|
|
|
1079
1874
|
};
|
|
1080
1875
|
const bodyProps = getBodyCellProps?.(bodyInput) ?? {};
|
|
1081
1876
|
const pinnedOffset = pinnedOffsets[column.id];
|
|
1877
|
+
const cellEffWidth = dragLiveWidth?.columnId === column.id ? dragLiveWidth.width : plannedCol.width;
|
|
1082
1878
|
const positionStyle = plannedCol.pinned === "left" && pinnedOffset !== void 0 ? {
|
|
1083
|
-
...getCellStyle(plannedCol.left,
|
|
1879
|
+
...getCellStyle(plannedCol.left, cellEffWidth),
|
|
1084
1880
|
...getPinnedCellStyle(pinnedOffset)
|
|
1085
|
-
} : getCellStyle(plannedCol.left,
|
|
1881
|
+
} : getCellStyle(plannedCol.left, cellEffWidth);
|
|
1882
|
+
const isRowSelectCell = column.id === ROW_SELECT_COLUMN_ID;
|
|
1883
|
+
const rowCheckState = fullySelectedRowIds.has(id) ? "true" : indeterminateRowIds.has(id) ? "mixed" : "false";
|
|
1086
1884
|
return /* @__PURE__ */ createElement(
|
|
1087
1885
|
"div",
|
|
1088
1886
|
{
|
|
1089
1887
|
...bodyProps,
|
|
1888
|
+
"aria-colindex": plannedCol.index + 1,
|
|
1889
|
+
"aria-selected": cellIsSelected ? "true" : void 0,
|
|
1090
1890
|
className: getBodyCellClassName?.(bodyInput),
|
|
1091
1891
|
"data-column-id": column.id,
|
|
1092
|
-
"data-focused":
|
|
1892
|
+
"data-focused": cellIsFocused ? "true" : "false",
|
|
1093
1893
|
"data-pinned": column.pinned === "left" ? "left" : void 0,
|
|
1094
1894
|
"data-pretable-cell": "",
|
|
1095
1895
|
"data-pretable-wrap": column.wrap ? "true" : void 0,
|
|
1096
|
-
"data-
|
|
1896
|
+
"data-row-select-cell": isRowSelectCell ? "true" : void 0,
|
|
1897
|
+
"data-selected": cellIsSelected ? "true" : "false",
|
|
1097
1898
|
key: `${id}:${column.id}`,
|
|
1899
|
+
onClick: (event) => {
|
|
1900
|
+
if (column.id === ROW_SELECT_COLUMN_ID) return;
|
|
1901
|
+
handleCellClick({
|
|
1902
|
+
cmd: event.metaKey || event.ctrlKey,
|
|
1903
|
+
columnId: column.id,
|
|
1904
|
+
columns: effectiveColumns,
|
|
1905
|
+
grid,
|
|
1906
|
+
onFocusChange,
|
|
1907
|
+
onSelectedRowIdChange,
|
|
1908
|
+
onSelectionChange,
|
|
1909
|
+
rowId: id,
|
|
1910
|
+
shift: event.shiftKey
|
|
1911
|
+
});
|
|
1912
|
+
},
|
|
1913
|
+
onPointerDown: (event) => {
|
|
1914
|
+
if (event.button !== 0) return;
|
|
1915
|
+
if (column.id === ROW_SELECT_COLUMN_ID) return;
|
|
1916
|
+
const cmd = event.metaKey || event.ctrlKey;
|
|
1917
|
+
if (event.shiftKey || cmd) return;
|
|
1918
|
+
dragStartSelectionRef.current = grid.getSnapshot().selection;
|
|
1919
|
+
dragAnchorRef.current = {
|
|
1920
|
+
rowId: id,
|
|
1921
|
+
columnId: column.id
|
|
1922
|
+
};
|
|
1923
|
+
handleCellClick({
|
|
1924
|
+
cmd: false,
|
|
1925
|
+
columnId: column.id,
|
|
1926
|
+
columns: effectiveColumns,
|
|
1927
|
+
grid,
|
|
1928
|
+
onFocusChange,
|
|
1929
|
+
onSelectedRowIdChange,
|
|
1930
|
+
onSelectionChange,
|
|
1931
|
+
rowId: id,
|
|
1932
|
+
shift: false
|
|
1933
|
+
});
|
|
1934
|
+
try {
|
|
1935
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
1936
|
+
} catch {
|
|
1937
|
+
}
|
|
1938
|
+
},
|
|
1939
|
+
onPointerEnter: () => {
|
|
1940
|
+
if (!dragAnchorRef.current) return;
|
|
1941
|
+
if (column.id === ROW_SELECT_COLUMN_ID) return;
|
|
1942
|
+
const before = grid.getSnapshot();
|
|
1943
|
+
const addr = {
|
|
1944
|
+
rowId: id,
|
|
1945
|
+
columnId: column.id
|
|
1946
|
+
};
|
|
1947
|
+
grid.extendRangeFromAnchor(addr);
|
|
1948
|
+
grid.setFocus(addr);
|
|
1949
|
+
const after = grid.getSnapshot();
|
|
1950
|
+
if (before.focus.rowId !== after.focus.rowId || before.focus.columnId !== after.focus.columnId) {
|
|
1951
|
+
onFocusChange?.(after.focus);
|
|
1952
|
+
}
|
|
1953
|
+
if (JSON.stringify(before.selection) !== JSON.stringify(after.selection)) {
|
|
1954
|
+
onSelectionChange?.(after.selection);
|
|
1955
|
+
const beforeFullRow = singleFullRowSelection(
|
|
1956
|
+
before.selection,
|
|
1957
|
+
effectiveColumns.filter(
|
|
1958
|
+
(c) => c.id !== ROW_SELECT_COLUMN_ID
|
|
1959
|
+
)
|
|
1960
|
+
);
|
|
1961
|
+
const afterFullRow = singleFullRowSelection(
|
|
1962
|
+
after.selection,
|
|
1963
|
+
effectiveColumns.filter(
|
|
1964
|
+
(c) => c.id !== ROW_SELECT_COLUMN_ID
|
|
1965
|
+
)
|
|
1966
|
+
);
|
|
1967
|
+
if (beforeFullRow !== afterFullRow) {
|
|
1968
|
+
onSelectedRowIdChange?.(afterFullRow);
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
},
|
|
1972
|
+
onPointerUp: () => {
|
|
1973
|
+
dragAnchorRef.current = null;
|
|
1974
|
+
},
|
|
1975
|
+
onPointerCancel: () => {
|
|
1976
|
+
dragAnchorRef.current = null;
|
|
1977
|
+
},
|
|
1978
|
+
ref: (node) => {
|
|
1979
|
+
if (node) {
|
|
1980
|
+
cellNodesRef.current.set(cellKey, node);
|
|
1981
|
+
} else {
|
|
1982
|
+
cellNodesRef.current.delete(cellKey);
|
|
1983
|
+
}
|
|
1984
|
+
},
|
|
1985
|
+
role: "gridcell",
|
|
1098
1986
|
style: {
|
|
1987
|
+
outline: "none",
|
|
1099
1988
|
overflowWrap: column.wrap ? "anywhere" : "normal",
|
|
1100
1989
|
whiteSpace: column.wrap ? "pre-wrap" : "nowrap",
|
|
1101
1990
|
...positionStyle
|
|
1102
|
-
}
|
|
1991
|
+
},
|
|
1992
|
+
tabIndex: cellIsFocused ? 0 : -1
|
|
1103
1993
|
},
|
|
1104
|
-
|
|
1994
|
+
isRowSelectCell ? /* @__PURE__ */ jsx(
|
|
1995
|
+
"button",
|
|
1996
|
+
{
|
|
1997
|
+
"aria-checked": rowCheckState,
|
|
1998
|
+
"aria-label": "Select row",
|
|
1999
|
+
"data-pretable-row-select": "true",
|
|
2000
|
+
onClick: (event) => {
|
|
2001
|
+
event.stopPropagation();
|
|
2002
|
+
event.preventDefault();
|
|
2003
|
+
const before = grid.getSnapshot();
|
|
2004
|
+
const visible = before.visibleRows;
|
|
2005
|
+
if (event.shiftKey && lastCheckedRowAnchorRef.current) {
|
|
2006
|
+
const anchorId = lastCheckedRowAnchorRef.current;
|
|
2007
|
+
const anchorIdx = visible.findIndex(
|
|
2008
|
+
(r) => r.id === anchorId
|
|
2009
|
+
);
|
|
2010
|
+
const clickedIdx = visible.findIndex(
|
|
2011
|
+
(r) => r.id === id
|
|
2012
|
+
);
|
|
2013
|
+
if (anchorIdx >= 0 && clickedIdx >= 0) {
|
|
2014
|
+
const [lo, hi] = anchorIdx <= clickedIdx ? [anchorIdx, clickedIdx] : [clickedIdx, anchorIdx];
|
|
2015
|
+
for (let i = lo; i <= hi; i += 1) {
|
|
2016
|
+
const r = visible[i];
|
|
2017
|
+
if (r && !fullySelectedRowIds.has(r.id)) {
|
|
2018
|
+
grid.toggleRowSelection(r.id);
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
2022
|
+
} else {
|
|
2023
|
+
grid.toggleRowSelection(id);
|
|
2024
|
+
}
|
|
2025
|
+
lastCheckedRowAnchorRef.current = id;
|
|
2026
|
+
const after = grid.getSnapshot();
|
|
2027
|
+
if (JSON.stringify(before.selection) !== JSON.stringify(after.selection)) {
|
|
2028
|
+
onSelectionChange?.(after.selection);
|
|
2029
|
+
}
|
|
2030
|
+
},
|
|
2031
|
+
role: "checkbox",
|
|
2032
|
+
type: "button",
|
|
2033
|
+
children: rowCheckState === "true" ? "\u2713" : rowCheckState === "mixed" ? "\u2013" : ""
|
|
2034
|
+
}
|
|
2035
|
+
) : /* @__PURE__ */ jsx(
|
|
2036
|
+
MemoizedCellContent,
|
|
2037
|
+
{
|
|
2038
|
+
rowId: id,
|
|
2039
|
+
columnId: column.id,
|
|
2040
|
+
value,
|
|
2041
|
+
formattedValue,
|
|
2042
|
+
isFocused: cellIsFocused,
|
|
2043
|
+
isSelected: cellIsSelected,
|
|
2044
|
+
renderRef: column.render ?? null,
|
|
2045
|
+
fallbackRenderRef: renderBodyCell ?? null,
|
|
2046
|
+
cellRenderInput: bodyInput
|
|
2047
|
+
}
|
|
2048
|
+
)
|
|
1105
2049
|
);
|
|
1106
2050
|
})
|
|
1107
2051
|
);
|
|
1108
2052
|
})
|
|
1109
2053
|
}
|
|
1110
|
-
)
|
|
2054
|
+
),
|
|
2055
|
+
reorderDrag ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2056
|
+
/* @__PURE__ */ jsx(
|
|
2057
|
+
"div",
|
|
2058
|
+
{
|
|
2059
|
+
"data-pretable-reorder-ghost": "",
|
|
2060
|
+
style: {
|
|
2061
|
+
left: reorderDrag.cursorX + 8,
|
|
2062
|
+
top: reorderDrag.cursorY + 8,
|
|
2063
|
+
width: reorderDrag.ghostWidth,
|
|
2064
|
+
height: reorderDrag.ghostHeight,
|
|
2065
|
+
display: "flex",
|
|
2066
|
+
alignItems: "center",
|
|
2067
|
+
paddingLeft: 12
|
|
2068
|
+
},
|
|
2069
|
+
children: reorderDrag.ghostHeader
|
|
2070
|
+
}
|
|
2071
|
+
),
|
|
2072
|
+
/* @__PURE__ */ jsx(
|
|
2073
|
+
"div",
|
|
2074
|
+
{
|
|
2075
|
+
"data-pretable-reorder-drop-indicator": "",
|
|
2076
|
+
style: {
|
|
2077
|
+
left: computeDropIndicatorLeft(
|
|
2078
|
+
reorderDrag.dropIndex,
|
|
2079
|
+
columnLefts,
|
|
2080
|
+
columnWidths
|
|
2081
|
+
),
|
|
2082
|
+
height: reorderDrag.ghostHeight + bodyViewportHeight
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
)
|
|
2086
|
+
] }) : null
|
|
1111
2087
|
]
|
|
1112
2088
|
}
|
|
1113
2089
|
);
|
|
1114
2090
|
}
|
|
2091
|
+
function replaceSelectionWithFullRow(grid, rowId, columns) {
|
|
2092
|
+
const firstColumn = columns[0];
|
|
2093
|
+
const lastColumn = columns[columns.length - 1];
|
|
2094
|
+
if (!firstColumn || !lastColumn) {
|
|
2095
|
+
grid.setSelection({ ranges: [], anchor: null });
|
|
2096
|
+
return;
|
|
2097
|
+
}
|
|
2098
|
+
grid.setSelection({
|
|
2099
|
+
ranges: [
|
|
2100
|
+
{
|
|
2101
|
+
startRowId: rowId,
|
|
2102
|
+
endRowId: rowId,
|
|
2103
|
+
startColumnId: firstColumn.id,
|
|
2104
|
+
endColumnId: lastColumn.id
|
|
2105
|
+
}
|
|
2106
|
+
],
|
|
2107
|
+
anchor: { rowId, columnId: firstColumn.id }
|
|
2108
|
+
});
|
|
2109
|
+
}
|
|
2110
|
+
function handleCellClick(args) {
|
|
2111
|
+
const {
|
|
2112
|
+
cmd,
|
|
2113
|
+
columnId,
|
|
2114
|
+
columns,
|
|
2115
|
+
grid,
|
|
2116
|
+
onFocusChange,
|
|
2117
|
+
onSelectedRowIdChange,
|
|
2118
|
+
onSelectionChange,
|
|
2119
|
+
rowId,
|
|
2120
|
+
shift
|
|
2121
|
+
} = args;
|
|
2122
|
+
const before = grid.getSnapshot();
|
|
2123
|
+
const addr = { rowId, columnId };
|
|
2124
|
+
if (shift && !cmd && before.selection.anchor) {
|
|
2125
|
+
grid.extendRangeFromAnchor(addr);
|
|
2126
|
+
grid.setFocus(addr);
|
|
2127
|
+
} else if (cmd) {
|
|
2128
|
+
grid.addRange({
|
|
2129
|
+
startRowId: rowId,
|
|
2130
|
+
endRowId: rowId,
|
|
2131
|
+
startColumnId: columnId,
|
|
2132
|
+
endColumnId: columnId
|
|
2133
|
+
});
|
|
2134
|
+
grid.setFocus(addr);
|
|
2135
|
+
} else {
|
|
2136
|
+
grid.setFocus(addr);
|
|
2137
|
+
grid.setSelection({
|
|
2138
|
+
ranges: [
|
|
2139
|
+
{
|
|
2140
|
+
startRowId: rowId,
|
|
2141
|
+
endRowId: rowId,
|
|
2142
|
+
startColumnId: columnId,
|
|
2143
|
+
endColumnId: columnId
|
|
2144
|
+
}
|
|
2145
|
+
],
|
|
2146
|
+
anchor: addr
|
|
2147
|
+
});
|
|
2148
|
+
}
|
|
2149
|
+
const after = grid.getSnapshot();
|
|
2150
|
+
if (before.focus.rowId !== after.focus.rowId || before.focus.columnId !== after.focus.columnId) {
|
|
2151
|
+
onFocusChange?.(after.focus);
|
|
2152
|
+
}
|
|
2153
|
+
const selectionChanged = JSON.stringify(before.selection) !== JSON.stringify(after.selection);
|
|
2154
|
+
if (selectionChanged) {
|
|
2155
|
+
onSelectionChange?.(after.selection);
|
|
2156
|
+
const dataColumns = columns.filter((c) => c.id !== ROW_SELECT_COLUMN_ID);
|
|
2157
|
+
const beforeFullRow = singleFullRowSelection(before.selection, dataColumns);
|
|
2158
|
+
const afterFullRow = singleFullRowSelection(after.selection, dataColumns);
|
|
2159
|
+
if (beforeFullRow !== afterFullRow) {
|
|
2160
|
+
onSelectedRowIdChange?.(afterFullRow);
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2163
|
+
}
|
|
2164
|
+
function singleFullRowSelection(selection, columns) {
|
|
2165
|
+
if (selection.ranges.length !== 1 || columns.length === 0) {
|
|
2166
|
+
return null;
|
|
2167
|
+
}
|
|
2168
|
+
const range = selection.ranges[0];
|
|
2169
|
+
if (!range) return null;
|
|
2170
|
+
if (range.startRowId !== range.endRowId) return null;
|
|
2171
|
+
const firstColumn = columns[0];
|
|
2172
|
+
const lastColumn = columns[columns.length - 1];
|
|
2173
|
+
if (!firstColumn || !lastColumn) return null;
|
|
2174
|
+
const startMatchesFirst = range.startColumnId === firstColumn.id;
|
|
2175
|
+
const endMatchesLast = range.endColumnId === lastColumn.id;
|
|
2176
|
+
const startMatchesLast = range.startColumnId === lastColumn.id;
|
|
2177
|
+
const endMatchesFirst = range.endColumnId === firstColumn.id;
|
|
2178
|
+
const coversAllColumns = startMatchesFirst && endMatchesLast || startMatchesLast && endMatchesFirst;
|
|
2179
|
+
return coversAllColumns ? range.startRowId : null;
|
|
2180
|
+
}
|
|
1115
2181
|
function getRowMeasurementKey(rowNode) {
|
|
1116
2182
|
const rowParts = [
|
|
1117
2183
|
rowNode.getAttribute("class") ?? "",
|
|
@@ -1138,6 +2204,281 @@ function getRowMeasurementKey(rowNode) {
|
|
|
1138
2204
|
function normalizeStyleSignature(styleValue) {
|
|
1139
2205
|
return styleValue.split(";").map((declaration) => declaration.trim()).filter(Boolean).filter((declaration) => !/^top\s*:/i.test(declaration)).join(";");
|
|
1140
2206
|
}
|
|
2207
|
+
function computeSelectionExtent(ranges, snapshot, effectiveColumns) {
|
|
2208
|
+
const visibleRows = snapshot.visibleRows;
|
|
2209
|
+
const dataColumns = effectiveColumns.filter(
|
|
2210
|
+
(c) => c.id !== ROW_SELECT_COLUMN_ID
|
|
2211
|
+
);
|
|
2212
|
+
if (ranges.length === 0 || visibleRows.length === 0 || dataColumns.length === 0) {
|
|
2213
|
+
return { rowCount: 0, columnCount: 0, isAll: false };
|
|
2214
|
+
}
|
|
2215
|
+
const rowOrder = /* @__PURE__ */ new Map();
|
|
2216
|
+
for (let i = 0; i < visibleRows.length; i += 1) {
|
|
2217
|
+
const r = visibleRows[i];
|
|
2218
|
+
if (r) rowOrder.set(r.id, i);
|
|
2219
|
+
}
|
|
2220
|
+
const columnOrder = /* @__PURE__ */ new Map();
|
|
2221
|
+
for (let i = 0; i < effectiveColumns.length; i += 1) {
|
|
2222
|
+
const c = effectiveColumns[i];
|
|
2223
|
+
if (c) columnOrder.set(c.id, i);
|
|
2224
|
+
}
|
|
2225
|
+
const coveredRows = /* @__PURE__ */ new Set();
|
|
2226
|
+
const coveredCols = /* @__PURE__ */ new Set();
|
|
2227
|
+
for (const range of ranges) {
|
|
2228
|
+
const r1 = rowOrder.get(range.startRowId);
|
|
2229
|
+
const r2 = rowOrder.get(range.endRowId);
|
|
2230
|
+
if (r1 === void 0 || r2 === void 0) continue;
|
|
2231
|
+
const rowLo = Math.min(r1, r2);
|
|
2232
|
+
const rowHi = Math.max(r1, r2);
|
|
2233
|
+
const startSynth = range.startColumnId === ROW_SELECT_COLUMN_ID;
|
|
2234
|
+
const endSynth = range.endColumnId === ROW_SELECT_COLUMN_ID;
|
|
2235
|
+
let colsForRange;
|
|
2236
|
+
if (startSynth && endSynth) {
|
|
2237
|
+
continue;
|
|
2238
|
+
}
|
|
2239
|
+
if (startSynth || endSynth) {
|
|
2240
|
+
colsForRange = dataColumns.slice();
|
|
2241
|
+
} else {
|
|
2242
|
+
const c1 = columnOrder.get(range.startColumnId);
|
|
2243
|
+
const c2 = columnOrder.get(range.endColumnId);
|
|
2244
|
+
if (c1 === void 0 || c2 === void 0) continue;
|
|
2245
|
+
const colLo = Math.min(c1, c2);
|
|
2246
|
+
const colHi = Math.max(c1, c2);
|
|
2247
|
+
colsForRange = [];
|
|
2248
|
+
for (let i = colLo; i <= colHi; i += 1) {
|
|
2249
|
+
const col = effectiveColumns[i];
|
|
2250
|
+
if (col && col.id !== ROW_SELECT_COLUMN_ID) {
|
|
2251
|
+
colsForRange.push(col);
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
if (colsForRange.length === 0) continue;
|
|
2256
|
+
for (let i = rowLo; i <= rowHi; i += 1) {
|
|
2257
|
+
const row = visibleRows[i];
|
|
2258
|
+
if (row) coveredRows.add(row.id);
|
|
2259
|
+
}
|
|
2260
|
+
for (const col of colsForRange) {
|
|
2261
|
+
coveredCols.add(col.id);
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
const rowCount = coveredRows.size;
|
|
2265
|
+
const columnCount = coveredCols.size;
|
|
2266
|
+
const isAll = rowCount === visibleRows.length && columnCount === dataColumns.length;
|
|
2267
|
+
return { rowCount, columnCount, isAll };
|
|
2268
|
+
}
|
|
2269
|
+
var ARROW_DIRECTIONS = {
|
|
2270
|
+
ArrowUp: "up",
|
|
2271
|
+
ArrowDown: "down",
|
|
2272
|
+
ArrowLeft: "left",
|
|
2273
|
+
ArrowRight: "right"
|
|
2274
|
+
};
|
|
2275
|
+
function handleSurfaceKeyDown(event, ctx) {
|
|
2276
|
+
const {
|
|
2277
|
+
bodyViewportHeight,
|
|
2278
|
+
columns: allColumns,
|
|
2279
|
+
grid,
|
|
2280
|
+
onSelectedRowIdChange,
|
|
2281
|
+
selectFocusedRowOnArrowKey,
|
|
2282
|
+
tabBehavior
|
|
2283
|
+
} = ctx;
|
|
2284
|
+
const columns = allColumns.filter((c) => c.id !== ROW_SELECT_COLUMN_ID);
|
|
2285
|
+
const { key } = event;
|
|
2286
|
+
const cmd = event.metaKey || event.ctrlKey;
|
|
2287
|
+
const shift = event.shiftKey;
|
|
2288
|
+
const snapshot = grid.getSnapshot();
|
|
2289
|
+
const focus = snapshot.focus;
|
|
2290
|
+
const visibleRows = snapshot.visibleRows;
|
|
2291
|
+
const firstColumn = columns[0];
|
|
2292
|
+
const lastColumn = columns[columns.length - 1];
|
|
2293
|
+
const direction = ARROW_DIRECTIONS[key];
|
|
2294
|
+
if (direction) {
|
|
2295
|
+
grid.moveFocus(direction, {
|
|
2296
|
+
extend: shift,
|
|
2297
|
+
jumpToEdge: cmd
|
|
2298
|
+
});
|
|
2299
|
+
const after = grid.getSnapshot();
|
|
2300
|
+
if (after.focus.columnId === ROW_SELECT_COLUMN_ID && firstColumn) {
|
|
2301
|
+
const rowId = after.focus.rowId;
|
|
2302
|
+
if (rowId) {
|
|
2303
|
+
grid.setFocus({ rowId, columnId: firstColumn.id });
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
if (selectFocusedRowOnArrowKey) {
|
|
2307
|
+
const nextFocus = grid.getSnapshot().focus;
|
|
2308
|
+
if (nextFocus.rowId) {
|
|
2309
|
+
replaceSelectionWithFullRow(grid, nextFocus.rowId, columns);
|
|
2310
|
+
onSelectedRowIdChange?.(nextFocus.rowId);
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
return true;
|
|
2314
|
+
}
|
|
2315
|
+
if (key === "Home") {
|
|
2316
|
+
if (!firstColumn) return false;
|
|
2317
|
+
if (cmd) {
|
|
2318
|
+
const firstRow = visibleRows[0];
|
|
2319
|
+
if (!firstRow) return false;
|
|
2320
|
+
grid.setFocus({ rowId: firstRow.id, columnId: firstColumn.id });
|
|
2321
|
+
} else if (focus.rowId) {
|
|
2322
|
+
grid.setFocus({ rowId: focus.rowId, columnId: firstColumn.id });
|
|
2323
|
+
} else {
|
|
2324
|
+
const firstRow = visibleRows[0];
|
|
2325
|
+
if (!firstRow) return false;
|
|
2326
|
+
grid.setFocus({ rowId: firstRow.id, columnId: firstColumn.id });
|
|
2327
|
+
}
|
|
2328
|
+
return true;
|
|
2329
|
+
}
|
|
2330
|
+
if (key === "End") {
|
|
2331
|
+
if (!lastColumn) return false;
|
|
2332
|
+
if (cmd) {
|
|
2333
|
+
const lastRow = visibleRows[visibleRows.length - 1];
|
|
2334
|
+
if (!lastRow) return false;
|
|
2335
|
+
grid.setFocus({ rowId: lastRow.id, columnId: lastColumn.id });
|
|
2336
|
+
} else if (focus.rowId) {
|
|
2337
|
+
grid.setFocus({ rowId: focus.rowId, columnId: lastColumn.id });
|
|
2338
|
+
} else {
|
|
2339
|
+
const firstRow = visibleRows[0];
|
|
2340
|
+
if (!firstRow) return false;
|
|
2341
|
+
grid.setFocus({ rowId: firstRow.id, columnId: lastColumn.id });
|
|
2342
|
+
}
|
|
2343
|
+
return true;
|
|
2344
|
+
}
|
|
2345
|
+
if (key === "PageUp" || key === "PageDown") {
|
|
2346
|
+
if (visibleRows.length === 0 || !firstColumn) return false;
|
|
2347
|
+
const pageRowCount = Math.max(1, Math.floor(bodyViewportHeight / 32));
|
|
2348
|
+
const currentRowIdx = focus.rowId ? visibleRows.findIndex((r) => r.id === focus.rowId) : -1;
|
|
2349
|
+
const baseRowIdx = currentRowIdx === -1 ? 0 : currentRowIdx;
|
|
2350
|
+
const nextRowIdx = key === "PageUp" ? Math.max(0, baseRowIdx - pageRowCount) : Math.min(visibleRows.length - 1, baseRowIdx + pageRowCount);
|
|
2351
|
+
const nextRow = visibleRows[nextRowIdx];
|
|
2352
|
+
if (!nextRow) return false;
|
|
2353
|
+
const columnId = focus.columnId ?? firstColumn.id;
|
|
2354
|
+
const addr = { rowId: nextRow.id, columnId };
|
|
2355
|
+
if (shift) {
|
|
2356
|
+
if (!snapshot.selection.anchor && focus.rowId && focus.columnId) {
|
|
2357
|
+
grid.setSelection({
|
|
2358
|
+
ranges: [
|
|
2359
|
+
{
|
|
2360
|
+
startRowId: focus.rowId,
|
|
2361
|
+
endRowId: focus.rowId,
|
|
2362
|
+
startColumnId: focus.columnId,
|
|
2363
|
+
endColumnId: focus.columnId
|
|
2364
|
+
}
|
|
2365
|
+
],
|
|
2366
|
+
anchor: { rowId: focus.rowId, columnId: focus.columnId }
|
|
2367
|
+
});
|
|
2368
|
+
}
|
|
2369
|
+
grid.setFocus(addr);
|
|
2370
|
+
grid.extendRangeFromAnchor(addr);
|
|
2371
|
+
} else {
|
|
2372
|
+
grid.setFocus(addr);
|
|
2373
|
+
}
|
|
2374
|
+
return true;
|
|
2375
|
+
}
|
|
2376
|
+
if (key === "Tab") {
|
|
2377
|
+
if (tabBehavior === "exit") {
|
|
2378
|
+
return false;
|
|
2379
|
+
}
|
|
2380
|
+
if (visibleRows.length === 0 || columns.length === 0) return false;
|
|
2381
|
+
const currentRowIdx = focus.rowId ? visibleRows.findIndex((r) => r.id === focus.rowId) : -1;
|
|
2382
|
+
const currentColIdx = focus.columnId ? columns.findIndex((c) => c.id === focus.columnId) : -1;
|
|
2383
|
+
const baseRowIdx = currentRowIdx === -1 ? 0 : currentRowIdx;
|
|
2384
|
+
const baseColIdx = currentColIdx === -1 ? 0 : currentColIdx;
|
|
2385
|
+
let nextRowIdx = baseRowIdx;
|
|
2386
|
+
let nextColIdx = baseColIdx;
|
|
2387
|
+
if (shift) {
|
|
2388
|
+
if (baseColIdx === 0) {
|
|
2389
|
+
nextColIdx = columns.length - 1;
|
|
2390
|
+
nextRowIdx = Math.max(0, baseRowIdx - 1);
|
|
2391
|
+
if (baseRowIdx === 0) {
|
|
2392
|
+
nextColIdx = 0;
|
|
2393
|
+
nextRowIdx = 0;
|
|
2394
|
+
}
|
|
2395
|
+
} else {
|
|
2396
|
+
nextColIdx = baseColIdx - 1;
|
|
2397
|
+
}
|
|
2398
|
+
} else {
|
|
2399
|
+
if (baseColIdx === columns.length - 1) {
|
|
2400
|
+
nextColIdx = 0;
|
|
2401
|
+
nextRowIdx = Math.min(visibleRows.length - 1, baseRowIdx + 1);
|
|
2402
|
+
if (baseRowIdx === visibleRows.length - 1) {
|
|
2403
|
+
nextColIdx = columns.length - 1;
|
|
2404
|
+
nextRowIdx = visibleRows.length - 1;
|
|
2405
|
+
}
|
|
2406
|
+
} else {
|
|
2407
|
+
nextColIdx = baseColIdx + 1;
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
const nextRow = visibleRows[nextRowIdx];
|
|
2411
|
+
const nextCol = columns[nextColIdx];
|
|
2412
|
+
if (!nextRow || !nextCol) return false;
|
|
2413
|
+
grid.setFocus({ rowId: nextRow.id, columnId: nextCol.id });
|
|
2414
|
+
return true;
|
|
2415
|
+
}
|
|
2416
|
+
if (cmd && (key === "a" || key === "A")) {
|
|
2417
|
+
grid.selectAll();
|
|
2418
|
+
return true;
|
|
2419
|
+
}
|
|
2420
|
+
if (key === "Escape" || key === "Esc") {
|
|
2421
|
+
grid.clearSelection();
|
|
2422
|
+
return true;
|
|
2423
|
+
}
|
|
2424
|
+
if (key === "Enter" || key === " " || key === "Space") {
|
|
2425
|
+
const focusedRowId = focus.rowId;
|
|
2426
|
+
if (focusedRowId) {
|
|
2427
|
+
replaceSelectionWithFullRow(grid, focusedRowId, columns);
|
|
2428
|
+
onSelectedRowIdChange?.(focusedRowId);
|
|
2429
|
+
return true;
|
|
2430
|
+
}
|
|
2431
|
+
return false;
|
|
2432
|
+
}
|
|
2433
|
+
return false;
|
|
2434
|
+
}
|
|
2435
|
+
function buildWidthsMap(grid) {
|
|
2436
|
+
const result = {};
|
|
2437
|
+
for (const col of grid.options.columns) {
|
|
2438
|
+
if (col.id === ROW_SELECT_COLUMN_ID) continue;
|
|
2439
|
+
if (typeof col.widthPx === "number") {
|
|
2440
|
+
result[col.id] = col.widthPx;
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
return result;
|
|
2444
|
+
}
|
|
2445
|
+
function buildPinnedMap(grid) {
|
|
2446
|
+
const result = {};
|
|
2447
|
+
for (const col of grid.options.columns) {
|
|
2448
|
+
if (col.id === ROW_SELECT_COLUMN_ID) continue;
|
|
2449
|
+
result[col.id] = col.pinned === "left" ? "left" : null;
|
|
2450
|
+
}
|
|
2451
|
+
return result;
|
|
2452
|
+
}
|
|
2453
|
+
function pinnedMapsEqual(a, b) {
|
|
2454
|
+
const aKeys = Object.keys(a);
|
|
2455
|
+
const bKeys = Object.keys(b);
|
|
2456
|
+
if (aKeys.length !== bKeys.length) return false;
|
|
2457
|
+
for (const k of aKeys) {
|
|
2458
|
+
if (a[k] !== b[k]) return false;
|
|
2459
|
+
}
|
|
2460
|
+
return true;
|
|
2461
|
+
}
|
|
2462
|
+
function computeDropIndex(cursorX, columnCount, columnLefts, columnWidths, surfaceLeft) {
|
|
2463
|
+
const x = cursorX - surfaceLeft;
|
|
2464
|
+
for (let i = 0; i < columnCount; i += 1) {
|
|
2465
|
+
const left = columnLefts[i] ?? 0;
|
|
2466
|
+
const width = columnWidths[i] ?? 0;
|
|
2467
|
+
const mid = left + width / 2;
|
|
2468
|
+
if (x < mid) {
|
|
2469
|
+
return i;
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
return Math.max(0, columnCount - 1);
|
|
2473
|
+
}
|
|
2474
|
+
function computeDropIndicatorLeft(dropIndex, columnLefts, columnWidths) {
|
|
2475
|
+
if (dropIndex >= columnLefts.length) {
|
|
2476
|
+
const lastIdx = columnLefts.length - 1;
|
|
2477
|
+
if (lastIdx < 0) return 0;
|
|
2478
|
+
return (columnLefts[lastIdx] ?? 0) + (columnWidths[lastIdx] ?? 0);
|
|
2479
|
+
}
|
|
2480
|
+
return columnLefts[dropIndex] ?? 0;
|
|
2481
|
+
}
|
|
1141
2482
|
var VIEWPORT_HEIGHT = 320;
|
|
1142
2483
|
var BENCHMARK_VIEWPORT_STYLE = {
|
|
1143
2484
|
contain: "none",
|
|
@@ -1149,7 +2490,16 @@ var BENCHMARK_VIEWPORT_STYLE = {
|
|
|
1149
2490
|
function Pretable({
|
|
1150
2491
|
columns,
|
|
1151
2492
|
getRowId,
|
|
1152
|
-
rows
|
|
2493
|
+
rows,
|
|
2494
|
+
rowSelectionColumn,
|
|
2495
|
+
tabBehavior,
|
|
2496
|
+
copyWithHeaders,
|
|
2497
|
+
onCopy,
|
|
2498
|
+
copyToClipboard,
|
|
2499
|
+
messages,
|
|
2500
|
+
onColumnWidthsChange,
|
|
2501
|
+
onColumnOrderChange,
|
|
2502
|
+
onColumnPinnedChange
|
|
1153
2503
|
}) {
|
|
1154
2504
|
const resolvedGetRowId = getRowId ?? ((row, index) => {
|
|
1155
2505
|
const candidate = row.id;
|
|
@@ -1233,6 +2583,15 @@ function Pretable({
|
|
|
1233
2583
|
)
|
|
1234
2584
|
] }),
|
|
1235
2585
|
rows,
|
|
2586
|
+
rowSelectionColumn,
|
|
2587
|
+
tabBehavior,
|
|
2588
|
+
copyWithHeaders,
|
|
2589
|
+
onCopy,
|
|
2590
|
+
copyToClipboard,
|
|
2591
|
+
messages,
|
|
2592
|
+
onColumnWidthsChange,
|
|
2593
|
+
onColumnOrderChange,
|
|
2594
|
+
onColumnPinnedChange,
|
|
1236
2595
|
viewportStyle: BENCHMARK_VIEWPORT_STYLE,
|
|
1237
2596
|
viewportHeight: VIEWPORT_HEIGHT
|
|
1238
2597
|
}
|
|
@@ -1252,7 +2611,7 @@ var inspectionColumns = [
|
|
|
1252
2611
|
id: "tags",
|
|
1253
2612
|
header: "Tags",
|
|
1254
2613
|
widthPx: 200,
|
|
1255
|
-
|
|
2614
|
+
value: (row) => row.tags.join(", ")
|
|
1256
2615
|
},
|
|
1257
2616
|
{ id: "message", header: "Message", wrap: true, widthPx: 480 }
|
|
1258
2617
|
];
|
|
@@ -1265,22 +2624,33 @@ function LabeledGridSurface({
|
|
|
1265
2624
|
getHeaderCellProps,
|
|
1266
2625
|
getRowId,
|
|
1267
2626
|
headerCellClassName,
|
|
1268
|
-
|
|
2627
|
+
state,
|
|
1269
2628
|
labelClassName,
|
|
1270
2629
|
overscan,
|
|
1271
2630
|
onSelectedRowIdChange,
|
|
2631
|
+
onSelectionChange,
|
|
2632
|
+
onFocusChange,
|
|
1272
2633
|
onSortChange,
|
|
2634
|
+
onColumnWidthsChange,
|
|
2635
|
+
onColumnOrderChange,
|
|
2636
|
+
onColumnPinnedChange,
|
|
1273
2637
|
onTelemetryChange,
|
|
1274
2638
|
pinnedClassName,
|
|
1275
2639
|
rowClassName,
|
|
1276
2640
|
rows,
|
|
2641
|
+
rowSelectionColumn,
|
|
1277
2642
|
selectFocusedRowOnArrowKey,
|
|
2643
|
+
tabBehavior,
|
|
2644
|
+
copyWithHeaders,
|
|
2645
|
+
onCopy,
|
|
2646
|
+
copyToClipboard,
|
|
2647
|
+
messages,
|
|
1278
2648
|
valueClassName,
|
|
1279
2649
|
viewportHeight
|
|
1280
2650
|
}) {
|
|
1281
2651
|
const getPinnedClassName = (column) => column.pinned === "left" && pinnedClassName ? pinnedClassName : void 0;
|
|
1282
2652
|
const activeFilterColumns = new Set(
|
|
1283
|
-
Object.entries(
|
|
2653
|
+
Object.entries(state?.filters ?? {}).filter(([, value]) => value.trim() !== "").map(([columnId]) => columnId)
|
|
1284
2654
|
);
|
|
1285
2655
|
const getFormattedValue = ({
|
|
1286
2656
|
column,
|
|
@@ -1312,10 +2682,15 @@ function LabeledGridSurface({
|
|
|
1312
2682
|
),
|
|
1313
2683
|
getRowClassName: () => rowClassName,
|
|
1314
2684
|
getRowId,
|
|
1315
|
-
|
|
2685
|
+
state,
|
|
1316
2686
|
overscan,
|
|
1317
2687
|
onSelectedRowIdChange,
|
|
2688
|
+
onSelectionChange,
|
|
2689
|
+
onFocusChange,
|
|
1318
2690
|
onSortChange,
|
|
2691
|
+
onColumnWidthsChange,
|
|
2692
|
+
onColumnOrderChange,
|
|
2693
|
+
onColumnPinnedChange,
|
|
1319
2694
|
onTelemetryChange,
|
|
1320
2695
|
renderBodyCell: ({ column, row, value }) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1321
2696
|
/* @__PURE__ */ jsx("span", { className: labelClassName, children: column.header ?? column.id }),
|
|
@@ -1330,7 +2705,13 @@ function LabeledGridSurface({
|
|
|
1330
2705
|
sortDirection ? /* @__PURE__ */ jsx("span", { className: "sort-indicator", children: sortDirection === "desc" ? "\u25BC" : "\u25B2" }) : null
|
|
1331
2706
|
] }),
|
|
1332
2707
|
rows,
|
|
2708
|
+
rowSelectionColumn,
|
|
1333
2709
|
selectFocusedRowOnArrowKey,
|
|
2710
|
+
tabBehavior,
|
|
2711
|
+
copyWithHeaders,
|
|
2712
|
+
onCopy,
|
|
2713
|
+
copyToClipboard,
|
|
2714
|
+
messages,
|
|
1334
2715
|
viewportHeight
|
|
1335
2716
|
}
|
|
1336
2717
|
);
|
|
@@ -1367,12 +2748,23 @@ var filterableHeaderProps = {
|
|
|
1367
2748
|
function InspectionGrid({
|
|
1368
2749
|
ariaLabel,
|
|
1369
2750
|
filterableColumnIds,
|
|
1370
|
-
|
|
2751
|
+
state,
|
|
1371
2752
|
onSelectedRowIdChange,
|
|
2753
|
+
onSelectionChange,
|
|
2754
|
+
onFocusChange,
|
|
1372
2755
|
onSortChange,
|
|
2756
|
+
onColumnWidthsChange,
|
|
2757
|
+
onColumnOrderChange,
|
|
2758
|
+
onColumnPinnedChange,
|
|
1373
2759
|
onTelemetryChange,
|
|
1374
2760
|
overscan,
|
|
1375
2761
|
rows,
|
|
2762
|
+
rowSelectionColumn,
|
|
2763
|
+
tabBehavior,
|
|
2764
|
+
copyWithHeaders,
|
|
2765
|
+
onCopy,
|
|
2766
|
+
copyToClipboard,
|
|
2767
|
+
messages,
|
|
1376
2768
|
viewportHeight
|
|
1377
2769
|
}) {
|
|
1378
2770
|
const filterableColumns = new Set(filterableColumnIds);
|
|
@@ -1387,16 +2779,27 @@ function InspectionGrid({
|
|
|
1387
2779
|
getHeaderCellProps: ({ column }) => filterableColumns.has(column.id) ? filterableHeaderProps : void 0,
|
|
1388
2780
|
getRowId: getInspectionRowId,
|
|
1389
2781
|
headerCellClassName: "inspection-header-cell",
|
|
1390
|
-
|
|
2782
|
+
state,
|
|
1391
2783
|
labelClassName: "inspection-cell-label",
|
|
1392
2784
|
overscan,
|
|
1393
2785
|
onSelectedRowIdChange,
|
|
2786
|
+
onSelectionChange,
|
|
2787
|
+
onFocusChange,
|
|
1394
2788
|
onSortChange,
|
|
2789
|
+
onColumnWidthsChange,
|
|
2790
|
+
onColumnOrderChange,
|
|
2791
|
+
onColumnPinnedChange,
|
|
1395
2792
|
onTelemetryChange,
|
|
1396
2793
|
pinnedClassName: "is-pinned",
|
|
1397
2794
|
rowClassName: "inspection-row",
|
|
1398
2795
|
rows,
|
|
2796
|
+
rowSelectionColumn,
|
|
1399
2797
|
selectFocusedRowOnArrowKey: true,
|
|
2798
|
+
tabBehavior,
|
|
2799
|
+
copyWithHeaders,
|
|
2800
|
+
onCopy,
|
|
2801
|
+
copyToClipboard,
|
|
2802
|
+
messages,
|
|
1400
2803
|
valueClassName: "inspection-cell-value",
|
|
1401
2804
|
viewportHeight
|
|
1402
2805
|
}
|
|
@@ -1409,4 +2812,4 @@ function formatInspectionValue(value) {
|
|
|
1409
2812
|
return String(value ?? "");
|
|
1410
2813
|
}
|
|
1411
2814
|
|
|
1412
|
-
export { InspectionGrid, LabeledGridSurface, Pretable, PretableSurface,
|
|
2815
|
+
export { InspectionGrid, LabeledGridSurface, Pretable, PretableSurface, defaultCoerceForCopy, serializeRangesAsTsv, usePretable, ROW_SELECT_COLUMN_ID as ɵROW_SELECT_COLUMN_ID, measureRenderedRowHeight as ɵmeasureRenderedRowHeight, useResolvedHeights as ɵuseResolvedHeights };
|