antd-multi-asl-cascader
Version:
A multiple cascader component for antd
134 lines (133 loc) • 5.18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const react_1 = require("react");
const unstated_next_1 = require("unstated-next");
const utils_1 = require("./libs/utils");
const useFlattenData_1 = tslib_1.__importDefault(require("./hooks/useFlattenData"));
const useCascade = (params) => {
const {
// 全部级联数据
data,
// 用户选中的数据
value: valueProp, onChange, onCascaderChange, selectLeafOnly, } = params || {};
// 是否显示下垃圾
const [popupVisible, setPopupVisible] = react_1.useState(false);
// 被拍平后的全部数据
const { flattenData } = useFlattenData_1.default(data);
// menu里全部的数据,按列分
const [menuData, setMenuData] = react_1.useState([]);
// 点击显示两的路径
const [menuPath, setMenuPath] = react_1.useState([]);
// 把从props传入的value 转换成节点类型,并兼容其父子节点
const transformValue = react_1.useCallback((propsValue) => {
const value = utils_1.transPropsValueToValues(propsValue, data || []);
const nextValue = utils_1.transformValue(value, flattenData);
// if (onChange && !shallowEqualArray(nextValue, value)) {
// requestAnimationFrame(() => triggerChange(nextValue))
// }
return nextValue;
}, [flattenData]);
// 选中的全部数据(合并后)
const [value, setValue] = react_1.useState([]);
// 选中的全部数据(合并前,原始数据)
const selectedLeafNode = react_1.useMemo(() => utils_1.findAllLeafNode(value), [value]);
// selector 的改变触发的函数
const triggerChange = react_1.useCallback((nextValue) => {
const selectedLeafNode = utils_1.findAllLeafNode(nextValue);
const hasError = onChange && onChange(utils_1.transTreeNodesToArray(selectedLeafNode), selectedLeafNode);
if (hasError) {
return;
}
setValue(nextValue);
console.log(1);
setPopupVisible(false);
}, []);
// 用户点击 menuItem 的时候的回调函数,动态显示columns
const addMenu = 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 = useCallback(
// (target: TreeNode, children: TreeNode[]): TreeNode[] => {
// const found = findNodeByValue(target.value, dataRef.current!)
// if (found) {
// found.children = children
// }
// return [...dataRef.current!]
// },
// []
// )
const lastItemRef = react_1.useRef(null);
const handleCascaderChange = react_1.useCallback((item, depth) => {
const { children } = item;
lastItemRef.current = item;
// onCascaderChange?.(item, {
// add: (newChildren: TreeNode[]) => {
// 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 = react_1.useCallback((item, checked, value) => {
const newValue = utils_1.reconcile(item, checked, value);
const selectedLeafNode = utils_1.findAllLeafNode(newValue);
const hasError = onChange && onChange(utils_1.transTreeNodesToArray(selectedLeafNode), selectedLeafNode);
if (hasError) {
return;
}
setValue([...newValue]);
}, [flattenData]);
const resetMenuState = react_1.useCallback(() => {
if (flattenData.length === 1) {
return setMenuData([]);
}
else {
setMenuData([flattenData.filter((item) => !item.parent)]);
}
setMenuPath([]);
}, [flattenData]);
// 传入的 value 有变更时重新计算
react_1.useEffect(() => {
if (popupVisible) {
setValue(transformValue(valueProp || []));
resetMenuState();
}
}, [popupVisible]);
react_1.useEffect(() => {
setValue(transformValue(valueProp || []));
}, [valueProp]);
return {
menuPath,
popupVisible,
setPopupVisible,
menuData,
addMenu,
setMenuData,
value,
setValue,
handleCascaderChange,
handleSelectChange,
flattenData,
resetMenuState,
triggerChange,
selectLeafOnly,
selectedLeafNode
};
};
exports.default = unstated_next_1.createContainer(useCascade);