UNPKG

@ovine/craft

Version:
84 lines (83 loc) 3.34 kB
/** * 预览时的节点导航 * * TODO: 重写 tree 组件 */ import { Collapse } from 'amis'; import cls from 'classnames'; import { throttle } from 'lodash'; import { observer } from 'mobx-react'; import React, { useState } from 'react'; import { useSubscriber } from '@core/utils/hooks'; import { previewStore } from "../../preview/store"; import { message } from "../../../constants"; import { useAsideStore } from "../store"; import { StyledTree } from "./styled"; const hasNodeId = (id) => id && id.indexOf('none') === -1; const treeSponsor = 'asideTree'; export default observer((props) => { const { classPrefix: ns, classnames: cx } = props; const { nodes = [] } = useAsideStore(); const [hoverId, setHoverId] = useState(''); const [selectedId, setSelectedId] = useState(''); const [foldId, setFoldId] = useState(''); const toggleFold = (id) => { setFoldId((v) => (v === id ? '' : id)); }; const onSelect = (id) => { if (hasNodeId(id)) { setSelectedId(id); previewStore.setSelectedId(id, treeSponsor); } }; const onHover = throttle((id) => { setHoverId(''); previewStore.setHoverId(hasNodeId(id) ? id : '', treeSponsor); }, 10); const onLeave = () => { setHoverId(''); previewStore.setHoverId('', treeSponsor); }; const getItemCls = (id, classStr = '') => { const hasId = hasNodeId(id); const isSelected = hasId && selectedId === id; const isHover = hasId && hoverId === id; return cls(classStr, { 'node-hover': isHover, 'node-selected': isSelected, 'node-normal': hasId && !isHover && !isSelected, }); }; useSubscriber([message.updateHover, message.updateSelected], (data, key) => { const { id, sponsor } = data; if (sponsor === treeSponsor) { return; } if (key === message.updateHover) { setHoverId(id); } else { setSelectedId(id); } }); const renderItem = (item) => { const { id, type } = item; return (React.createElement("span", { onMouseEnter: () => onHover(id), onClick: () => onSelect(id) }, type)); }; const renderSubTree = (items, deep = 0) => { return (React.createElement("ul", { className: cls({ 'tree-root': deep === 0 }) }, items.map((item, index) => { const { id } = item; if (!item.children || !item.children.length) { return (React.createElement("li", { key: index, className: getItemCls(id, 'tree-leaf') }, renderItem(item))); } return (React.createElement("li", { key: index }, React.createElement("div", { className: getItemCls(id, 'tree-label') }, React.createElement("span", { className: cls(`icon-arrow ${ns}Collapse-arrow`, { 'is-fold': foldId === id, }), onClick: () => toggleFold(id) }), renderItem(item)), React.createElement(Collapse, { show: foldId !== id, classnames: cx, classPrefix: ns }, renderSubTree(item.children, deep + 1)))); }))); }; return React.createElement(StyledTree, { onMouseLeave: onLeave }, renderSubTree(nodes)); });