Files
initiative/specs/011-quick-hp-input/research.md

3.6 KiB

Research: Quick HP Input

R1: Domain layer readiness

Decision: No domain changes needed.

Rationale: The existing adjustHp(encounter, combatantId, delta) function already accepts positive deltas (healing) and negative deltas (damage) with full clamping to [0, maxHp]. The function validates non-zero integer deltas and returns errors for invalid input. The adjustHpUseCase in the application layer already wraps this with store persistence.

Alternatives considered: Adding a dedicated applyDamage/applyHeal domain function pair was considered but rejected -- it would duplicate adjustHp logic. The direction (damage vs heal) is a UI concern; the domain only needs a signed delta.

R2: UI component pattern

Decision: Create a standalone QuickHpInput React component that renders inline within CombatantRow.

Rationale: The component needs its own local state (input value, damage/heal mode) and keyboard event handling. Keeping it as a separate component follows the existing pattern (e.g., CurrentHpInput, MaxHpInput are already sub-components within combatant-row.tsx). However, since QuickHpInput has more complex behavior (mode toggle, visual states), it warrants its own file.

Alternatives considered: Inline implementation within combatant-row.tsx was considered but rejected due to the component's interaction complexity (mode state, keyboard handling, visual treatments).

R3: Damage/heal mode toggle UX

Decision: Use a segmented toggle button adjacent to the input field. Damage mode uses a red/destructive color treatment; heal mode uses a green/positive color treatment. A Lucide icon (e.g., Sword or Minus for damage, Heart or Plus for heal) reinforces the mode.

Rationale: Color + icon provides two visual channels for quick recognition during combat. A segmented toggle is a single-click interaction (FR-004) and is familiar UI pattern. Tab key toggles mode when input is focused (keyboard workflow).

Alternatives considered:

  • Dropdown select: Too slow (2 clicks minimum).
  • Two separate inputs (one for damage, one for heal): More screen space, but eliminates mode confusion entirely. Rejected for space efficiency in the combatant row.
  • Prefix sign (type "-7" for damage, "+5" for heal): Requires extra keystroke per entry and is error-prone.

R4: Keyboard workflow

Decision: Enter confirms and applies the value, Escape clears without applying, Tab toggles damage/heal mode while keeping focus in the input.

Rationale: Enter-to-confirm is the standard web input pattern. Tab for mode toggle prevents the user from leaving the input (Tab's default behavior would move focus away). Escape-to-cancel follows dialog dismissal convention.

Alternatives considered: Using a keyboard shortcut like D/H keys was considered but rejected since the input field accepts numeric characters and letter keys would conflict.

R5: Coexistence with direct HP entry

Decision: The existing CurrentHpInput (absolute value entry) and MaxHpInput remain unchanged. The new QuickHpInput is added as an additional control in the combatant row, visually grouped with the HP display.

Rationale: Per clarification, both direct entry and quick input must coexist. Direct entry is for GM overrides/corrections; quick input is for combat flow. They call different interactions: direct entry computes a delta from old-to-new absolute values, while quick input directly provides the delta.

Alternatives considered: Merging both into a single smart input was considered but rejected -- it would complicate the interaction model and violate the principle of minimal complexity.