Skip to content

refactor(frontend): extract mobile nav and header projection from app.ts into a bounded-context module #215

Closed

Description

@cristim

Problem

frontend/src/app.ts is well past the 500-line ceiling stated in CLAUDE.md
("Keep files under 500 lines"), and the mobile navigation / header projection
behaviour is the largest self-contained chunk in it.

Line counts:

Revision frontend/src/app.ts
before PR LeanerCloud/cloud-commitments-cli#1877 (b83c5d14e) 802
PR LeanerCloud/cloud-commitments-cli#1877 head 883

The violation predates PR LeanerCloud/cloud-commitments-cli#1877. At 802 lines the file was already 60%
over the ceiling. PR LeanerCloud/cloud-commitments-cli#1877 added 81 lines to it: 63 in the fix for LeanerCloud/cloud-commitments-cli#1779 plus
18 in the accessibility follow-up on the widening path.

CodeRabbit raised the extraction on PR LeanerCloud/cloud-commitments-cli#1877 and it was declined there on
scope grounds: it is a restructuring of a file shared by most of the frontend,
unrelated to the p1 bug that PR fixes, and bundling it would have both blown
the PR's blast radius and buried the actual fix.

Proposal

Move the mobile-nav and header-projection behaviour out of app.ts into its
own bounded-context module (for example frontend/src/nav/mobile-nav.ts)
exposing a typed public API rather than loose exported functions.

Symbols to move (all currently in frontend/src/app.ts):

  • MOBILE_NAV_QUERY, the (max-width: 768px) breakpoint constant
  • DRAWER_PROJECTED_IDS
  • syncHeaderPlacement(isNarrow: boolean)
  • setupMobileNav() and its inner openDrawer / closeDrawer /
    releaseDrawerForDesktop transitions

Blast radius

Small, which is what makes this worth doing as its own change:

  • frontend/src/__tests__/mobile-nav.test.ts is the only importer
    (import { setupMobileNav, syncHeaderPlacement } from '../app'). The jest
    coverage already lives in its own file, so the test move is a re-point of
    one import.
  • frontend/tests-e2e/mobile-header-drawer.spec.ts drives the behaviour
    through the browser and needs no change.
  • Three comments name the current home and should be updated in the same
    change: frontend/src/index.html (the #sidebar-extras slot),
    frontend/src/styles/responsive.css lines 76 and 178.

Acceptance

  • frontend/src/app.ts drops below 500 lines, or the remaining excess is
    identified as a separate follow-up with its own extraction target.
  • The new module exports a typed API; no behaviour change.
  • npm test, npm run lint, tsc --noEmit and the full Playwright suite
    stay green, with the mobile-nav jest and e2e coverage unchanged in substance.

Activity

  1. IAmJSD commented on Oct 24, 2026

    @IAmJSD
    Collaborator

    Claiming: working on this

  2. self-assigned this
    on Oct 24, 2026
  3. IAmJSD commented on Oct 26, 2026

    @IAmJSD
    Collaborator

    Closing as done. #1340 extracted the mobile nav and header projection out of app.ts into their own module, which is what this issue asked for. app.ts is still over the 500-line ceiling (949 lines), and that is tracked by #210 (frontend files over 500 lines).

    Checked against main at 3bfc2fe5. Closed by IAmJSD's agent at IAmJSD's request (acting owner) as part of a sweep of stale assigned issues; reopen if anything is missing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions