UNPKG

react-native-tree-multi-select

Version:

A super-fast, customizable tree view component for React Native with multi-selection, checkboxes, and search filtering capabilities.

149 lines (146 loc) 5.48 kB
"use strict"; import React from "react"; import { InteractionManager } from "react-native"; import NodeList from "./components/NodeList"; import { selectAll, selectAllFiltered, unselectAll, unselectAllFiltered, initializeNodeMaps, expandAll, collapseAll, toggleCheckboxes, expandNodes, collapseNodes } from "./helpers"; import { getTreeViewStore, useTreeViewStore } from "./store/treeView.store"; import usePreviousState from "./utils/usePreviousState"; import { useShallow } from "zustand/react/shallow"; import uuid from "react-native-uuid"; import useDeepCompareEffect from "./utils/useDeepCompareEffect"; import { typedMemo } from "./utils/typedMemo"; import { jsx as _jsx } from "react/jsx-runtime"; function _innerTreeView(props, ref) { const { data, onCheck, onExpand, selectionPropagation, preselectedIds = [], preExpandedIds = [], initialScrollNodeID, treeFlashListProps, checkBoxViewStyleProps, indentationMultiplier, CheckboxComponent, ExpandCollapseIconComponent, ExpandCollapseTouchableComponent, CustomNodeRowComponent } = props; const storeId = React.useMemo(() => uuid.v4(), []); const { expanded, updateExpanded, initialTreeViewData, updateInitialTreeViewData, searchText, updateSearchText, updateSearchKeys, checked, indeterminate, setSelectionPropagation, cleanUpTreeViewStore } = useTreeViewStore(storeId)(useShallow(state => ({ expanded: state.expanded, updateExpanded: state.updateExpanded, initialTreeViewData: state.initialTreeViewData, updateInitialTreeViewData: state.updateInitialTreeViewData, searchText: state.searchText, updateSearchText: state.updateSearchText, updateSearchKeys: state.updateSearchKeys, checked: state.checked, indeterminate: state.indeterminate, setSelectionPropagation: state.setSelectionPropagation, cleanUpTreeViewStore: state.cleanUpTreeViewStore }))); React.useImperativeHandle(ref, () => ({ selectAll: () => selectAll(storeId), unselectAll: () => unselectAll(storeId), selectAllFiltered: () => selectAllFiltered(storeId), unselectAllFiltered: () => unselectAllFiltered(storeId), expandAll: () => expandAll(storeId), collapseAll: () => collapseAll(storeId), expandNodes: ids => expandNodes(storeId, ids), collapseNodes: ids => collapseNodes(storeId, ids), selectNodes: ids => selectNodes(ids), unselectNodes: ids => unselectNodes(ids), setSearchText, scrollToNodeID, getChildToParentMap })); const scrollToNodeHandlerRef = React.useRef(null); const prevSearchText = usePreviousState(searchText); useDeepCompareEffect(() => { cleanUpTreeViewStore(); updateInitialTreeViewData(data); if (selectionPropagation) setSelectionPropagation(selectionPropagation); initializeNodeMaps(storeId, data); // Check any pre-selected nodes toggleCheckboxes(storeId, preselectedIds, true); // Expand pre-expanded nodes expandNodes(storeId, [...preExpandedIds, ...(initialScrollNodeID ? [initialScrollNodeID] : [])]); }, [data]); function selectNodes(ids) { toggleCheckboxes(storeId, ids, true); } function unselectNodes(ids) { toggleCheckboxes(storeId, ids, false); } function setSearchText(text, keys = ["name"]) { updateSearchText(text); updateSearchKeys(keys); } function scrollToNodeID(params) { scrollToNodeHandlerRef.current?.scrollToNodeID(params); } function getChildToParentMap() { const treeViewStore = getTreeViewStore(storeId); return treeViewStore.getState().childToParentMap; } const getIds = React.useCallback(node => { if (!node.children || node.children.length === 0) { return [node.id]; } else { return [node.id, ...node.children.flatMap(item => getIds(item))]; } }, []); React.useEffect(() => { onCheck?.(Array.from(checked), Array.from(indeterminate)); }, [onCheck, checked, indeterminate]); React.useEffect(() => { onExpand?.(Array.from(expanded)); }, [onExpand, expanded]); React.useEffect(() => { if (searchText) { InteractionManager.runAfterInteractions(() => { updateExpanded(new Set(initialTreeViewData.flatMap(item => getIds(item)))); }); } else if (prevSearchText && prevSearchText !== "") { /* Collapse all nodes only if previous search query was non-empty: this is done to prevent node collapse on first render if preExpandedIds is provided */ InteractionManager.runAfterInteractions(() => { updateExpanded(new Set()); }); } }, [getIds, initialTreeViewData, prevSearchText, searchText, updateExpanded]); React.useEffect(() => { return () => { cleanUpTreeViewStore(); }; }, [cleanUpTreeViewStore]); return /*#__PURE__*/_jsx(NodeList, { storeId: storeId, scrollToNodeHandlerRef: scrollToNodeHandlerRef, initialScrollNodeID: initialScrollNodeID, treeFlashListProps: treeFlashListProps, checkBoxViewStyleProps: checkBoxViewStyleProps, indentationMultiplier: indentationMultiplier, CheckboxComponent: CheckboxComponent, ExpandCollapseIconComponent: ExpandCollapseIconComponent, ExpandCollapseTouchableComponent: ExpandCollapseTouchableComponent, CustomNodeRowComponent: CustomNodeRowComponent }); } const _TreeView = /*#__PURE__*/React.forwardRef(_innerTreeView); export const TreeView = typedMemo(_TreeView); //# sourceMappingURL=TreeView.js.map