75 lines
2.3 KiB
TypeScript
75 lines
2.3 KiB
TypeScript
import {
|
|
DEFAULT_SIDEBAR_WIDTH,
|
|
MAX_SIDEBAR_WIDTH,
|
|
MIN_SIDEBAR_WIDTH,
|
|
} from "@/app/constant";
|
|
import { useAppConfig } from "@/app/store/config";
|
|
import { useRef } from "react";
|
|
import { updateGlobalCSSVars } from "@/app/utils/client";
|
|
|
|
export default function useDragSideBar() {
|
|
const limit = (x: number) =>
|
|
Math.max(MIN_SIDEBAR_WIDTH, Math.min(MAX_SIDEBAR_WIDTH, x));
|
|
|
|
const config = useAppConfig();
|
|
const startX = useRef(0);
|
|
const startDragWidth = useRef(config.sidebarWidth ?? DEFAULT_SIDEBAR_WIDTH);
|
|
const lastUpdateTime = useRef(Date.now());
|
|
|
|
const toggleSideBar = () => {
|
|
config.update((config) => {
|
|
config.sidebarWidth = DEFAULT_SIDEBAR_WIDTH;
|
|
});
|
|
};
|
|
|
|
const onDragStart = (e: MouseEvent) => {
|
|
// Remembers the initial width each time the mouse is pressed
|
|
startX.current = e.clientX;
|
|
startDragWidth.current = config.sidebarWidth;
|
|
const dragStartTime = Date.now();
|
|
|
|
const handleDragMove = (e: MouseEvent) => {
|
|
if (Date.now() < lastUpdateTime.current + 20) {
|
|
return;
|
|
}
|
|
lastUpdateTime.current = Date.now();
|
|
const d = e.clientX - startX.current;
|
|
const nextWidth = limit(startDragWidth.current + d);
|
|
|
|
const { menuWidth } = updateGlobalCSSVars(nextWidth);
|
|
|
|
document.documentElement.style.setProperty(
|
|
"--menu-width",
|
|
`${menuWidth}px`,
|
|
);
|
|
config.update((config) => {
|
|
config.sidebarWidth = nextWidth;
|
|
});
|
|
};
|
|
|
|
const handleDragEnd = () => {
|
|
// In useRef the data is non-responsive, so `config.sidebarWidth` can't get the dynamic sidebarWidth
|
|
window.removeEventListener("pointermove", handleDragMove);
|
|
window.removeEventListener("pointerup", handleDragEnd);
|
|
|
|
// if user click the drag icon, should toggle the sidebar
|
|
const shouldFireClick = Date.now() - dragStartTime < 300;
|
|
if (shouldFireClick) {
|
|
toggleSideBar();
|
|
}
|
|
};
|
|
|
|
window.addEventListener("pointermove", handleDragMove);
|
|
window.addEventListener("pointerup", handleDragEnd);
|
|
};
|
|
|
|
// useLayoutEffect(() => {
|
|
// const barWidth = limit(config.sidebarWidth ?? DEFAULT_SIDEBAR_WIDTH);
|
|
// document.documentElement.style.setProperty("--menu-width", `${barWidth}px`);
|
|
// }, [config.sidebarWidth]);
|
|
|
|
return {
|
|
onDragStart,
|
|
};
|
|
}
|