# Tasks: Quick HP Input **Input**: Design documents from `/specs/011-quick-hp-input/` **Prerequisites**: plan.md (required), spec.md (required), research.md, data-model.md **Tests**: No test tasks included (not explicitly requested in spec). Domain logic is already fully tested via `adjustHp.test.ts`. **Organization**: US1 (damage), US2 (healing), and US3 (mode toggle) are all P1 and form a single inseparable component (`QuickHpInput`). They are combined into one phase since you cannot meaningfully implement damage input without the mode concept. US4 (keyboard workflow) is P2 and layered on top. ## 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, US3) - Include exact file paths in descriptions --- ## Phase 1: Core Quick HP Input Component (US1 + US2 + US3, Priority: P1) **Goal**: Deliver a working inline damage/heal input per combatant with mode toggle and visual distinction. Covers the primary combat workflow: type a number, apply as damage or healing. **Independent Test**: Set a combatant's max HP to 20, type "7" in damage mode and confirm -- HP drops to 13. Toggle to heal mode, type "5" and confirm -- HP rises to 18. Mode is visually distinguishable at a glance. ### Implementation - [x] T001 [US1] [US2] [US3] Create `QuickHpInput` component skeleton with local state (`mode: "damage" | "heal"`, `inputValue: string`), props interface (`combatantId`, `disabled`, `onAdjustHp`), and basic render structure in `apps/web/src/components/quick-hp-input.tsx` - [x] T002 [US1] [US2] Implement numeric input field that only accepts digit characters, parses to integer on confirm, computes signed delta based on mode (damage = negative, heal = positive), calls `onAdjustHp(combatantId, delta)`, and clears input after successful application. Reject zero and empty input. File: `apps/web/src/components/quick-hp-input.tsx` - [x] T003 [US3] Implement damage/heal mode toggle button adjacent to the input field. Use distinct visual treatments: damage mode with destructive color (red tones) and a damage icon (e.g., `Sword` or `Minus` from Lucide), heal mode with positive color (green tones) and a heal icon (e.g., `Heart` or `Plus` from Lucide). Toggle with a single click. File: `apps/web/src/components/quick-hp-input.tsx` - [x] T004 [US1] [US2] [US3] Integrate `QuickHpInput` into `CombatantRow` grid layout. Add it alongside the existing `CurrentHpInput`/`MaxHpInput` display. Pass `onAdjustHp` prop through. Only render when combatant has HP tracking active (`maxHp` is defined). Ensure the compact resting state fits the existing row height. File: `apps/web/src/components/combatant-row.tsx` **Checkpoint**: Damage and healing can be applied via the inline input with mouse interaction. Mode toggle works with clear visual distinction. Direct HP entry still functions alongside. --- ## Phase 2: Keyboard-Driven Workflow (US4, Priority: P2) **Goal**: Enable full keyboard-driven damage/heal workflow so the game master never needs to reach for the mouse during combat. **Independent Test**: Focus the quick input, type "7", press Enter -- value applies and input clears. Press Escape -- input clears without applying. Press Tab -- mode toggles between damage and heal while keeping focus. ### Implementation - [x] T005 [US4] Add `onKeyDown` handler to the quick input: Enter confirms and applies the value (same as existing confirm logic), Escape clears the input without applying. File: `apps/web/src/components/quick-hp-input.tsx` - [x] T006 [US4] Add Tab key handling to toggle mode while preventing default tab-to-next-element behavior. When Tab is pressed while the input is focused, flip mode (`damage` <-> `heal`) and keep focus in the input. File: `apps/web/src/components/quick-hp-input.tsx` **Checkpoint**: Full keyboard workflow functional -- Enter to apply, Escape to dismiss, Tab to toggle mode. No mouse required. --- ## Phase 3: Polish & Cross-Cutting Concerns **Purpose**: Final validation, visual polish, and quality gate - [x] T007 Verify compact resting state styling: input should be minimal/subtle when not focused and expand to full interactive state on focus. Ensure consistent look with existing combatant row elements (same height, alignment, font). File: `apps/web/src/components/quick-hp-input.tsx` - [x] T008 Run `pnpm check` (knip + format + lint + typecheck + test) and fix any issues. Ensure no unused exports, no type errors, and all existing tests still pass. --- ## Dependencies & Execution Order ### Phase Dependencies - **Phase 1 (Core Component)**: Can start immediately -- no setup or foundational work needed. Domain `adjustHp` and `useEncounter` hook already exist. - **Phase 2 (Keyboard)**: Depends on Phase 1 completion (T001-T004). Keyboard handlers are added to the existing component. - **Phase 3 (Polish)**: Depends on Phase 2 completion. ### User Story Dependencies - **US1 (Damage) + US2 (Healing) + US3 (Mode Toggle)**: Implemented together in Phase 1 as they form one inseparable component. Cannot apply damage without the mode concept, cannot toggle without both modes. - **US4 (Keyboard)**: Depends on US1+US2+US3 (the component must exist before adding keyboard handlers). ### Within Phase 1 ``` T001 (skeleton) → T002 (input logic) → T004 (integration) T001 (skeleton) → T003 (toggle UI) → T004 (integration) ``` T002 and T003 can run in parallel after T001 (different concerns in the same file, but T002 is input logic and T003 is toggle UI -- recommend sequential to avoid merge conflicts in the same file). ### Parallel Opportunities Limited parallelism due to single-file component. Recommended sequential execution: `T001 → T002 → T003 → T004 → T005 → T006 → T007 → T008` --- ## Implementation Strategy ### MVP First (Phase 1 Only) 1. Complete T001-T004 (core component + integration) 2. **STOP and VALIDATE**: Test damage and healing with mouse clicks 3. This delivers the core value: quick numeric HP adjustment ### Full Feature 1. Complete Phase 1 → Validate 2. Complete Phase 2 (keyboard workflow) → Validate 3. Complete Phase 3 (polish + quality gate) → Ready for commit --- ## Notes - No domain or application layer changes needed. All tasks are in `apps/web/src/`. - The existing `adjustHp(id, delta)` from `useEncounter` hook handles clamping, persistence, and event emission. - The `QuickHpInput` component only needs to: parse user input to integer, determine sign from mode, and call `onAdjustHp`. - Existing `CurrentHpInput` and `MaxHpInput` remain untouched per clarification.