mirror of
https://github.com/barkstone2/vault-to-blog.git
synced 2026-07-22 05:21:19 +00:00
feat: add draggable left sidebar resizing
This commit is contained in:
parent
4f1cec17e9
commit
7a6fae8f6c
3 changed files with 57 additions and 11 deletions
|
|
@ -1,10 +1,11 @@
|
|||
import {CSSProperties} from "react";
|
||||
import {CSSProperties, MouseEvent} from "react";
|
||||
|
||||
interface WorkspaceLeafResizeHandleProps {
|
||||
style?: CSSProperties;
|
||||
onMouseDown?: (event: MouseEvent<HTMLHRElement>) => void;
|
||||
}
|
||||
export function WorkspaceLeafResizeHandle({style}: WorkspaceLeafResizeHandleProps) {
|
||||
export function WorkspaceLeafResizeHandle({style, onMouseDown}: WorkspaceLeafResizeHandleProps) {
|
||||
return (
|
||||
<hr className="workspace-leaf-resize-handle" style={style}/>
|
||||
<hr className="workspace-leaf-resize-handle" style={style} onMouseDown={onMouseDown}/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import {ReactNode, useEffect, useState} from "react";
|
||||
import {MouseEvent as ReactMouseEvent, ReactNode, useCallback, useEffect, useState} from "react";
|
||||
import {WorkspaceSplitContainer} from "./WorkspaceSplitContainer";
|
||||
import TreeContainer from "../components/TreeContainer";
|
||||
import {WorkspaceTabs} from "../components/tab-header/WorkspaceTabs";
|
||||
|
|
@ -33,6 +33,9 @@ export function resolveTocHeaders(
|
|||
|
||||
const leftSideDockOpenedClassName = 'is-left-sidedock-open';
|
||||
const rightSideDockOpenedClassName = 'is-right-sidedock-open';
|
||||
const defaultLeftSideDockWidth = 300;
|
||||
const minLeftSideDockWidth = 220;
|
||||
const maxLeftSideDockWidth = 560;
|
||||
|
||||
export function WorkspaceContainer({children}: {children: ReactNode}) {
|
||||
const {'*': filePath } = useParams();
|
||||
|
|
@ -54,6 +57,7 @@ export function WorkspaceContainer({children}: {children: ReactNode}) {
|
|||
|
||||
const [isLeftSideDockOpened, setIsLeftSideDockOpened] = useState(!isMobile);
|
||||
const [isRightSideDockOpened, setIsRightSideDockOpened] = useState(!isMobile);
|
||||
const [leftSideDockWidth, setLeftSideDockWidth] = useState(defaultLeftSideDockWidth);
|
||||
|
||||
useEffect(() => {
|
||||
setIsLeftSideDockOpened(!isMobile)
|
||||
|
|
@ -69,11 +73,39 @@ export function WorkspaceContainer({children}: {children: ReactNode}) {
|
|||
workspaceClassName += ' ' + rightSideDockOpenedClassName;
|
||||
}
|
||||
|
||||
const handleLeftSidebarResizeMouseDown = useCallback((event: ReactMouseEvent<HTMLHRElement>) => {
|
||||
if (isMobile || !isLeftSideDockOpened) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
const startX = event.clientX;
|
||||
const startWidth = leftSideDockWidth;
|
||||
|
||||
const handleMouseMove = (moveEvent: MouseEvent) => {
|
||||
const nextWidth = Math.min(
|
||||
maxLeftSideDockWidth,
|
||||
Math.max(minLeftSideDockWidth, startWidth + (moveEvent.clientX - startX)),
|
||||
);
|
||||
setLeftSideDockWidth(nextWidth);
|
||||
};
|
||||
|
||||
const handleMouseUp = () => {
|
||||
window.removeEventListener('mousemove', handleMouseMove);
|
||||
window.removeEventListener('mouseup', handleMouseUp);
|
||||
};
|
||||
|
||||
window.addEventListener('mousemove', handleMouseMove);
|
||||
window.addEventListener('mouseup', handleMouseUp);
|
||||
}, [isLeftSideDockOpened, isMobile, leftSideDockWidth]);
|
||||
|
||||
return (
|
||||
<div className={workspaceClassName}>
|
||||
<WorkspaceSplitContainer modOrientation={'mod-horizontal'}
|
||||
isSideDock={true}
|
||||
isSideDockCollapse={!isLeftSideDockOpened}
|
||||
width={leftSideDockWidth}
|
||||
onResizeMouseDown={handleLeftSidebarResizeMouseDown}
|
||||
modSplitDirection={'mod-left-split'}>
|
||||
<WorkspaceTabs spaceDirection={'mod-top-left-space'}>
|
||||
<WorkspaceTabHeaderContainer
|
||||
|
|
|
|||
|
|
@ -1,24 +1,37 @@
|
|||
import {WorkspaceLeafResizeHandle} from "../components/WorkspaceLeafResizeHandle";
|
||||
import {CSSProperties} from "react";
|
||||
import {CSSProperties, MouseEvent, ReactNode} from "react";
|
||||
|
||||
interface WorkspaceSplitContainerProps {
|
||||
modOrientation: "mod-vertical" | "mod-horizontal";
|
||||
isSideDock: boolean;
|
||||
modSplitDirection?: "mod-left-split" | "mod-right-split";
|
||||
isSideDockCollapse?: boolean;
|
||||
children?: React.ReactNode;
|
||||
width?: number;
|
||||
onResizeMouseDown?: (event: MouseEvent<HTMLHRElement>) => void;
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
export function WorkspaceSplitContainer({modOrientation, isSideDock, modSplitDirection, isSideDockCollapse, children}: WorkspaceSplitContainerProps) {
|
||||
export function WorkspaceSplitContainer({
|
||||
modOrientation,
|
||||
isSideDock,
|
||||
modSplitDirection,
|
||||
isSideDockCollapse,
|
||||
width,
|
||||
onResizeMouseDown,
|
||||
children,
|
||||
}: WorkspaceSplitContainerProps) {
|
||||
const collapsedClass = isSideDockCollapse && "is-sidedock-collapsed";
|
||||
let styles: CSSProperties = isSideDock ? {width: '300px'} : {}
|
||||
let styles: CSSProperties = isSideDock ? {width: `${width ?? 300}px`} : {}
|
||||
styles = isSideDockCollapse ? {width: 0, display: 'none'} : styles;
|
||||
return (
|
||||
<div
|
||||
className={`workspace-split ${modOrientation} ${isSideDock ? 'mod-sidedock' : 'mod-root'} ${modSplitDirection} ${collapsedClass}`}
|
||||
style={styles}>
|
||||
<WorkspaceLeafResizeHandle style={(isSideDock && !isSideDockCollapse) ? {opacity: 1} : {opacity: 0}}/>
|
||||
<WorkspaceLeafResizeHandle
|
||||
style={(isSideDock && !isSideDockCollapse) ? {opacity: 1} : {opacity: 0}}
|
||||
onMouseDown={onResizeMouseDown}
|
||||
/>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue