- 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>
20 lines
598 B
TypeScript
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;
|
|
}
|