jjb-lc-designable
Version:
基于alibaba-designable源码二次封装的表单设计器。
105 lines • 3.06 kB
JavaScript
import React, { useEffect, useState, useRef } from 'react';
import { useHover, useSelection, usePrefix } from '../../hooks';
import { IconWidget } from '../IconWidget';
import { NodeTitleWidget } from '../NodeTitleWidget';
import { Button } from 'antd';
import { observer } from 'jjb-lc-formily/reactive-react';
const useMouseHover = (ref, enter, leave) => {
useEffect(() => {
let timer = null;
let unmounted = false;
const onMouseOver = e => {
const target = e.target;
clearTimeout(timer);
timer = setTimeout(() => {
if (unmounted) return;
if (ref?.current?.contains(target)) {
enter && enter();
} else {
leave && leave();
}
}, 100);
};
document.addEventListener('mouseover', onMouseOver);
return () => {
unmounted = true;
document.removeEventListener('mouseover', onMouseOver);
};
}, []);
};
export const Selector = observer(({
node
}) => {
const hover = useHover();
const [expand, setExpand] = useState(false);
const ref = useRef(null);
const selection = useSelection();
const prefix = usePrefix('aux-selector');
const renderIcon = node => {
const icon = node.designerProps.icon;
if (icon) {
return /*#__PURE__*/React.createElement(IconWidget, {
infer: icon
});
}
if (node === node.root) {
return /*#__PURE__*/React.createElement(IconWidget, {
infer: "Page"
});
} else if (node.designerProps?.droppable) {
return /*#__PURE__*/React.createElement(IconWidget, {
infer: "Container"
});
}
return /*#__PURE__*/React.createElement(IconWidget, {
infer: "Component"
});
};
const renderMenu = () => {
const parents = node.getParents();
return /*#__PURE__*/React.createElement("div", {
className: prefix + '-menu',
style: {
position: 'absolute',
top: '100%',
left: 0
}
}, parents.slice(0, 4).map(parent => {
return /*#__PURE__*/React.createElement(Button, {
key: parent.id,
type: "primary",
onClick: () => {
selection.select(parent.id);
},
onMouseEnter: () => {
hover.setHover(parent);
}
}, renderIcon(parent), /*#__PURE__*/React.createElement("span", {
style: {
transform: 'scale(0.85)',
marginLeft: 2
}
}, /*#__PURE__*/React.createElement(NodeTitleWidget, {
node: parent
})));
}));
};
useMouseHover(ref, () => {
setExpand(true);
}, () => {
setExpand(false);
});
return /*#__PURE__*/React.createElement("div", {
ref: ref,
className: prefix
}, /*#__PURE__*/React.createElement(Button, {
className: prefix + '-title',
type: "primary",
onMouseEnter: () => {
hover.setHover(node);
}
}, renderIcon(node), /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(NodeTitleWidget, {
node: node
}))), expand && renderMenu());
});
Selector.displayName = 'Selector';