Skip to content

ux(chargen): render stats as label-above-value grid for scannability#169

Merged
slabgorb merged 2 commits intodevelopfrom
ux/chargen-stats-grid
Apr 26, 2026
Merged

ux(chargen): render stats as label-above-value grid for scannability#169
slabgorb merged 2 commits intodevelopfrom
ux/chargen-stats-grid

Conversation

@slabgorb
Copy link
Copy Markdown
Owner

Summary

Per playtest 2026-04-26 ping-pong section [UX] Stats line on the chargen sheet is dense horizontal text — Alex-unfriendly.

The "Your Character" review surface rendered the stats row as a single dense horizontal line — STR 10 DEX 7 CON 12 INT 17 WIS 5 CHA 11 — because the server emits stats as a flat string in character_preview.stats (built in sidequest-server/sidequest/server/dispatch/chargen_summary.py ~line 193).

Per CLAUDE.md playgroup notes: Alex (slow reader) loses this at-a-glance, and Sebastien (mechanics-first) wants stats clearly visible. This PR detects the stat-line shape client-side and renders it as a 3-column label-above-value mini-grid that mirrors the creation-rolled-stats layout already used during the chargen scene where stats are rolled.

Pure presentational — wire data shape unchanged. The detector keys off the value shape (uppercase 2-4 letter label + signed integer pairs), not the literal "Stats" key, so genre packs that label the field "Vitals", "Attributes", etc. still get the scannable layout.

Files changed

  • src/components/CharacterCreation/parseStatLine.ts — new helper module (split out so react-refresh's only-export-components rule stays happy on CharacterCreation.tsx).
  • src/components/CharacterCreation/CharacterCreation.tsx — confirmation preview branch now calls parseStatLine(value) per row; if it returns pairs, render a <dl> grid with data-testid="review-stats-grid" and per-stat data-testid="review-stat-{NAME}" cells using <dt>/<dd>. Falls through to the existing <p> for non-stat rows.
  • src/components/CharacterCreation/__tests__/CharacterCreation.stats-grid.test.tsx — unit suite (10 tests): pure-helper boundary cases (canonical line, single-space tolerance, negative values, prose rejection, non-string rejection) + grid render assertions (testid present, grid-cols-3 class pinned, term/definition roles, dense one-liner not present, edit button still wired, fallback to plain text for non-stat rows, key-name agnostic).
  • src/__tests__/chargen-stats-grid-wiring.test.tsx — wiring test (per CLAUDE.md "Every Test Suite Needs a Wiring Test"): drives a CHARACTER_CREATION{phase:"confirmation"} frame through the live App → MemoryRouter → MockWebSocket pipeline (modeled on lobby-start-ws-open.test.tsx) and asserts the grid is reachable in the live DOM with all six stat cells.

Test plan

  • npx vitest run src/components/CharacterCreation/__tests__/ src/__tests__/chargen-stats-grid-wiring.test.tsx → 13/13 pass
  • npx eslint on touched files → clean (no warnings)
  • Manual verification next playtest: open chargen review surface, confirm stats render as a 3-col grid with label above value, dark aesthetic preserved (bg-background/40 border-border/30 cells, text-[var(--primary)] values).

Out of scope

  • Pre-existing failures on develop in character-creation-wiring.test.tsx (Router context error) — unrelated; flagged by playtest pingpong.

@slabgorb slabgorb merged commit 78c56a4 into develop Apr 26, 2026
1 check failed
@slabgorb slabgorb deleted the ux/chargen-stats-grid branch April 26, 2026 11:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant