UNPKG

@1771technologies/lytenyte-pro

Version:

Blazingly fast headless React data grid with 100s of features.

170 lines (169 loc) 7.78 kB
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; }