1
0
forked from boos/BoosAPI

feat: add mobile layout detection

This commit is contained in:
cita
2026-03-10 14:39:57 +08:00
parent dbf828467b
commit 4e3d82aae1
3 changed files with 34 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
import { describe, expect, it } from 'vitest';
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
describe('App mobile layout', () => {
it('sets data-layout attribute when switching layouts', () => {
const source = readFileSync(resolve(process.cwd(), 'src/web/App.tsx'), 'utf8');
expect(source).toContain('useIsMobile(768)');
expect(source).toContain("document.documentElement.setAttribute('data-layout'");
});
});
+6
View File
@@ -16,6 +16,7 @@ import { I18nProvider, useI18n } from './i18n.js';
import { resolveLoginErrorMessage } from './loginError.js';
import { SITE_DOCS_URL } from './docsLink.js';
import { useAnimatedVisibility } from './components/useAnimatedVisibility.js';
import { useIsMobile } from './components/useIsMobile.js';
const Dashboard = lazy(() => import('./pages/Dashboard.js'));
const Sites = lazy(() => import('./pages/Sites.js'));
const Accounts = lazy(() => import('./pages/Accounts.js'));
@@ -383,6 +384,7 @@ function AppShell() {
const notifBtnRef = useRef<HTMLButtonElement>(null);
const latestTaskEventIdRef = useRef(0);
const toast = useToast();
const isMobile = useIsMobile(768);
const resolvedTheme: 'light' | 'dark' = themeMode === 'system'
? (systemPrefersDark ? 'dark' : 'light')
: themeMode;
@@ -415,6 +417,10 @@ function AppShell() {
}
}, [resolvedTheme, themeMode]);
useEffect(() => {
document.documentElement.setAttribute('data-layout', isMobile ? 'mobile' : 'desktop');
}, [isMobile]);
useEffect(() => {
const handler = (e: KeyboardEvent) => {
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
+16
View File
@@ -0,0 +1,16 @@
import { useEffect, useState } from 'react';
export function useIsMobile(breakpoint = 768) {
const [isMobile, setIsMobile] = useState(() => (
typeof window !== 'undefined' ? window.innerWidth < breakpoint : false
));
useEffect(() => {
const update = () => setIsMobile(window.innerWidth < breakpoint);
update();
window.addEventListener('resize', update);
return () => window.removeEventListener('resize', update);
}, [breakpoint]);
return isMobile;
}