fix(folder): keep mobile sidebars closed on initial load
Prevent left and right sidebars from auto-opening on small screens during folder page initialization, regardless of persisted open state. Gate mobile sidebar sheets behind restored panel state to avoid initial sidebar pop-in.
This commit is contained in:
@@ -280,14 +280,22 @@ function MobileFolderWorkspaceShell({
|
|||||||
}: {
|
}: {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
}) {
|
}) {
|
||||||
const { isOpen: sidebarOpen, toggle: toggleSidebar } = useSidebarContext()
|
const {
|
||||||
const { isOpen: auxOpen, toggle: toggleAux } = useAuxPanelContext()
|
isOpen: sidebarOpen,
|
||||||
|
restored: sidebarRestored,
|
||||||
|
toggle: toggleSidebar,
|
||||||
|
} = useSidebarContext()
|
||||||
|
const {
|
||||||
|
isOpen: auxOpen,
|
||||||
|
restored: auxRestored,
|
||||||
|
toggle: toggleAux,
|
||||||
|
} = useAuxPanelContext()
|
||||||
const { isOpen: terminalOpen, toggle: toggleTerminal } = useTerminalContext()
|
const { isOpen: terminalOpen, toggle: toggleTerminal } = useTerminalContext()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-1 min-h-0 overflow-hidden">
|
<div className="flex flex-1 min-h-0 overflow-hidden">
|
||||||
{/* Sidebar Sheet (left) */}
|
{/* Sidebar Sheet (left) */}
|
||||||
<Sheet open={sidebarOpen} onOpenChange={toggleSidebar}>
|
<Sheet open={sidebarRestored && sidebarOpen} onOpenChange={toggleSidebar}>
|
||||||
<SheetContent
|
<SheetContent
|
||||||
side="left"
|
side="left"
|
||||||
showCloseButton={false}
|
showCloseButton={false}
|
||||||
@@ -304,7 +312,7 @@ function MobileFolderWorkspaceShell({
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
{/* Aux panel Sheet (right) */}
|
{/* Aux panel Sheet (right) */}
|
||||||
<Sheet open={auxOpen} onOpenChange={toggleAux}>
|
<Sheet open={auxRestored && auxOpen} onOpenChange={toggleAux}>
|
||||||
<SheetContent
|
<SheetContent
|
||||||
side="right"
|
side="right"
|
||||||
showCloseButton={false}
|
showCloseButton={false}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ const DEFAULT_IS_OPEN = false
|
|||||||
|
|
||||||
interface AuxPanelContextValue {
|
interface AuxPanelContextValue {
|
||||||
isOpen: boolean
|
isOpen: boolean
|
||||||
|
restored: boolean
|
||||||
width: number
|
width: number
|
||||||
minWidth: number
|
minWidth: number
|
||||||
maxWidth: number
|
maxWidth: number
|
||||||
@@ -94,9 +95,11 @@ export function AuxPanelProvider({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const stored = loadPersistedPanelState(storageKey)
|
const stored = loadPersistedPanelState(storageKey)
|
||||||
|
const isMobileViewport = window.innerWidth < 768
|
||||||
|
const defaultOpen = isMobileViewport ? false : DEFAULT_IS_OPEN
|
||||||
// Hydrate from localStorage after mount to keep SSR/CSR markup consistent.
|
// Hydrate from localStorage after mount to keep SSR/CSR markup consistent.
|
||||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||||
setIsOpen(stored?.isOpen ?? DEFAULT_IS_OPEN)
|
setIsOpen(isMobileViewport ? false : (stored?.isOpen ?? defaultOpen))
|
||||||
setWidthState(clampWidth(stored?.width ?? DEFAULT_WIDTH))
|
setWidthState(clampWidth(stored?.width ?? DEFAULT_WIDTH))
|
||||||
setRestored(true)
|
setRestored(true)
|
||||||
}, [storageKey])
|
}, [storageKey])
|
||||||
@@ -109,6 +112,7 @@ export function AuxPanelProvider({
|
|||||||
const value = useMemo(
|
const value = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
isOpen,
|
isOpen,
|
||||||
|
restored,
|
||||||
width,
|
width,
|
||||||
minWidth: MIN_WIDTH,
|
minWidth: MIN_WIDTH,
|
||||||
maxWidth: MAX_WIDTH,
|
maxWidth: MAX_WIDTH,
|
||||||
@@ -123,6 +127,7 @@ export function AuxPanelProvider({
|
|||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
isOpen,
|
isOpen,
|
||||||
|
restored,
|
||||||
width,
|
width,
|
||||||
activeTab,
|
activeTab,
|
||||||
toggle,
|
toggle,
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ const DEFAULT_IS_OPEN = true
|
|||||||
|
|
||||||
interface SidebarContextValue {
|
interface SidebarContextValue {
|
||||||
isOpen: boolean
|
isOpen: boolean
|
||||||
|
restored: boolean
|
||||||
width: number
|
width: number
|
||||||
minWidth: number
|
minWidth: number
|
||||||
maxWidth: number
|
maxWidth: number
|
||||||
@@ -82,13 +83,14 @@ export function SidebarProvider({ children, folderId }: SidebarProviderProps) {
|
|||||||
const value = useMemo(
|
const value = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
isOpen,
|
isOpen,
|
||||||
|
restored,
|
||||||
width,
|
width,
|
||||||
minWidth: MIN_WIDTH,
|
minWidth: MIN_WIDTH,
|
||||||
maxWidth: MAX_WIDTH,
|
maxWidth: MAX_WIDTH,
|
||||||
toggle,
|
toggle,
|
||||||
setWidth,
|
setWidth,
|
||||||
}),
|
}),
|
||||||
[isOpen, width, toggle, setWidth]
|
[isOpen, restored, width, toggle, setWidth]
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user