hamburger nav on all touch devices, add eruda for debugging
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,24 +2,25 @@ import { useDock } from 'officerdev';
|
||||
import { Background } from './Background';
|
||||
import { Header } from './Header';
|
||||
import { Dock, ALL_DOCK_ITEMS, DEFAULT_DOCK_PATHS } from './Dock';
|
||||
import { useIsTouch } from './useIsTouch';
|
||||
|
||||
type DashboardLayoutProps = {
|
||||
children?: React.ReactNode;
|
||||
};
|
||||
export function DashboardLayout({ children }: DashboardLayoutProps) {
|
||||
const { items: visibleItems } = useDock(ALL_DOCK_ITEMS, DEFAULT_DOCK_PATHS);
|
||||
const isTouch = useIsTouch();
|
||||
|
||||
return (
|
||||
<div className="relative overflow-hidden h-dvh outline-none inset-0">
|
||||
<Header dockItems={visibleItems} />
|
||||
<section className="relative h-dvh snap-start overflow-hidden">
|
||||
<Background />
|
||||
<Dock items={visibleItems} className="hidden md:flex" />
|
||||
{!isTouch && <Dock items={visibleItems} className="hidden md:flex" />}
|
||||
<div className="absolute inset-0 z-2 pt-[52px] md:pt-[64px] pb-2 overflow-y-auto">
|
||||
{children}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,8 +2,8 @@ import { useState } from 'react';
|
||||
import { Link, useLocation } from 'react-router';
|
||||
import { Menu } from 'lucide-react';
|
||||
import { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet';
|
||||
import { useIsMobile } from 'hooks/useIsMobile';
|
||||
import type { DockItem } from '../Dock';
|
||||
import { useIsTouch } from '../useIsTouch';
|
||||
import { UserMenu } from './UserMenu';
|
||||
|
||||
type HeaderProps = {
|
||||
@@ -12,7 +12,7 @@ type HeaderProps = {
|
||||
|
||||
export function Header({ dockItems }: HeaderProps) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const isMobile = useIsMobile();
|
||||
const isTouch = useIsTouch();
|
||||
const location = useLocation();
|
||||
|
||||
const isActive = (to: string) => (to === '/' ? location.pathname === '/' : location.pathname.startsWith(to));
|
||||
@@ -24,7 +24,7 @@ export function Header({ dockItems }: HeaderProps) {
|
||||
style={{ backgroundColor: 'rgba(255, 255, 255, 0.25)', borderColor: 'rgba(255, 255, 255, 0.35)' }}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
{isMobile && dockItems && (
|
||||
{isTouch && dockItems && (
|
||||
<button onClick={() => setOpen(true)} className="p-1.5 rounded-md hover:bg-white/20 transition-colors">
|
||||
<Menu className="h-5 w-5 text-white" />
|
||||
</button>
|
||||
@@ -41,7 +41,7 @@ export function Header({ dockItems }: HeaderProps) {
|
||||
<UserMenu />
|
||||
</div>
|
||||
|
||||
{isMobile && dockItems && (
|
||||
{isTouch && dockItems && (
|
||||
<Sheet open={open} onOpenChange={setOpen}>
|
||||
<SheetContent side="left">
|
||||
<SheetHeader>
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
export const useIsTouch = () => {
|
||||
const [isTouch, setIsTouch] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const mql = window.matchMedia('(pointer: coarse)');
|
||||
setIsTouch(mql.matches);
|
||||
const onChange = (ev: MediaQueryListEvent) => setIsTouch(ev.matches);
|
||||
mql.addEventListener('change', onChange);
|
||||
return () => mql.removeEventListener('change', onChange);
|
||||
}, []);
|
||||
|
||||
return isTouch;
|
||||
};
|
||||
@@ -31,6 +31,8 @@
|
||||
<link rel="manifest" href="https://static.officer.dev/site.webmanifest" />
|
||||
<meta name="theme-color" content="#1F2620" />
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/eruda"></script>
|
||||
<script>eruda.init();</script>
|
||||
<script type="module" src="./frontend.tsx" async></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Reference in New Issue
Block a user