UNPKG

@lonli-lokli/react-mosaic-component

Version:
189 lines (187 loc) 6.87 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); // libs/react-mosaic-component/src/lib/Split.tsx var Split_exports = {}; __export(Split_exports, { Split: () => Split }); module.exports = __toCommonJS(Split_exports); var import_classnames = __toESM(require("classnames"), 1); var import_lodash_es = require("lodash-es"); var import_lodash_es2 = require("lodash-es"); var import_react = __toESM(require("react"), 1); var import_BoundingBox = require("./util/BoundingBox.cjs"); var RESIZE_THROTTLE_MS = 1e3 / 30; var TOUCH_EVENT_OPTIONS = { capture: true, passive: false }; var Split = class extends import_react.default.PureComponent { rootElement = import_react.default.createRef(); listenersBound = false; static defaultProps = { onChange: () => void 0, onRelease: () => void 0, minimumPaneSizePercentage: 10 // Updated default }; render() { const { direction } = this.props; return /* @__PURE__ */ import_react.default.createElement( "div", { className: (0, import_classnames.default)("mosaic-split", { "-row": direction === "row", "-column": direction === "column" }), ref: this.rootElement, onMouseDown: this.onMouseDown, style: this.computeStyle() }, /* @__PURE__ */ import_react.default.createElement("div", { className: "mosaic-split-line" }) ); } componentDidMount() { this.rootElement.current.addEventListener( "touchstart", this.onMouseDown, TOUCH_EVENT_OPTIONS ); } componentWillUnmount() { this.unbindListeners(); if (this.rootElement.current) { this.rootElement.current.ownerDocument.removeEventListener( "touchstart", this.onMouseDown, TOUCH_EVENT_OPTIONS ); } } computeStyle() { const { boundingBox, direction, splitPercentages, splitIndex } = this.props; const relativeSplitterPosition = (0, import_lodash_es.sum)( splitPercentages.slice(0, splitIndex + 1) ); const absolutePercentage = (0, import_BoundingBox.getAbsoluteSplitPercentage)( boundingBox, relativeSplitterPosition, direction ); const positionStyle = direction === "column" ? "top" : "left"; return { ...(0, import_BoundingBox.boundingBoxAsStyles)(boundingBox), [positionStyle]: `${absolutePercentage}%` }; } onMouseDown = (event) => { if (!isTouchEvent(event) && event.button !== 0) return; event.preventDefault(); this.bindListeners(); }; onMouseUp = (event) => { this.unbindListeners(); const newPercentages = this.calculateNewPercentages(event); this.props.onRelease(newPercentages); }; onMouseMove = (event) => { event.preventDefault(); this.throttledUpdatePercentage(event); }; throttledUpdatePercentage = (0, import_lodash_es2.throttle)( (event) => { const newPercentages = this.calculateNewPercentages(event); this.props.onChange(newPercentages); }, RESIZE_THROTTLE_MS ); calculateNewPercentages(event) { const { minimumPaneSizePercentage, direction, boundingBox, splitPercentages, splitIndex } = this.props; const parentBBox = this.rootElement.current.parentElement.getBoundingClientRect(); const location = isTouchEvent(event) ? event.changedTouches[0] : event; let mouseAbsolutePercentage; if (direction === "column") { mouseAbsolutePercentage = (location.clientY - parentBBox.top) / parentBBox.height * 100; } else { mouseAbsolutePercentage = (location.clientX - parentBBox.left) / parentBBox.width * 100; } const mouseRelativePercentage = (0, import_BoundingBox.getRelativeSplitPercentage)( boundingBox, mouseAbsolutePercentage, direction ); const startPercentage = (0, import_lodash_es.sum)(splitPercentages.slice(0, splitIndex)); const totalSizeOfPanes = splitPercentages[splitIndex] + splitPercentages[splitIndex + 1]; let newLeftPaneSize = mouseRelativePercentage - startPercentage; newLeftPaneSize = (0, import_lodash_es.clamp)( newLeftPaneSize, minimumPaneSizePercentage, totalSizeOfPanes - minimumPaneSizePercentage ); const newRightPaneSize = totalSizeOfPanes - newLeftPaneSize; const newSplitPercentages = [...splitPercentages]; newSplitPercentages[splitIndex] = newLeftPaneSize; newSplitPercentages[splitIndex + 1] = newRightPaneSize; return newSplitPercentages; } // These bindings can remain as they were bindListeners() { if (!this.listenersBound) { const doc = this.rootElement.current.ownerDocument; doc.addEventListener("mousemove", this.onMouseMove, true); doc.addEventListener("touchmove", this.onMouseMove, TOUCH_EVENT_OPTIONS); doc.addEventListener("mouseup", this.onMouseUp, true); doc.addEventListener("touchend", this.onMouseUp, true); this.listenersBound = true; } } unbindListeners() { if (this.listenersBound && this.rootElement.current) { const doc = this.rootElement.current.ownerDocument; doc.removeEventListener("mousemove", this.onMouseMove, true); doc.removeEventListener( "touchmove", this.onMouseMove, TOUCH_EVENT_OPTIONS ); doc.removeEventListener("mouseup", this.onMouseUp, true); doc.removeEventListener("touchend", this.onMouseUp, true); this.listenersBound = false; } } }; function isTouchEvent(event) { return event.changedTouches != null; }