# `useMobile()` — viewport-width breakpoint hook _(no submodules)_ ## Purpose Returns `true` when the viewport width is at or below the supplied `breakpointPx` (defaulting to 768px, which mirrors Tailwind's `md` breakpoint). The hook subscribes to a `matchMedia` listener — NOT a polling timer — so layout changes propagate without forcing a re-render on every scroll/resize tick. SSR-safe. ## Features - Subscribes via `matchMedia` so re-renders happen only on actual threshold crossings - Returns `false` server-side (no `window`) so SSR HTML matches the desktop layout by default - Configurable breakpoint per-call site - Cleans up the listener on unmount ## Usage: Basic example ```tsx import { useMobile } from "@suaveplan/react-ui/hooks/use-mobile"; function Layout() { const isMobile = useMobile(); return
{isMobile ? : }
; } ``` ## Usage: Advanced example ```tsx import { useMobile } from "@suaveplan/react-ui/hooks/use-mobile"; function ResponsiveTable() { const isCompact = useMobile(640); return ( {isCompact ? : <>} …
ItemSKUNamePrice
); } ``` ## API Reference - `useMobile(breakpointPx?: number = 768): boolean` ## Implementation notes The hook holds a `useState` initialised by reading `window.matchMedia(...).matches` synchronously inside the initialiser when `window` is available — this gets the post-mount state right without an extra render. The post-mount `useEffect` then calls the listener once to sync against any state drift between SSR and the client. The `change` listener tears down on unmount AND when `breakpointPx` changes so a parent that swaps the breakpoint mid-life gets a fresh subscription. The chassis defaults to 768px (Tailwind's `md` boundary) but consumers picking other breakpoints get the same zero-extra-render behaviour. Defensive guards: when `matchMedia` itself throws (some restricted-permissions browsers), the listener setup short-circuits and `isMobile` stays at its initial value.