hermes-agent/web/src/hooks/useBelowBreakpoint.ts
Austin Pickett 6fa1701bd3
feat(web): mobile dashboard UX polish (#28127)
* feat(web): mobile dashboard UX polish

Bottom sheets for sidebar theme/language pickers on narrow viewports with
enter/exit animation and drag-to-close; inline header badges beside titles;
bottom padding on the route outlet for scroll clearance; profiles loading uses a
unicode braille spinner; align profile/cron card actions to the top; viewport-fit
cover and supporting layout tweaks across dashboard pages.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix Nix web npm hash and mobile sheet accessibility.

Align fetchNpmDeps in nix/web.nix with web/package-lock.json for CI. Improve BottomPickSheet backdrop labeling, avoid aria-hidden on the dialog during exit animation, and wire theme/language sheets with listbox semantics and localized dismiss labels.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 15:20:31 -04:00

19 lines
619 B
TypeScript

import { useEffect, useState } from "react";
/** True when viewport width is strictly below `px` (matches Tailwind `min-width: px`). */
export function useBelowBreakpoint(px: number) {
const query = `(max-width: ${px - 1}px)`;
const [matches, setMatches] = useState(() =>
typeof window !== "undefined" ? window.matchMedia(query).matches : false,
);
useEffect(() => {
const mql = window.matchMedia(query);
const sync = () => setMatches(mql.matches);
sync();
mql.addEventListener("change", sync);
return () => mql.removeEventListener("change", sync);
}, [query]);
return matches;
}