Overhaul bottom bar: batch add, custom fields, stat block viewer

Unify the action bar into a single search input with inline bestiary
dropdown. Clicking a dropdown entry queues it with +/- count controls
and a confirm button; Enter or confirm adds N copies to combat.

When no bestiary match exists, optional Init/AC/MaxHP fields appear
for custom creatures. The eye icon opens a separate search dropdown
to preview stat blocks without leaving the add flow.

Fix batch-add bug where only the last creature got a creatureId by
using store.save() instead of setEncounter() in addFromBestiary.
Prevent dropdown buttons from stealing input focus so Enter confirms
the queued batch.

Remove the now-redundant BestiarySearch component.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lukas
2026-03-11 15:27:06 +01:00
parent 460c65bf49
commit b6e052f198
13 changed files with 931 additions and 213 deletions

View File

@@ -0,0 +1,68 @@
# Implementation Plan: Bottom Bar Overhaul
**Branch**: `036-bottombar-overhaul` | **Date**: 2026-03-11 | **Spec**: [spec.md](./spec.md)
**Input**: Feature specification from `/specs/036-bottombar-overhaul/spec.md`
## Summary
Overhaul the bottom bar action bar to support batch-adding predefined creatures (click-to-queue with count + confirm), optional stat fields for custom creatures (initiative, AC, max HP), stat block preview from the search dropdown, and improved placeholder text. All changes are in the adapter (web) layer — no domain or application changes needed. The existing `addFromBestiary` hook method is called N times in a loop for batch adds.
## Technical Context
**Language/Version**: TypeScript 5.8 (strict mode, `verbatimModuleSyntax`)
**Primary Dependencies**: React 19, Tailwind CSS v4, Lucide React (icons)
**Storage**: N/A (no persistence changes — queue state and custom fields are ephemeral)
**Testing**: Vitest (unit tests for any extracted logic)
**Target Platform**: Web (desktop + mobile responsive)
**Project Type**: Web application (monorepo: apps/web, packages/domain, packages/application)
**Performance Goals**: Instant UI response for queue interactions
**Constraints**: Local-first, single-user, offline-capable
**Scale/Scope**: Single encounter screen, bottom bar component
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
| Principle | Status | Notes |
|-----------|--------|-------|
| I. Deterministic Domain Core | PASS | No domain changes. Queue state is UI-only. |
| II. Layered Architecture | PASS | All changes in adapter layer (apps/web). Calls existing domain/application functions. |
| III. Clarification-First | PASS | No non-trivial assumptions — spec is detailed. |
| IV. Escalation Gates | PASS | Implementation stays within spec scope. |
| V. MVP Baseline Language | PASS | No permanent bans introduced. |
| VI. No Gameplay Rules | PASS | No gameplay mechanics in plan. |
## Project Structure
### Documentation (this feature)
```text
specs/036-bottombar-overhaul/
├── plan.md # This file
├── research.md # Phase 0 output
├── data-model.md # Phase 1 output
├── quickstart.md # Phase 1 output
└── tasks.md # Phase 2 output (/speckit.tasks)
```
### Source Code (repository root)
```text
apps/web/src/
├── components/
│ ├── action-bar.tsx # MODIFY: overhaul with batch queue, custom fields, stat block button
│ └── bestiary-search.tsx # MODIFY or REMOVE: functionality merges into action-bar
├── hooks/
│ └── use-encounter.ts # EXISTING: addFromBestiary called N times for batch
├── App.tsx # MODIFY: pass stat block view callback to action bar
packages/domain/src/
├── add-combatant.ts # EXISTING: no changes
├── auto-number.ts # EXISTING: handles name deduplication for batch adds
└── types.ts # EXISTING: Combatant already has initiative?, ac?, maxHp?
```
**Structure Decision**: All changes are within `apps/web/src/components/` (adapter layer). The action bar component is the primary modification target. The existing `BestiarySearch` component's dropdown functionality will be integrated directly into the action bar's unified search flow. No new packages or layers needed.
## Complexity Tracking
> No constitution violations. Table intentionally left empty.