Files
initiative/specs/024-fix-hp-popover-overflow/tasks.md

4.7 KiB

Tasks: Fix HP Popover Overflow

Input: Design documents from /specs/024-fix-hp-popover-overflow/ Prerequisites: plan.md (required), spec.md (required for user stories), research.md

Tests: Not explicitly requested in spec. No test tasks generated.

Organization: Tasks are grouped by user story to enable independent implementation and testing of each story.

Format: [ID] [P?] [Story] Description

  • [P]: Can run in parallel (different files, no dependencies)
  • [Story]: Which user story this task belongs to (e.g., US1, US2)
  • Include exact file paths in descriptions

Phase 1: User Story 1 - HP popover stays fully visible (Priority: P1) 🎯 MVP

Goal: The HP adjustment popover repositions itself to stay within the viewport when it would otherwise overflow to the right.

Independent Test: Open the HP adjustment popover for any combatant. The entire popover (input, damage button, healing button) is visible without horizontal scrolling, even when the HP display is near the right edge of the viewport.

Implementation for User Story 1

  • T001 [US1] Switch HpAdjustPopover in apps/web/src/components/hp-adjust-popover.tsx from position: absolute to position: fixed with viewport-aware positioning — use a useLayoutEffect to measure the trigger's viewport rect via parentElement.getBoundingClientRect() and the popover's width, then compute top (trigger bottom + 4px) and left (trigger left, clamped to [8, vw - popover.width - 8] using document.documentElement.clientWidth). Render with visibility: hidden until positioned to avoid flash. This escapes the scroll container's overflow clipping that made position: absolute approaches ineffective.
  • T002 [US1] Manual QA: Verify that no horizontal scrollbar appears when the popover is open by ensuring the repositioned popover does not extend beyond window.innerWidth. Test with a combatant whose HP display is near the right viewport edge.

Checkpoint: At this point, the HP popover should be fully visible for all combatant rows. No horizontal scrollbar should appear.


Phase 2: User Story 2 - Popover remains usable with stat block panel open (Priority: P2)

Goal: The HP popover stays fully visible even when the stat block side panel is open, which narrows the available width.

Independent Test: Open the stat block panel, then open the HP popover for a combatant. The popover is fully visible within the encounter tracker area.

Implementation for User Story 2

  • T003 [US2] Manual QA: Verify that the viewport-aware positioning from T001 correctly handles the reduced-width scenario when the stat block panel is open in apps/web/src/App.tsx. The getBoundingClientRect() measurement should already account for the narrowed layout since it measures against the actual viewport. If the popover still overflows (e.g., because the stat block panel is an overlay and the popover's right edge is under it), adjust the overflow detection threshold to account for the panel width. Test at narrow viewport widths (e.g., 375px mobile).

Checkpoint: HP popover is fully visible at all viewport widths, including with stat block panel open.


Phase 3: Polish & Cross-Cutting Concerns

  • T004 Run pnpm check to ensure all linting, formatting, type checks, and tests pass in the repository

Dependencies & Execution Order

Phase Dependencies

  • Phase 1 (US1): No dependencies — can start immediately
  • Phase 2 (US2): Depends on Phase 1 (T001) — verifies the same positioning logic in a narrower viewport context
  • Phase 3 (Polish): Depends on Phase 1 and Phase 2

Parallel Opportunities

  • T001 is the only implementation task; T002 and T003 are verification tasks that depend on T001
  • No parallel implementation opportunities (single-file change)

Implementation Strategy

MVP First (User Story 1 Only)

  1. Complete T001: Add viewport-aware positioning
  2. Complete T002: Verify no horizontal scrollbar
  3. STOP and VALIDATE: Test with combatants at various positions
  4. If MVP is sufficient, proceed to Polish

Incremental Delivery

  1. T001 → Core fix (popover repositions)
  2. T002 → Validate fix works in standard layout
  3. T003 → Validate fix works with stat block panel
  4. T004 → Ensure merge gate passes

Notes

  • This is a single-component bug fix. The entire implementation is in apps/web/src/components/hp-adjust-popover.tsx.
  • The ConditionPicker pattern (position: absolute + flipped flag) was not usable here because the popover sits inside a scroll container that clips absolutely-positioned children. position: fixed was used instead.
  • The existing ref on the popover div is reused for measurement.
  • Commit after T001 as the atomic implementation change.