@logicflow/react-node-registry
Version:
LogicFlow React Shape
194 lines • 7.85 kB
JavaScript
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