@uiw/react-split
Version:
A piece of content can be divided into areas that can be dragged to adjust the width or height.
154 lines • 6.79 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
var _excluded = ["prefixCls", "visiable", "mode", "className", "children", "visible", "renderBar", "lineBar", "disable", "onDragEnd", "onDragging"];
import React, { useState, useRef, useEffect, useCallback } from 'react';
import "./style/index.css";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
var Split = props => {
var _props$visible;
var {
prefixCls = 'w-split',
visiable = true,
mode = 'horizontal',
className,
children,
visible = (_props$visible = props.visible) != null ? _props$visible : props.visiable,
renderBar,
lineBar,
disable,
onDragEnd,
onDragging
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
var [dragging, setDragging] = useState(false);
var wrapperRef = useRef(null);
var paneNumberRef = useRef(0);
var startXRef = useRef(0);
var startYRef = useRef(0);
var moveRef = useRef(false);
var targetRef = useRef(null);
var boxWidthRef = useRef(0);
var boxHeightRef = useRef(0);
var preWidthRef = useRef(0);
var nextWidthRef = useRef(0);
var preHeightRef = useRef(0);
var nextHeightRef = useRef(0);
var preSizeRef = useRef(0);
var nextSizeRef = useRef(0);
var removeEvent = useCallback(() => {
window.removeEventListener('mousemove', onDraggingHandler, false);
window.removeEventListener('mouseup', onDragEndHandler, false);
}, []);
var onDraggingHandler = useCallback(env => {
var _targetRef$current, _targetRef$current2;
if (!moveRef.current) {
return;
}
if (!dragging) {
setDragging(true);
}
var nextTarget = (_targetRef$current = targetRef.current) == null ? void 0 : _targetRef$current.nextElementSibling;
var prevTarget = (_targetRef$current2 = targetRef.current) == null ? void 0 : _targetRef$current2.previousElementSibling;
var x = env.clientX - startXRef.current;
var y = env.clientY - startYRef.current;
preSizeRef.current = 0;
nextSizeRef.current = 0;
if (mode === 'horizontal') {
preSizeRef.current = preWidthRef.current + x > -1 ? preWidthRef.current + x : 0;
nextSizeRef.current = nextWidthRef.current - x > -1 ? nextWidthRef.current - x : 0;
if (preSizeRef.current === 0 || nextSizeRef.current === 0) {
return;
}
preSizeRef.current = (preSizeRef.current / boxWidthRef.current >= 1 ? 1 : preSizeRef.current / boxWidthRef.current) * 100;
nextSizeRef.current = (nextSizeRef.current / boxWidthRef.current >= 1 ? 1 : nextSizeRef.current / boxWidthRef.current) * 100;
if (prevTarget && nextTarget) {
prevTarget.style.width = preSizeRef.current + "%";
nextTarget.style.width = nextSizeRef.current + "%";
}
}
if (mode === 'vertical' && preHeightRef.current + y > -1 && nextHeightRef.current - y > -1) {
preSizeRef.current = preHeightRef.current + y > -1 ? preHeightRef.current + y : 0;
nextSizeRef.current = nextHeightRef.current - y > -1 ? nextHeightRef.current - y : 0;
preSizeRef.current = (preSizeRef.current / boxHeightRef.current >= 1 ? 1 : preSizeRef.current / boxHeightRef.current) * 100;
nextSizeRef.current = (nextSizeRef.current / boxHeightRef.current >= 1 ? 1 : nextSizeRef.current / boxHeightRef.current) * 100;
if (preSizeRef.current === 0 || nextSizeRef.current === 0) {
return;
}
if (prevTarget && nextTarget) {
prevTarget.style.height = preSizeRef.current + "%";
nextTarget.style.height = nextSizeRef.current + "%";
}
}
onDragging && onDragging(preSizeRef.current, nextSizeRef.current, paneNumberRef.current);
}, [mode, onDragging, dragging]);
var onDragEndHandler = useCallback(() => {
moveRef.current = false;
onDragEnd && onDragEnd(preSizeRef.current, nextSizeRef.current, paneNumberRef.current);
removeEvent();
setDragging(false);
}, [onDragEnd, removeEvent]);
var _onMouseDown = useCallback((paneNumber, env) => {
if (!env.target || !wrapperRef.current) {
return;
}
paneNumberRef.current = paneNumber;
startXRef.current = env.clientX;
startYRef.current = env.clientY;
moveRef.current = true;
targetRef.current = env.target.parentNode;
var prevTarget = targetRef.current.previousElementSibling;
var nextTarget = targetRef.current.nextElementSibling;
boxWidthRef.current = wrapperRef.current.clientWidth;
boxHeightRef.current = wrapperRef.current.clientHeight;
if (prevTarget) {
preWidthRef.current = prevTarget.clientWidth;
preHeightRef.current = prevTarget.clientHeight;
}
if (nextTarget) {
nextWidthRef.current = nextTarget.clientWidth;
nextHeightRef.current = nextTarget.clientHeight;
}
window.addEventListener('mousemove', onDraggingHandler);
window.addEventListener('mouseup', onDragEndHandler, false);
setDragging(true);
}, [onDraggingHandler, onDragEndHandler]);
useEffect(() => {
return () => {
removeEvent();
};
}, [removeEvent]);
var cls = [prefixCls, className, prefixCls + "-" + mode, dragging ? 'dragging' : null].filter(Boolean).join(' ').trim();
var child = React.Children.toArray(children);
return /*#__PURE__*/_jsx("div", _extends({
className: cls
}, other, {
ref: wrapperRef,
children: React.Children.map(child, (element, idx) => {
var props = Object.assign({}, element.props, {
className: [prefixCls + "-pane", element.props.className].filter(Boolean).join(' ').trim(),
style: _extends({}, element.props.style)
});
var visibleBar = visible === true || visible && visible.includes(idx + 1) || false;
var barProps = {
className: [prefixCls + "-bar", lineBar ? prefixCls + "-line-bar" : null, !lineBar ? prefixCls + "-large-bar" : null].filter(Boolean).join(' ').trim()
};
if (disable === true || disable && disable.includes(idx + 1)) {
barProps.className = [barProps.className, disable ? 'disable' : null].filter(Boolean).join(' ').trim();
}
var BarCom = null;
if (idx !== 0 && visibleBar && renderBar) {
BarCom = renderBar(_extends({}, barProps, {
onMouseDown: e => _onMouseDown(idx + 1, e)
}));
} else if (idx !== 0 && visibleBar) {
BarCom = /*#__PURE__*/React.createElement('div', _extends({}, barProps), /*#__PURE__*/_jsx("div", {
onMouseDown: e => _onMouseDown(idx + 1, e)
}));
}
return /*#__PURE__*/_jsxs(React.Fragment, {
children: [BarCom, /*#__PURE__*/React.cloneElement(element, _extends({}, props))]
}, idx);
})
}));
};
export default Split;