Replaces every em-dash and en-dash with regular ASCII hyphens across comments, JSX strings, and dev-facing logs. Mostly cosmetic but stops the inconsistent mix that crept in over the last few months (some files used em-dashes in comments, others didn't, some used both). Bundles two small dashboard-layout tweaks that touch a couple of already-modified files: - (dashboard)/layout.tsx main padding goes from p-6 to pt-3 px-6 pb-6 so page content sits closer to the topbar. - Sidebar now receives the ports list it needs for the footer port switcher. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
30 lines
969 B
TypeScript
30 lines
969 B
TypeScript
'use client';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
|
|
const MOBILE_QUERY = '(max-width: 1023.98px)';
|
|
|
|
/**
|
|
* Returns true when the viewport is below the `lg` Tailwind breakpoint.
|
|
* Backed by a media-query listener; safe to call from any client component.
|
|
* Server renders return `false` (desktop default) - clients hydrate to the
|
|
* true viewport state on mount.
|
|
*
|
|
* Not unit-tested: the repo's vitest is configured for environment='node'
|
|
* (no @testing-library/react / DOM env). Verified through the mobile-shell
|
|
* Playwright visual snapshots in Task 23.
|
|
*/
|
|
export function useIsMobile(): boolean {
|
|
const [isMobile, setIsMobile] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const mq = window.matchMedia(MOBILE_QUERY);
|
|
const update = (e: { matches: boolean }) => setIsMobile(e.matches);
|
|
setIsMobile(mq.matches);
|
|
mq.addEventListener('change', update);
|
|
return () => mq.removeEventListener('change', update);
|
|
}, []);
|
|
|
|
return isMobile;
|
|
}
|