@cainiaofe/cn-ui-layout
Version:
- 安装 cone-cli | [Cone-CLI 使用指引](https://alidocs.dingtalk.com/i/nodes/xdqZp24KneBJzvGM6XezJvyb7RA0Nr1E) - `tnpm i -g @alife/cone-cli@latest` - 安装依赖包 - `cone install` - 启动研发 - `cone start`
282 lines (277 loc) • 9.26 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import { Fragment } from "react";
import React, { useRef, useEffect, useState, useCallback } from 'react';
import ReactDOM from 'react-dom';
import { splitNodeByDimension } from "./split/auto-cell";
import { CELL, ROW, COL, TILE, BLOCK } from "../../../common/util/const";
import "./divider.scss";
var FUSION_UI_VIEW_PREFIX = 'fd-layout-view';
export var initSingletonDivider = function initSingletonDivider(id) {
var dividerId = id || 'default-layout-divider';
var pageC = getPageRootDOMNode();
if (!pageC) return;
var $el = pageC.ownerDocument.getElementById(dividerId);
if (!$el) {
var dividerWrapper = createDividerWrapperNode(dividerId);
pageC && pageC.appendChild(dividerWrapper);
ReactDOM.render(/*#__PURE__*/React.createElement(Divider, {
split: splitNodeByDimension
}), dividerWrapper);
}
};
export var Divider = function Divider(props) {
var engine = useRef(window.parent.AliLowCodeEngine);
var _useState = useState([]),
cuts = _useState[0],
setCuts = _useState[1];
var _useState2 = useState(false),
disabled = _useState2[0],
setDisabled = _useState2[1];
var computCuts = useCallback(function (selectedNode) {
var dimension = getSplitDimension(selectedNode.componentName);
var rect = selectedNode.getRect();
var newCuts = [];
var pageC = getPageRootDOMNode();
var pageCRect = pageC ? pageC.getBoundingClientRect() : {
left: 0,
top: 0
};
if (!rect || !pageCRect) {
return;
}
if (dimension.h) {
newCuts.push({
dimension: 'h',
left: rect.left - pageCRect.left,
top: rect.top + rect.height / 2 - pageCRect.top,
node: selectedNode
});
}
if (dimension.v && rect && pageCRect) {
newCuts.push({
dimension: 'v',
left: rect.left + rect.width / 2 - pageCRect.left,
top: rect.top - pageCRect.top,
node: selectedNode
});
}
if (dimension.m) {
newCuts.push({
dimension: 'm',
left: rect.left + rect.width / 2 - pageCRect.left,
top: rect.top + rect.height / 2 - pageCRect.top,
node: selectedNode
});
}
setCuts(newCuts);
}, []);
var onSelectionChange = useCallback(function (timer) {
if (timer === void 0) {
timer = 100;
}
setDisabled(false);
var selectedNode = getSelectedNode(engine.current);
if (!selectedNode) {
setCuts([]);
return;
}
// TODO
// 目前 selectionChang 时 dom 结构可能还在变化
// 会偶尔导致 computCuts 计算尺寸出现问题,需要优化
if (timer) {
setTimeout(function () {
computCuts(selectedNode);
}, timer);
} else {
computCuts(selectedNode);
}
}, []);
useEffect(function () {
var _project$currentDocum;
var project = engine.current.project;
if (!project) return;
(_project$currentDocum = project.currentDocument) === null || _project$currentDocum === void 0 ? void 0 : _project$currentDocum.onChangeSelection(function () {
return onSelectionChange(100);
});
}, []);
/*
// 目前在 resize 开始/结束时会重新计算
// 所以暂时不需要去监听了
const resizeObserver = useRef(
new ResizeObserver(() => {
onSelectionChange();
}),
);
useEffect(() => {
engine.current.selection.onSelectionChange(() => {
const selectedNode = getSelectedNode(engine.current);
try {
setTimeout(() => {
resizeObserver.current.disconnect();
selectedNode &&
selectedNode.getDOMNode() &&
resizeObserver.current.observe(selectedNode.getDOMNode());
}, 50);
} catch (error) {
console.err(error);
}
});
}, []);
*/
var onDisabled = useCallback(function () {
setDisabled(true);
}, []);
var onEnabled = useCallback(function () {
setDisabled(false);
onSelectionChange(0);
}, [onSelectionChange]);
useEffect(function () {
var contentWindow = engine.current.project.simulator.contentWindow;
contentWindow.addEventListener('dividerDisable', onDisabled);
contentWindow.addEventListener('dividerEnable', onEnabled);
return function () {
contentWindow.removeEventListener('dividerDisable', onDisabled);
contentWindow.removeEventListener('dividerEnable', onEnabled);
};
}, [onDisabled, onEnabled]);
if (disabled) return null;
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Cut, {
pos: cuts.find(function (p) {
return p.dimension === 'v';
}),
split: props.split
}), /*#__PURE__*/React.createElement(Cut, {
pos: cuts.find(function (p) {
return p.dimension === 'h';
}),
split: props.split
}));
};
var Cut = function Cut(props) {
var _useState3 = useState(false),
showLine = _useState3[0],
setLineVisibility = _useState3[1];
var pos = props.pos,
split = props.split;
if (!pos || !pos.node) return null;
var objectRect = pos.node.getRect() || {};
var computeLineStyle = function computeLineStyle() {
if ((pos === null || pos === void 0 ? void 0 : pos.dimension) === 'v') {
return _extends({
width: 1,
height: objectRect.height,
transform: 'translate(-50%, 0)'
}, pos);
} else if ((pos === null || pos === void 0 ? void 0 : pos.dimension) === 'h') {
return _extends({
width: objectRect.width,
height: 1
}, pos);
} else if ((pos === null || pos === void 0 ? void 0 : pos.dimension) === 'm') {
return _extends({
width: objectRect.width,
height: objectRect.height,
transform: 'translate(-50%, 0)'
}, pos);
}
return null;
};
var computeCutStyle = function computeCutStyle() {
var isNanoSized = objectRect.width <= 60;
var getTransform = function getTransform() {
var gap = isNanoSized ? 0 : 8;
var scale = isNanoSized ? 'scale(.6)' : '';
switch (pos === null || pos === void 0 ? void 0 : pos.dimension) {
case 'v':
return "translate(-50%, " + gap + "px) " + scale;
case 'h':
return "translate(" + gap + "px, -50%) rotate(270deg) " + scale;
case 'm':
default:
return "translate(-50%, -50%) rotate(45deg) " + scale;
}
};
return _extends({}, pos, {
transform: getTransform()
});
};
var lineStyle = computeLineStyle() || {};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
className: FUSION_UI_VIEW_PREFIX + "-divider",
style: computeCutStyle(),
onMouseEnter: function onMouseEnter() {
return setLineVisibility(true);
},
onMouseLeave: function onMouseLeave() {
return setLineVisibility(false);
},
onClick: function onClick() {
split(pos.dimension, pos.node);
setTimeout(function () {
return setLineVisibility(false);
}, 20);
}
}, /*#__PURE__*/React.createElement("div", {
className: FUSION_UI_VIEW_PREFIX + "-dividerImg"
})), showLine && (pos.dimension === 'm' ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
className: FUSION_UI_VIEW_PREFIX + "-dividerLine",
style: _extends({}, lineStyle, {
height: 1
})
}), /*#__PURE__*/React.createElement("div", {
className: FUSION_UI_VIEW_PREFIX + "-dividerLine",
style: _extends({}, lineStyle, {
width: 1,
top: Number(lineStyle.top) - Number(lineStyle.height) / 2
})
})) : /*#__PURE__*/React.createElement("div", {
className: FUSION_UI_VIEW_PREFIX + "-dividerLine",
style: lineStyle
})));
};
// utils
var getSplitDimension = function getSplitDimension(componentName) {
var dimension = {
v: false,
h: false,
m: false
};
switch (componentName) {
case ROW:
case COL:
dimension.v = true;
dimension.h = true;
break;
case CELL:
dimension.v = true;
dimension.h = true;
// dimension.m = true;
break;
case TILE:
case BLOCK:
dimension.v = true;
break;
default:
break;
}
return dimension;
};
// FIXME:Project类型缺失
var getSelectedNode = function getSelectedNode(_ref) {
var _project$currentDocum2;
var project = _ref.project;
return (_project$currentDocum2 = project.currentDocument) === null || _project$currentDocum2 === void 0 ? void 0 : _project$currentDocum2.selection.getNodes()[0];
};
var getPageRootDOMNode = function getPageRootDOMNode() {
var _window$parent$AliLow, _window$parent$AliLow2;
return (_window$parent$AliLow = window.parent.AliLowCodeEngine.project.currentDocument) === null || _window$parent$AliLow === void 0 ? void 0 : (_window$parent$AliLow2 = _window$parent$AliLow.root) === null || _window$parent$AliLow2 === void 0 ? void 0 : _window$parent$AliLow2.getDOMNode();
};
var createDividerWrapperNode = function createDividerWrapperNode(dividerId) {
var node = document.createElement('div');
node.id = dividerId;
node.style.position = 'absolute';
node.style.top = '0';
node.style.left = '0';
node.style.zIndex = '10001';
return node;
};