Files
2026-04-01 09:14:15 +02:00

7.2 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
09-md3-components 02 execute 1
src/components/wizard/StepIndicator.tsx
src/components/wizard/StepIndicator.test.tsx
true
COMP-04
truths artifacts key_links
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)
path provides exports min_lines
src/components/wizard/StepIndicator.tsx Rebuilt MD3 step indicator with circles and connectors
StepIndicator
40
from to via pattern
src/components/wizard/StepIndicator.tsx src/store/context.tsx useWizard() hook for state.currentStep and dispatch 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.

<execution_context> @C:/Users/SebastienQUEROL/.claude/get-shit-done/workflows/execute-plan.md @C:/Users/SebastienQUEROL/.claude/get-shit-done/templates/summary.md </execution_context>

@.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:

type WizardAction =
  | { type: 'SET_STEP'; payload: number }
  | { type: 'SET_REMOTE_PARAMS'; payload: Record<string, unknown> }
  | ...

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 `<nav aria-label="Wizard steps"><ol className="flex items-center w-full">...</ol></nav>`
- Each step is an `<li>` containing a circle + label + optional connector
- Completed steps: `<button>` with checkmark icon, `bg-primary text-on-primary`, `aria-label="Go to step N: Label"`
- Active step: `<span>` with number, `border-2 border-primary bg-primary/10 text-primary font-bold`
- Future steps: `<span>` with number, `border-2 border-outline text-on-surface-container/40`
- All circles: `w-8 h-8 rounded-full flex items-center justify-center text-sm`
- Labels below circles: `text-xs mt-1 text-center`
- Connector lines between steps: `flex-1 h-0.5 mx-2`, `bg-primary` if completed else `bg-outline`
- Connector is `aria-hidden="true"`

CRITICAL for test compatibility: Completed step buttons MUST include the label text in their content so `b.textContent?.includes('Backend')` still works. Structure the button as:
```tsx
<button ...>
  <span aria-hidden="true">&#10003;</span>
  <span className="sr-only">{label}</span>
</button>
```
AND render the label as a visible `<span>` 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
<button ... aria-label={`Go to step ${i + 1}: ${label}`}>
  &#10003; {label}
</button>
```
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 `<span>` 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
<button type="button" onClick={() => handleStepClick(i)}
  className="flex flex-col items-center gap-1 shrink-0 group focus-visible:outline-none">
  <span className="w-8 h-8 rounded-full bg-primary text-on-primary flex items-center justify-center text-sm font-medium group-focus-visible:ring-2 group-focus-visible:ring-primary/50">
    &#10003;
  </span>
  <span className="text-xs text-primary">{label}</span>
</button>
```
This way `button.textContent` is `"✓Backend"` which includes "Backend".

For active and future steps (non-clickable), use a `<div>` wrapper with the circle `<span>` and label `<span>` 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

<success_criteria>

  • 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) </success_criteria>
After completion, create `.planning/phases/09-md3-components/09-02-SUMMARY.md`