UMBRA/frontend/src/hooks/useMediaQuery.ts
Kyle Pope a737f06e85 Action deferred QA items: shared overlay, sort, touch, a11y
- S-01/W-06/S-02/S-04: Extract MobileDetailOverlay shared component
  with Escape key, body scroll lock, and ARIA dialog attributes.
  Refactored Todos, Reminders, People, Locations, ProjectDetail.
- W-02: Add specificity contract comment to mobile-scale CSS
- W-03: Enforce 10px floor for text-[9px] on mobile
- W-05: Add sort dropdown to EntityTable mobile card view
- S-03: Export MOBILE/DESKTOP breakpoint constants from useMediaQuery,
  updated all 8 consumer files to use constants
- S-06: Bump KanbanBoard TouchSensor tolerance from 5 to 8
- S-07: Hover state audit — no action needed, hoverOnlyWhenSupported
  in Tailwind config already handles touch devices correctly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 03:43:25 +08:00

20 lines
598 B
TypeScript

import { useState, useEffect } from 'react';
export const MOBILE = '(max-width: 767px)';
export const DESKTOP = '(min-width: 1024px)';
export function useMediaQuery(query: string): boolean {
const [matches, setMatches] = useState(() =>
typeof window !== 'undefined' ? window.matchMedia(query).matches : false
);
useEffect(() => {
const mql = window.matchMedia(query);
const handler = (e: MediaQueryListEvent) => setMatches(e.matches);
mql.addEventListener('change', handler);
return () => mql.removeEventListener('change', handler);
}, [query]);
return matches;
}