diff --git a/packages/ui/src/components/AppShell.tsx b/packages/ui/src/components/AppShell.tsx index b9399eed..8f4cea16 100644 --- a/packages/ui/src/components/AppShell.tsx +++ b/packages/ui/src/components/AppShell.tsx @@ -1,3 +1,5 @@ +'use client'; + import * as React from 'react'; import { clsx } from 'clsx'; import { Menu, X } from 'lucide-react'; @@ -6,6 +8,42 @@ type ShellStyle = React.CSSProperties & { '--bl-app-sidebar-width'?: string; }; +type ShellMediaQueryList = { + matches: boolean; + addEventListener?: (type: 'change', listener: () => void) => void; + removeEventListener?: (type: 'change', listener: () => void) => void; + addListener?: (listener: () => void) => void; + removeListener?: (listener: () => void) => void; +}; + +function useDesktopShell() { + const [isDesktop, setIsDesktop] = React.useState(false); + + React.useEffect(() => { + const browser = globalThis as typeof globalThis & { + matchMedia?: (query: string) => ShellMediaQueryList; + }; + const media = browser.matchMedia?.('(min-width: 1024px)'); + + if (!media) { + return undefined; + } + + const sync = () => setIsDesktop(media.matches); + + sync(); + if (media.addEventListener && media.removeEventListener) { + media.addEventListener('change', sync); + return () => media.removeEventListener?.('change', sync); + } + + media.addListener?.(sync); + return () => media.removeListener?.(sync); + }, []); + + return isDesktop; +} + export interface AppShellProps extends React.HTMLAttributes { sidebarWidth?: number; } @@ -78,6 +116,12 @@ export function AppShellMobileToggle({ children, ...props }: AppShellMobileToggleProps) { + const isDesktop = useDesktopShell(); + + if (isDesktop) { + return null; + } + return (