--- phase: 09-md3-components plan: 02 type: execute wave: 1 depends_on: [] files_modified: - src/components/wizard/StepIndicator.tsx - src/components/wizard/StepIndicator.test.tsx autonomous: true requirements: [COMP-04] must_haves: truths: - "Step indicator shows numbered circles for each wizard step" - "Completed steps display a checkmark and are clickable buttons" - "Current step is visually highlighted with primary color" - "Future steps appear muted" - "Connector lines link steps — filled for completed, muted for future" - "Clicking step 0 dispatches SET_REMOTE_PARAMS({}) then SET_STEP(0)" artifacts: - path: "src/components/wizard/StepIndicator.tsx" provides: "Rebuilt MD3 step indicator with circles and connectors" exports: ["StepIndicator"] min_lines: 40 key_links: - from: "src/components/wizard/StepIndicator.tsx" to: "src/store/context.tsx" via: "useWizard() hook for state.currentStep and dispatch" pattern: "useWizard" --- Rebuild StepIndicator from text breadcrumbs to MD3 visual step indicator with numbered circles, connector lines, checkmarks on completed steps, and proper semantic tokens. Purpose: Replace the current text-based breadcrumb (using inline styles and hardcoded colors) with an MD3-compliant visual stepper that is dark-mode aware and accessible. Output: Rebuilt StepIndicator.tsx + updated tests. @C:/Users/SebastienQUEROL/.claude/get-shit-done/workflows/execute-plan.md @C:/Users/SebastienQUEROL/.claude/get-shit-done/templates/summary.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/09-md3-components/09-RESEARCH.md @src/components/wizard/StepIndicator.tsx @src/components/wizard/StepIndicator.test.tsx From src/store/context.tsx: ```typescript function useWizard(): { state: WizardState; dispatch: Dispatch } ``` From src/store/types.ts: ```typescript type WizardAction = | { type: 'SET_STEP'; payload: number } | { type: 'SET_REMOTE_PARAMS'; payload: Record } | ... ``` Current StepIndicator test selectors (MUST remain compatible): - `screen.getByText(/Backend/)` — finds step label - `screen.getAllByRole('button')` — finds completed step buttons - `buttons.find(b => b.textContent?.includes('Backend'))` — locates specific step button - `screen.findByText(/Deployment/)` — finds step label async Task 1: Rebuild StepIndicator with MD3 circles and connectors src/components/wizard/StepIndicator.tsx, src/components/wizard/StepIndicator.test.tsx Rebuild `src/components/wizard/StepIndicator.tsx` from the text breadcrumb to a visual MD3 step indicator. Keep the existing `handleStepClick` logic EXACTLY as-is (SET_REMOTE_PARAMS({}) before SET_STEP when going to step 0). Remove ALL inline `style={{}}` props. Structure (from research Pattern 4): - Wrap in `` - Each step is an `
  • ` containing a circle + label + optional connector - Completed steps: ` ``` AND render the label as a visible `` adjacent to the button (inside the same flex container). The test checks `b.textContent?.includes('Backend')` on the button element itself, so the label text must be INSIDE the button. Use: ```tsx ``` This way `textContent` includes "Backend" and `aria-label` provides accessible name. The visual label below the circle can be separate. Actually, looking at the test more carefully: the label text appears as a visible `` below the circle in the new design. But the button `textContent` needs to include the label for the test. Solution: render the label text INSIDE the button element so textContent includes it, and use CSS to visually position it below the circle icon. Simplest approach that preserves tests: make the completed step button contain BOTH the checkmark and the label text: ```tsx ``` This way `button.textContent` is `"✓Backend"` which includes "Backend". For active and future steps (non-clickable), use a `
    ` wrapper with the circle `` and label `` inside. Update `StepIndicator.test.tsx` only if needed. The existing 5 tests should pass with this structure since: - `screen.getByText(/Backend/)` will match the label span - `screen.getAllByRole('button')` finds completed step buttons - `buttons.find(b => b.textContent?.includes('Backend'))` works because label is inside button - Dispatch behavior is unchanged Run the full test suite after rebuild to catch any regressions. npx vitest run src/components/wizard/StepIndicator.test.tsx --reporter=dot && npx vitest run --reporter=dot StepIndicator renders numbered circles connected by lines, completed steps show checkmarks and are clickable, current step is highlighted, future steps are muted. All inline styles removed. All 5 existing WIZD-03 tests pass. No regressions in full suite. - `npx vitest run src/components/wizard/StepIndicator.test.tsx` — all 5 WIZD-03 tests pass - `npx vitest run --reporter=dot` — full suite green - No inline `style={{}}` props remain in StepIndicator.tsx - No hardcoded color values (`#999`, etc.) remain - StepIndicator uses MD3 circles with numbered/checkmark states - Connector lines between steps show progress visually - All semantic tokens used (no hardcoded colors) - All existing tests pass without modification (or with minimal test selector updates if button textContent changed) After completion, create `.planning/phases/09-md3-components/09-02-SUMMARY.md`