forked from boos/BoosAPI
feat: add mobile layout detection
This commit is contained in:
@@ -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'");
|
||||
});
|
||||
});
|
||||
@@ -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') {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user