@gravity-ui/graph
Version:
Modern graph editor component
58 lines (57 loc) • 2.11 kB
JavaScript
import React from "react";
import { createPortal } from "react-dom";
import { Layer } from "../../services/Layer";
import { parseClassNames } from "../../utils/functions";
import { BlocksList } from "../BlocksList";
export class ReactLayer extends Layer {
constructor(props) {
super({
html: {
zIndex: 3,
classNames: ["no-user-select"],
transformByCameraPosition: true,
},
...props,
});
}
afterInit() {
super.afterInit();
this.applyBlockListClassName(undefined, this.props.blockListClassName);
}
propsChanged(nextProps) {
if (this.props.blockListClassName !== nextProps.blockListClassName) {
this.applyBlockListClassName(this.props.blockListClassName, nextProps.blockListClassName);
}
super.propsChanged(nextProps);
}
applyBlockListClassName(oldClassName, newClassName) {
const htmlElement = this.getHTML();
if (!htmlElement)
return;
// Remove previous blockListClassName classes if they exist
if (oldClassName) {
const oldClasses = parseClassNames(oldClassName);
htmlElement.classList.remove(...oldClasses);
}
// Add new blockListClassName classes if they exist
// If newClassName is provided (even if undefined), use it instead of this.props.blockListClassName
if (newClassName) {
const newClasses = parseClassNames(newClassName);
htmlElement.classList.add(...newClasses);
}
}
/**
* Renders React components inside the layer's HTML element using React Portal
* @param renderBlock Function to render a block component
* @returns React Portal with BlocksList component
*/
renderPortal(renderBlock) {
if (!this.getHTML()) {
return null;
}
return createPortal(React.createElement(BlocksList, {
graphObject: this.context.graph,
renderBlock: renderBlock,
}), this.getHTML(), "graph-blocks-list");
}
}