Skip to content

feat(web): collapsible Focus Mode sidebars (desktop)#1375

Open
simple-agent-manager[bot] wants to merge 8 commits into
mainfrom
sam/focus-mode-sidebars
Open

feat(web): collapsible Focus Mode sidebars (desktop)#1375
simple-agent-manager[bot] wants to merge 8 commits into
mainfrom
sam/focus-mode-sidebars

Conversation

@simple-agent-manager

Copy link
Copy Markdown
Contributor

Summary

  • Adds a desktop-only three-state Focus Mode that progressively collapses the main nav sidebar and the project-chat session sidebar:
    • Default — full nav (220px) + full sessions (288px), segmented toggle.
    • Focus — icon-only nav rail (56px) + session status strip (64px), compact cycle button.
    • Zen — both collapse to 0px with glowing edge "peek" seams; hover/focus to peek, click or Escape-handled keyboard to expand.
  • State persists to localStorage (sam:focus-mode) and is cycled with the F key. Forced to default on mobile.
  • SAM idea 01KVK5TMZXFA1YQC1M8KYEGZ2F.

Validation

  • pnpm lint (0 errors; pre-existing a11y warnings only)
  • pnpm typecheck
  • pnpm test (2420 web tests pass)
  • Playwright visual audit (desktop 1280 + mobile 375, no horizontal overflow)

Staging Verification (REQUIRED for all code changes — merge-blocking)

N/A: staging deployment explicitly skipped by user request for this PR. Feature is desktop-only UI with no API/infra/DB changes; verified locally via 2420 unit tests + Playwright visual audits (desktop + mobile, overflow asserted).

  • Staging deployment green — skipped per user request
  • Live app verified via Playwright on staging — skipped per user request
  • Existing workflows confirmed working — full web suite (196 files / 2420 tests) green, no regressions
  • New feature verified — focus-mode unit tests (50) + focus-mode-audit.spec.ts desktop/mobile pass
  • N/A: no infra changes
  • Mobile and desktop verification notes added (Focus Mode disabled on mobile; verified by AppShell mobile tests + Playwright mobile audit)

Staging Verification Evidence

Staging skipped at user's explicit request. Local evidence: focus-mode-audit.spec.ts drives the segmented toggle and F cycle at 1280x800 and asserts scrollWidth <= innerWidth in every desktop state; mobile (375x667) confirms the toggle never renders and F is a no-op.

UI Compliance Checklist (Required for UI changes)

  • Mobile-first layout verified (Focus Mode is desktop-only; mobile unchanged)
  • Accessibility checks completed (aria-live mode announcements, tooltip aria-describedby, F-key input/select/contenteditable guard, Escape-to-close zen peek, prefers-reduced-motion on all transitions)
  • Shared UI components used (SessionTreeItem, shared ATTENTION_ICON map)
  • Playwright visual audit run locally — desktop + mobile, no horizontal overflow

End-to-End Verification

  • Data flow traced (see below)
  • Capability test exercises the happy path (focus-mode-audit.spec.ts drives toggle + F-key across all three states)
  • N/A: full flow covered by automated tests

Data Flow Trace

  1. User clicks segment / presses FAppShell.tsx keydown handler / FocusModeTogglecycleFocusMode() / setFocusMode()
  2. focus-mode.ts:cycleFocusMode advances FOCUS_MODE_ORDER, persists to localStorage
  3. AppShell recomputes gridTemplateColumns via navWidthForMode(focusMode); provides focusMode through AppShellContext
  4. project-chat/index.tsx reads context → sessionWidthForMode(focusMode); renders FocusStrip (focus) / ZenPeekRail (zen)

Untested Gaps

N/A: full flow covered by automated tests (unit + Playwright).

Post-Mortem

N/A: not a bug fix (new feature).

Specialist Review Evidence

  • All dispatched reviewers completed and findings addressed before merge
Reviewer Status Outcome
task-completion-validator PASS 0 CRITICAL/HIGH; 2 LOW wording notes addressed in task file
ui-ux-specialist ADDRESSED 2 HIGH + 4 MEDIUM + 5 LOW, all fixed in commit 70bc656 (F-key SELECT guard, tooltip aria-describedby, aria-live region, Escape-to-close zen peek, motion-reduce glow, focus-retention, regression tests)

Exceptions

  • Scope: staging verification skipped
  • Rationale: user explicitly requested skipping staging deployment for this PR; desktop-only UI, no API/infra/DB changes, fully covered by local unit + Playwright tests
  • Expiration: this PR only

Agent Preflight (Required)

  • Preflight completed before code changes

Classification

  • cross-component-change
  • ui-change

External References

N/A: uses existing React + Tailwind + react-router patterns already in the codebase.

Codebase Impact Analysis

apps/web/src/components/AppShell.tsx, apps/web/src/components/NavSidebar.tsx, apps/web/src/components/ZenPeekRail.tsx, apps/web/src/components/FocusModeToggle.tsx, apps/web/src/lib/focus-mode.ts, apps/web/src/lib/chat-session-utils.ts, apps/web/src/pages/project-chat/index.tsx, apps/web/src/pages/project-chat/FocusStrip.tsx. No API/shared/infra changes.

Documentation & Specs

N/A: no public-facing behavior docs affected; feature documented in archived task file tasks/archive/2026-06-20-collapsible-focus-mode-sidebars.md.

Constitution & Risk Check

Principle XI (no hardcoded values): widths centralized in focus-mode.ts helpers, storage key is a named constant. Risk: layout overflow — mitigated by Playwright overflow assertions on all states + viewports.

raphaeltm and others added 8 commits June 20, 2026 22:51
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds the shared three-state Focus Mode model and the nav-sidebar half:
- lib/focus-mode.ts: FocusMode type, width helpers, cycle/persist helpers
- AppShell: shared context + localStorage hydration + F-key cycle, dynamic
  grid column width, focus-aware aside, zen seam
- NavSidebar: iconOnly (56px) rail variant across all three layouts
- FocusModeToggle: segmented + cycle controls
- ZenPeekRail: 0px glowing edge seam with hover/focus peek panel

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wire FocusStrip (64px status-icon rail) and ZenPeekRail into project-chat
sidebar so it collapses with Focus Mode alongside the nav. Extract shared
ATTENTION_ICON map into chat-session-utils so SessionItem and FocusStrip
render identical status iconography.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…udit

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ooltip portal, reduced-motion)

Adds behavioral coverage flagged by the task-completion-validator:
- AppShell: persists focus mode to localStorage + collapses nav column,
  hydrates persisted mode across reload, F-key cycle, F-key ignored in
  inputs, mobile-disabled, and prefers-reduced-motion opt-out.
- FocusStrip: tooltip is portaled to document.body (escapes glass clipping),
  hover/focus peek, onSelect/onNewChat wiring, blur close-delay.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- F-key guard ignores <select> (type-ahead) — HIGH
- FocusStrip tooltip id + aria-describedby association (WCAG 1.3.1) — HIGH
- aria-live region announces Focus Mode changes — MEDIUM
- Escape closes zen peek + refocuses seam button — MEDIUM
- motion-reduce on zen glow transition — MEDIUM
- keep peek open while focus is inside, aria-hidden rotated label,
  drop noise aria-hidden={false} — LOW
- add SELECT-guard + aria-describedby regression tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
7.2% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@codspeed-hq

codspeed-hq Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 6 untouched benchmarks


Comparing sam/focus-mode-sidebars (70bc656) with main (326072a)

Open in CodSpeed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant