diff --git a/apps/client/src/features/share/atoms/shared-page-atom.ts b/apps/client/src/features/share/atoms/shared-page-atom.ts index edd0f7fa8..bf8929942 100644 --- a/apps/client/src/features/share/atoms/shared-page-atom.ts +++ b/apps/client/src/features/share/atoms/shared-page-atom.ts @@ -6,6 +6,6 @@ import { SharedPageTreeNode } from "@/features/share/utils"; export const sharedPageTreeAtom = atom(null); export const sharedTreeDataAtom = atom(null); export const sharedPageFullWidthAtom = atomWithStorage( - "shared-page-full-width", + "sharedPageFullWidth", false, ); \ No newline at end of file diff --git a/apps/client/src/features/share/components/share-shell.tsx b/apps/client/src/features/share/components/share-shell.tsx index e59d41317..1bd559258 100644 --- a/apps/client/src/features/share/components/share-shell.tsx +++ b/apps/client/src/features/share/components/share-shell.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo } from "react"; +import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { ActionIcon, AppShell, @@ -23,6 +23,7 @@ import { buildSharedPageTree } from "@/features/share/utils"; import { desktopSidebarAtom, mobileSidebarAtom, + sidebarWidthAtom, } from "@/components/layouts/global/hooks/atoms/sidebar-atom.ts"; import SidebarToggle from "@/components/ui/sidebar-toggle-button.tsx"; import { useTranslation } from "react-i18next"; @@ -60,6 +61,45 @@ export default function ShareShell({ const toggleTocMobile = useToggleToc(mobileTableOfContentAsideAtom); const toggleToc = useToggleToc(tableOfContentAsideAtom); const [fullWidth, setFullWidth] = useAtom(sharedPageFullWidthAtom); + const [sidebarWidth, setSidebarWidth] = useAtom(sidebarWidthAtom); + const [isResizing, setIsResizing] = useState(false); + const sidebarRef = useRef(null); + + const startResizing = useCallback((e: React.MouseEvent) => { + e.preventDefault(); + setIsResizing(true); + }, []); + + const stopResizing = useCallback(() => { + setIsResizing(false); + }, []); + + const resize = useCallback( + (e: MouseEvent) => { + if (!isResizing || !sidebarRef.current) return; + const newWidth = + e.clientX - sidebarRef.current.getBoundingClientRect().left; + if (newWidth < 220) { + setSidebarWidth(220); + return; + } + if (newWidth > 600) { + setSidebarWidth(600); + return; + } + setSidebarWidth(newWidth); + }, + [isResizing, setSidebarWidth], + ); + + useEffect(() => { + window.addEventListener("mousemove", resize); + window.addEventListener("mouseup", stopResizing); + return () => { + window.removeEventListener("mousemove", resize); + window.removeEventListener("mouseup", stopResizing); + }; + }, [resize, stopResizing]); const { shareId } = useParams(); const { data } = useGetSharedPageTreeQuery(shareId); @@ -86,7 +126,7 @@ export default function ShareShell({ header={{ height: 50 }} {...(data?.pageTree?.length > 1 && { navbar: { - width: 300, + width: sidebarWidth, breakpoint: "sm", collapsed: { mobile: !mobileOpened, @@ -193,7 +233,11 @@ export default function ShareShell({ {data?.pageTree?.length > 1 && ( - + +
)} diff --git a/apps/client/src/features/share/components/share.module.css b/apps/client/src/features/share/components/share.module.css index 617768ff1..11c8a6b24 100644 --- a/apps/client/src/features/share/components/share.module.css +++ b/apps/client/src/features/share/components/share.module.css @@ -18,3 +18,26 @@ width: 350px; } } + +.resizeHandle { + width: 3px; + cursor: col-resize; + position: absolute; + right: 0; + top: 0; + bottom: 0; + z-index: 1; + + &:hover, + &:active { + width: 5px; + background: light-dark( + var(--mantine-color-gray-4), + var(--mantine-color-dark-5) + ); + } + + @media (max-width: $mantine-breakpoint-sm) { + display: none; + } +}