Files

3.7 KiB

phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
phase plan subsystem tags dependency_graph tech_stack key_files decisions metrics
09-md3-components 01 ui-components
md3
floating-label
aria
accessibility
debt
requires provides affects
TextFieldMD3
MD3_BTN_FILLED
MD3_BTN_OUTLINED
MD3_BTN_TEXT
FieldRenderer-aria-fix
FieldRenderer
PasswordField
RemoteConfigStep.test
added patterns
css-peer-floating-label
aria-label-direct
md3-button-constants
created modified
src/components/ui/TextFieldMD3.tsx
src/components/ui/TextFieldMD3.test.tsx
src/styles/md3-buttons.ts
src/components/ui/FieldRenderer.test.tsx
src/components/ui/FieldRenderer.tsx
src/components/ui/PasswordField.tsx
src/components/wizard/RemoteConfigStep.test.tsx
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)
duration_seconds completed_date tasks_completed tasks_total files_created files_modified
381 2026-04-01 2 2 4 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