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>
3.0 KiB
3.0 KiB
Data Model: Bottom Bar Overhaul
Existing Domain Entities (no changes)
Combatant
Already supports all fields needed for custom creature input:
| Field | Type | Notes |
|---|---|---|
| id | CombatantId (branded string) | Auto-generated (c-1, c-2, ...) |
| name | string | Required, non-empty |
| initiative | number? | Optional — new: settable at add time for custom creatures |
| maxHp | number? | Optional — new: settable at add time for custom creatures |
| currentHp | number? | Optional — set equal to maxHp when provided |
| ac | number? | Optional — new: settable at add time for custom creatures |
| conditions | readonly ConditionId[]? | Not relevant to this feature |
| isConcentrating | boolean? | Not relevant to this feature |
| creatureId | CreatureId? | Set for bestiary creatures, absent for custom |
SearchResult (BestiaryIndexEntry)
| Field | Type | Notes |
|---|---|---|
| name | string | Creature name |
| source | string | Source code (e.g., "srd") |
| sourceDisplayName | string | Display name of sourcebook |
| ac | number | Armor class |
| hp | number | Average HP |
| dex | number | Dexterity score |
| cr | string | Challenge rating |
| size | string | Size category |
| type | string | Creature type |
New UI-Only State (ephemeral, not persisted)
QueuedCreature
Transient state held in the action bar component representing a bestiary creature selected for batch-add.
| Field | Type | Notes |
|---|---|---|
| result | SearchResult | The bestiary entry to add |
| count | number | Number of copies to add (starts at 1, increments on re-click) |
Lifecycle: Created on first click of a dropdown entry. Incremented on re-click of same entry. Replaced on click of different entry. Cleared on confirm, Escape, or when the queued creature leaves search results.
CustomCreatureFields
Transient state held in the action bar component for optional fields shown when no bestiary match exists.
| Field | Type | Notes |
|---|---|---|
| initiative | string | Raw input (parsed to number on submit, empty = omit) |
| ac | string | Raw input (parsed to number on submit, empty = omit) |
| maxHp | string | Raw input (parsed to number on submit, empty = omit) |
Lifecycle: Visible when search query yields no bestiary results. Cleared on submit or when bestiary results appear.
State Transitions
[Empty input]
→ type 2+ chars with matches → [Dropdown with bestiary results]
→ type 2+ chars without matches → [Custom creature fields visible]
[Dropdown with bestiary results]
→ click entry → [Queue: entry x1]
→ click same entry → [Queue: entry x(N+1)]
→ click different entry → [Queue: new entry x1]
→ click confirm / Enter → add N copies → [Empty input]
→ Escape → [Empty input]
→ change query (queued creature gone from results) → [Queue cleared]
[Custom creature fields visible]
→ submit → add custom creature with optional fields → [Empty input]
→ type changes to match bestiary → [Dropdown with bestiary results]