react-glide-table 2.0.2 → 2.2.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/README.md +35 -0
- package/dist/compound.cjs +590 -126
- package/dist/compound.d.cts +3 -3
- package/dist/compound.d.ts +3 -3
- package/dist/compound.js +571 -102
- package/dist/core.cjs +444 -11
- package/dist/core.d.cts +53 -14
- package/dist/core.d.ts +53 -14
- package/dist/core.js +443 -11
- package/dist/index.cjs +509 -33
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +492 -17
- package/dist/{types-bgEceyRV.d.cts → types-Iot4g4sq.d.cts} +38 -2
- package/dist/{types-bgEceyRV.d.ts → types-Iot4g4sq.d.ts} +38 -2
- package/package.json +1 -1
package/dist/compound.js
CHANGED
|
@@ -21,6 +21,7 @@ var DATA_TABLE_VIRTUAL_OVERSCAN = 8;
|
|
|
21
21
|
var DATA_TABLE_COLUMN_SIZE = 150;
|
|
22
22
|
var DATA_TABLE_COLUMN_MIN_SIZE = 40;
|
|
23
23
|
var DATA_TABLE_COLUMN_MAX_SIZE = 800;
|
|
24
|
+
var DATA_TABLE_COLUMN_REORDER_THRESHOLD = 4;
|
|
24
25
|
|
|
25
26
|
// src/components/ui/table/DataTableContext.tsx
|
|
26
27
|
import { createContext, use } from "react";
|
|
@@ -861,23 +862,49 @@ var useConvertTreeData = ({
|
|
|
861
862
|
function getRowFieldValue(row, key) {
|
|
862
863
|
return row[key];
|
|
863
864
|
}
|
|
864
|
-
function
|
|
865
|
+
function normalizeRowSpanParent(value) {
|
|
866
|
+
if (!value) return [];
|
|
867
|
+
return typeof value === "string" ? [value] : [...value];
|
|
868
|
+
}
|
|
869
|
+
function toParentSpanList(parentSpans) {
|
|
870
|
+
if (!parentSpans?.length) return [];
|
|
871
|
+
const first = parentSpans[0];
|
|
872
|
+
if (!Array.isArray(first)) {
|
|
873
|
+
return [parentSpans];
|
|
874
|
+
}
|
|
875
|
+
return parentSpans;
|
|
876
|
+
}
|
|
877
|
+
function buildStartRowLookup(spans) {
|
|
878
|
+
const startRows = new Array(spans.length);
|
|
879
|
+
let origin = 0;
|
|
880
|
+
for (let i = 0; i < spans.length; i++) {
|
|
881
|
+
if ((spans[i]?.rowSpan ?? 1) > 0) origin = i;
|
|
882
|
+
startRows[i] = origin;
|
|
883
|
+
}
|
|
884
|
+
return startRows;
|
|
885
|
+
}
|
|
886
|
+
function sharesParentGroup(parentStartRows, rowIndex) {
|
|
887
|
+
if (parentStartRows.length === 0 || rowIndex <= 0) return true;
|
|
888
|
+
return parentStartRows.every(
|
|
889
|
+
(startRows) => startRows[rowIndex - 1] === startRows[rowIndex]
|
|
890
|
+
);
|
|
891
|
+
}
|
|
892
|
+
function computeRowSpans(data, rowSpanKey, parentSpans) {
|
|
865
893
|
if (data.length === 0) return [];
|
|
894
|
+
const parentStartRows = toParentSpanList(parentSpans).map(buildStartRowLookup);
|
|
866
895
|
const result = [];
|
|
867
896
|
for (let index = 0; index < data.length; index++) {
|
|
868
897
|
const currentValue = getRowFieldValue(data[index], rowSpanKey);
|
|
869
898
|
const previousValue = index > 0 ? getRowFieldValue(data[index - 1], rowSpanKey) : void 0;
|
|
870
|
-
if (index > 0 && currentValue === previousValue) {
|
|
899
|
+
if (index > 0 && currentValue === previousValue && sharesParentGroup(parentStartRows, index)) {
|
|
871
900
|
result.push({ rowSpan: 0, isFirstInGroup: false });
|
|
872
901
|
continue;
|
|
873
902
|
}
|
|
874
903
|
let span = 1;
|
|
875
904
|
for (let nextIndex = index + 1; nextIndex < data.length; nextIndex++) {
|
|
876
|
-
if (getRowFieldValue(data[nextIndex], rowSpanKey)
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
break;
|
|
880
|
-
}
|
|
905
|
+
if (getRowFieldValue(data[nextIndex], rowSpanKey) !== currentValue) break;
|
|
906
|
+
if (!sharesParentGroup(parentStartRows, nextIndex)) break;
|
|
907
|
+
span++;
|
|
881
908
|
}
|
|
882
909
|
result.push({ rowSpan: span, isFirstInGroup: true });
|
|
883
910
|
}
|
|
@@ -899,10 +926,50 @@ function resolveRowSpanAt(rowSpans, rowIndex) {
|
|
|
899
926
|
}
|
|
900
927
|
return { startRow: rowIndex, rowSpan: 1 };
|
|
901
928
|
}
|
|
929
|
+
function findRowSpanColumn(spec, ref) {
|
|
930
|
+
return spec.find((column) => column.columnId === ref) ?? spec.find((column) => column.rowSpanKey === ref);
|
|
931
|
+
}
|
|
902
932
|
function buildColumnRowSpanMap(data, columnKeys) {
|
|
903
933
|
const map = /* @__PURE__ */ new Map();
|
|
904
|
-
|
|
905
|
-
|
|
934
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
935
|
+
const warnedCycles = /* @__PURE__ */ new Set();
|
|
936
|
+
const virtualParents = /* @__PURE__ */ new Map();
|
|
937
|
+
const spansForColumn = (columnId) => {
|
|
938
|
+
const cached = map.get(columnId);
|
|
939
|
+
if (cached !== void 0) return cached;
|
|
940
|
+
const column = columnKeys.find((item) => item.columnId === columnId);
|
|
941
|
+
if (!column) return void 0;
|
|
942
|
+
if (visiting.has(columnId)) {
|
|
943
|
+
if (!warnedCycles.has(columnId)) {
|
|
944
|
+
warnedCycles.add(columnId);
|
|
945
|
+
console.warn(
|
|
946
|
+
`[rowSpan] rowSpanParent cycle detected at column "${columnId}"; dropping the cyclic parent reference.`
|
|
947
|
+
);
|
|
948
|
+
}
|
|
949
|
+
return void 0;
|
|
950
|
+
}
|
|
951
|
+
visiting.add(columnId);
|
|
952
|
+
const parentSpans = (column.rowSpanParent ?? []).map((ref) => spansForParentRef(ref)).filter((spans2) => Boolean(spans2));
|
|
953
|
+
visiting.delete(columnId);
|
|
954
|
+
const spans = computeRowSpans(
|
|
955
|
+
data,
|
|
956
|
+
column.rowSpanKey,
|
|
957
|
+
parentSpans.length > 0 ? parentSpans : void 0
|
|
958
|
+
);
|
|
959
|
+
map.set(columnId, spans);
|
|
960
|
+
return spans;
|
|
961
|
+
};
|
|
962
|
+
const spansForParentRef = (ref) => {
|
|
963
|
+
const parentColumn = findRowSpanColumn(columnKeys, ref);
|
|
964
|
+
if (parentColumn) return spansForColumn(parentColumn.columnId);
|
|
965
|
+
const cached = virtualParents.get(ref);
|
|
966
|
+
if (cached !== void 0) return cached;
|
|
967
|
+
const spans = computeRowSpans(data, ref);
|
|
968
|
+
virtualParents.set(ref, spans);
|
|
969
|
+
return spans;
|
|
970
|
+
};
|
|
971
|
+
for (const column of columnKeys) {
|
|
972
|
+
spansForColumn(column.columnId);
|
|
906
973
|
}
|
|
907
974
|
return map;
|
|
908
975
|
}
|
|
@@ -918,7 +985,8 @@ function collectRowSpanColumns(columns) {
|
|
|
918
985
|
if (!columnId || !columnDef.meta?.rowSpan) continue;
|
|
919
986
|
result.push({
|
|
920
987
|
columnId,
|
|
921
|
-
rowSpanKey: columnDef.meta.rowSpanKey ?? columnId
|
|
988
|
+
rowSpanKey: columnDef.meta.rowSpanKey ?? columnId,
|
|
989
|
+
rowSpanParent: normalizeRowSpanParent(columnDef.meta.rowSpanParent)
|
|
922
990
|
});
|
|
923
991
|
}
|
|
924
992
|
};
|
|
@@ -1757,6 +1825,348 @@ function getMergedHeaderGroups(headerGroups) {
|
|
|
1757
1825
|
}));
|
|
1758
1826
|
}
|
|
1759
1827
|
|
|
1828
|
+
// src/components/ui/table/features/column-reorder/columnReorder.ts
|
|
1829
|
+
function getColumnDefId(column) {
|
|
1830
|
+
if (column.id != null && column.id !== "") return column.id;
|
|
1831
|
+
if ("accessorKey" in column && column.accessorKey != null) {
|
|
1832
|
+
return String(column.accessorKey);
|
|
1833
|
+
}
|
|
1834
|
+
return void 0;
|
|
1835
|
+
}
|
|
1836
|
+
function getColumnDefChildren(column) {
|
|
1837
|
+
if (!("columns" in column) || !Array.isArray(column.columns)) return void 0;
|
|
1838
|
+
if (column.columns.length === 0) return void 0;
|
|
1839
|
+
return column.columns;
|
|
1840
|
+
}
|
|
1841
|
+
function collectLeafColumnIds(columns) {
|
|
1842
|
+
const ids = [];
|
|
1843
|
+
for (const column of columns) {
|
|
1844
|
+
const children = getColumnDefChildren(column);
|
|
1845
|
+
if (children) {
|
|
1846
|
+
ids.push(...collectLeafColumnIds(children));
|
|
1847
|
+
continue;
|
|
1848
|
+
}
|
|
1849
|
+
const id = getColumnDefId(column);
|
|
1850
|
+
if (id) ids.push(id);
|
|
1851
|
+
}
|
|
1852
|
+
return ids;
|
|
1853
|
+
}
|
|
1854
|
+
function areColumnOrdersEqual(left, right) {
|
|
1855
|
+
if (left.length !== right.length) return false;
|
|
1856
|
+
return left.every((id, index) => id === right[index]);
|
|
1857
|
+
}
|
|
1858
|
+
function resolveLeafColumnOrder(columns, order) {
|
|
1859
|
+
const leafIds = collectLeafColumnIds(columns);
|
|
1860
|
+
if (!order?.length) return leafIds;
|
|
1861
|
+
const leafSet = new Set(leafIds);
|
|
1862
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1863
|
+
const next = order.filter((id) => {
|
|
1864
|
+
if (!leafSet.has(id) || seen.has(id)) return false;
|
|
1865
|
+
seen.add(id);
|
|
1866
|
+
return true;
|
|
1867
|
+
});
|
|
1868
|
+
for (const id of leafIds) {
|
|
1869
|
+
if (!seen.has(id)) next.push(id);
|
|
1870
|
+
}
|
|
1871
|
+
return next;
|
|
1872
|
+
}
|
|
1873
|
+
function flattenColumnSlots(columns, group) {
|
|
1874
|
+
const slots = [];
|
|
1875
|
+
for (const column of columns) {
|
|
1876
|
+
const id = getColumnDefId(column);
|
|
1877
|
+
const children = getColumnDefChildren(column);
|
|
1878
|
+
if (children) {
|
|
1879
|
+
const nestedGroup = id ? { id, def: column } : group;
|
|
1880
|
+
slots.push(...flattenColumnSlots(children, nestedGroup));
|
|
1881
|
+
continue;
|
|
1882
|
+
}
|
|
1883
|
+
if (!id) continue;
|
|
1884
|
+
slots.push({ id, def: column, group });
|
|
1885
|
+
}
|
|
1886
|
+
return slots;
|
|
1887
|
+
}
|
|
1888
|
+
function rebuildColumnTree(slots) {
|
|
1889
|
+
const result = [];
|
|
1890
|
+
let index = 0;
|
|
1891
|
+
while (index < slots.length) {
|
|
1892
|
+
const slot = slots[index];
|
|
1893
|
+
if (!slot.group) {
|
|
1894
|
+
result.push(slot.def);
|
|
1895
|
+
index += 1;
|
|
1896
|
+
continue;
|
|
1897
|
+
}
|
|
1898
|
+
const groupId = slot.group.id;
|
|
1899
|
+
const children = [];
|
|
1900
|
+
while (index < slots.length && slots[index]?.group?.id === groupId) {
|
|
1901
|
+
children.push(slots[index].def);
|
|
1902
|
+
index += 1;
|
|
1903
|
+
}
|
|
1904
|
+
const firstChildId = children[0] ? getColumnDefId(children[0]) : groupId;
|
|
1905
|
+
result.push({
|
|
1906
|
+
...slot.group.def,
|
|
1907
|
+
id: `${groupId}::${firstChildId}`,
|
|
1908
|
+
columns: children
|
|
1909
|
+
});
|
|
1910
|
+
}
|
|
1911
|
+
return result;
|
|
1912
|
+
}
|
|
1913
|
+
function applyLeafColumnOrder(columns, order) {
|
|
1914
|
+
const resolved = resolveLeafColumnOrder(columns, order);
|
|
1915
|
+
const defaultOrder = collectLeafColumnIds(columns);
|
|
1916
|
+
if (areColumnOrdersEqual(resolved, defaultOrder)) {
|
|
1917
|
+
return columns;
|
|
1918
|
+
}
|
|
1919
|
+
const byId = new Map(
|
|
1920
|
+
flattenColumnSlots(columns).map((slot) => [
|
|
1921
|
+
slot.id,
|
|
1922
|
+
slot
|
|
1923
|
+
])
|
|
1924
|
+
);
|
|
1925
|
+
const ordered = [];
|
|
1926
|
+
for (const id of resolved) {
|
|
1927
|
+
const slot = byId.get(id);
|
|
1928
|
+
if (slot) ordered.push(slot);
|
|
1929
|
+
}
|
|
1930
|
+
return rebuildColumnTree(ordered);
|
|
1931
|
+
}
|
|
1932
|
+
function moveColumnIds(order, fromIds, targetIds, edge) {
|
|
1933
|
+
if (fromIds.length === 0 || targetIds.length === 0) return [...order];
|
|
1934
|
+
const fromSet = new Set(fromIds);
|
|
1935
|
+
if (targetIds.some((id) => fromSet.has(id))) return [...order];
|
|
1936
|
+
const rest = order.filter((id) => !fromSet.has(id));
|
|
1937
|
+
const anchorId = edge === "before" ? targetIds[0] : targetIds[targetIds.length - 1];
|
|
1938
|
+
const anchorIndex = rest.indexOf(anchorId);
|
|
1939
|
+
if (anchorIndex < 0) return [...order];
|
|
1940
|
+
const insertAt = edge === "before" ? anchorIndex : anchorIndex + 1;
|
|
1941
|
+
return [...rest.slice(0, insertAt), ...fromIds, ...rest.slice(insertAt)];
|
|
1942
|
+
}
|
|
1943
|
+
function resolveDropEdge(clientX, rect) {
|
|
1944
|
+
return clientX < rect.left + rect.width / 2 ? "before" : "after";
|
|
1945
|
+
}
|
|
1946
|
+
function parseReorderIds(value) {
|
|
1947
|
+
if (!value) return [];
|
|
1948
|
+
return value.split(",").filter(Boolean);
|
|
1949
|
+
}
|
|
1950
|
+
function serializeReorderIds(ids) {
|
|
1951
|
+
return ids.join(",");
|
|
1952
|
+
}
|
|
1953
|
+
function isColumnReorderable(meta) {
|
|
1954
|
+
return meta?.reorderable !== false;
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1957
|
+
// src/components/ui/table/features/column-reorder/useColumnReorder.ts
|
|
1958
|
+
import {
|
|
1959
|
+
useCallback,
|
|
1960
|
+
useEffect as useEffect3,
|
|
1961
|
+
useRef as useRef3,
|
|
1962
|
+
useState
|
|
1963
|
+
} from "react";
|
|
1964
|
+
function hitTestReorderHeader(table, clientX, clientY) {
|
|
1965
|
+
const headers = Array.from(
|
|
1966
|
+
table.querySelectorAll(
|
|
1967
|
+
"thead th[data-column-id][data-reorder-ids]"
|
|
1968
|
+
)
|
|
1969
|
+
);
|
|
1970
|
+
const containing = headers.find((element) => {
|
|
1971
|
+
const rect = element.getBoundingClientRect();
|
|
1972
|
+
return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
|
|
1973
|
+
});
|
|
1974
|
+
if (containing) {
|
|
1975
|
+
return {
|
|
1976
|
+
columnId: containing.dataset.columnId ?? "",
|
|
1977
|
+
edge: resolveDropEdge(clientX, containing.getBoundingClientRect())
|
|
1978
|
+
};
|
|
1979
|
+
}
|
|
1980
|
+
const leaves = headers.filter(
|
|
1981
|
+
(element) => element.hasAttribute("data-reorder-leaf")
|
|
1982
|
+
);
|
|
1983
|
+
let match;
|
|
1984
|
+
for (const element of leaves) {
|
|
1985
|
+
const rect = element.getBoundingClientRect();
|
|
1986
|
+
if (clientX >= rect.left && clientX <= rect.right) {
|
|
1987
|
+
match = element;
|
|
1988
|
+
break;
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1991
|
+
if (!match && leaves.length > 0) {
|
|
1992
|
+
const first = leaves[0].getBoundingClientRect();
|
|
1993
|
+
const last = leaves[leaves.length - 1].getBoundingClientRect();
|
|
1994
|
+
if (clientX < first.left) match = leaves[0];
|
|
1995
|
+
else if (clientX > last.right) match = leaves[leaves.length - 1];
|
|
1996
|
+
}
|
|
1997
|
+
if (!match) return null;
|
|
1998
|
+
return {
|
|
1999
|
+
columnId: match.dataset.columnId ?? "",
|
|
2000
|
+
edge: resolveDropEdge(clientX, match.getBoundingClientRect())
|
|
2001
|
+
};
|
|
2002
|
+
}
|
|
2003
|
+
function readTargetIds(table, columnId) {
|
|
2004
|
+
const element = table.querySelector(
|
|
2005
|
+
`thead th[data-column-id="${CSS.escape(columnId)}"]`
|
|
2006
|
+
);
|
|
2007
|
+
return parseReorderIds(element?.getAttribute("data-reorder-ids"));
|
|
2008
|
+
}
|
|
2009
|
+
function useColumnReorder(options) {
|
|
2010
|
+
const { enabled, columnOrder, onColumnOrderChange } = options;
|
|
2011
|
+
const sessionRef = useRef3(null);
|
|
2012
|
+
const columnOrderRef = useRef3(columnOrder);
|
|
2013
|
+
const onColumnOrderChangeRef = useRef3(onColumnOrderChange);
|
|
2014
|
+
const [draggingColumnId, setDraggingColumnId] = useState(null);
|
|
2015
|
+
const [dropTarget, setDropTarget] = useState(
|
|
2016
|
+
null
|
|
2017
|
+
);
|
|
2018
|
+
const dropTargetRef = useRef3(dropTarget);
|
|
2019
|
+
const previousUserSelectRef = useRef3(null);
|
|
2020
|
+
columnOrderRef.current = columnOrder;
|
|
2021
|
+
onColumnOrderChangeRef.current = onColumnOrderChange;
|
|
2022
|
+
dropTargetRef.current = dropTarget;
|
|
2023
|
+
const resetDrag = useCallback(() => {
|
|
2024
|
+
sessionRef.current = null;
|
|
2025
|
+
setDraggingColumnId(null);
|
|
2026
|
+
setDropTarget(null);
|
|
2027
|
+
const backup = previousUserSelectRef.current;
|
|
2028
|
+
previousUserSelectRef.current = null;
|
|
2029
|
+
if (backup) {
|
|
2030
|
+
if (backup.value) {
|
|
2031
|
+
document.body.style.setProperty("user-select", backup.value, backup.priority);
|
|
2032
|
+
} else {
|
|
2033
|
+
document.body.style.removeProperty("user-select");
|
|
2034
|
+
}
|
|
2035
|
+
return;
|
|
2036
|
+
}
|
|
2037
|
+
document.body.style.removeProperty("user-select");
|
|
2038
|
+
}, []);
|
|
2039
|
+
useEffect3(() => {
|
|
2040
|
+
if (!enabled) resetDrag();
|
|
2041
|
+
}, [enabled, resetDrag]);
|
|
2042
|
+
useEffect3(() => {
|
|
2043
|
+
return () => {
|
|
2044
|
+
resetDrag();
|
|
2045
|
+
};
|
|
2046
|
+
}, [resetDrag]);
|
|
2047
|
+
const onHeaderPointerDown = useCallback(
|
|
2048
|
+
(event, meta) => {
|
|
2049
|
+
if (!enabled || !meta.canDrag) return;
|
|
2050
|
+
if (event.button !== 0) return;
|
|
2051
|
+
if (event.pointerType === "mouse" && event.ctrlKey) return;
|
|
2052
|
+
const target = event.target;
|
|
2053
|
+
if (target instanceof Element && target.closest("[data-table-disable-cell-selection]")) {
|
|
2054
|
+
return;
|
|
2055
|
+
}
|
|
2056
|
+
const table = event.currentTarget.closest("table");
|
|
2057
|
+
if (!(table instanceof HTMLTableElement)) return;
|
|
2058
|
+
sessionRef.current = {
|
|
2059
|
+
pointerId: event.pointerId,
|
|
2060
|
+
startX: event.clientX,
|
|
2061
|
+
startY: event.clientY,
|
|
2062
|
+
columnId: meta.columnId,
|
|
2063
|
+
fromIds: meta.leafIds,
|
|
2064
|
+
table,
|
|
2065
|
+
active: false
|
|
2066
|
+
};
|
|
2067
|
+
},
|
|
2068
|
+
[enabled]
|
|
2069
|
+
);
|
|
2070
|
+
useEffect3(() => {
|
|
2071
|
+
if (!enabled) return;
|
|
2072
|
+
const onPointerMove = (event) => {
|
|
2073
|
+
const session = sessionRef.current;
|
|
2074
|
+
if (!session || event.pointerId !== session.pointerId) return;
|
|
2075
|
+
const deltaX = event.clientX - session.startX;
|
|
2076
|
+
const deltaY = event.clientY - session.startY;
|
|
2077
|
+
const distance = Math.hypot(deltaX, deltaY);
|
|
2078
|
+
if (!session.active) {
|
|
2079
|
+
if (distance < DATA_TABLE_COLUMN_REORDER_THRESHOLD) return;
|
|
2080
|
+
session.active = true;
|
|
2081
|
+
if (!previousUserSelectRef.current) {
|
|
2082
|
+
previousUserSelectRef.current = {
|
|
2083
|
+
value: document.body.style.getPropertyValue("user-select"),
|
|
2084
|
+
priority: document.body.style.getPropertyPriority("user-select")
|
|
2085
|
+
};
|
|
2086
|
+
}
|
|
2087
|
+
document.body.style.setProperty("user-select", "none");
|
|
2088
|
+
setDraggingColumnId(session.columnId);
|
|
2089
|
+
}
|
|
2090
|
+
event.preventDefault();
|
|
2091
|
+
const nextTarget = hitTestReorderHeader(
|
|
2092
|
+
session.table,
|
|
2093
|
+
event.clientX,
|
|
2094
|
+
event.clientY
|
|
2095
|
+
);
|
|
2096
|
+
if (!nextTarget || !nextTarget.columnId) {
|
|
2097
|
+
setDropTarget(null);
|
|
2098
|
+
return;
|
|
2099
|
+
}
|
|
2100
|
+
const targetIds = readTargetIds(session.table, nextTarget.columnId);
|
|
2101
|
+
const fromSet = new Set(session.fromIds);
|
|
2102
|
+
if (targetIds.some((id) => fromSet.has(id))) {
|
|
2103
|
+
setDropTarget(null);
|
|
2104
|
+
return;
|
|
2105
|
+
}
|
|
2106
|
+
setDropTarget((previous) => {
|
|
2107
|
+
if (previous?.columnId === nextTarget.columnId && previous.edge === nextTarget.edge) {
|
|
2108
|
+
return previous;
|
|
2109
|
+
}
|
|
2110
|
+
return nextTarget;
|
|
2111
|
+
});
|
|
2112
|
+
};
|
|
2113
|
+
const onPointerUp = (event) => {
|
|
2114
|
+
const session = sessionRef.current;
|
|
2115
|
+
if (!session || event.pointerId !== session.pointerId) {
|
|
2116
|
+
return;
|
|
2117
|
+
}
|
|
2118
|
+
if (session.active) {
|
|
2119
|
+
event.preventDefault();
|
|
2120
|
+
const target = dropTargetRef.current;
|
|
2121
|
+
if (target) {
|
|
2122
|
+
const targetIds = readTargetIds(session.table, target.columnId);
|
|
2123
|
+
const next = moveColumnIds(
|
|
2124
|
+
columnOrderRef.current,
|
|
2125
|
+
session.fromIds,
|
|
2126
|
+
targetIds,
|
|
2127
|
+
target.edge
|
|
2128
|
+
);
|
|
2129
|
+
onColumnOrderChangeRef.current(next);
|
|
2130
|
+
}
|
|
2131
|
+
const suppressClick = (clickEvent) => {
|
|
2132
|
+
clickEvent.preventDefault();
|
|
2133
|
+
clickEvent.stopPropagation();
|
|
2134
|
+
document.removeEventListener("click", suppressClick, true);
|
|
2135
|
+
};
|
|
2136
|
+
document.addEventListener("click", suppressClick, true);
|
|
2137
|
+
window.setTimeout(() => {
|
|
2138
|
+
document.removeEventListener("click", suppressClick, true);
|
|
2139
|
+
}, 0);
|
|
2140
|
+
}
|
|
2141
|
+
resetDrag();
|
|
2142
|
+
};
|
|
2143
|
+
const onPointerCancel = (event) => {
|
|
2144
|
+
const session = sessionRef.current;
|
|
2145
|
+
if (!session || event.pointerId !== session.pointerId) {
|
|
2146
|
+
return;
|
|
2147
|
+
}
|
|
2148
|
+
if (session.active) {
|
|
2149
|
+
event.preventDefault();
|
|
2150
|
+
}
|
|
2151
|
+
resetDrag();
|
|
2152
|
+
};
|
|
2153
|
+
document.addEventListener("pointermove", onPointerMove);
|
|
2154
|
+
document.addEventListener("pointerup", onPointerUp);
|
|
2155
|
+
document.addEventListener("pointercancel", onPointerCancel);
|
|
2156
|
+
return () => {
|
|
2157
|
+
document.removeEventListener("pointermove", onPointerMove);
|
|
2158
|
+
document.removeEventListener("pointerup", onPointerUp);
|
|
2159
|
+
document.removeEventListener("pointercancel", onPointerCancel);
|
|
2160
|
+
};
|
|
2161
|
+
}, [enabled, resetDrag]);
|
|
2162
|
+
return {
|
|
2163
|
+
isReordering: draggingColumnId != null,
|
|
2164
|
+
draggingColumnId,
|
|
2165
|
+
dropTarget,
|
|
2166
|
+
onHeaderPointerDown
|
|
2167
|
+
};
|
|
2168
|
+
}
|
|
2169
|
+
|
|
1760
2170
|
// src/core/useGlideTable.ts
|
|
1761
2171
|
import {
|
|
1762
2172
|
getCoreRowModel,
|
|
@@ -1766,15 +2176,15 @@ import {
|
|
|
1766
2176
|
useVirtualizer
|
|
1767
2177
|
} from "@tanstack/react-virtual";
|
|
1768
2178
|
import {
|
|
1769
|
-
useCallback as
|
|
1770
|
-
useEffect as
|
|
2179
|
+
useCallback as useCallback5,
|
|
2180
|
+
useEffect as useEffect7,
|
|
1771
2181
|
useMemo as useMemo3,
|
|
1772
|
-
useRef as
|
|
1773
|
-
useState as
|
|
2182
|
+
useRef as useRef7,
|
|
2183
|
+
useState as useState5
|
|
1774
2184
|
} from "react";
|
|
1775
2185
|
|
|
1776
2186
|
// src/components/ui/table/features/cell-edit/useCellEdit.ts
|
|
1777
|
-
import { useCallback, useEffect as
|
|
2187
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef4, useState as useState2 } from "react";
|
|
1778
2188
|
|
|
1779
2189
|
// src/components/ui/table/features/cell-render/commitCellValue.ts
|
|
1780
2190
|
function commitCellValue({
|
|
@@ -1814,21 +2224,21 @@ function useCellEdit({
|
|
|
1814
2224
|
onDataChange,
|
|
1815
2225
|
onCellChange
|
|
1816
2226
|
}) {
|
|
1817
|
-
const [editingCell, setEditingCell] =
|
|
1818
|
-
const [draftValue, setDraftValue] =
|
|
1819
|
-
const draftValueRef =
|
|
1820
|
-
const editingCellRef =
|
|
1821
|
-
|
|
2227
|
+
const [editingCell, setEditingCell] = useState2(null);
|
|
2228
|
+
const [draftValue, setDraftValue] = useState2("");
|
|
2229
|
+
const draftValueRef = useRef4(draftValue);
|
|
2230
|
+
const editingCellRef = useRef4(editingCell);
|
|
2231
|
+
useEffect4(() => {
|
|
1822
2232
|
draftValueRef.current = draftValue;
|
|
1823
2233
|
}, [draftValue]);
|
|
1824
|
-
|
|
2234
|
+
useEffect4(() => {
|
|
1825
2235
|
editingCellRef.current = editingCell;
|
|
1826
2236
|
}, [editingCell]);
|
|
1827
|
-
const cancelEdit =
|
|
2237
|
+
const cancelEdit = useCallback2(() => {
|
|
1828
2238
|
setEditingCell(null);
|
|
1829
2239
|
setDraftValue("");
|
|
1830
2240
|
}, []);
|
|
1831
|
-
const commitEdit =
|
|
2241
|
+
const commitEdit = useCallback2(
|
|
1832
2242
|
(raw) => {
|
|
1833
2243
|
const current = editingCellRef.current;
|
|
1834
2244
|
if (!current) return true;
|
|
@@ -1864,7 +2274,7 @@ function useCellEdit({
|
|
|
1864
2274
|
},
|
|
1865
2275
|
[cancelEdit, data, onCellChange, onDataChange, rows]
|
|
1866
2276
|
);
|
|
1867
|
-
const startEdit =
|
|
2277
|
+
const startEdit = useCallback2(
|
|
1868
2278
|
(rowIndex, colIndex) => {
|
|
1869
2279
|
const cell = rows[rowIndex]?.getVisibleCells()[colIndex];
|
|
1870
2280
|
if (!cell || !isColumnEditable(cell.column.columnDef)) return;
|
|
@@ -2100,7 +2510,7 @@ function formatDefaultCellValue(value) {
|
|
|
2100
2510
|
}
|
|
2101
2511
|
|
|
2102
2512
|
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
2103
|
-
import { useCallback as
|
|
2513
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef5, useState as useState3 } from "react";
|
|
2104
2514
|
|
|
2105
2515
|
// src/components/ui/table/features/cell-selection/copyData.ts
|
|
2106
2516
|
function formatPrimitive(value) {
|
|
@@ -2379,15 +2789,15 @@ function useCellSelection({
|
|
|
2379
2789
|
onRowsPaste,
|
|
2380
2790
|
onCellNavigate
|
|
2381
2791
|
}) {
|
|
2382
|
-
const [dragState, setDragState] =
|
|
2383
|
-
const pendingPasteModeRef =
|
|
2384
|
-
const dragStateRef =
|
|
2385
|
-
const onCellNavigateRef =
|
|
2792
|
+
const [dragState, setDragState] = useState3(INITIAL_DRAG_STATE);
|
|
2793
|
+
const pendingPasteModeRef = useRef5(null);
|
|
2794
|
+
const dragStateRef = useRef5(dragState);
|
|
2795
|
+
const onCellNavigateRef = useRef5(onCellNavigate);
|
|
2386
2796
|
dragStateRef.current = dragState;
|
|
2387
2797
|
onCellNavigateRef.current = onCellNavigate;
|
|
2388
2798
|
const cellSelectionBounds = getCellSelectionBounds(dragState.start, dragState.end);
|
|
2389
2799
|
const activeSelectionBounds = enabled ? getActiveSelectionBounds(dragState, cellSelectionBounds) : null;
|
|
2390
|
-
const handleCellMouseDown =
|
|
2800
|
+
const handleCellMouseDown = useCallback3(
|
|
2391
2801
|
(rowIndex, colIndex, options) => {
|
|
2392
2802
|
if (!enabled) return;
|
|
2393
2803
|
setDragState((prev) => {
|
|
@@ -2413,7 +2823,7 @@ function useCellSelection({
|
|
|
2413
2823
|
},
|
|
2414
2824
|
[enabled]
|
|
2415
2825
|
);
|
|
2416
|
-
const handleCellMouseEnter =
|
|
2826
|
+
const handleCellMouseEnter = useCallback3(
|
|
2417
2827
|
(rowIndex, colIndex) => {
|
|
2418
2828
|
if (!enabled) return;
|
|
2419
2829
|
setDragState((prev) => {
|
|
@@ -2428,7 +2838,7 @@ function useCellSelection({
|
|
|
2428
2838
|
},
|
|
2429
2839
|
[enabled]
|
|
2430
2840
|
);
|
|
2431
|
-
const handleFillHandleMouseDown =
|
|
2841
|
+
const handleFillHandleMouseDown = useCallback3(
|
|
2432
2842
|
(rowIndex, colIndex) => {
|
|
2433
2843
|
if (!enabled) return;
|
|
2434
2844
|
setDragState((prev) => {
|
|
@@ -2445,12 +2855,12 @@ function useCellSelection({
|
|
|
2445
2855
|
},
|
|
2446
2856
|
[enabled]
|
|
2447
2857
|
);
|
|
2448
|
-
|
|
2858
|
+
useEffect5(() => {
|
|
2449
2859
|
if (!enabled) {
|
|
2450
2860
|
setDragState(INITIAL_DRAG_STATE);
|
|
2451
2861
|
}
|
|
2452
2862
|
}, [enabled]);
|
|
2453
|
-
|
|
2863
|
+
useEffect5(() => {
|
|
2454
2864
|
if (!enabled) return;
|
|
2455
2865
|
const handleKeyDown = (e) => {
|
|
2456
2866
|
if (e.ctrlKey || e.metaKey || e.altKey) return;
|
|
@@ -2497,7 +2907,7 @@ function useCellSelection({
|
|
|
2497
2907
|
window.addEventListener("keydown", handleKeyDown);
|
|
2498
2908
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
2499
2909
|
}, [columnCount, enabled, rows]);
|
|
2500
|
-
const copySelection =
|
|
2910
|
+
const copySelection = useCallback3(
|
|
2501
2911
|
async (options) => {
|
|
2502
2912
|
if (!enabled || !activeSelectionBounds) return false;
|
|
2503
2913
|
const mode = options?.includeDescendants && enableSubtreeCopy ? "subtree" : "visible";
|
|
@@ -2505,7 +2915,7 @@ function useCellSelection({
|
|
|
2505
2915
|
},
|
|
2506
2916
|
[activeSelectionBounds, enableSubtreeCopy, enabled, rows]
|
|
2507
2917
|
);
|
|
2508
|
-
|
|
2918
|
+
useEffect5(() => {
|
|
2509
2919
|
if (!enabled) return;
|
|
2510
2920
|
const handleKeyDown = (e) => {
|
|
2511
2921
|
if (!activeSelectionBounds) return;
|
|
@@ -2519,7 +2929,7 @@ function useCellSelection({
|
|
|
2519
2929
|
window.addEventListener("keydown", handleKeyDown);
|
|
2520
2930
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
2521
2931
|
}, [activeSelectionBounds, copySelection, enableSubtreeCopy, enabled]);
|
|
2522
|
-
const emitRowsPaste =
|
|
2932
|
+
const emitRowsPaste = useCallback3(
|
|
2523
2933
|
(text, mode) => {
|
|
2524
2934
|
if (!onRowsPaste || !activeSelectionBounds) return false;
|
|
2525
2935
|
const payload = buildRowsPastePayload(
|
|
@@ -2536,7 +2946,7 @@ function useCellSelection({
|
|
|
2536
2946
|
},
|
|
2537
2947
|
[activeSelectionBounds, onRowsPaste, rows]
|
|
2538
2948
|
);
|
|
2539
|
-
|
|
2949
|
+
useEffect5(() => {
|
|
2540
2950
|
if (!enabled || !onRowsPaste) return;
|
|
2541
2951
|
const pasteHandledRef = { current: false };
|
|
2542
2952
|
const ignoreNextPasteRef = { current: false };
|
|
@@ -2604,7 +3014,7 @@ function useCellSelection({
|
|
|
2604
3014
|
enabled,
|
|
2605
3015
|
onRowsPaste
|
|
2606
3016
|
]);
|
|
2607
|
-
|
|
3017
|
+
useEffect5(() => {
|
|
2608
3018
|
if (!enabled) return;
|
|
2609
3019
|
const handleMouseUp = () => {
|
|
2610
3020
|
setDragState((prev) => {
|
|
@@ -2656,12 +3066,12 @@ function useCellSelection({
|
|
|
2656
3066
|
|
|
2657
3067
|
// src/components/ui/table/features/inline-search/useInlineSearch.ts
|
|
2658
3068
|
import {
|
|
2659
|
-
useCallback as
|
|
2660
|
-
useEffect as
|
|
3069
|
+
useCallback as useCallback4,
|
|
3070
|
+
useEffect as useEffect6,
|
|
2661
3071
|
useId,
|
|
2662
3072
|
useMemo as useMemo2,
|
|
2663
|
-
useRef as
|
|
2664
|
-
useState as
|
|
3073
|
+
useRef as useRef6,
|
|
3074
|
+
useState as useState4
|
|
2665
3075
|
} from "react";
|
|
2666
3076
|
var EMPTY_MATCH_KEYS = /* @__PURE__ */ new Set();
|
|
2667
3077
|
function useInlineSearch({
|
|
@@ -2680,45 +3090,45 @@ function useInlineSearch({
|
|
|
2680
3090
|
rootRef
|
|
2681
3091
|
}) {
|
|
2682
3092
|
const searchInputId = useId();
|
|
2683
|
-
const searchInputRef =
|
|
2684
|
-
const [internalShowSearch, setInternalShowSearch] =
|
|
2685
|
-
const [internalSearchValue, setInternalSearchValue] =
|
|
2686
|
-
const [internalResults, setInternalResults] =
|
|
3093
|
+
const searchInputRef = useRef6(null);
|
|
3094
|
+
const [internalShowSearch, setInternalShowSearch] = useState4(false);
|
|
3095
|
+
const [internalSearchValue, setInternalSearchValue] = useState4("");
|
|
3096
|
+
const [internalResults, setInternalResults] = useState4(
|
|
2687
3097
|
[]
|
|
2688
3098
|
);
|
|
2689
|
-
const [searchStatus, setSearchStatus] =
|
|
2690
|
-
const searchStatusRef =
|
|
3099
|
+
const [searchStatus, setSearchStatus] = useState4();
|
|
3100
|
+
const searchStatusRef = useRef6(searchStatus);
|
|
2691
3101
|
searchStatusRef.current = searchStatus;
|
|
2692
|
-
const abortControllerRef =
|
|
2693
|
-
const searchHandleRef =
|
|
2694
|
-
const initialStartRowRef =
|
|
3102
|
+
const abortControllerRef = useRef6(null);
|
|
3103
|
+
const searchHandleRef = useRef6(void 0);
|
|
3104
|
+
const initialStartRowRef = useRef6(initialStartRow);
|
|
2695
3105
|
initialStartRowRef.current = initialStartRow;
|
|
2696
|
-
const getCellValueRef =
|
|
3106
|
+
const getCellValueRef = useRef6(getCellValue);
|
|
2697
3107
|
getCellValueRef.current = getCellValue;
|
|
2698
3108
|
const showSearch = controlledShowSearch ?? internalShowSearch;
|
|
2699
3109
|
const searchValue = controlledSearchValue ?? internalSearchValue;
|
|
2700
3110
|
const searchResults = controlledSearchResults ?? internalResults;
|
|
2701
|
-
const setSearchValue =
|
|
3111
|
+
const setSearchValue = useCallback4(
|
|
2702
3112
|
(value) => {
|
|
2703
3113
|
setInternalSearchValue(value);
|
|
2704
3114
|
onSearchValueChange?.(value);
|
|
2705
3115
|
},
|
|
2706
3116
|
[onSearchValueChange]
|
|
2707
3117
|
);
|
|
2708
|
-
const cancelSearch =
|
|
3118
|
+
const cancelSearch = useCallback4(() => {
|
|
2709
3119
|
if (searchHandleRef.current !== void 0) {
|
|
2710
3120
|
window.cancelAnimationFrame(searchHandleRef.current);
|
|
2711
3121
|
searchHandleRef.current = void 0;
|
|
2712
3122
|
}
|
|
2713
3123
|
abortControllerRef.current?.abort();
|
|
2714
3124
|
}, []);
|
|
2715
|
-
const emitResultsChanged =
|
|
3125
|
+
const emitResultsChanged = useCallback4(
|
|
2716
3126
|
(results, navIndex) => {
|
|
2717
3127
|
onSearchResultsChanged?.(results, navIndex);
|
|
2718
3128
|
},
|
|
2719
3129
|
[onSearchResultsChanged]
|
|
2720
3130
|
);
|
|
2721
|
-
const navigateToIndex =
|
|
3131
|
+
const navigateToIndex = useCallback4(
|
|
2722
3132
|
(results, navIndex) => {
|
|
2723
3133
|
if (onSearchResultsChanged) return;
|
|
2724
3134
|
if (navIndex < 0 || navIndex >= results.length) return;
|
|
@@ -2728,7 +3138,7 @@ function useInlineSearch({
|
|
|
2728
3138
|
},
|
|
2729
3139
|
[onNavigateToResult, onSearchResultsChanged]
|
|
2730
3140
|
);
|
|
2731
|
-
const beginSearch =
|
|
3141
|
+
const beginSearch = useCallback4(
|
|
2732
3142
|
(query) => {
|
|
2733
3143
|
if (controlledSearchResults !== void 0) return;
|
|
2734
3144
|
const totalRows = rowCount;
|
|
@@ -2800,12 +3210,12 @@ function useInlineSearch({
|
|
|
2800
3210
|
rowCount
|
|
2801
3211
|
]
|
|
2802
3212
|
);
|
|
2803
|
-
const openSearch =
|
|
3213
|
+
const openSearch = useCallback4(() => {
|
|
2804
3214
|
if (controlledShowSearch === void 0) {
|
|
2805
3215
|
setInternalShowSearch(true);
|
|
2806
3216
|
}
|
|
2807
3217
|
}, [controlledShowSearch]);
|
|
2808
|
-
const closeSearch =
|
|
3218
|
+
const closeSearch = useCallback4(() => {
|
|
2809
3219
|
if (controlledShowSearch === void 0) {
|
|
2810
3220
|
setInternalShowSearch(false);
|
|
2811
3221
|
}
|
|
@@ -2820,7 +3230,7 @@ function useInlineSearch({
|
|
|
2820
3230
|
emitResultsChanged,
|
|
2821
3231
|
onSearchClose
|
|
2822
3232
|
]);
|
|
2823
|
-
const goToNext =
|
|
3233
|
+
const goToNext = useCallback4(() => {
|
|
2824
3234
|
if (!searchStatus || searchStatus.results === 0) return;
|
|
2825
3235
|
const newIndex = nextSearchIndex(
|
|
2826
3236
|
searchStatus.selectedIndex,
|
|
@@ -2830,7 +3240,7 @@ function useInlineSearch({
|
|
|
2830
3240
|
emitResultsChanged(searchResults, newIndex);
|
|
2831
3241
|
navigateToIndex(searchResults, newIndex);
|
|
2832
3242
|
}, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
|
|
2833
|
-
const goToPrevious =
|
|
3243
|
+
const goToPrevious = useCallback4(() => {
|
|
2834
3244
|
if (!searchStatus || searchStatus.results === 0) return;
|
|
2835
3245
|
const newIndex = previousSearchIndex(
|
|
2836
3246
|
searchStatus.selectedIndex,
|
|
@@ -2840,7 +3250,7 @@ function useInlineSearch({
|
|
|
2840
3250
|
emitResultsChanged(searchResults, newIndex);
|
|
2841
3251
|
navigateToIndex(searchResults, newIndex);
|
|
2842
3252
|
}, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
|
|
2843
|
-
|
|
3253
|
+
useEffect6(() => {
|
|
2844
3254
|
if (controlledSearchResults === void 0) return;
|
|
2845
3255
|
if (controlledSearchResults.length > 0) {
|
|
2846
3256
|
setSearchStatus((current) => ({
|
|
@@ -2852,7 +3262,7 @@ function useInlineSearch({
|
|
|
2852
3262
|
setSearchStatus(void 0);
|
|
2853
3263
|
}
|
|
2854
3264
|
}, [controlledSearchResults, rowCount]);
|
|
2855
|
-
|
|
3265
|
+
useEffect6(() => {
|
|
2856
3266
|
if (!enabled) return;
|
|
2857
3267
|
setSearchStatus(void 0);
|
|
2858
3268
|
setInternalResults([]);
|
|
@@ -2865,7 +3275,7 @@ function useInlineSearch({
|
|
|
2865
3275
|
cancelSearch();
|
|
2866
3276
|
}
|
|
2867
3277
|
}, [enabled, showSearch]);
|
|
2868
|
-
|
|
3278
|
+
useEffect6(() => {
|
|
2869
3279
|
if (!enabled || !showSearch) return;
|
|
2870
3280
|
if (controlledSearchResults !== void 0) return;
|
|
2871
3281
|
if (searchValue.trim() === "") {
|
|
@@ -2885,7 +3295,7 @@ function useInlineSearch({
|
|
|
2885
3295
|
searchValue,
|
|
2886
3296
|
showSearch
|
|
2887
3297
|
]);
|
|
2888
|
-
|
|
3298
|
+
useEffect6(() => {
|
|
2889
3299
|
if (!enabled) return;
|
|
2890
3300
|
const handleKeyDown = (event) => {
|
|
2891
3301
|
if (!(event.ctrlKey || event.metaKey)) return;
|
|
@@ -2912,7 +3322,7 @@ function useInlineSearch({
|
|
|
2912
3322
|
window.addEventListener("keydown", handleKeyDown, true);
|
|
2913
3323
|
return () => window.removeEventListener("keydown", handleKeyDown, true);
|
|
2914
3324
|
}, [controlledShowSearch, enabled, rootRef, showSearch]);
|
|
2915
|
-
|
|
3325
|
+
useEffect6(() => () => cancelSearch(), [cancelSearch]);
|
|
2916
3326
|
const searchMatchKeys = useMemo2(
|
|
2917
3327
|
() => buildSearchMatchKeys(searchResults),
|
|
2918
3328
|
[searchResults]
|
|
@@ -2982,6 +3392,7 @@ var DEFAULT_DATA_TABLE_LABELS = {
|
|
|
2982
3392
|
expandRow: "Expand row",
|
|
2983
3393
|
collapseRow: "Collapse row",
|
|
2984
3394
|
resizeColumn: "Resize column",
|
|
3395
|
+
reorderColumn: "Reorder column",
|
|
2985
3396
|
searchPlaceholder: "Search\u2026",
|
|
2986
3397
|
searchResultHint: "Type to search",
|
|
2987
3398
|
searchPrevious: "Previous result",
|
|
@@ -3039,6 +3450,9 @@ function useGlideTable(options) {
|
|
|
3039
3450
|
columnSizing: controlledColumnSizing,
|
|
3040
3451
|
onColumnSizingChange,
|
|
3041
3452
|
columnResizeMode = "onChange",
|
|
3453
|
+
enableColumnReorder = false,
|
|
3454
|
+
columnOrder: controlledColumnOrder,
|
|
3455
|
+
onColumnOrderChange,
|
|
3042
3456
|
enableColumnFreeze = false,
|
|
3043
3457
|
enableInlineSearch = false,
|
|
3044
3458
|
showSearch,
|
|
@@ -3059,16 +3473,17 @@ function useGlideTable(options) {
|
|
|
3059
3473
|
}, [labelsProp, emptyText, loadingText, selectionLabel]);
|
|
3060
3474
|
const enableExpand = Boolean(toggleField);
|
|
3061
3475
|
const resolvedEnableSubtreeCopy = enableSubtreeCopy ?? enableExpand;
|
|
3062
|
-
const [internalRowSelection, setInternalRowSelection] =
|
|
3063
|
-
const [internalColumnSizing, setInternalColumnSizing] =
|
|
3064
|
-
const [
|
|
3476
|
+
const [internalRowSelection, setInternalRowSelection] = useState5({});
|
|
3477
|
+
const [internalColumnSizing, setInternalColumnSizing] = useState5({});
|
|
3478
|
+
const [internalColumnOrder, setInternalColumnOrder] = useState5([]);
|
|
3479
|
+
const [internalExpandedRows, setInternalExpandedRows] = useState5(
|
|
3065
3480
|
() => /* @__PURE__ */ new Set()
|
|
3066
3481
|
);
|
|
3067
|
-
const [hoveredRowIndex, setHoveredRowIndex] =
|
|
3068
|
-
const scrollRef =
|
|
3069
|
-
const rootRef =
|
|
3482
|
+
const [hoveredRowIndex, setHoveredRowIndex] = useState5(null);
|
|
3483
|
+
const scrollRef = useRef7(null);
|
|
3484
|
+
const rootRef = useRef7(null);
|
|
3070
3485
|
const shouldVirtualize = enableVirtualization && !enableRowSpan;
|
|
3071
|
-
|
|
3486
|
+
useEffect7(() => {
|
|
3072
3487
|
if (enableVirtualization && enableRowSpan) {
|
|
3073
3488
|
console.warn(
|
|
3074
3489
|
"[useGlideTable] enableRowSpan is on; virtualization is disabled to preserve cell merges."
|
|
@@ -3081,8 +3496,23 @@ function useGlideTable(options) {
|
|
|
3081
3496
|
internalRowSelection
|
|
3082
3497
|
);
|
|
3083
3498
|
const columnSizing = controlledColumnSizing ?? internalColumnSizing;
|
|
3499
|
+
const columnOrder = controlledColumnOrder ?? internalColumnOrder;
|
|
3500
|
+
const tableColumns = useMemo3(() => {
|
|
3501
|
+
if (!enableColumnReorder) return columns;
|
|
3502
|
+
return applyLeafColumnOrder(columns, columnOrder);
|
|
3503
|
+
}, [columnOrder, columns, enableColumnReorder]);
|
|
3504
|
+
const setColumnOrder = useCallback5(
|
|
3505
|
+
(next) => {
|
|
3506
|
+
if (onColumnOrderChange) {
|
|
3507
|
+
onColumnOrderChange(next);
|
|
3508
|
+
return;
|
|
3509
|
+
}
|
|
3510
|
+
setInternalColumnOrder(next);
|
|
3511
|
+
},
|
|
3512
|
+
[onColumnOrderChange]
|
|
3513
|
+
);
|
|
3084
3514
|
const expandedRows = controlledExpandedRows ?? internalExpandedRows;
|
|
3085
|
-
const handleExpandedRowsChange =
|
|
3515
|
+
const handleExpandedRowsChange = useCallback5(
|
|
3086
3516
|
(next) => {
|
|
3087
3517
|
if (onExpandedRowsChange) {
|
|
3088
3518
|
onExpandedRowsChange(next);
|
|
@@ -3105,7 +3535,7 @@ function useGlideTable(options) {
|
|
|
3105
3535
|
});
|
|
3106
3536
|
const table = useReactTable({
|
|
3107
3537
|
data: tableData,
|
|
3108
|
-
columns,
|
|
3538
|
+
columns: tableColumns,
|
|
3109
3539
|
...enableColumnResize ? {
|
|
3110
3540
|
defaultColumn: {
|
|
3111
3541
|
minSize: DATA_TABLE_COLUMN_MIN_SIZE,
|
|
@@ -3185,7 +3615,7 @@ function useGlideTable(options) {
|
|
|
3185
3615
|
}
|
|
3186
3616
|
return indices;
|
|
3187
3617
|
}, [selectedRows]);
|
|
3188
|
-
const scrollCellIntoView =
|
|
3618
|
+
const scrollCellIntoView = useCallback5(
|
|
3189
3619
|
(rowIndex, colIndex, options2) => {
|
|
3190
3620
|
const align = options2?.align ?? "nearest";
|
|
3191
3621
|
const blockAlign = align === "center" ? "center" : "nearest";
|
|
@@ -3212,7 +3642,7 @@ function useGlideTable(options) {
|
|
|
3212
3642
|
},
|
|
3213
3643
|
[rowVirtualizer, shouldVirtualize]
|
|
3214
3644
|
);
|
|
3215
|
-
const handleCellNavigate =
|
|
3645
|
+
const handleCellNavigate = useCallback5(
|
|
3216
3646
|
(position) => {
|
|
3217
3647
|
scrollCellIntoView(position.row, position.col, { align: "nearest" });
|
|
3218
3648
|
},
|
|
@@ -3249,7 +3679,7 @@ function useGlideTable(options) {
|
|
|
3249
3679
|
() => createCellRendererRegistry(cellRenderers),
|
|
3250
3680
|
[cellRenderers]
|
|
3251
3681
|
);
|
|
3252
|
-
const commitRenderedCellValue =
|
|
3682
|
+
const commitRenderedCellValue = useCallback5(
|
|
3253
3683
|
(rowId, columnId, value) => commitCellValue({
|
|
3254
3684
|
data: tableData,
|
|
3255
3685
|
rows,
|
|
@@ -3261,11 +3691,11 @@ function useGlideTable(options) {
|
|
|
3261
3691
|
}),
|
|
3262
3692
|
[onCellChange, onDataChange, rows, tableData]
|
|
3263
3693
|
);
|
|
3264
|
-
const getCellContext =
|
|
3694
|
+
const getCellContext = useCallback5(
|
|
3265
3695
|
(cell) => withCellUpdate(cell.getContext(), commitRenderedCellValue),
|
|
3266
3696
|
[commitRenderedCellValue]
|
|
3267
3697
|
);
|
|
3268
|
-
const handleCellMouseDownWithCommit =
|
|
3698
|
+
const handleCellMouseDownWithCommit = useCallback5(
|
|
3269
3699
|
(rowIndex, colIndex, options2) => {
|
|
3270
3700
|
const isSameEditingCell = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === colIndex;
|
|
3271
3701
|
if (editingCell && !isSameEditingCell && !commitEdit()) {
|
|
@@ -3275,7 +3705,7 @@ function useGlideTable(options) {
|
|
|
3275
3705
|
},
|
|
3276
3706
|
[commitEdit, editingCell, handleCellMouseDown]
|
|
3277
3707
|
);
|
|
3278
|
-
const navigateToSearchResult =
|
|
3708
|
+
const navigateToSearchResult = useCallback5(
|
|
3279
3709
|
(item) => {
|
|
3280
3710
|
const [colIndex, rowIndex] = item;
|
|
3281
3711
|
handleCellMouseDownWithCommit(rowIndex, colIndex);
|
|
@@ -3283,7 +3713,7 @@ function useGlideTable(options) {
|
|
|
3283
3713
|
},
|
|
3284
3714
|
[handleCellMouseDownWithCommit, scrollCellIntoView]
|
|
3285
3715
|
);
|
|
3286
|
-
const resolveSearchRowId =
|
|
3716
|
+
const resolveSearchRowId = useCallback5(
|
|
3287
3717
|
(row, index) => {
|
|
3288
3718
|
if (getRowId) return getRowId(row, index);
|
|
3289
3719
|
if (enableExpand) {
|
|
@@ -3323,7 +3753,7 @@ function useGlideTable(options) {
|
|
|
3323
3753
|
tableData,
|
|
3324
3754
|
toggleField
|
|
3325
3755
|
]);
|
|
3326
|
-
const searchCorpusRef =
|
|
3756
|
+
const searchCorpusRef = useRef7(searchCorpus);
|
|
3327
3757
|
searchCorpusRef.current = searchCorpus;
|
|
3328
3758
|
const visibleRowIndexById = useMemo3(() => {
|
|
3329
3759
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -3332,7 +3762,7 @@ function useGlideTable(options) {
|
|
|
3332
3762
|
}
|
|
3333
3763
|
return map;
|
|
3334
3764
|
}, [resolveSearchRowId, rows]);
|
|
3335
|
-
const getSearchCellValue =
|
|
3765
|
+
const getSearchCellValue = useCallback5(
|
|
3336
3766
|
(rowIndex, colIndex) => {
|
|
3337
3767
|
const corpusRow = searchCorpusRef.current[rowIndex];
|
|
3338
3768
|
const column = visibleLeafColumns[colIndex];
|
|
@@ -3355,14 +3785,14 @@ function useGlideTable(options) {
|
|
|
3355
3785
|
},
|
|
3356
3786
|
[rows, visibleLeafColumns, visibleRowIndexById]
|
|
3357
3787
|
);
|
|
3358
|
-
const pendingSearchNavRef =
|
|
3359
|
-
const focusSearchResult =
|
|
3788
|
+
const pendingSearchNavRef = useRef7(null);
|
|
3789
|
+
const focusSearchResult = useCallback5(
|
|
3360
3790
|
(colIndex, visibleRowIndex) => {
|
|
3361
3791
|
navigateToSearchResult([colIndex, visibleRowIndex]);
|
|
3362
3792
|
},
|
|
3363
3793
|
[navigateToSearchResult]
|
|
3364
3794
|
);
|
|
3365
|
-
const navigateToCorpusSearchResult =
|
|
3795
|
+
const navigateToCorpusSearchResult = useCallback5(
|
|
3366
3796
|
(item) => {
|
|
3367
3797
|
const [colIndex, corpusRowIndex] = item;
|
|
3368
3798
|
const corpusRow = searchCorpusRef.current[corpusRowIndex];
|
|
@@ -3395,7 +3825,7 @@ function useGlideTable(options) {
|
|
|
3395
3825
|
visibleRowIndexById
|
|
3396
3826
|
]
|
|
3397
3827
|
);
|
|
3398
|
-
|
|
3828
|
+
useEffect7(() => {
|
|
3399
3829
|
const pending = pendingSearchNavRef.current;
|
|
3400
3830
|
if (!pending) return;
|
|
3401
3831
|
const visibleRowIndex = visibleRowIndexById.get(pending.rowId);
|
|
@@ -3445,13 +3875,13 @@ function useGlideTable(options) {
|
|
|
3445
3875
|
searchCorpus,
|
|
3446
3876
|
visibleRowIndexById
|
|
3447
3877
|
]);
|
|
3448
|
-
const clearHover =
|
|
3878
|
+
const clearHover = useCallback5(() => {
|
|
3449
3879
|
setHoveredRowIndex(null);
|
|
3450
3880
|
}, []);
|
|
3451
|
-
const handleRowHover =
|
|
3881
|
+
const handleRowHover = useCallback5((rowIndex, _rowData) => {
|
|
3452
3882
|
setHoveredRowIndex(rowIndex);
|
|
3453
3883
|
}, []);
|
|
3454
|
-
const handleToggleSelect =
|
|
3884
|
+
const handleToggleSelect = useCallback5(
|
|
3455
3885
|
(row) => {
|
|
3456
3886
|
if (!row.getCanSelect()) return;
|
|
3457
3887
|
if (preserveRowSelection && row.getIsSelected()) {
|
|
@@ -3461,7 +3891,7 @@ function useGlideTable(options) {
|
|
|
3461
3891
|
},
|
|
3462
3892
|
[preserveRowSelection]
|
|
3463
3893
|
);
|
|
3464
|
-
const handleToggleExpand =
|
|
3894
|
+
const handleToggleExpand = useCallback5(
|
|
3465
3895
|
(rowKey) => {
|
|
3466
3896
|
if (preventExpand) return;
|
|
3467
3897
|
handleExpandedRowsChange(toggleExpandedRowId(rowKey, expandedRows));
|
|
@@ -3567,12 +3997,12 @@ function useGlideTable(options) {
|
|
|
3567
3997
|
visibleSearchMatchKeys,
|
|
3568
3998
|
visibleActiveMatch
|
|
3569
3999
|
]);
|
|
3570
|
-
const copySelectionRef =
|
|
3571
|
-
|
|
4000
|
+
const copySelectionRef = useRef7(copySelection);
|
|
4001
|
+
useEffect7(() => {
|
|
3572
4002
|
copySelectionRef.current = copySelection;
|
|
3573
4003
|
}, [copySelection]);
|
|
3574
|
-
const stableCopySelection =
|
|
3575
|
-
|
|
4004
|
+
const stableCopySelection = useCallback5((options2) => copySelectionRef.current(options2), []);
|
|
4005
|
+
useEffect7(() => {
|
|
3576
4006
|
onCopyActionsReady?.({ copySelection: stableCopySelection });
|
|
3577
4007
|
}, [onCopyActionsReady, stableCopySelection]);
|
|
3578
4008
|
return {
|
|
@@ -3587,6 +4017,7 @@ function useGlideTable(options) {
|
|
|
3587
4017
|
selectionLabel: labels.selection,
|
|
3588
4018
|
enableCellSelection,
|
|
3589
4019
|
enableColumnResize,
|
|
4020
|
+
enableColumnReorder,
|
|
3590
4021
|
enableColumnFreeze,
|
|
3591
4022
|
enableInlineSearch,
|
|
3592
4023
|
shouldVirtualize,
|
|
@@ -3600,6 +4031,7 @@ function useGlideTable(options) {
|
|
|
3600
4031
|
getCellContext,
|
|
3601
4032
|
handleToggleSelect,
|
|
3602
4033
|
clearHover,
|
|
4034
|
+
setColumnOrder,
|
|
3603
4035
|
copySelection: stableCopySelection,
|
|
3604
4036
|
inlineSearch: {
|
|
3605
4037
|
showSearch: inlineSearch.showSearch,
|
|
@@ -3683,6 +4115,7 @@ function DataTable({
|
|
|
3683
4115
|
selectionLabel,
|
|
3684
4116
|
enableCellSelection,
|
|
3685
4117
|
enableColumnResize,
|
|
4118
|
+
enableColumnReorder,
|
|
3686
4119
|
enableColumnFreeze,
|
|
3687
4120
|
enableInlineSearch,
|
|
3688
4121
|
shouldVirtualize,
|
|
@@ -3695,6 +4128,7 @@ function DataTable({
|
|
|
3695
4128
|
rowContextValue,
|
|
3696
4129
|
handleToggleSelect,
|
|
3697
4130
|
clearHover,
|
|
4131
|
+
setColumnOrder,
|
|
3698
4132
|
inlineSearch
|
|
3699
4133
|
} = useGlideTable(glideOptions);
|
|
3700
4134
|
const ToolbarSlot = slots?.Toolbar ?? DataTableToolbar;
|
|
@@ -3704,6 +4138,12 @@ function DataTable({
|
|
|
3704
4138
|
const EmptySlot = slots?.Empty ?? DefaultEmpty;
|
|
3705
4139
|
const freezeOffsets = rowContextValue.columnFreeze.offsets;
|
|
3706
4140
|
const headerGroups = getMergedHeaderGroups(table.getHeaderGroups());
|
|
4141
|
+
const leafColumnIds = table.getVisibleLeafColumns().map((column) => column.id);
|
|
4142
|
+
const { isReordering, draggingColumnId, dropTarget, onHeaderPointerDown } = useColumnReorder({
|
|
4143
|
+
enabled: enableColumnReorder,
|
|
4144
|
+
columnOrder: leafColumnIds,
|
|
4145
|
+
onColumnOrderChange: setColumnOrder
|
|
4146
|
+
});
|
|
3707
4147
|
const contextValue = useMemo4(
|
|
3708
4148
|
() => ({ ...rowContextValue, classNames }),
|
|
3709
4149
|
[rowContextValue, classNames]
|
|
@@ -3726,6 +4166,8 @@ function DataTable({
|
|
|
3726
4166
|
"DataTableJSX",
|
|
3727
4167
|
!enableCellSelection && "DataTableJSX--no-cell-selection",
|
|
3728
4168
|
enableColumnResize && "DataTableJSX--column-resize",
|
|
4169
|
+
enableColumnReorder && "DataTableJSX--column-reorder",
|
|
4170
|
+
isReordering && "DataTableJSX--column-reordering",
|
|
3729
4171
|
enableColumnFreeze && "DataTableJSX--column-freeze",
|
|
3730
4172
|
enableInlineSearch && "DataTableJSX--inline-search",
|
|
3731
4173
|
classNames?.root,
|
|
@@ -3794,20 +4236,43 @@ function DataTable({
|
|
|
3794
4236
|
...sizeStyle,
|
|
3795
4237
|
...freezeStyle
|
|
3796
4238
|
};
|
|
4239
|
+
const isPlaceholder = header.isPlaceholder;
|
|
4240
|
+
const leafColumns = header.column.getLeafColumns();
|
|
4241
|
+
const leafIds = leafColumns.map((leafColumn) => leafColumn.id);
|
|
4242
|
+
const isLeafHeader = !isPlaceholder && header.subHeaders.length === 0;
|
|
4243
|
+
const canDrag = enableColumnReorder && !isPlaceholder && leafIds.length > 0 && leafColumns.every(
|
|
4244
|
+
(leafColumn) => isColumnReorderable(leafColumn.columnDef.meta)
|
|
4245
|
+
);
|
|
4246
|
+
const isDragging = draggingColumnId === header.column.id;
|
|
4247
|
+
const dropEdge = !isPlaceholder && dropTarget?.columnId === header.column.id ? dropTarget.edge : void 0;
|
|
3797
4248
|
return /* @__PURE__ */ jsxs6(
|
|
3798
4249
|
"th",
|
|
3799
4250
|
{
|
|
3800
4251
|
colSpan: header.colSpan,
|
|
3801
4252
|
rowSpan: header.mergedRowSpan,
|
|
4253
|
+
"data-column-id": enableColumnReorder && !isPlaceholder ? header.column.id : void 0,
|
|
4254
|
+
"data-reorder-ids": enableColumnReorder && !isPlaceholder ? serializeReorderIds(leafIds) : void 0,
|
|
4255
|
+
"data-reorder-leaf": enableColumnReorder && isLeafHeader ? "" : void 0,
|
|
4256
|
+
"data-reorderable": canDrag ? "" : void 0,
|
|
4257
|
+
"data-reordering": isDragging ? "" : void 0,
|
|
4258
|
+
"data-drop-edge": dropEdge,
|
|
3802
4259
|
"data-resizing": header.column.getIsResizing() ? "" : void 0,
|
|
3803
4260
|
"data-frozen": freezeOffset?.side,
|
|
3804
4261
|
"data-freeze-edge": getColumnFreezeEdgeAttr(freezeOffset),
|
|
4262
|
+
"aria-grabbed": isDragging ? true : void 0,
|
|
4263
|
+
title: canDrag ? labels.reorderColumn : void 0,
|
|
4264
|
+
onPointerDown: enableColumnReorder ? (event) => onHeaderPointerDown(event, {
|
|
4265
|
+
columnId: header.column.id,
|
|
4266
|
+
leafIds,
|
|
4267
|
+
canDrag
|
|
4268
|
+
}) : void 0,
|
|
3805
4269
|
style: Object.keys(headerStyle).length > 0 ? headerStyle : void 0,
|
|
3806
4270
|
className: cn(
|
|
3807
4271
|
"data-table-head-cell",
|
|
3808
4272
|
freezeOffset && `data-table-head-cell--frozen-${freezeOffset.side}`,
|
|
3809
4273
|
CELL_ALIGN_CLASS[align],
|
|
3810
4274
|
classNames?.headCell,
|
|
4275
|
+
dropEdge && classNames?.dropEdge,
|
|
3811
4276
|
headerClassName
|
|
3812
4277
|
),
|
|
3813
4278
|
children: [
|
|
@@ -3929,10 +4394,10 @@ function DataTable({
|
|
|
3929
4394
|
}
|
|
3930
4395
|
|
|
3931
4396
|
// src/components/ui/table/components/Table/Table.tsx
|
|
3932
|
-
import { useCallback as
|
|
4397
|
+
import { useCallback as useCallback7, useMemo as useMemo5, useState as useState6 } from "react";
|
|
3933
4398
|
|
|
3934
4399
|
// src/components/ui/table/features/cell-render/ResolvedTableCell.tsx
|
|
3935
|
-
import { useCallback as
|
|
4400
|
+
import { useCallback as useCallback6 } from "react";
|
|
3936
4401
|
function ResolvedTableCell({
|
|
3937
4402
|
info
|
|
3938
4403
|
}) {
|
|
@@ -3941,7 +4406,7 @@ function ResolvedTableCell({
|
|
|
3941
4406
|
const meta = column.columnDef.meta;
|
|
3942
4407
|
const value = getValue();
|
|
3943
4408
|
const columnId = column.id;
|
|
3944
|
-
const update =
|
|
4409
|
+
const update = useCallback6(
|
|
3945
4410
|
(next) => {
|
|
3946
4411
|
cellRender.commitValue(row.id, columnId, next);
|
|
3947
4412
|
},
|
|
@@ -4001,10 +4466,12 @@ function buildColumnDef(props, sort, onSort) {
|
|
|
4001
4466
|
minWidth,
|
|
4002
4467
|
maxWidth,
|
|
4003
4468
|
resizable,
|
|
4469
|
+
reorderable,
|
|
4004
4470
|
frozen,
|
|
4005
4471
|
align,
|
|
4006
4472
|
rowSpan,
|
|
4007
4473
|
rowSpanKey,
|
|
4474
|
+
rowSpanParent,
|
|
4008
4475
|
editable,
|
|
4009
4476
|
editType,
|
|
4010
4477
|
editInputProps,
|
|
@@ -4039,6 +4506,7 @@ function buildColumnDef(props, sort, onSort) {
|
|
|
4039
4506
|
align,
|
|
4040
4507
|
rowSpan,
|
|
4041
4508
|
rowSpanKey,
|
|
4509
|
+
rowSpanParent,
|
|
4042
4510
|
editable,
|
|
4043
4511
|
editType,
|
|
4044
4512
|
editInputProps,
|
|
@@ -4046,6 +4514,7 @@ function buildColumnDef(props, sort, onSort) {
|
|
|
4046
4514
|
cellProps,
|
|
4047
4515
|
cellRender: render,
|
|
4048
4516
|
frozen,
|
|
4517
|
+
reorderable,
|
|
4049
4518
|
className,
|
|
4050
4519
|
headerClassName
|
|
4051
4520
|
}
|
|
@@ -4293,8 +4762,8 @@ function TableRoot({
|
|
|
4293
4762
|
() => parseTableChildren(children),
|
|
4294
4763
|
[children]
|
|
4295
4764
|
);
|
|
4296
|
-
const [sort, setSort] =
|
|
4297
|
-
const handleSort =
|
|
4765
|
+
const [sort, setSort] = useState6(null);
|
|
4766
|
+
const handleSort = useCallback7((field) => {
|
|
4298
4767
|
setSort((previous) => {
|
|
4299
4768
|
if (previous?.field !== field) {
|
|
4300
4769
|
return { field, direction: "asc" };
|