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>
79 lines
3.0 KiB
Markdown
79 lines
3.0 KiB
Markdown
# 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]
|
|
```
|