Implement the 010-ui-baseline feature that establishes a modern UI using Tailwind CSS v4 and shadcn/ui-style components for the encounter screen
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
78
specs/010-ui-baseline/contracts/ui-components.md
Normal file
78
specs/010-ui-baseline/contracts/ui-components.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# UI Component Contracts: UI Baseline
|
||||
|
||||
**Feature**: 010-ui-baseline | **Date**: 2026-03-05
|
||||
|
||||
## Layout Contract
|
||||
|
||||
The encounter screen follows a single-column layout with three zones:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ EncounterHeader │
|
||||
│ Title + Round/Turn status │
|
||||
├─────────────────────────────────┤
|
||||
│ CombatantList │
|
||||
│ ┌─ CombatantRow (active) ───┐ │
|
||||
│ │ Init │ Name │ HP │ Actions│ │
|
||||
│ └───────────────────────────┘ │
|
||||
│ ┌─ CombatantRow ────────────┐ │
|
||||
│ │ Init │ Name │ HP │ Actions│ │
|
||||
│ └───────────────────────────┘ │
|
||||
│ ... (scrollable if overflow) │
|
||||
│ │
|
||||
│ [EmptyState if no combatants] │
|
||||
├─────────────────────────────────┤
|
||||
│ ActionBar │
|
||||
│ [Name input] [Add] [Next Turn] │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
## CombatantRow Contract
|
||||
|
||||
**Props**:
|
||||
- `combatant: Combatant` — domain entity
|
||||
- `isActive: boolean` — whether this is the active turn
|
||||
- `onRename: (id, newName) => void`
|
||||
- `onSetInitiative: (id, value) => void`
|
||||
- `onRemove: (id) => void`
|
||||
- `onSetHp: (id, maxHp) => void`
|
||||
- `onAdjustHp: (id, delta) => void`
|
||||
|
||||
**Visual contract**:
|
||||
- Row uses consistent column widths across all combatant rows
|
||||
- Active row has visually distinct highlight (accent background or left border)
|
||||
- Name column truncates with ellipsis at max width
|
||||
- Remove action is an icon button (no text label)
|
||||
- All inputs use design system styling (no browser defaults)
|
||||
|
||||
**Interaction contract**:
|
||||
- Click name → enter inline edit mode
|
||||
- Enter/blur in edit mode → commit change
|
||||
- Escape in edit mode → cancel
|
||||
- Initiative input is always visible (not click-to-edit), direct typing only
|
||||
- HP inputs are direct-entry text fields with numeric keyboard (`inputmode="numeric"`)
|
||||
- All numeric inputs: no browser spinners, ch-based widths (`6ch`), tabular numerals, centered text
|
||||
|
||||
## ActionBar Contract
|
||||
|
||||
**Props**:
|
||||
- `onAddCombatant: (name: string) => void`
|
||||
- `onAdvanceTurn: () => void`
|
||||
|
||||
**Visual contract**:
|
||||
- Visually separated from combatant list (spacing, background, or border)
|
||||
- Add form: text input + submit button in a row
|
||||
- Next Turn: distinct button, visually secondary to Add
|
||||
|
||||
**Interaction contract**:
|
||||
- Enter in name input → add combatant + clear input
|
||||
- Empty name → no action (button may be disabled or form simply ignores)
|
||||
|
||||
## EmptyState Contract
|
||||
|
||||
**Displayed when**: `encounter.combatants.length === 0`
|
||||
|
||||
**Visual contract**:
|
||||
- Centered message in the combatant list area
|
||||
- Muted/secondary text color
|
||||
- Suggests adding a combatant
|
||||
Reference in New Issue
Block a user