UNPKG

mui-extended

Version:

Extended UI Components built on Material UI

269 lines (268 loc) 12 kB
import { __assign, __extends } from "tslib"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { Box } from "@mui/material"; import { Children, Component } from "react"; import { Pane } from "./Pane"; import { Resizer } from "./Resizer"; var unFocus = function (window) { if (window.document.getSelection) { window.document.getSelection().empty(); } else { try { window.getSelection().removeAllRanges(); // eslint-disable-next-line no-empty } catch (e) { } } }; function getDefaultSize(defaultSize, minSize, maxSize, draggedSize) { if (typeof draggedSize === "number") { var min = typeof minSize === "number" ? minSize : 0; var max = typeof maxSize === "number" && maxSize >= 0 ? maxSize : Infinity; return Math.max(min, Math.min(max, draggedSize)); } if (defaultSize !== undefined) { return defaultSize; } return minSize; } function removeNullChildren(children) { return Children.toArray(children).filter(function (c) { return c; }); } /** * This component is rendered in `absolute` position stretching 100% height and width of the parent `relative` element */ var SplitPane = /** @class */ (function (_super) { __extends(SplitPane, _super); function SplitPane(props) { var _this = _super.call(this, props) || this; _this.onMouseDown = _this.onMouseDown.bind(_this); _this.onTouchStart = _this.onTouchStart.bind(_this); _this.onMouseMove = _this.onMouseMove.bind(_this); _this.onTouchMove = _this.onTouchMove.bind(_this); _this.onMouseUp = _this.onMouseUp.bind(_this); // order of setting panel sizes. // 1. size // 2. getDefaultSize(defaultSize, minsize, maxSize) var size = props.size, defaultSize = props.defaultSize, minSize = props.minSize, maxSize = props.maxSize; var initialSize = size !== undefined ? size : getDefaultSize(defaultSize, minSize, maxSize, null); _this.state = { active: false, resized: false, primaryPaneSize: initialSize, // these are props that are needed in static functions. ie: gDSFP instanceProps: { size: size } }; return _this; } SplitPane.prototype.componentDidMount = function () { document.addEventListener("mouseup", this.onMouseUp); document.addEventListener("mousemove", this.onMouseMove); document.addEventListener("touchmove", this.onTouchMove); this.setState(SplitPane.getSizeUpdate(this.props, this.state)); }; SplitPane.getDerivedStateFromProps = function (nextProps, prevState) { return SplitPane.getSizeUpdate(nextProps, prevState); }; SplitPane.prototype.componentWillUnmount = function () { document.removeEventListener("mouseup", this.onMouseUp); document.removeEventListener("mousemove", this.onMouseMove); document.removeEventListener("touchmove", this.onTouchMove); }; SplitPane.prototype.onMouseDown = function (event) { var eventWithTouches = Object.assign({}, event, { touches: [{ clientX: event.clientX, clientY: event.clientY }] }); this.onTouchStart(eventWithTouches); }; SplitPane.prototype.onTouchStart = function (event) { var _a = this.props, allowResize = _a.allowResize, onDragStarted = _a.onDragStarted, split = _a.split; if (allowResize) { unFocus(window); var position = split === "vertical" ? event.touches[0].clientX : event.touches[0].clientY; if (typeof onDragStarted === "function") { onDragStarted(); } this.setState({ active: true, position: position }); } }; SplitPane.prototype.onMouseMove = function (event) { var eventWithTouches = Object.assign({}, event, { touches: [{ clientX: event.clientX, clientY: event.clientY }] }); this.onTouchMove(eventWithTouches); }; SplitPane.prototype.onTouchMove = function (event) { var _a = this.props, allowResize = _a.allowResize, maxSize = _a.maxSize, minSize = _a.minSize, onChange = _a.onChange, split = _a.split, step = _a.step; var _b = this.state, active = _b.active, position = _b.position; if (allowResize && active) { unFocus(window); var isPrimaryFirst = this.props.primary === "first"; var ref = isPrimaryFirst ? this.pane1 : this.pane2; var ref2 = isPrimaryFirst ? this.pane2 : this.pane1; if (ref) { var node = ref; var node2 = ref2; if (node.getBoundingClientRect) { var width = node.getBoundingClientRect().width; var height = node.getBoundingClientRect().height; var current = split === "vertical" ? event.touches[0].clientX : event.touches[0].clientY; var size = split === "vertical" ? width : height; var positionDelta = position - current; if (step) { if (Math.abs(positionDelta) < step) { return; } // Integer division // eslint-disable-next-line no-bitwise positionDelta = ~~(positionDelta / step) * step; } var sizeDelta = isPrimaryFirst ? positionDelta : -positionDelta; var pane1Order = parseInt(window.getComputedStyle(node).order); var pane2Order = parseInt(window.getComputedStyle(node2).order); if (pane1Order > pane2Order) { sizeDelta = -sizeDelta; } var newMaxSize = maxSize; if (maxSize !== undefined && maxSize <= 0) { var splitPane = this.splitPane; if (split === "vertical") { newMaxSize = splitPane.getBoundingClientRect().width + maxSize; } else { newMaxSize = splitPane.getBoundingClientRect().height + maxSize; } } var newSize = size - sizeDelta; var newPosition = position - positionDelta; if (newSize < minSize) { newSize = minSize; } else if (maxSize !== undefined && newSize > newMaxSize) { newSize = newMaxSize; } else { this.setState({ position: newPosition, resized: true }); } if (onChange) onChange(newSize); this.setState({ draggedSize: newSize, primaryPaneSize: newSize }); } } } }; SplitPane.prototype.onMouseUp = function () { var _a = this.props, allowResize = _a.allowResize, onDragFinished = _a.onDragFinished; var _b = this.state, active = _b.active, draggedSize = _b.draggedSize; if (allowResize && active) { if (typeof onDragFinished === "function") { onDragFinished(draggedSize); } this.setState({ active: false }); } }; // we have to check values since gDSFP is called on every render and more in StrictMode SplitPane.getSizeUpdate = function (props, state) { var newState = {}; var instanceProps = state.instanceProps; if (instanceProps.size === props.size && props.size !== undefined) { return {}; } var newSize = props.size !== undefined ? props.size : getDefaultSize(props.defaultSize, props.minSize, props.maxSize, state.draggedSize); if (props.size !== undefined) { newState.draggedSize = newSize; } newState.primaryPaneSize = newSize; newState.instanceProps = { size: props.size }; return newState; }; SplitPane.prototype.render = function () { var _this = this; var _a = this.props, split = _a.split, onResizerClick = _a.onResizerClick, onResizerDoubleClick = _a.onResizerDoubleClick, sx = _a.sx, resizerSx = _a.resizerSx, primary = _a.primary, children = _a.children, hidePrimary = _a.hidePrimary; var primaryPaneSize = this.state.primaryPaneSize; var resizerSize = 7; var notNullChildren = removeNullChildren(children); var style = __assign({ display: "flex", flex: 1, height: "100%", position: "absolute", outline: "none", overflow: "hidden" }, sx); if (split === "vertical") { Object.assign(style, { flexDirection: "row", left: 0, right: 0 }); } else { Object.assign(style, { bottom: 0, flexDirection: "column", minHeight: "100%", top: 0, width: "100%" }); } var pane1Sx = { transition: "margin ease-in-out 500ms" }; var pane2Sx = { transition: "margin ease-in-out 500ms" }; var resizerSxForSlide = { transition: "all ease-in-out 500ms" }; if (hidePrimary) { var offsetPaneMargin = -1 * primaryPaneSize + "px"; var offsetResizerMargin = -1 * resizerSize + "px"; if (split == "vertical") { if (primary == "first") { pane1Sx.marginLeft = offsetPaneMargin; resizerSxForSlide.marginLeft = offsetResizerMargin; } else { pane2Sx.marginRight = offsetPaneMargin; resizerSxForSlide.marginRight = offsetResizerMargin; } } else { if (primary == "first") { pane1Sx.marginTop = offsetPaneMargin; resizerSxForSlide.marginTop = offsetResizerMargin; } else { pane2Sx.marginBottom = offsetPaneMargin; resizerSxForSlide.marginBottom = offsetResizerMargin; } } } return (_jsxs(Box, { id: "split-pane-root", ref: function (node) { _this.splitPane = node; }, sx: style, children: [_jsx(Pane, { ref: function (node) { _this.pane1 = node; }, size: primary == "first" ? primaryPaneSize : undefined, split: split, sx: pane1Sx, children: notNullChildren[0] }, "pane1"), _jsx(Resizer, { onClick: onResizerClick, onDoubleClick: onResizerDoubleClick, onMouseDown: function (event) { return _this.onMouseDown(event.nativeEvent); }, onTouchStart: function (event) { return _this.onTouchStart(event.nativeEvent); }, onTouchEnd: this.onMouseUp, sx: __assign(__assign({}, resizerSx), resizerSxForSlide), split: split, size: resizerSize }, "resizer"), _jsx(Pane, { ref: function (node) { _this.pane2 = node; }, size: primary == "second" ? primaryPaneSize : undefined, split: split, sx: pane2Sx, children: notNullChildren[1] }, "pane2")] })); }; SplitPane.defaultProps = { allowResize: true, minSize: 100, primary: "first", split: "vertical" }; return SplitPane; }(Component)); export { SplitPane };