UNPKG

@lonli-lokli/react-mosaic-component

Version:
129 lines (128 loc) 4.2 kB
// libs/react-mosaic-component/src/lib/MosaicRoot.tsx import { flatten } from "lodash-es"; import React from "react"; import { MosaicContext } from "./contextTypes.mjs"; import { Split } from "./Split.mjs"; import { boundingBoxAsStyles, emptyBoundingBox, splitBoundingBox } from "./util/BoundingBox.mjs"; import { convertLegacyToNary } from "./util/mosaicUtilities.mjs"; import { MosaicTabs } from "./MosaicTabs.mjs"; var MosaicRoot = class extends React.PureComponent { static contextType = MosaicContext; render() { const naryRoot = convertLegacyToNary(this.props.root); if (naryRoot === null) { return null; } return /* @__PURE__ */ React.createElement("div", { className: "mosaic-root" }, this.renderRecursively(naryRoot, emptyBoundingBox(), [])); } // The recursive renderer is now updated for the n-ary tree structure renderRecursively(node, boundingBox, path) { if (typeof node === "string" || typeof node === "number") { return /* @__PURE__ */ React.createElement( "div", { key: node, className: "mosaic-tile", style: { ...boundingBoxAsStyles(boundingBox) } }, this.props.renderTile(node, path) ); } switch (node.type) { // Case 2: Node is a split container case "split": { const { children, direction } = node; const splitPercentages = node.splitPercentages ?? children.map(() => 100 / children.length); const childBoxes = splitBoundingBox( boundingBox, splitPercentages, direction ); const renderedChildren = children.flatMap((child, index) => { const childPath = path.concat(index); const elements = [ this.renderRecursively(child, childBoxes[index], childPath) ]; if (index < children.length - 1) { elements.push(this.renderSplit(node, path, index, boundingBox)); } return elements; }); const flattenedElements = flatten(renderedChildren).filter(nonNullElement); return /* @__PURE__ */ React.createElement(React.Fragment, null, flattenedElements.map( (element, index) => React.cloneElement(element, { key: element.key || `${path.join("-")}-${index}` }) )); } // Case 3: Node is a tab container case "tabs": { return /* @__PURE__ */ React.createElement( MosaicTabs, { node, path, renderTile: this.props.renderTile, renderTabToolbar: this.props.renderTabToolbar, boundingBox, renderTabTitle: this.props.renderTabTitle, renderTabButton: this.props.renderTabButton, canClose: this.props.canClose } ); } default: console.error("Unknown mosaic node type:", node); return null; } } renderSplit(parentNode, path, splitIndex, boundingBox) { const { resize } = this.props; if (resize !== "DISABLED" && parentNode.children.length > 1) { const { direction } = parentNode; const splitPercentages = parentNode.splitPercentages ?? parentNode.children.map(() => 100 / parentNode.children.length); return /* @__PURE__ */ React.createElement( Split, { key: `split-${path.join("-")}-${splitIndex}`, ...resize, direction, boundingBox, splitIndex, splitPercentages, onChange: (percentages) => this.onResize(percentages, path, true), onRelease: (percentages) => this.onResize(percentages, path, false) } ); } else { return null; } } // onResize now handles an array of percentages onResize = (percentages, path, suppressOnRelease) => { this.context.mosaicActions.updateTree( [ { path, // Path to the parent MosaicSplitNode spec: { splitPercentages: { $set: percentages } } } ], { suppressOnRelease } ); }; }; function nonNullElement(x) { return x !== null; } export { MosaicRoot };