UNPKG

react-mosaic-component2

Version:
258 lines (256 loc) 11.9 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/MosaicWindow.tsx var MosaicWindow_exports = {}; __export(MosaicWindow_exports, { InternalMosaicWindow: () => InternalMosaicWindow, MosaicWindow: () => MosaicWindow }); module.exports = __toCommonJS(MosaicWindow_exports); var import_classnames = __toESM(require("classnames"), 1); var import_lodash_es = require("lodash-es"); var import_react = __toESM(require("react"), 1); var import_react_dnd = require("react-dnd"); var import_defaultToolbarControls = require("./buttons/defaultToolbarControls.cjs"); var import_Separator = require("./buttons/Separator.cjs"); var import_contextTypes = require("./contextTypes.cjs"); var import_internalTypes = require("./internalTypes.cjs"); var import_MosaicDropTarget = require("./MosaicDropTarget.cjs"); var import_types = require("./types.cjs"); var import_mosaicUpdates = require("./util/mosaicUpdates.cjs"); var import_mosaicUtilities = require("./util/mosaicUtilities.cjs"); var import_OptionalBlueprint = require("./util/OptionalBlueprint.cjs"); var InternalMosaicWindow = class extends import_react.default.Component { static defaultProps = { additionalControlButtonText: "More", draggable: true, renderPreview: ({ title }) => /* @__PURE__ */ import_react.default.createElement("div", { className: "mosaic-preview" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "mosaic-window-toolbar" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "mosaic-window-title" }, title)), /* @__PURE__ */ import_react.default.createElement("div", { className: "mosaic-window-body" }, /* @__PURE__ */ import_react.default.createElement("h4", null, title), /* @__PURE__ */ import_react.default.createElement(import_OptionalBlueprint.OptionalBlueprint.Icon, { className: "default-preview-icon", size: "large", icon: "APPLICATION" }))), renderToolbar: null }; static contextType = import_contextTypes.MosaicContext; state = { additionalControlsOpen: false }; rootElement = null; render() { const { className, isOver, renderPreview, additionalControls, connectDropTarget, connectDragPreview, draggedMosaicId, disableAdditionalControlsOverlay } = this.props; return /* @__PURE__ */ import_react.default.createElement(import_contextTypes.MosaicWindowContext.Provider, { value: this.childContext }, connectDropTarget( /* @__PURE__ */ import_react.default.createElement( "div", { className: (0, import_classnames.default)("mosaic-window mosaic-drop-target", className, { "drop-target-hover": isOver && draggedMosaicId === this.context.mosaicId, "additional-controls-open": this.state.additionalControlsOpen }), ref: (element) => { this.rootElement = element; } }, this.renderToolbar(), /* @__PURE__ */ import_react.default.createElement("div", { className: "mosaic-window-body" }, this.props.children), !disableAdditionalControlsOverlay && /* @__PURE__ */ import_react.default.createElement( "div", { className: "mosaic-window-body-overlay", onClick: () => { this.setAdditionalControlsOpen(false); } } ), /* @__PURE__ */ import_react.default.createElement("div", { className: "mosaic-window-additional-actions-bar" }, additionalControls), connectDragPreview(renderPreview(this.props)), /* @__PURE__ */ import_react.default.createElement("div", { className: "drop-target-container" }, (0, import_lodash_es.values)(import_internalTypes.MosaicDropTargetPosition).map(this.renderDropTarget)) ) )); } getToolbarControls() { const { toolbarControls, createNode } = this.props; if (toolbarControls) { return toolbarControls; } else if (createNode) { return import_defaultToolbarControls.DEFAULT_CONTROLS_WITH_CREATION; } else { return import_defaultToolbarControls.DEFAULT_CONTROLS_WITHOUT_CREATION; } } renderToolbar() { const { title, draggable, additionalControls, additionalControlButtonText, path, renderToolbar } = this.props; const { additionalControlsOpen } = this.state; const toolbarControls = this.getToolbarControls(); const draggableAndNotRoot = draggable && path.length > 0; const connectIfDraggable = draggableAndNotRoot ? this.props.connectDragSource : (el) => el; if (renderToolbar) { const connectedToolbar = connectIfDraggable(renderToolbar(this.props, draggable)); return /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)("mosaic-window-toolbar", { draggable: draggableAndNotRoot }) }, connectedToolbar); } const titleDiv = connectIfDraggable( /* @__PURE__ */ import_react.default.createElement("div", { title, className: "mosaic-window-title" }, title) ); const hasAdditionalControls = !(0, import_lodash_es.isEmpty)(additionalControls); return /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)("mosaic-window-toolbar", { draggable: draggableAndNotRoot }) }, titleDiv, /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)("mosaic-window-controls", import_OptionalBlueprint.OptionalBlueprint.getClasses("BUTTON_GROUP")) }, hasAdditionalControls && /* @__PURE__ */ import_react.default.createElement( "button", { onClick: () => this.setAdditionalControlsOpen(!additionalControlsOpen), className: (0, import_classnames.default)( import_OptionalBlueprint.OptionalBlueprint.getClasses(this.context.blueprintNamespace, "BUTTON", "MINIMAL"), import_OptionalBlueprint.OptionalBlueprint.getIconClass(this.context.blueprintNamespace, "MORE"), { [import_OptionalBlueprint.OptionalBlueprint.getClasses(this.context.blueprintNamespace, "ACTIVE")]: additionalControlsOpen } ) }, /* @__PURE__ */ import_react.default.createElement("span", { className: "control-text" }, additionalControlButtonText) ), hasAdditionalControls && /* @__PURE__ */ import_react.default.createElement(import_Separator.Separator, null), toolbarControls)); } renderDropTarget = (position) => { const { path } = this.props; return /* @__PURE__ */ import_react.default.createElement(import_MosaicDropTarget.MosaicDropTarget, { position, path, key: position }); }; checkCreateNode() { if (this.props.createNode == null) { throw new Error("Operation invalid unless `createNode` is defined"); } } split = (...args) => { this.checkCreateNode(); const { createNode, path } = this.props; const { mosaicActions } = this.context; const root = mosaicActions.getRoot(); const direction = this.rootElement.offsetWidth > this.rootElement.offsetHeight ? "row" : "column"; return Promise.resolve(createNode(...args)).then( (second) => mosaicActions.replaceWith(path, { direction, second, first: (0, import_mosaicUtilities.getAndAssertNodeAtPathExists)(root, path) }) ); }; swap = (...args) => { this.checkCreateNode(); const { mosaicActions } = this.context; const { createNode, path } = this.props; return Promise.resolve(createNode(...args)).then((node) => mosaicActions.replaceWith(path, node)); }; setAdditionalControlsOpen = (additionalControlsOpenOption) => { const additionalControlsOpen = additionalControlsOpenOption === "toggle" ? !this.state.additionalControlsOpen : additionalControlsOpenOption; this.setState({ additionalControlsOpen }); this.props.onAdditionalControlsToggle?.(additionalControlsOpen); }; getPath = () => this.props.path; connectDragSource = (connectedElements) => { const { connectDragSource } = this.props; return connectDragSource(connectedElements); }; childContext = { // @ts-ignore blueprintNamespace: this.context.blueprintNamespace, mosaicWindowActions: { split: this.split, replaceWithNew: this.swap, setAdditionalControlsOpen: this.setAdditionalControlsOpen, getPath: this.getPath, connectDragSource: this.connectDragSource } }; }; function ConnectedInternalMosaicWindow(props) { const { mosaicActions, mosaicId } = (0, import_react.useContext)(import_contextTypes.MosaicContext); const [, connectDragSource, connectDragPreview] = (0, import_react_dnd.useDrag)({ type: import_types.MosaicDragType.WINDOW, item: (_monitor) => { if (props.onDragStart) { props.onDragStart(); } const hideTimer = (0, import_lodash_es.defer)(() => mosaicActions.hide(props.path)); return { mosaicId, hideTimer }; }, end: (item, monitor) => { const { hideTimer } = item; window.clearTimeout(hideTimer); const ownPath = props.path; const dropResult = monitor.getDropResult() || {}; const { position, path: destinationPath } = dropResult; if (position != null && destinationPath != null && !(0, import_lodash_es.isEqual)(destinationPath, ownPath)) { mosaicActions.updateTree((0, import_mosaicUpdates.createDragToUpdates)(mosaicActions.getRoot(), ownPath, destinationPath, position)); if (props.onDragEnd) { props.onDragEnd("drop"); } } else { mosaicActions.updateTree([ { path: (0, import_lodash_es.dropRight)(ownPath), spec: { splitPercentage: { $set: void 0 } } } ]); if (props.onDragEnd) { props.onDragEnd("reset"); } } } }); const [{ isOver, draggedMosaicId }, connectDropTarget] = (0, import_react_dnd.useDrop)({ accept: import_types.MosaicDragType.WINDOW, collect: (monitor) => ({ isOver: monitor.isOver(), draggedMosaicId: monitor.getItem()?.mosaicId }) }); return /* @__PURE__ */ import_react.default.createElement( InternalMosaicWindow, { ...props, connectDragPreview, connectDragSource, connectDropTarget, isOver, draggedMosaicId } ); } var MosaicWindow = class extends import_react.default.PureComponent { render() { return /* @__PURE__ */ import_react.default.createElement(ConnectedInternalMosaicWindow, { ...this.props }); } };