@visactor/react-vtable
Version:
The react version of VTable
129 lines (124 loc) • 8.11 kB
JavaScript
import { DefaultAttribute, ReactAttributePlugin, application } from "@visactor/vtable/es/vrender";
import { calculateAnchorOfBounds, isFunction, isNil, isObject, isString, styleStringToObject } from "@visactor/vutils";
import { CUSTOM_CONTAINER_NAME } from "@visactor/vtable";
export class VTableReactAttributePlugin extends ReactAttributePlugin {
removeElement(id) {
super.removeElement(id), delete this.htmlMap[id];
}
renderGraphicHTML(graphic) {
var _a;
const {react: react} = graphic.attribute;
if (!react) return;
const stage = graphic.stage;
if (!stage) return;
const ReactDOM = stage.params.ReactDOM, {element: element} = react;
let {container: container} = react;
if (container && (container = checkFrozenContainer(graphic)), !element || !ReactDOM || !ReactDOM.createRoot && !ReactDOM.render) return;
const id = isNil(react.id) ? `${null !== (_a = graphic.id) && void 0 !== _a ? _a : graphic._uid}_react` : react.id;
if (this.htmlMap && this.htmlMap[id] && container && container !== this.htmlMap[id].container && this.removeElement(id),
this.htmlMap && this.htmlMap[id]) ReactDOM.createRoot ? this.htmlMap[id].root.render(element) : ReactDOM.render(element, this.htmlMap[id].wrapContainer); else {
const {wrapContainer: wrapContainer, nativeContainer: nativeContainer} = this.getWrapContainer(stage, container);
if (wrapContainer) if (this.htmlMap || (this.htmlMap = {}), ReactDOM.createRoot) {
const root = ReactDOM.createRoot(wrapContainer);
root.render(element), this.htmlMap[id] = {
root: root,
wrapContainer: wrapContainer,
nativeContainer: nativeContainer,
container: container,
renderId: this.renderId,
graphic: graphic
};
} else ReactDOM.render(element, wrapContainer), this.htmlMap[id] = {
wrapContainer: wrapContainer,
nativeContainer: nativeContainer,
container: container,
renderId: this.renderId,
unmount: () => {
ReactDOM.unmountComponentAtNode(wrapContainer);
},
graphic: graphic
};
}
if (!this.htmlMap || !this.htmlMap[id]) return;
const {wrapContainer: wrapContainer, nativeContainer: nativeContainer} = this.htmlMap[id];
this.updateStyleOfWrapContainer(graphic, stage, wrapContainer, nativeContainer, react),
this.htmlMap[id].renderId = this.renderId;
}
getWrapContainer(stage, userContainer, domParams) {
let nativeContainer;
return nativeContainer = userContainer ? "string" == typeof userContainer ? application.global.getElementById(userContainer) : userContainer : stage.window.getContainer(),
{
wrapContainer: application.global.createDom(Object.assign({
tagName: "div",
parent: nativeContainer
}, domParams)),
nativeContainer: nativeContainer
};
}
updateStyleOfWrapContainer(graphic, stage, wrapContainer, nativeContainer, options) {
const {pointerEvents: pointerEvents, penetrateEventList: penetrateEventList = []} = options;
let calculateStyle = this.parseDefaultStyleFromGraphic(graphic);
calculateStyle.display = !1 !== graphic.attribute.visible ? "block" : "none", calculateStyle.pointerEvents = !0 === pointerEvents ? "all" : pointerEvents || "none",
"none" !== calculateStyle.pointerEvents && (this.removeWrapContainerEventListener(wrapContainer),
penetrateEventList.forEach((event => {
"wheel" === event && (wrapContainer.addEventListener("wheel", this.onWheel), wrapContainer.addEventListener("wheel", (e => {
e.preventDefault();
}), !0));
}))), wrapContainer.style.position || (wrapContainer.style.position = "absolute");
let left = 0, top = 0;
const b = graphic.globalAABBBounds;
let anchorType = options.anchorType;
if (isNil(anchorType) && (anchorType = "text" === graphic.type ? "position" : "boundsLeftTop"),
"boundsLeftTop" === anchorType && (anchorType = "top-left"), "position" === anchorType || b.empty()) {
const matrix = graphic.globalTransMatrix;
left = matrix.e, top = matrix.f;
} else {
const anchor = calculateAnchorOfBounds(b, anchorType);
left = anchor.x, top = anchor.y;
}
const containerTL = application.global.getElementTopLeft(nativeContainer, !1), windowTL = stage.window.getTopLeft(!1), offsetX = left + windowTL.left - containerTL.left, offsetTop = top + windowTL.top - containerTL.top;
if (calculateStyle.left = `${offsetX}px`, calculateStyle.top = `${offsetTop}px`,
"text" === graphic.type && "position" === anchorType && (calculateStyle = Object.assign(Object.assign({}, calculateStyle), this.getTransformOfText(graphic))),
isFunction(options.style)) {
const userStyle = options.style({
top: offsetTop,
left: offsetX,
width: b.width(),
height: b.height()
}, graphic, wrapContainer);
userStyle && (calculateStyle = Object.assign(Object.assign({}, calculateStyle), userStyle));
} else isObject(options.style) ? calculateStyle = Object.assign(Object.assign({}, calculateStyle), options.style) : isString(options.style) && options.style && (calculateStyle = Object.assign(Object.assign({}, calculateStyle), styleStringToObject(options.style)));
application.global.updateDom(wrapContainer, {
width: options.width,
height: options.height,
style: calculateStyle,
graphic: graphic
});
}
drawHTML() {
var _a;
"browser" === (null === (_a = null == application ? void 0 : application.global) || void 0 === _a ? void 0 : _a.env) && (this.pluginService.stage.children.sort(((a, b) => {
var _a, _b;
return (null !== (_a = a.attribute.zIndex) && void 0 !== _a ? _a : DefaultAttribute.zIndex) - (null !== (_b = b.attribute.zIndex) && void 0 !== _b ? _b : DefaultAttribute.zIndex);
})).forEach((group => {
this.renderGroupHTML(group);
})), this.clearCacheContainer());
}
}
function checkFrozenContainer(graphic) {
const targetGroup = getTargetGroup(graphic);
if (!targetGroup) return null;
const {col: col, row: row, stage: stage} = targetGroup;
let {container: container} = graphic.attribute.react;
const {table: table} = stage;
return container === table.bodyDomContainer && col < table.frozenColCount && row >= table.rowCount - table.bottomFrozenRowCount ? container = table.bottomFrozenBodyDomContainer : container === table.bodyDomContainer && col >= table.colCount - table.rightFrozenColCount && row >= table.rowCount - table.bottomFrozenRowCount ? container = table.rightFrozenBottomDomContainer : container === table.bodyDomContainer && row >= table.rowCount - table.bottomFrozenRowCount ? container = table.bottomFrozenBodyDomContainer : container === table.bodyDomContainer && col < table.frozenColCount ? container = table.frozenBodyDomContainer : container === table.bodyDomContainer && col >= table.colCount - table.rightFrozenColCount ? container = table.rightFrozenBodyDomContainer : container === table.headerDomContainer && col < table.frozenColCount ? container = table.frozenHeaderDomContainer : container === table.headerDomContainer && col >= table.colCount - table.rightFrozenColCount && (container = table.rightFrozenHeaderDomContainer),
container;
}
function getTargetGroup(target) {
for (;target && target.parent; ) {
if (target.name === CUSTOM_CONTAINER_NAME) return target;
target = target.parent;
}
return null;
}
//# sourceMappingURL=vtable-react-attribute-plugin.js.map