9.4 KiB
Feature Specification: Combatant Row Declutter
Feature Branch: 019-combatant-row-declutter
Created: 2026-03-06
Status: Draft
Input: User description: "Declutter combatant row with click-to-edit patterns — replace always-visible HP adjustment and AC inputs with compact, on-demand interactions"
User Scenarios & Testing (mandatory)
User Story 1 - HP Click-to-Adjust Popover (Priority: P1)
As a DM running combat, I want to click on a combatant's current HP value to open a small adjustment popover, so the combatant row is visually clean and I can still quickly apply damage or healing when needed.
Why this priority: HP adjustment is the most frequent mid-combat interaction and the QuickHpInput with its Sword/Heart buttons is the biggest source of visual clutter. Replacing it with an on-demand popover delivers the largest declutter impact.
Independent Test: Can be fully tested by clicking a combatant's current HP, entering a number, and pressing Enter (damage) or Shift+Enter (heal), then verifying the HP updates correctly and the popover dismisses.
Acceptance Scenarios:
- Given a combatant with max HP set (e.g., 30/30), When I look at the row, Then I see only the current HP number and max HP — no delta input or action buttons are visible.
- Given a combatant with max HP set, When I click the current HP number, Then a small popover opens containing an auto-focused numeric input and Damage/Heal buttons.
- Given the HP popover is open with a valid number entered, When I press Enter, Then damage is applied (negative delta), the popover closes, and the HP value updates.
- Given the HP popover is open with a valid number entered, When I press Shift+Enter, Then healing is applied (positive delta), the popover closes, and the HP value updates.
- Given the HP popover is open with a valid number entered, When I click the Damage button, Then damage is applied and the popover closes.
- Given the HP popover is open with a valid number entered, When I click the Heal button, Then healing is applied and the popover closes.
- Given the HP popover is open, When I press Escape, Then the popover closes without applying any change.
- Given the HP popover is open, When I click outside the popover, Then the popover closes without applying any change.
- Given a combatant whose HP is at or below half (bloodied), When I view the row, Then the current HP number displays in the bloodied color (amber).
- Given a combatant whose HP is at 0 (unconscious), When I view the row, Then the current HP number displays in the unconscious color (red).
- Given a combatant with no max HP set, When I view the row, Then the HP area shows only the max HP input — no clickable current HP value.
User Story 2 - AC Click-to-Edit (Priority: P2)
As a DM, I want the AC field to appear as a compact static display (shield icon + number) that I can click to edit inline, so the row is less cluttered while AC remains easy to set or change.
Why this priority: AC is set less frequently than HP is adjusted, so converting it to a click-to-edit pattern provides good declutter value with lower interaction frequency impact.
Independent Test: Can be fully tested by clicking the AC display, editing the value, and confirming via Enter or blur, then verifying the AC updates correctly.
Acceptance Scenarios:
- Given a combatant with AC set (e.g., 15), When I view the row, Then I see a shield icon followed by the number "15" as static text — not an input field.
- Given a combatant with no AC set, When I view the row, Then I see just the shield icon (no number) as a clickable element.
- Given a combatant's AC display, When I click it, Then an inline input appears with the current AC value pre-filled and selected.
- Given the AC inline edit is active, When I type a new value and press Enter, Then the AC updates and the display reverts to static mode.
- Given the AC inline edit is active, When I click away (blur), Then the AC updates and the display reverts to static mode.
- Given the AC inline edit is active, When I press Escape, Then the edit is cancelled, the original value is preserved, and the display reverts to static mode.
- Given the AC inline edit is active, When I clear the field and press Enter, Then the AC is unset and the display shows just the shield icon.
User Story 3 - Max HP Click-to-Edit (Priority: P2)
As a DM, I want the max HP field to appear as a compact static display that I can click to edit inline, so the row is consistent with the AC click-to-edit pattern and further reduces visual clutter.
Why this priority: Max HP is set once during encounter setup and rarely changed. Converting it to click-to-edit applies the same declutter pattern as AC for consistency.
Independent Test: Can be fully tested by clicking the max HP display, editing the value, and confirming via Enter or blur, then verifying the max HP updates correctly.
Acceptance Scenarios:
- Given a combatant with max HP set (e.g., 30), When I view the row, Then I see the max HP as static text — not an input field.
- Given a combatant with no max HP set, When I view the row, Then I see a clickable placeholder to set max HP.
- Given a combatant's max HP display, When I click it, Then an inline input appears with the current max HP value pre-filled and selected.
- Given the max HP inline edit is active, When I type a new value and press Enter, Then the max HP updates and the display reverts to static mode.
- Given the max HP inline edit is active, When I click away (blur), Then the max HP updates and the display reverts to static mode.
- Given the max HP inline edit is active, When I press Escape, Then the edit is cancelled and the display reverts to static mode.
- Given the max HP inline edit is active, When I clear the field and press Enter, Then the max HP is unset and HP tracking is removed.
Edge Cases
- What happens when the user enters non-numeric or negative values in the HP popover? The input only accepts positive integers; non-numeric input is ignored.
- What happens when the user enters 0 in the HP popover? Zero is not a valid delta and the action buttons remain disabled.
- What happens when the HP popover is open and the user tabs away? The popover closes without applying changes (same as blur/click-outside).
- What happens on tablet-width screens? The popover and inline edit must remain accessible and not overflow or clip at viewports ≥ 768px wide (Tailwind
mdbreakpoint).
Requirements (mandatory)
Functional Requirements
- FR-001: System MUST replace the always-visible QuickHpInput (delta input + Sword/Heart buttons) with a clickable current HP display that opens a popover on interaction.
- FR-002: The HP popover MUST contain a single auto-focused numeric input and two action buttons (Damage and Heal).
- FR-003: The HP popover MUST support keyboard shortcuts: Enter for damage, Shift+Enter for heal, Escape to dismiss.
- FR-004: The HP popover MUST dismiss automatically after an action is applied, on Escape, or when clicking outside.
- FR-005: The current HP display MUST retain color-coded status indicators (amber for bloodied, red for unconscious) when the popover is closed.
- FR-006: System MUST replace the always-visible AC input field with a static display (shield icon + number).
- FR-007: Clicking the AC static display MUST open an inline edit input that commits on Enter or blur and cancels on Escape.
- FR-008: The max HP MUST display as compact static text with click-to-edit, consistent with the AC pattern.
- FR-009: The existing callback signatures (
onAdjustHp,onSetAc) MUST remain unchanged — this is a UI-only change. - FR-010: All interactive elements MUST remain keyboard-accessible (focusable, operable via keyboard).
- FR-011: The HP popover input MUST only accept positive integers as valid delta values.
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: The combatant row displays fewer always-visible interactive controls — specifically, 3 fewer visible elements (delta input, Damage button, Heal button) per combatant when HP is set.
- SC-002: The AC field takes up less horizontal space in its default state compared to an always-visible input field.
- SC-003: Users can apply damage or healing in 3 or fewer interactions (click HP, type number, press Enter/Shift+Enter).
- SC-004: Users can edit AC in 3 or fewer interactions (click AC, type number, press Enter).
- SC-005: All HP and AC interactions remain fully operable using only a keyboard.
Assumptions
- The popover is a lightweight component positioned near the current HP value — not a full modal dialog.
- The HP popover uses a simple overlay/click-outside pattern, consistent with how the condition picker already works in the app.
- The AC click-to-edit follows the exact same pattern as the existing editable name component (click to edit, Enter/blur to commit, Escape to cancel).
- Domain and application layers require zero changes — all modifications are confined to the web adapter (React components).
- The CurrentHpInput component is either removed or repurposed as a static display + popover trigger, rather than being an always-visible input.