import { useEffect, useState } from "react"; /** * Tres tamaños, alineados con los breakpoints del CSS del calendario: * phone <= 640px (iPhone 12: 390, iPhone 16 Pro Max: 440) * tablet 641-1024px (iPad mini: 744, iPad 10.9": 820, iPad Pro portrait: 1024) * desktop >= 1025px (iPad landscape: 1180, iPad Pro landscape: 1366) * * El límite de tablet incluye 1024 a propósito: un iPad Pro en portrait mide justo * 1024px y, descontando la barra lateral, deja ~712px para el calendario. Con 7 * columnas son ~100px por día, y con dos citas solapadas los títulos quedan en * "A...". No coincide con el `lg:` de Tailwind (también 1024), así que a 1024px hay * barra lateral fija Y vista de 3 días: es justo lo que se busca en ese equipo. */ export type Breakpoint = "phone" | "tablet" | "desktop"; const PHONE = "(max-width: 640px)"; const TABLET = "(min-width: 641px) and (max-width: 1024px)"; function currentBreakpoint(): Breakpoint { if (typeof window === "undefined") return "desktop"; if (window.matchMedia(PHONE).matches) return "phone"; if (window.matchMedia(TABLET).matches) return "tablet"; return "desktop"; } export function useBreakpoint(): Breakpoint { const [bp, setBp] = useState(currentBreakpoint); useEffect(() => { const lists = [window.matchMedia(PHONE), window.matchMedia(TABLET)]; const onChange = () => setBp(currentBreakpoint()); lists.forEach((l) => l.addEventListener("change", onChange)); // Al rotar un iPad se cruza de 820 a 1180 y los media queries ya lo cubren, // pero en iOS el evento de orientación llega antes de que se reasienten las // medidas; re-evaluamos para no quedar con el layout de la orientación previa. window.addEventListener("orientationchange", onChange); return () => { lists.forEach((l) => l.removeEventListener("change", onChange)); window.removeEventListener("orientationchange", onChange); }; }, []); return bp; }