docs(11-02): complete step animation and scroll-to-error plan

- Create 11-02-SUMMARY.md documenting POLISH-03 and POLISH-04 completion
- Update STATE.md: phase 11 complete, 100% progress, new decisions added
- Update ROADMAP.md: phase 11 plan progress (2/2 complete)
- Update REQUIREMENTS.md: mark POLISH-03 and POLISH-04 complete
This commit is contained in:
2026-04-01 13:32:39 +02:00
parent 90cdeda142
commit 0c27818030
4 changed files with 142 additions and 20 deletions
+4 -4
View File
@@ -28,8 +28,8 @@
- [x] **POLISH-01**: Wizard layout adapts to mobile screens — backend cards stack, form fields go full-width, step indicator collapses, buttons stretch
- [x] **POLISH-02**: All interactive elements have visible MD3 focus indicators (3px outline) using `focus-visible` for keyboard navigation
- [ ] **POLISH-03**: Step transitions use subtle fade/slide animation that respects `prefers-reduced-motion`
- [ ] **POLISH-04**: On validation failure, the view auto-scrolls to the first errored field
- [x] **POLISH-03**: Step transitions use subtle fade/slide animation that respects `prefers-reduced-motion`
- [x] **POLISH-04**: On validation failure, the view auto-scrolls to the first errored field
### Tech Debt
@@ -69,8 +69,8 @@
| UX-04 | Phase 10 | Complete |
| POLISH-01 | Phase 11 | Complete |
| POLISH-02 | Phase 11 | Complete |
| POLISH-03 | Phase 11 | Pending |
| POLISH-04 | Phase 11 | Pending |
| POLISH-03 | Phase 11 | Complete |
| POLISH-04 | Phase 11 | Complete |
**Coverage:**
- v1.2 requirements: 15 total
+3 -3
View File
@@ -38,7 +38,7 @@ Full phase details: [.planning/milestones/v1.1-ROADMAP.md](milestones/v1.1-ROADM
- [x] **Phase 8: Theme Foundation** - MD3 color token system and dark mode infrastructure (completed 2026-04-01)
- [x] **Phase 9: MD3 Components** - UI primitives and component migration to semantic tokens (completed 2026-04-01)
- [x] **Phase 10: Content & Clarity** - Intro section, step descriptions, and contextual help (completed 2026-04-01)
- [ ] **Phase 11: Polish & Responsiveness** - Mobile layout, focus states, transitions, scroll-to-error
- [x] **Phase 11: Polish & Responsiveness** - Mobile layout, focus states, transitions, scroll-to-error (completed 2026-04-01)
## Phase Details
@@ -98,7 +98,7 @@ Plans:
2. Every interactive element shows a visible 3px MD3 focus outline when navigated via keyboard (using `focus-visible`)
3. Step transitions use a subtle fade/slide animation that is suppressed when the user has `prefers-reduced-motion` enabled
4. When form validation fails, the view auto-scrolls to the first field with an error
**Plans:** 1/2 plans executed
**Plans:** 2/2 plans complete
Plans:
- [ ] 11-01-PLAN.md — Mobile responsive layout + MD3 focus-visible indicators
- [ ] 11-02-PLAN.md — Step transition animation + auto-scroll to first error
@@ -117,4 +117,4 @@ Plans:
| 8. Theme Foundation | v1.2 | 2/2 | Complete | 2026-04-01 |
| 9. MD3 Components | v1.2 | 5/5 | Complete | 2026-04-01 |
| 10. Content & Clarity | v1.2 | 3/3 | Complete | 2026-04-01 |
| 11. Polish & Responsiveness | 1/2 | In Progress| | - |
| 11. Polish & Responsiveness | 2/2 | Complete | 2026-04-01 | - |
+15 -13
View File
@@ -3,15 +3,15 @@ gsd_state_version: 1.0
milestone: v1.2
milestone_name: UI Polish & Clarity
status: completed
stopped_at: Completed 11-01-PLAN.md
last_updated: "2026-04-01T11:26:15.869Z"
last_activity: 2026-04-01 — Phase 11 plan 01 complete (POLISH-01, POLISH-02 satisfied)
stopped_at: Completed 11-02-PLAN.md
last_updated: "2026-04-01T11:32:08.129Z"
last_activity: 2026-04-01 — Phase 11 plan 02 complete (POLISH-03, POLISH-04 satisfied)
progress:
total_phases: 4
completed_phases: 3
completed_phases: 4
total_plans: 12
completed_plans: 11
percent: 98
completed_plans: 12
percent: 100
---
# Project State
@@ -25,12 +25,12 @@ See: .planning/PROJECT.md (updated 2026-03-31)
## Current Position
Phase: 11 of 11 (Polish & Responsiveness) — In Progress
Plan: 11-01 (complete)
Status: Phase 11 in progress, plan 11-01 complete (POLISH-01, POLISH-02 satisfied)
Last activity: 2026-04-01 — Phase 11 plan 01 complete (POLISH-01, POLISH-02 satisfied)
Phase: 11 of 11 (Polish & Responsiveness) — Complete
Plan: 11-02 (complete)
Status: Phase 11 complete — all plans done (POLISH-01, POLISH-02, POLISH-03, POLISH-04 satisfied)
Last activity: 2026-04-01 — Phase 11 plan 02 complete (POLISH-03, POLISH-04 satisfied)
Progress: [██████████] 98% (v1.2)
Progress: [██████████] 100% (v1.2)
## Accumulated Context
@@ -67,6 +67,8 @@ Recent decisions affecting current work:
- [Phase 11-polish-responsiveness]: ring-inset on ThemeToggle focus ring because overflow-hidden on container clips outset rings
- [Phase 11-polish-responsiveness]: No ring-offset-2 on BackendCard to avoid dark mode surface color issues
- [Phase 11-polish-responsiveness]: FieldRenderer select uses focus-visible:ring-2 (not focus:ring-2) for keyboard-only ring on selects
- [Phase 11-polish-responsiveness]: CSS-only reduced-motion guard via @media (prefers-reduced-motion: reduce) — no JS listener needed
- [Phase 11-polish-responsiveness]: key={state.currentStep} on step wrapper forces React remount triggering CSS animation from initial state
### Pending Todos
@@ -78,6 +80,6 @@ None yet.
## Session Continuity
Last session: 2026-04-01T11:26:10.100Z
Stopped at: Completed 11-01-PLAN.md
Last session: 2026-04-01T11:32:08.126Z
Stopped at: Completed 11-02-PLAN.md
Resume file: None
@@ -0,0 +1,120 @@
---
phase: 11-polish-responsiveness
plan: 02
subsystem: ui
tags: [react, tailwind, css-animation, react-hook-form, accessibility, reduced-motion]
# Dependency graph
requires:
- phase: 11-01
provides: focus rings and BackendCard hover states (polish foundation)
- phase: 10-content-clarity
provides: App.tsx WizardShell structure with step content wrapper
provides:
- CSS @keyframes step-in animation with 200ms ease-out fade/slide-up on step change
- prefers-reduced-motion guard disabling animation for accessibility
- Auto-scroll to first errored field on validation failure in BackendSelectionStep and RemoteConfigStep
affects: [11-03, any future plan modifying App.tsx WizardShell or wizard form steps]
# Tech tracking
tech-stack:
added: []
patterns:
- "key={state.currentStep} on step wrapper forces React remount, triggering CSS animation from initial state"
- "@theme --animate-step-in token pattern for Tailwind v4 custom animation utility"
- "onInvalidSubmit second arg to handleSubmit for scroll-to-error without JS media query listener"
- "document.getElementById(firstKey)?.scrollIntoView for registry-driven field error targeting"
key-files:
created: []
modified:
- src/index.css
- src/App.tsx
- src/components/wizard/BackendSelectionStep.tsx
- src/components/wizard/BackendSelectionStep.test.tsx
- src/components/wizard/RemoteConfigStep.tsx
- src/components/wizard/RemoteConfigStep.test.tsx
key-decisions:
- "CSS-only reduced-motion guard via @media (prefers-reduced-motion: reduce) — no JS listener needed"
- "key={state.currentStep} on step wrapper (not on step components themselves) to trigger animation"
- "onInvalidSubmit hardcodes getElementById('remote-name') in BackendSelectionStep — only one validatable field exists"
- "FieldErrors type added to react-hook-form imports in RemoteConfigStep for typed errors param"
patterns-established:
- "Tailwind v4 custom animation: register --animate-X in @theme, define @keyframes, add reduced-motion guard"
- "react-hook-form scroll-to-error: pass onInvalidSubmit as second arg to handleSubmit"
requirements-completed: [POLISH-03, POLISH-04]
# Metrics
duration: 3min
completed: 2026-04-01
---
# Phase 11 Plan 02: Polish & Responsiveness — Animation & Scroll-to-Error Summary
**CSS step-in animation (200ms fade/slide-up) with reduced-motion guard, plus auto-scroll to first errored form field via react-hook-form onInvalidSubmit handler**
## Performance
- **Duration:** 3 min
- **Started:** 2026-04-01T11:28:03Z
- **Completed:** 2026-04-01T11:31:00Z
- **Tasks:** 2 (Task 2 used TDD: RED → GREEN)
- **Files modified:** 6
## Accomplishments
- Wizard step transitions now play a 200ms opacity/translateY(8px) fade-slide animation on step change
- Users with `prefers-reduced-motion` enabled see zero animation (declarative CSS guard, no JS)
- BackendSelectionStep scrolls to `remote-name` input when form submitted with invalid/empty name
- RemoteConfigStep scrolls to the first errored field (by key) when form submitted with missing required fields
- Both scroll behaviors verified by unit tests with `vi.fn()` mock on `Element.prototype.scrollIntoView`
- Full test suite: 204 tests pass, 0 failures, 0 regressions
## Task Commits
Each task was committed atomically:
1. **Task 1: Step transition animation with reduced-motion guard** - `9af58bc` (feat)
2. **Task 2 RED: Failing tests for auto-scroll to first error** - `8b7daa8` (test)
3. **Task 2 GREEN: Auto-scroll to first errored field implementation** - `90cdeda` (feat)
**Plan metadata:** (docs commit follows)
_Note: Task 2 used TDD — separate test commit (RED) then implementation commit (GREEN)._
## Files Created/Modified
- `src/index.css` - Added `--animate-step-in` token in `@theme`, `@keyframes step-in`, and `@media prefers-reduced-motion: reduce` guard
- `src/App.tsx` - Step content wrapper: added `key={state.currentStep}` and `animate-step-in` class
- `src/components/wizard/BackendSelectionStep.tsx` - Added `onInvalidSubmit` scrolling to `remote-name`, wired to form `onSubmit` and `handleCardClick`
- `src/components/wizard/BackendSelectionStep.test.tsx` - Added `scrollIntoView` mock in `beforeEach`, added POLISH-04 scroll test
- `src/components/wizard/RemoteConfigStep.tsx` - Added `FieldErrors` import, `onInvalidSubmit` scrolling to first error key, wired to form `onSubmit`
- `src/components/wizard/RemoteConfigStep.test.tsx` - Added `scrollIntoView` mock in `beforeEach`, added POLISH-04 scroll test
## Decisions Made
- CSS-only reduced-motion guard via `@media (prefers-reduced-motion: reduce)` — consistent with existing `prefers-reduced-motion: no-preference` pattern at line 45 of index.css. No JS listener.
- `key={state.currentStep}` on the step content wrapper div (not on step components themselves) — forces React to unmount/remount the wrapper, reliably triggering the CSS animation from its `from` state on every step change.
- BackendSelectionStep `onInvalidSubmit` uses `getElementById('remote-name')` directly (hardcoded) — only one validatable field exists in that step, no dynamic key needed.
- Added `FieldErrors` to react-hook-form imports in RemoteConfigStep (alongside existing `FieldError`) for typed `errors` parameter in `onInvalidSubmit`.
## Deviations from Plan
None - plan executed exactly as written.
## Issues Encountered
None.
## User Setup Required
None - no external service configuration required.
## Next Phase Readiness
- POLISH-03 (step animation) and POLISH-04 (scroll-to-error) are complete
- Phase 11 plan 02 satisfies all must_haves and success criteria
- Ready for plan 11-03 if it exists, or phase 11 completion
---
*Phase: 11-polish-responsiveness*
*Completed: 2026-04-01*