useIsWideLayout.ts 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. import { useState, useEffect } from 'react';
  2. /**
  3. * Tailwind's `lg`. Kept in sync with the `lg:` classes it is paired with —
  4. * components using this hook usually also switch layout via `lg:` utilities,
  5. * and the two disagreeing produces a half-applied layout.
  6. */
  7. const WIDE_LAYOUT_BREAKPOINT = 1024;
  8. /**
  9. * True when there is room for a side-by-side layout.
  10. *
  11. * Prefer plain `lg:` classes where CSS alone can do the job. This exists for
  12. * the cases where the *behaviour* differs rather than only the styling — a
  13. * disclosure that collapses on narrow screens but is permanently open when it
  14. * has its own column, for instance, which CSS cannot express on its own.
  15. */
  16. export function useIsWideLayout(): boolean {
  17. const [isWide, setIsWide] = useState(() =>
  18. typeof window !== 'undefined' ? window.innerWidth >= WIDE_LAYOUT_BREAKPOINT : false
  19. );
  20. useEffect(() => {
  21. const mediaQuery = window.matchMedia(`(min-width: ${WIDE_LAYOUT_BREAKPOINT}px)`);
  22. const handleChange = (e: MediaQueryListEvent) => {
  23. setIsWide(e.matches);
  24. };
  25. setIsWide(mediaQuery.matches);
  26. mediaQuery.addEventListener('change', handleChange);
  27. return () => mediaQuery.removeEventListener('change', handleChange);
  28. }, []);
  29. return isWide;
  30. }