Files
Ready2Blob/.planning/phases/09-md3-components/09-01-SUMMARY.md
T

74 lines
3.7 KiB
Markdown

---
phase: 09-md3-components
plan: "01"
subsystem: ui-components
tags: [md3, floating-label, aria, accessibility, debt]
dependency_graph:
requires: []
provides: [TextFieldMD3, MD3_BTN_FILLED, MD3_BTN_OUTLINED, MD3_BTN_TEXT, FieldRenderer-aria-fix]
affects: [FieldRenderer, PasswordField, RemoteConfigStep.test]
tech_stack:
added: []
patterns: [css-peer-floating-label, aria-label-direct, md3-button-constants]
key_files:
created:
- src/components/ui/TextFieldMD3.tsx
- src/components/ui/TextFieldMD3.test.tsx
- src/styles/md3-buttons.ts
- src/components/ui/FieldRenderer.test.tsx
modified:
- src/components/ui/FieldRenderer.tsx
- src/components/ui/PasswordField.tsx
- src/components/wizard/RemoteConfigStep.test.tsx
decisions:
- "Used peer-[:not(:placeholder-shown)] arbitrary variant for has-value floating label detection (Tailwind v4 supports bracket syntax)"
- "TextFieldMD3 uses placeholder=' ' (space) to drive CSS-only floating label, not JS state"
- "Updated RemoteConfigStep.test.tsx getByLabelText to add { selector: 'input' } to prevent matching tooltip button aria-labels (Rule 1 regression fix)"
metrics:
duration_seconds: 381
completed_date: "2026-04-01"
tasks_completed: 2
tasks_total: 2
files_created: 4
files_modified: 3
---
# Phase 9 Plan 01: MD3 UI Primitives Summary
**One-liner:** CSS-only floating label TextFieldMD3 component + MD3 button class constants + DEBT-01 aria-label consistency fix across FieldRenderer, PasswordField, and tooltip buttons.
## Tasks Completed
| Task | Name | Commit | Status |
|------|------|--------|--------|
| 1 | Create TextFieldMD3 + MD3 button constants | 9441dcd | Complete |
| 2 | Fix DEBT-01 aria-label in FieldRenderer + tests | 532a994 | Complete |
## Verification
- `npx vitest run src/components/ui/TextFieldMD3.test.tsx` — 9/9 tests pass
- `npx vitest run src/components/ui/FieldRenderer.test.tsx` — 4/4 tests pass
- `npx vitest run --reporter=dot` — 179/179 tests pass (zero regressions)
- `src/styles/md3-buttons.ts` exports `MD3_BTN_FILLED`, `MD3_BTN_OUTLINED`, `MD3_BTN_TEXT`
## Decisions Made
1. **Tailwind v4 `peer-[:not(:placeholder-shown)]` arbitrary variant:** Used the bracket syntax form directly — verified it passes through the test suite correctly. No need for the `data-has-value` JS fallback.
2. **`placeholder=" "` (space) for floating label:** TextFieldMD3 always renders with `placeholder=" "` and `placeholder-transparent` CSS. This is the CSS-only detection mechanism for the `:not(:placeholder-shown)` pseudo-class — no React state needed.
3. **`{ selector: 'input' }` added to RemoteConfigStep.test.tsx:** Once tooltip buttons received `aria-label="More info about {field.label}"`, the `getByLabelText(/sas url/i)` query matched both the input (via its `<label>` association) and the tooltip button (via its `aria-label`). Fixed by scoping the query to `{ selector: 'input' }` in 6 call sites. This is correct behavior — the tests were too broad before.
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 1 - Bug] Test regression from DEBT-01 aria-label fix**
- **Found during:** Task 2, after fixing FieldRenderer.tsx
- **Issue:** `getByLabelText(/sas url/i)` in RemoteConfigStep.test.tsx started matching both the PasswordField input (via label association) AND the new tooltip button `aria-label="More info about SAS URL"`, causing "Found multiple elements" errors in 9 tests.
- **Fix:** Added `{ selector: 'input' }` option to 6 `getByLabelText` call sites in RemoteConfigStep.test.tsx that queried fields with tooltip buttons. This scopes the accessible name lookup to input elements only.
- **Files modified:** `src/components/wizard/RemoteConfigStep.test.tsx`
- **Commit:** 532a994 (included in Task 2 commit)
## Self-Check: PASSED