Implement stat block panel fold/unfold and pin-to-second-panel
Replace the close button and heading with fold/unfold controls that collapse the panel to a slim right-edge tab showing the creature name vertically, and add a pin button (xl+ viewports with creature loaded) that opens the creature in a second left-side panel for simultaneous reference. Fold state is respected on turn change. 19 acceptance tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
62
specs/035-statblock-fold-pin/data-model.md
Normal file
62
specs/035-statblock-fold-pin/data-model.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Data Model: Stat Block Panel Fold/Unfold and Pin
|
||||
|
||||
**Feature**: 035-statblock-fold-pin
|
||||
**Date**: 2026-03-11
|
||||
|
||||
## Entities
|
||||
|
||||
### Panel State
|
||||
|
||||
This feature introduces UI-only ephemeral state — no persistence changes, no domain model changes.
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `selectedCreatureId` | `CreatureId \| null` | Currently browsed creature (right panel). **Exists already.** |
|
||||
| `pinnedCreatureId` | `CreatureId \| null` | Creature locked to left panel. **New.** |
|
||||
| `isRightPanelFolded` | `boolean` | Whether the right (browse) panel is collapsed to a tab. **New.** |
|
||||
|
||||
### State Transitions
|
||||
|
||||
```
|
||||
No panel → Open panel
|
||||
Trigger: Click combatant row / auto-show on turn change
|
||||
Effect: selectedCreatureId = creatureId, isRightPanelFolded = false
|
||||
|
||||
Open panel → Folded tab
|
||||
Trigger: Click fold button
|
||||
Effect: isRightPanelFolded = true (selectedCreatureId preserved)
|
||||
|
||||
Folded tab → Open panel
|
||||
Trigger: Click folded tab
|
||||
Effect: isRightPanelFolded = false
|
||||
|
||||
Open panel → Open panel + Pinned panel
|
||||
Trigger: Click pin button (xl+ viewport only)
|
||||
Effect: pinnedCreatureId = selectedCreatureId
|
||||
|
||||
Pinned panel → No pinned panel
|
||||
Trigger: Click unpin button
|
||||
Effect: pinnedCreatureId = null
|
||||
|
||||
Open panel (mobile) → Dismissed
|
||||
Trigger: Click backdrop
|
||||
Effect: selectedCreatureId = null
|
||||
```
|
||||
|
||||
### Viewport Breakpoints
|
||||
|
||||
| Breakpoint | Panels Available | Pin Button |
|
||||
|------------|-----------------|------------|
|
||||
| < 1024px (mobile) | Mobile drawer only | Hidden |
|
||||
| 1024px–1279px (lg) | Right panel only | Hidden |
|
||||
| >= 1280px (xl) | Right + optional left pinned | Visible |
|
||||
|
||||
## Existing Entities (Unchanged)
|
||||
|
||||
- **Creature** (`CreatureId`, `name`, stats…) — read-only, no changes
|
||||
- **Encounter state** — no changes
|
||||
- **Bestiary cache** — no changes
|
||||
|
||||
## Persistence
|
||||
|
||||
No persistence changes. All new state (pinnedCreatureId, isRightPanelFolded) is ephemeral React component state that resets on page reload. This aligns with the existing pattern where selectedCreatureId is also ephemeral.
|
||||
Reference in New Issue
Block a user