feat(mobile): add useIsMobile() hook backed by matchMedia (visual-test-only)
This commit is contained in:
29
src/hooks/use-is-mobile.ts
Normal file
29
src/hooks/use-is-mobile.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
const MOBILE_QUERY = '(max-width: 1023.98px)';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true when the viewport is below the `lg` Tailwind breakpoint.
|
||||||
|
* Backed by a media-query listener; safe to call from any client component.
|
||||||
|
* Server renders return `false` (desktop default) — clients hydrate to the
|
||||||
|
* true viewport state on mount.
|
||||||
|
*
|
||||||
|
* Not unit-tested: the repo's vitest is configured for environment='node'
|
||||||
|
* (no @testing-library/react / DOM env). Verified through the mobile-shell
|
||||||
|
* Playwright visual snapshots in Task 23.
|
||||||
|
*/
|
||||||
|
export function useIsMobile(): boolean {
|
||||||
|
const [isMobile, setIsMobile] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const mq = window.matchMedia(MOBILE_QUERY);
|
||||||
|
const update = (e: { matches: boolean }) => setIsMobile(e.matches);
|
||||||
|
setIsMobile(mq.matches);
|
||||||
|
mq.addEventListener('change', update);
|
||||||
|
return () => mq.removeEventListener('change', update);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return isMobile;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user