@1771technologies/lytenyte-pro
Version:
Blazingly fast headless React data grid with 100s of features.
170 lines (169 loc) • 7.78 kB
JavaScript
import { useMemo } from "react";
import { useSourceState } from "./hooks/use-controlled-ds-state.js";
import { useEvent, useGlobalRefresh, useIdUniverse, useLeafNodes, useOnRowsSelected, useOnRowsUpdated, usePiece, useRowAdd, useRowById, useRowByIndex, useRowChildren, useRowDelete, useRowIsSelected, useRowLeafs, useRowParents, useRows, useRowsBetween, useRowSelection, useRowSelectionState, useRowSelectSplitLookup, useRowSiblings, } from "@1771technologies/lytenyte-core/internal";
import { useFlattenedData } from "./hooks/use-flattened-data.js";
import { usePivotData } from "./hooks/use-pivot/use-pivot-data.js";
import { usePivotState } from "./hooks/use-pivot/use-pivot-state.js";
const groupIdFallback = (p) => p.map((x) => (x == null ? "_null_" : x)).join("->");
export function useClientDataSource(props) {
const leafsTuple = useLeafNodes(props.topData, props.data, props.botData, props.leafIdFn);
const pivotControlled = usePivotState(props.pivotState, props.onPivotStateChange);
// s == state, f == flat, p == pivot
const s = useSourceState(props, pivotControlled);
const d = useFlattenedData(props, leafsTuple, s);
const p = usePivotData(props, leafsTuple, s, pivotControlled);
const f = props.pivotMode ? p : d;
const mode = props?.pivotMode === true;
const piece = usePiece(mode ? p.flatten : d.flatten);
const botPiece = usePiece(f.leafsBot.length);
const topPiece = usePiece(f.leafsTop.length);
const depth = props.group
? Array.isArray(props.group)
? props.group.length
: d.maxDepth
: props.pivotMode && props.pivotModel?.rows?.length
? p.maxDepth
: 0;
const maxDepthPiece = usePiece(depth);
const rowById = useRowById(f.tree, f.leafIdsRef);
const rowParents = useRowParents(rowById, f.tree, f.groupFn, props.groupIdFn ?? groupIdFallback);
const onRowsUpdated = useOnRowsUpdated(props.onRowDataChange);
const globalSignal = useGlobalRefresh();
const idToSpec = useEvent((id) => {
if (!f.tree)
return null;
const node = f.tree.groupLookup.get(id);
if (!node)
return null;
return { size: node.children.size, children: node.children };
});
const rowSelectionKey = useMemo(() => {
if (props.rowSelectKey)
return props.rowSelectKey;
return [props.group, props.filter];
}, [props.filter, props.group, props.rowSelectKey]);
const { idUniverse, rootIds } = useIdUniverse(f.tree, f.leafIdsRef.current, props.rowSelectionIdUniverseAdditions, props.rowSelectionIdUniverseSubtractions);
const selectionState = useRowSelection(props.rowSelection, props.onRowSelectionChange, props.rowsIsolatedSelection ?? false, rowSelectionKey, idUniverse, rootIds, rootIds.size, globalSignal);
const onRowsSelected = useOnRowsSelected(selectionState, idToSpec, rowParents, props.rowsIsolatedSelection ?? false, globalSignal);
const rowIsSelected = useRowIsSelected(selectionState, rowParents, rowById);
const rowsSelected = useRowSelectSplitLookup(selectionState, f.leafIdsRef.current, f.tree?.groupLookup, rowParents);
const rowSelectionState = useRowSelectionState(selectionState);
const { rowInvalidate, rowByIndex } = useRowByIndex(piece, globalSignal, selectionState, rowParents);
const rowsBetween = useRowsBetween(f.rowIdToRowIndexRef, rowByIndex);
const rowLeafs = useRowLeafs(f.tree);
const rowChildren = useRowChildren(f.tree);
const setExpansions = s.onExpansionsChange;
const setPivotState = pivotControlled.onPivotColumnStateChange;
const setPivotGroupState = pivotControlled.onPivotGroupStateChange;
const setPivotRowGroupExpansions = s.onPivotExpansionsChange;
const mode$ = usePiece(mode);
const flat = piece.get();
const rowAdd = useRowAdd(props);
const rowDelete = useRowDelete(props, rowById);
const rows$ = useRows(flat);
const rowSiblings = useRowSiblings(f.tree);
const selection$ = usePiece(selectionState.rowSelectionsRaw);
const source = useMemo(() => {
const rowCount$ = (x) => x.length;
const source = {
rowInvalidate,
rowByIndex,
rowIndexToRowId: (index) => f.rowByIndexRef.current.get(index)?.id ?? null,
rowIdToRowIndex: (id) => f.rowIdToRowIndexRef.current.get(id) ?? null,
rowById,
rowsBetween,
rowChildren,
rowLeafs,
rowIsSelected,
rowsSelected,
rowParents,
rowSelectionState,
rowAdd,
rowDelete,
rowUpdate: onRowsUpdated,
rowSiblings,
useBottomCount: botPiece.useValue,
useTopCount: topPiece.useValue,
useRowCount: () => piece.useValue(rowCount$),
useRows: () => rows$.useValue(),
useSelectionState: selection$.useValue,
useMaxRowGroupDepth: maxDepthPiece.useValue,
rowGroupExpansionChange: (deltaChanges) => {
if (mode$.get())
setPivotRowGroupExpansions(deltaChanges);
else
setExpansions(deltaChanges);
},
onRowsSelected,
onRowsUpdated,
onViewChange: () => { },
usePivotProps: () => {
const pivotColumns = p.pivotPiece.useValue();
const pivotGroups = p.pivotGroupPiece.useValue();
const mode = mode$.useValue();
return useMemo(() => {
if (!mode)
return {};
const object = {};
if (pivotColumns)
object.columns = pivotColumns;
if (pivotColumns)
object.columnGroupExpansions = pivotGroups.value;
const onColChange = (columns) => {
const ordering = columns.map((x) => x.id);
const resizingEntries = columns
.map((x) => (x.width == null ? null : [x.id, x.width]))
.filter(Boolean);
const pinnedEntries = columns
.map((x) => (x.pin === undefined ? null : [x.id, x.pin]))
.filter(Boolean);
setPivotState({
ordering,
resizing: Object.fromEntries(resizingEntries),
pinning: Object.fromEntries(pinnedEntries),
});
};
const onColumnGroup = (change) => {
setPivotGroupState(change);
};
object.onColumnsChange = onColChange;
object.onColumnGroupExpansionChange = onColumnGroup;
return object;
}, [mode, pivotColumns, pivotGroups.value]);
},
};
return source;
}, [
rowInvalidate,
rowByIndex,
rowById,
rowsBetween,
rowChildren,
rowLeafs,
rowIsSelected,
rowsSelected,
rowParents,
rowSelectionState,
rowAdd,
rowDelete,
onRowsUpdated,
rowSiblings,
botPiece.useValue,
topPiece.useValue,
selection$.useValue,
maxDepthPiece.useValue,
onRowsSelected,
f.rowByIndexRef,
f.rowIdToRowIndexRef,
piece,
rows$,
mode$,
setPivotRowGroupExpansions,
setExpansions,
p.pivotPiece,
p.pivotGroupPiece,
setPivotState,
setPivotGroupState,
]);
return source;
}