---
phase: 09-md3-components
plan: 05
type: execute
wave: 2
depends_on: ["09-04"]
files_modified:
- src/components/ui/TextFieldMD3.tsx
- src/components/ui/TextFieldMD3.test.tsx
- src/components/ui/FieldRenderer.tsx
- src/components/ui/FieldRenderer.test.tsx
- src/components/ui/PasswordField.tsx
autonomous: true
gap_closure: true
requirements: [COMP-04]
must_haves:
truths:
- "Hovering the tooltip info button reveals tooltip text without clicking"
- "Clicking the tooltip info button pins it open; clicking again dismisses it"
- "Tooltip icon appears beside the helpText below the field, not above the field"
- "Tooltip icon renders even when field has tooltipText but no helpText"
artifacts:
- path: "src/components/ui/TextFieldMD3.tsx"
provides: "helpTextPrefix prop for rendering inline content left of helpText"
contains: "helpTextPrefix"
- path: "src/components/ui/FieldRenderer.tsx"
provides: "Tooltip icon passed as helpTextPrefix, hover+click behavior"
contains: "onMouseEnter"
- path: "src/components/ui/PasswordField.tsx"
provides: "Same tooltip fix as FieldRenderer text-branch"
contains: "onMouseEnter"
key_links:
- from: "src/components/ui/FieldRenderer.tsx"
to: "src/components/ui/TextFieldMD3.tsx"
via: "helpTextPrefix prop"
pattern: "helpTextPrefix.*ⓘ"
- from: "src/components/ui/PasswordField.tsx"
to: "src/components/ui/TextFieldMD3.tsx"
via: "helpTextPrefix prop"
pattern: "helpTextPrefix.*ⓘ"
---
Fix two UAT-reported tooltip issues: (1) tooltip doesn't show on hover, only on click; (2) tooltip icon is positioned above the field instead of beside the helpText below it.
Purpose: Close the last remaining UAT gap in Phase 9 (test 7: Tooltip Info Buttons Accessibility).
Output: Tooltip icon renders inline with helpText below the field, and tooltip text appears on hover (pinnable via click).
@C:/Users/SebastienQUEROL/.claude/get-shit-done/workflows/execute-plan.md
@C:/Users/SebastienQUEROL/.claude/get-shit-done/templates/summary.md
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/09-md3-components/09-03-SUMMARY.md
From src/components/ui/TextFieldMD3.tsx:
```typescript
interface TextFieldMD3Props {
id: string;
label: string;
error?: FieldError;
registration: UseFormRegisterReturn;
type?: 'text' | 'password';
helpText?: string;
required?: boolean;
suffix?: React.ReactNode;
}
```
From src/components/ui/FieldRenderer.tsx:
```typescript
// text (default) — uses TextFieldMD3 for floating label
return (
)}
```
IMPORTANT: The outer guard MUST be `(helpText || helpTextPrefix) && !error` — not just `helpText && !error`. This ensures the tooltip icon (passed as helpTextPrefix) still renders when a field has `tooltipText` but no `helpText`. The inner `helpText &&` guard prevents an empty `
` tag when helpText is absent.
**FieldRenderer.tsx — Fix text-branch tooltip (lines 83-109):**
1. Remove the tooltip `
cd C:/Users/SebastienQUEROL/Documents/projets/Ready2Blob && npx vitest run --reporter=verbose 2>&1 | tail -30
- Tooltip icon renders inline to the left of helpText below the field (not above the field)
- Tooltip icon renders even when field has tooltipText but no helpText (guard is helpText || helpTextPrefix)
- Hovering the tooltip icon shows tooltip text
- Clicking the tooltip icon pins tooltip open; clicking again dismisses
- Mouse-leaving the icon hides tooltip (unless pinned via click)
- All existing tests pass including FieldRenderer aria-label tests
- PasswordField has identical fix
Task 2: Add tests for tooltip hover behavior and helpTextPrefix renderingsrc/components/ui/FieldRenderer.test.tsx, src/components/ui/TextFieldMD3.test.tsx
- Test: Hovering tooltip button shows tooltip text (fireEvent.mouseEnter on button, then expect tooltipText visible)
- Test: Mouse-leaving tooltip button hides tooltip text (fireEvent.mouseLeave, then expect tooltipText not visible)
- Test: Clicking tooltip button pins tooltip open, mouseLeave does NOT hide it
- Test: TextFieldMD3 renders helpTextPrefix inline with helpText when prop provided
- Test: TextFieldMD3 renders helpText normally when helpTextPrefix is not provided
- Test: TextFieldMD3 renders helpTextPrefix alone when helpText is absent (tooltip-only field)
**FieldRenderer.test.tsx — Add hover behavior tests:**
Add a new describe block `'FieldRenderer - tooltip hover behavior'` with these tests:
1. `'hovering tooltip button shows tooltip text'`:
- Render FieldRenderer with `textFieldWithTooltip` (already defined in test file)
- Get tooltip button via `screen.getByRole('button', { name: /more info about bucket name/i })`
- `fireEvent.mouseEnter(tooltipBtn)`
- `expect(screen.getByText('The name of your storage bucket')).toBeDefined()`
2. `'mouse-leaving tooltip button hides tooltip text'`:
- Render, mouseEnter, verify visible, then `fireEvent.mouseLeave(tooltipBtn)`
- `expect(screen.queryByText('The name of your storage bucket')).toBeNull()`
3. `'clicking tooltip button pins it open through mouseLeave'`:
- Render, `fireEvent.click(tooltipBtn)`, `fireEvent.mouseLeave(tooltipBtn)`
- `expect(screen.getByText('The name of your storage bucket')).toBeDefined()` (still visible because pinned)
4. `'clicking pinned tooltip button again dismisses it'`:
- Render, click (pin), click again (unpin)
- `expect(screen.queryByText('The name of your storage bucket')).toBeNull()`
Import `fireEvent` from `@testing-library/react` (add to existing import).
**TextFieldMD3.test.tsx — Add helpTextPrefix tests:**
Add tests in existing file (or create new describe block):
1. `'renders helpTextPrefix inline with helpText'`:
- Render TextFieldMD3 with `helpText="Some help"` and `helpTextPrefix={icon}`
- `expect(screen.getByTestId('prefix')).toBeDefined()`
- `expect(screen.getByText('Some help')).toBeDefined()`
2. `'renders helpText without wrapper issues when helpTextPrefix is undefined'`:
- Render TextFieldMD3 with `helpText="Some help"` and no helpTextPrefix
- `expect(screen.getByText('Some help')).toBeDefined()`
3. `'renders helpTextPrefix alone when helpText is absent'`:
- Render TextFieldMD3 with NO `helpText` and `helpTextPrefix={icon}`
- `expect(screen.getByTestId('prefix-only')).toBeDefined()`
- This verifies the `(helpText || helpTextPrefix) && !error` guard works correctly for tooltip-only fields
cd C:/Users/SebastienQUEROL/Documents/projets/Ready2Blob && npx vitest run src/components/ui/FieldRenderer.test.tsx src/components/ui/TextFieldMD3.test.tsx --reporter=verbose 2>&1 | tail -40
- All new tooltip hover tests pass (mouseEnter shows, mouseLeave hides, click pins, click again unpins)
- helpTextPrefix rendering test passes (with helpText, without helpText, and prefix-only)
- All pre-existing FieldRenderer and TextFieldMD3 tests still pass
1. `npx vitest run --reporter=verbose` — all tests pass (179+ existing + new tooltip tests)
2. Manual spot-check: tooltip icon appears beside helpText below field, not above field
3. Hover behavior: mouseEnter shows tooltip, mouseLeave hides it, click pins it
4. Edge case: field with tooltipText but no helpText still renders the tooltip icon
- UAT test 7 passes: tooltip info buttons show tooltip text on hover AND icon is positioned beside helpText below the field
- Zero test regressions
- Both FieldRenderer (text-branch + select-branch) and PasswordField have hover support
- TextFieldMD3 has helpTextPrefix prop for extensibility
- Fields with tooltipText but no helpText still show the tooltip icon (guard is not helpText-only)