UNPKG

antd-multi-cascader

Version:
154 lines (153 loc) 5.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = require("react"); const unstated_next_1 = require("unstated-next"); const utils_1 = require("./libs/utils"); const constants_1 = require("./constants"); const useCascade = (params) => { const { data, value: valueProp, selectAll, onChange, onCascaderChange, selectLeafOnly, } = params || {}; const [popupVisible, setPopupVisible] = (0, react_1.useState)(false); const dataRef = (0, react_1.useRef)(data); (0, react_1.useEffect)(() => { dataRef.current = data; }, [data]); const [flattenData, setFlattenData] = (0, react_1.useState)(() => { if (selectAll) { return (0, utils_1.flattenTree)([ { title: 'All', value: constants_1.All, parent: null, children: data, }, ]); } return (0, utils_1.flattenTree)(data || []); }); (0, react_1.useEffect)(() => { setFlattenData(() => { if (selectAll) { return (0, utils_1.flattenTree)([ { title: 'All', value: constants_1.All, parent: null, children: data, }, ]); } return (0, utils_1.flattenTree)(data || []); }); }, [data, selectAll]); const transformValue = (0, react_1.useCallback)((value) => { const nextValue = (0, utils_1.transformValue)(value, flattenData); if (onChange && !(0, utils_1.shallowEqualArray)(nextValue, value)) { requestAnimationFrame(() => triggerChange(nextValue)); } return nextValue; }, [flattenData]); const [menuData, setMenuData] = (0, react_1.useState)(() => { if (selectAll && flattenData.length === 1) { return []; } return [ selectAll ? flattenData[0].children : flattenData.filter((item) => !item.parent), ]; }); const [menuPath, setMenuPath] = (0, react_1.useState)([]); const [value, setValue] = (0, react_1.useState)(transformValue(valueProp || [])); const hackValue = (0, react_1.useRef)(value); const selectedItems = (0, react_1.useMemo)(() => { return flattenData.filter((node) => { return (valueProp || hackValue.current).includes(node.value); }); }, [flattenData, valueProp, popupVisible, hackValue.current]); const triggerChange = (0, react_1.useCallback)((nextValue) => { if (onChange) { onChange(nextValue, selectedItems.slice(0)); } hackValue.current = nextValue; setValue(nextValue); setPopupVisible(false); }, [selectedItems]); const addMenu = (0, react_1.useCallback)((menu, index) => { if (menu && menu.length) { setMenuData((prevMenuData) => [...prevMenuData.slice(0, index), menu]); } else { setMenuData((prevMenuData) => [...prevMenuData.slice(0, index)]); } }, []); const addChildrenToNode = (0, react_1.useCallback)((target, children) => { const found = (0, utils_1.findNodeByValue)(target.value, dataRef.current); if (found) { found.children = children; } return [...dataRef.current]; }, []); const lastItemRef = (0, react_1.useRef)(null); const handleCascaderChange = (0, react_1.useCallback)((item, depth) => { const { children } = item; lastItemRef.current = item; onCascaderChange === null || onCascaderChange === void 0 ? void 0 : onCascaderChange(item, { add: (newChildren) => { const newData = addChildrenToNode(item, newChildren); if (lastItemRef.current === item) { item.children = newChildren; newChildren.forEach((child) => { child.parent = item; }); setFlattenData((prev) => [...prev, ...newChildren]); handleCascaderChange(item, depth); } return newData; }, }); addMenu(children, depth + 1); setMenuPath((prevMenuPath) => prevMenuPath.slice(0, depth).concat(item)); }, [menuPath, onCascaderChange]); const handleSelectChange = (0, react_1.useCallback)((item, checked) => { setValue((prevValue) => (0, utils_1.sortByTree)((0, utils_1.reconcile)(item, checked, prevValue), flattenData)); }, [flattenData]); const resetMenuState = (0, react_1.useCallback)(() => { if (selectAll && flattenData.length === 1) { return setMenuData([]); } else { setMenuData([ selectAll ? flattenData[0].children : flattenData.filter((item) => !item.parent), ]); } setMenuPath([]); }, [flattenData, selectAll]); // 传入的 value 有变更时重新计算 (0, react_1.useEffect)(() => { if (popupVisible) { setValue(transformValue(valueProp || hackValue.current)); resetMenuState(); } }, [popupVisible]); return { menuPath, popupVisible, setPopupVisible, menuData, addMenu, setMenuData, value, setValue, handleCascaderChange, handleSelectChange, flattenData, resetMenuState, selectedItems, triggerChange, selectLeafOnly, hackValue, }; }; exports.default = (0, unstated_next_1.createContainer)(useCascade);