UNPKG

@logicflow/react-node-registry

Version:

LogicFlow React Shape

194 lines 7.85 kB
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 __()); }; })(); import { createElement } from 'react'; import { createRoot } from 'react-dom/client'; import { HtmlNode } from '@logicflow/core'; import { throttle, round, get, isFunction, isArray, clamp, isNumber, } from 'lodash-es'; import { Wrapper } from './wrapper'; import { Portal } from './portal'; import { createPortal } from 'react-dom'; var ReactNodeView = /** @class */ (function (_super) { __extends(ReactNodeView, _super); function ReactNodeView() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.__throttledUpdate = throttle(function () { return _this.measureAndUpdate(); }, 80); _this.measureAndUpdate = function () { try { var root = _this.containerEl; if (!root) return; var target = root.firstElementChild || root; var rect = target.getBoundingClientRect(); var width = round(rect.width); var height = round(rect.height); if (width <= 0 || height <= 0) return; if (width === _this.__lastWidth && height === _this.__lastHeight) return; _this.__lastWidth = width; _this.__lastHeight = height; var props = _this.props.model.properties; var extra = get(props, '_showTitle') ? isNumber(get(props, '_titleHeight')) ? get(props, '_titleHeight') : 28 : 0; var baseHeight = clamp(height - extra, 1, Number.MAX_SAFE_INTEGER); _this.props.model.setProperties({ width: width, height: baseHeight }); } catch (err) { console.error('measureAndUpdate error', err); } }; return _this; // TODO: 确认是否需要重写 onMouseDown 方法 // handleMouseDown(ev: MouseEvent, x: number, y: number) { // const target = ev.target as Element // const tagName = target.tagName.toLowerCase() // if (tagName === 'input') { // const type = target.getAttribute('type') // if ( // type == null || // [ // 'text', // 'password', // 'number', // 'email', // 'search', // 'tel', // 'url', // ].includes(type) // ) { // return // } // } // // console.log('pointer position, x:', x, 'y: ', y) // // TODO // // super.handleMouseDown(ev) // } } ReactNodeView.prototype.targetId = function () { return "".concat(this.props.graphModel.flowId, ":").concat(this.props.model.id); }; ReactNodeView.prototype.componentWillUnmount = function () { _super.prototype.componentWillUnmount.call(this); this.unmount(); }; ReactNodeView.prototype.setHtml = function (rootEl) { var existed = rootEl.querySelector('.custom-react-node-content'); if (existed) { this.containerEl = existed; } else { var el = document.createElement('div'); el.className = 'custom-react-node-content'; this.containerEl = el; this.renderReactComponent(el); rootEl.appendChild(el); } this.startResizeObserver(); }; // confirmUpdate(_rootEl: SVGForeignObjectElement) { // // TODO: 如有需要,可以先通过继承的方式,自定义该节点的更新逻辑;我们后续会根据实际需求,丰富该功能 // console.log('_rootEl', _rootEl) // } ReactNodeView.prototype.renderReactComponent = function (container) { this.unmountReactComponent(); var _a = this.props, model = _a.model, graphModel = _a.graphModel; if (container) { // 基于自定义节点新建 React 元素 var elem = createElement(Wrapper, { node: model, graph: graphModel, }); if (Portal.isActive()) { // 使用 Portal var portal = createPortal(elem, container, model.id); Portal.connect(this.targetId(), portal); } else { // 创建 Root 元素 this.root = createRoot(container); this.root.render(elem); } } }; ReactNodeView.prototype.unmountReactComponent = function () { if (this.rootEl && this.root) { this.stopResizeObserver(); this.root.unmount(); this.root = undefined; this.rootEl.innerHTML = ''; } }; // DONE: 是否需要 unmount 或 destroy 方法,在销毁后做一些处理 ReactNodeView.prototype.unmount = function () { this.unmountReactComponent(); }; ReactNodeView.prototype.startResizeObserver = function () { var _this = this; var _a; var root = this.containerEl; if (!root) return; try { if (isFunction(window.ResizeObserver)) { this.__resizeObserver = new window.ResizeObserver(function (entries) { if (!isArray(entries) || !entries.length) return; if (_this.__resizeRafId) cancelAnimationFrame(_this.__resizeRafId); _this.__resizeRafId = requestAnimationFrame(_this.__throttledUpdate); }); var target = root.firstElementChild || root; (_a = this.__resizeObserver) === null || _a === void 0 ? void 0 : _a.observe(target); } else { window.addEventListener('resize', function () { return _this.__throttledUpdate(); }); this.__fallbackUnlisten = function () { return window.removeEventListener('resize', function () { return _this.__throttledUpdate(); }); }; } } catch (err) { console.error('startResizeObserver error', err); } }; ReactNodeView.prototype.stopResizeObserver = function () { try { if (this.__resizeObserver) { this.__resizeObserver.disconnect(); this.__resizeObserver = undefined; } if (this.__resizeRafId) { cancelAnimationFrame(this.__resizeRafId); this.__resizeRafId = undefined; } if (this.__fallbackUnlisten) { this.__fallbackUnlisten(); this.__fallbackUnlisten = undefined; } } catch (err) { console.error('stopResizeObserver error', err); } }; return ReactNodeView; }(HtmlNode)); export { ReactNodeView }; export default ReactNodeView; //# sourceMappingURL=view.js.map