UNPKG

@logicflow/extension

Version:
298 lines (297 loc) 15.2 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Label = void 0; var jsx_runtime_1 = require("preact/jsx-runtime"); var core_1 = require("@logicflow/core"); var classnames_1 = __importDefault(require("classnames")); var lodash_es_1 = require("lodash-es"); var Label = /** @class */ (function (_super) { __extends(Label, _super); function Label(props) { var _this = _super.call(this, props) || this; _this.textRef = (0, core_1.createRef)(); _this.setHoverOn = function () { var element = _this.props.element; if (element.isDragging || _this.state.isHovered) return; // 当节点或边在拖拽中时,不触发 hover 态 _this.setState({ isHovered: true }); element.setHovered(true); }; _this.setHoverOff = function () { var element = _this.props.element; if (!_this.state.isHovered) return; _this.setState({ isHovered: false }); element.setHovered(false); }; _this.handleMouseDown = function (e) { var _a; var _b = _this.props, label = _b.label, graphModel = _b.graphModel; var nodeTextDraggable = graphModel.editConfigModel.nodeTextDraggable; // 当 label 允许拖拽 且不处于拖拽状态、不处于编辑状态时, StepDrag 开启拖拽 if (((_a = label.draggable) !== null && _a !== void 0 ? _a : nodeTextDraggable) && !_this.state.isDragging && !_this.state.isEditing) { _this.stepDrag.handleMouseDown(e); } }; _this.handleMouseUp = function (e) { if (_this.state.isDragging) { _this.stepDrag.handleMouseUp(e); } }; _this.handleDragging = function (_a) { var deltaX = _a.deltaX, deltaY = _a.deltaY; if (!_this.state.isDragging) { _this.setState({ isDragging: true }); } var _b = _this.props, label = _b.label, graphModel = _b.graphModel; // DONE: 添加缩放时拖拽的逻辑,对 deltaX 和 deltaY 进行按比例缩放 var transformModel = graphModel.transformModel; var _c = __read(transformModel.fixDeltaXY(deltaX, deltaY), 2), curDeltaX = _c[0], curDeltaY = _c[1]; _this.setElementModelLabelInfo({ x: label.x + curDeltaX, y: label.y + curDeltaY, }); graphModel.eventCenter.emit('label:drag', { data: label.getData(), model: label, }); }; _this.handleDragEnd = function () { _this.setState({ isDragging: false }); }; _this.handleClick = function (e) { var _a = _this.props, label = _a.label, element = _a.element, graphModel = _a.graphModel; // 更新当前Label选中状态 element.setSelected(!_this.state.isSelected); _this.setState({ isSelected: !_this.state.isSelected }); _this.setElementModelLabelInfo({ isSelected: true, }); graphModel.eventCenter.emit('label:click', { data: label.getData(), e: e, model: element, }); }; _this.handleDbClick = function (e) { var _a = _this.props, label = _a.label, element = _a.element, graphModel = _a.graphModel; graphModel.eventCenter.emit('label:dblclick', { data: label.getData(), e: e, model: element, }); if (!label.editable) { element.setSelected(true); return; } element.setSelected(); element.setElementState(core_1.ElementState.TEXT_EDIT); _this.setState({ isEditing: true }); // DONE: 触发当前 label 的 focus 事件,设置内容可编辑,且在文本最后添加光标 if (_this.textRef.current) { _this.textRef.current.contentEditable = 'true'; _this.textRef.current.focus(); var range = document.createRange(); var selection = window.getSelection(); range.selectNodeContents(_this.textRef.current); range.collapse(false); selection === null || selection === void 0 ? void 0 : selection.removeAllRanges(); selection === null || selection === void 0 ? void 0 : selection.addRange(range); } }; _this.handleBlur = function (e) { var _a = _this.props, label = _a.label, element = _a.element, eventCenter = _a.graphModel.eventCenter; // DONE: 触发 LABEL:BLUR 事件,并抛出相关的事件 eventCenter.emit('label:blur', { e: e, model: element, data: label.getData(), element: _this.textRef.current, }); _this.setState({ isDragging: false, isHovered: false, isSelected: false, }); }; _this.handleInput = function (e) { var _a = _this.props, label = _a.label, graphModel = _a.graphModel; graphModel.eventCenter.emit('label:input', { e: e, data: label.getData(), }); }; // 重新计算 Label 大小 _this.reCalcLabelSize = function () { }; var label = props.label, _a = props.graphModel, gridSize = _a.gridSize, eventCenter = _a.eventCenter; _this.stepDrag = new core_1.StepDrag({ onDragging: _this.handleDragging, onDragEnd: _this.handleDragEnd, step: gridSize, eventType: 'LABEL', model: label, eventCenter: eventCenter, }); _this.state = { isEditing: false, isHovered: false, isDragging: false, isSelected: false, }; return _this; } Label.prototype.setElementModelLabelInfo = function (data) { var _a = this.props, label = _a.label, element = _a.element, graphModel = _a.graphModel; var _label = element.properties._label; var elementLabel = _label; var idx = (0, lodash_es_1.findIndex)(elementLabel, function (cur) { return cur.id === label.id; }); var target = elementLabel[idx]; elementLabel[idx] = __assign(__assign({}, target), data); var targetElem = graphModel.getElement(element.id); targetElem === null || targetElem === void 0 ? void 0 : targetElem.setProperty('_label', elementLabel); }; // TODO:如何处理 Label zIndex 的问题, Label 永远会比节点层级高 // 当 Label 被元素遮盖时,隐藏它 Label.prototype.componentDidMount = function () { var _this = this; var _a = this.props, label = _a.label, element = _a.element, graphModel = _a.graphModel; // 在点击元素、边或者画布 时,结束 Label 的编辑态 graphModel.eventCenter.on('blank:click,node:click,edge:click,label:click', function (_a) { var _b, _c, _d, _e; var data = _a.data; // 点击的不是label 、点击的不是当前label、点击的是当前label,且当前 label 处于选中态 // 则取消选中态 if ((data === null || data === void 0 ? void 0 : data.type) !== 'label' || (data.type === 'label' && data.id !== label.id) || _this.state.isSelected) { _this.setState({ isSelected: false }); } // 点击的不是label 、点击的不是当前label、点击的是当前label,且当前 label 处于编辑态 // 则结束编辑态 if (((data === null || data === void 0 ? void 0 : data.type) !== 'label' || (data.type == 'label' && data.id !== label.id)) && _this.state.isEditing) { _this.setState({ isEditing: false }); var value = (_c = (_b = _this.textRef.current) === null || _b === void 0 ? void 0 : _b.innerText) !== null && _c !== void 0 ? _c : ''; var content = (_e = (_d = _this.textRef.current) === null || _d === void 0 ? void 0 : _d.innerHTML) !== null && _e !== void 0 ? _e : ''; _this.setElementModelLabelInfo({ value: value, content: content, isSelected: false, }); element.setElementState(core_1.ElementState.DEFAULT); } // 点击的不是label 、点击的不是当前label、点击的是当前label,且当前 label 的文本DOM存在 // 则结束文本DOM的编辑态 if (((data === null || data === void 0 ? void 0 : data.type) !== 'label' || (data.type == 'label' && data.id !== label.id)) && _this.textRef.current) { _this.textRef.current.contentEditable = 'false'; } }); // TODO: 节点拖拽结束后,更新 Label 的位置 // eventCenter.on('node:drag', () => {}) // eventCenter.on('node:drop', () => {}) // eventCenter.on('node:mousemove', () => {}) // // eventCenter.on('node:properties-change,node:properties-delete', () => {}) }; Label.prototype.componentDidUpdate = function () { // snapshot: any, // previousState: Readonly<ILabelState>, // previousProps: Readonly<ILabelProps>, // console.log('Label componentDidUpdate') // console.log('previousProps', previousProps) // console.log('previousState', previousState) // console.log('snapshot', snapshot) }; Label.prototype.componentWillUnmount = function () { var graphModel = this.props.graphModel; graphModel.eventCenter.off('blank:click,node:click,edge:click'); }; // TODO: 当某一个标签更新时,如何避免其它标签的更新 // shouldComponentUpdate or memo Label.prototype.render = function () { var _a; var _b = this.props, label = _b.label, element = _b.element, graphModel = _b.graphModel; var _c = this.state, isDragging = _c.isDragging, isHovered = _c.isHovered, isSelected = _c.isSelected, isEditing = _c.isEditing; var transformModel = graphModel.transformModel; var transform = transformModel.getTransformStyle().transform; var id = label.id, x = label.x, y = label.y, zIndex = label.zIndex, vertical = label.vertical, style = label.style, rotate = label.rotate, content = label.content, labelWidth = label.labelWidth, textOverflowMode = label.textOverflowMode; var maxLabelWidth = labelWidth !== null && labelWidth !== void 0 ? labelWidth : (element.BaseType === 'node' ? element.width - 20 : 80); var containerStyle = { left: "".concat(x - maxLabelWidth / 2, "px"), top: "".concat(y - 10, "px"), width: "".concat(maxLabelWidth, "px"), height: '20px', zIndex: zIndex !== null && zIndex !== void 0 ? zIndex : 1, transform: rotate ? "".concat(transform, " rotate(").concat(rotate, "deg)") : "".concat(transform, " rotate(").concat(vertical ? -0.25 : 0, "turn)"), }; return ((0, jsx_runtime_1.jsx)("div", { id: "element-container-".concat(id), className: (0, classnames_1.default)('lf-label-editor-container'), style: containerStyle, onMouseDown: this.handleMouseDown, onMouseUp: this.handleMouseUp, onClick: this.handleClick, onDblClick: this.handleDbClick, onBlur: this.handleBlur, onMouseEnter: this.setHoverOn, onMouseOver: this.setHoverOn, onMouseLeave: this.setHoverOff, children: (0, jsx_runtime_1.jsx)("div", { ref: this.textRef, id: "editor-container-".concat(id), className: (0, classnames_1.default)('lf-label-editor', (_a = { 'lf-label-editor-dragging': isDragging, 'lf-label-editor-editing': isEditing, 'lf-label-editor-hover': !isEditing && (isHovered || isSelected) }, _a["lf-label-editor-".concat(textOverflowMode)] = !isEditing, _a)), onInput: this.handleInput, style: __assign({ maxWidth: "".concat(maxLabelWidth, "px"), boxSizing: 'border-box', display: 'inline-block', background: isEditing || element.BaseType === 'edge' ? '#fff' : 'transparent' }, style), dangerouslySetInnerHTML: { __html: content } }) })); }; Label = __decorate([ core_1.observer ], Label); return Label; }(core_1.Component)); exports.Label = Label; exports.default = Label;