Files
coder/.claude
Michael Suchacz 3c3240836e refactor: consolidate viewport hooks and remove defineProperty matchMedia stub (#28460)
Follow-up to review feedback on #28387.

That PR added three hooks for one feature (`useIsBelowLgViewport`,
`useIsBelowMdViewport`, and the local single-use
`useRightPanelNarrowSuppression`) and stubbed `window.matchMedia` in
tests with `Object.defineProperty`.

- Replace the two single-purpose viewport hooks with one generic
`useMediaQuery(query)`. Callers pass the shared Tailwind-aligned query
constants from `utils/mobile.ts`. The one new hook replaces the two
deleted ones (net -1).
- Inline `useRightPanelNarrowSuppression` into `AgentChatPage`, its only
consumer, and drop its `renderHook` unit suite. The behavior stays
covered by the narrow-viewport stories; the widening-restore case moved
into the `NarrowingSuppressesExpandedPanel` play function.
- Rework `testHelpers/matchMedia.ts` to install the stub with `spyOn`
from `storybook/test` instead of `Object.defineProperty`. The helper is
story-only now (stories run in real Chromium; jsdom has no
`matchMedia`), so any future unit test needing a stub should use
`vi.stubGlobal` directly.
- Encode the feedback in the canonical FE contract so it gets caught
during development: `.claude/docs/FRONTEND_PATTERNS.md` now bans new
React hooks when an existing hook, a plain function, or component state
suffices (FE3) and bans replacing browser globals with
`Object.defineProperty` in tests or stories (FE9: `vi.stubGlobal` /
`spyOn`), and notes that `renderHook` suites for stateful UI hooks
belong in the consuming component's story (FE1). The `frontend-review`
skill checklist flags all three. `site/AGENTS.md` is unchanged since it
already defers to the patterns doc.

Validation: `pnpm check`, `pnpm format:check`, `pnpm lint` (biome,
types, knip, circular deps, compiler check), `AgentChatPage.test.ts` (70
passed), story runs for `AgentChatPage.stories.tsx` and
`WorkspacePill.stories.tsx` (49 passed in Chromium).

> Xum acted on Mike's behalf (@ibetitsmike).

<!-- xum-attribution: model=claude-opus-4-6 thinking=high -->
2026-08-24 16:52:54 +00:00
..