UNPKG

@ashxjs/split-view

Version:

Simple react split-view component with resizing divider

46 lines (45 loc) 2.08 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useEffect, useState, createRef } from "react"; import { LeftPanel } from "../LeftPanel/LeftPanel"; import { styles } from "../styles"; const MIN_WIDTH = 50; export const SplitView = ({ left, right, defaultLeftPanelWidth, }) => { const [isDragging, setIsDragging] = useState(false); const [leftWidth, setLeftWidth] = useState(defaultLeftPanelWidth); const [xPosition, setXPosition] = useState(); const splitPaneRef = createRef(); useEffect(() => { document.addEventListener("mousemove", onMouseMove); document.addEventListener("mouseup", onMouseUp); return () => { document.removeEventListener("mousemove", onMouseMove); document.removeEventListener("mouseup", onMouseUp); }; }); const onMouseUp = () => { setIsDragging(false); }; const onMouseMove = (event) => { if (isDragging && leftWidth && xPosition) { const newLeftWidth = leftWidth + event.clientX - xPosition; setXPosition(event.clientX); if (newLeftWidth < MIN_WIDTH) { setLeftWidth(MIN_WIDTH); return; } if (splitPaneRef.current) { const splitPaneWidth = splitPaneRef.current.clientWidth; if (newLeftWidth > splitPaneWidth - MIN_WIDTH) { setLeftWidth(splitPaneWidth - MIN_WIDTH); return; } } setLeftWidth(newLeftWidth); } }; const onMouseDown = (event) => { setXPosition(event.clientX); setIsDragging(true); }; return (_jsxs("div", { style: styles.SplitView, ref: splitPaneRef, children: [_jsx(LeftPanel, { leftWidth: leftWidth, setLeftWidth: setLeftWidth, children: left }), _jsx("div", { style: styles.DividerHitBox, onMouseDown: onMouseDown, children: _jsx("div", { style: styles.Divider, onMouseDown: onMouseDown }) }), _jsx("div", { style: styles.RightPanel, children: right })] })); };