# Research: Combatant Row Declutter **Feature**: 019-combatant-row-declutter **Date**: 2026-03-06 ## R1: Popover Dismissal Pattern **Decision**: Use a click-outside listener with ref-based boundary detection, consistent with the existing ConditionPicker component pattern. **Rationale**: The codebase already uses this pattern in `condition-picker.tsx` / `condition-tags.tsx` where clicking outside the picker closes it. Reusing the same approach maintains consistency and avoids introducing new dependencies (e.g., a popover library). The popover will use `useEffect` with a document-level click handler that checks if the click target is outside the popover ref. **Alternatives considered**: - Headless UI library (Radix Popover, Floating UI): Adds a dependency for a simple use case. Rejected — the project has no headless UI library and introducing one for a single popover is over-engineering. - HTML `` / `popover` attribute: Native browser support is good, but the `popover` attribute doesn't provide the positioning control needed (anchored to the HP value). Rejected for insufficient positioning semantics. ## R2: Click-to-Edit Pattern for AC **Decision**: Reuse the exact same pattern as the existing `EditableName` component — toggle between static display and input on click, commit on Enter/blur, cancel on Escape. **Rationale**: `EditableName` in `combatant-row.tsx` already implements this exact interaction pattern. The AC click-to-edit can follow the same state machine (editing boolean, draft state, commit/cancel callbacks). This ensures behavioral consistency across the row. **Alternatives considered**: - Popover (same as HP): AC editing is simpler (just set a value, no damage/heal distinction), so a popover adds unnecessary complexity. Rejected. - Double-click to edit: Less discoverable than single-click. Rejected — the existing name edit uses single-click. ## R3: HP Popover Positioning **Decision**: Position the popover directly below (or above if near viewport bottom) the current HP value using simple CSS absolute/relative positioning. **Rationale**: The popover only needs to appear near the trigger element. The combatant row is a simple list layout — no complex scrolling containers or overflow clipping that would require a positioning library. Simple CSS positioning (relative parent + absolute child) is sufficient. **Alternatives considered**: - Floating UI / Popper.js: Provides advanced positioning with flip/shift. Overkill for this use case since the encounter list is a straightforward vertical layout. Rejected. ## R4: Keyboard Shortcuts in Popover **Decision**: Handle Enter (damage) and Shift+Enter (heal) via `onKeyDown` on the popover's input element. Escape handled at the same level to close the popover. **Rationale**: This matches the existing QuickHpInput pattern where Enter applies damage. Adding Shift+Enter for healing is a natural modifier key extension. The input captures all keyboard events, so no global listeners are needed. **Alternatives considered**: - Separate keyboard shortcut system: Unnecessary complexity for two shortcuts scoped to a single input. Rejected.