import { useEffect, useState } from 'react'; import { Outlet } from 'react-router-dom'; import { usePersistentState } from '../lib/use-persistent-state'; import { Footer } from './Footer'; import { SidebarChromeContext } from './sidebar-chrome'; import { Sidebar } from './Sidebar'; import { clampSidebarWidth, SIDEBAR_DEFAULT_WIDTH_REM, SidebarResizer } from './SidebarResizer'; import { TopBar } from './TopBar'; export function AppLayout(): React.JSX.Element { const [sidebarCollapsed, setSidebarCollapsed] = usePersistentState('ui.sidebar.collapsed', false); const [sidebarWidth, setSidebarWidth] = usePersistentState( 'ui.sidebar.width', SIDEBAR_DEFAULT_WIDTH_REM, ); const [forcedHidden, setForcedHidden] = useState(false); const collapsed = sidebarCollapsed || forcedHidden; // Clamp on read too — the persisted value may predate a bounds change. const widthRem = clampSidebarWidth(sidebarWidth); // Ctrl/Cmd+\ toggles the sidebar (same shortcut as Notion), regardless of // which element has focus. useEffect(() => { function handleKeyDown(event: KeyboardEvent): void { if ((event.ctrlKey || event.metaKey) && event.key === '\\') { event.preventDefault(); setSidebarCollapsed(!sidebarCollapsed); } } window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [sidebarCollapsed, setSidebarCollapsed]); return (
setSidebarCollapsed(!sidebarCollapsed)} />
{!collapsed && }
); }