- SUMMARY.md: tooltip placement fix and hover+pin behavior documented - STATE.md: decisions added, session updated, progress at 100% - ROADMAP.md: Phase 9 plan 5/5 complete
119 lines
6.1 KiB
Markdown
119 lines
6.1 KiB
Markdown
---
|
|
phase: 09-md3-components
|
|
plan: "05"
|
|
subsystem: ui
|
|
tags: [react, tailwind, tooltip, accessibility, testing-library]
|
|
|
|
# Dependency graph
|
|
requires:
|
|
- phase: 09-md3-components/09-04
|
|
provides: TextFieldMD3 component with suffix/helpText props
|
|
provides:
|
|
- Tooltip hover+click behavior in FieldRenderer (text and select branches) and PasswordField
|
|
- helpTextPrefix prop on TextFieldMD3 for inline left-of-helpText slot
|
|
- Tooltip icon rendered beside helpText below the field (not above the field)
|
|
- Tests covering hover show/hide, click-pin, click-unpin, and helpTextPrefix rendering
|
|
affects: [RemoteConfigStep, PasswordField, TextFieldMD3]
|
|
|
|
# Tech tracking
|
|
tech-stack:
|
|
added: []
|
|
patterns:
|
|
- "hoverTooltip + showTooltip dual-state: hover shows, click pins, click-unpin clears both"
|
|
- "helpTextPrefix slot pattern: ReactNode prop for inline content left of helpText in TextFieldMD3"
|
|
- "Click-to-unpin guard: setShowTooltip(v => { if (v) setHoverTooltip(false); return !v; })"
|
|
|
|
key-files:
|
|
created: []
|
|
modified:
|
|
- src/components/ui/TextFieldMD3.tsx
|
|
- src/components/ui/FieldRenderer.tsx
|
|
- src/components/ui/PasswordField.tsx
|
|
- src/components/ui/FieldRenderer.test.tsx
|
|
- src/components/ui/TextFieldMD3.test.tsx
|
|
|
|
key-decisions:
|
|
- "Tooltip hover uses dual-state (hoverTooltip + showTooltip); click-unpin explicitly clears hoverTooltip to prevent sticky tooltip after dismiss"
|
|
- "helpTextPrefix guard is (helpText || helpTextPrefix) not just helpText, enabling icon-only rendering when field has tooltipText but no helpText"
|
|
- "Tooltip content rendered BELOW TextFieldMD3 (after component), not inside it — TextFieldMD3 stays self-contained"
|
|
|
|
patterns-established:
|
|
- "helpTextPrefix slot: pass ReactNode as inline prefix left of helpText text in TextFieldMD3"
|
|
- "Hover+click tooltip: mouseEnter shows, mouseLeave hides, click pins, second-click clears both states"
|
|
|
|
requirements-completed: [COMP-04]
|
|
|
|
# Metrics
|
|
duration: 10min
|
|
completed: 2026-04-01
|
|
---
|
|
|
|
# Phase 9 Plan 05: Tooltip Placement and Hover Fix Summary
|
|
|
|
**Tooltip icon moved from above field to inline with helpText below it, with hover-to-preview and click-to-pin behavior via dual hoverTooltip+showTooltip state**
|
|
|
|
## Performance
|
|
|
|
- **Duration:** ~10 min
|
|
- **Started:** 2026-04-01T09:10:00Z
|
|
- **Completed:** 2026-04-01T09:20:34Z
|
|
- **Tasks:** 2
|
|
- **Files modified:** 5
|
|
|
|
## Accomplishments
|
|
- Added `helpTextPrefix` prop to TextFieldMD3 for rendering inline content (tooltip icon) left of helpText below the field
|
|
- Fixed tooltip icon position: moved from above the floating-label input to beside helpText below it
|
|
- Implemented hover-to-preview (mouseEnter shows, mouseLeave hides) and click-to-pin (stays open through mouseLeave) in FieldRenderer and PasswordField
|
|
- Fixed click-unpin edge case: second click explicitly clears hoverTooltip so tooltip dismisses even when mouse stays on button
|
|
- Added 7 new tests covering all tooltip hover/pin/unpin behaviors and helpTextPrefix rendering
|
|
|
|
## Task Commits
|
|
|
|
Each task was committed atomically:
|
|
|
|
1. **Task 1: Add helpTextPrefix prop and fix tooltip placement + hover** - `23617c0` (feat)
|
|
2. **Task 2: Add tests for tooltip hover behavior and helpTextPrefix rendering** - `d2b6da2` (test)
|
|
|
|
## Files Created/Modified
|
|
- `src/components/ui/TextFieldMD3.tsx` - Added `helpTextPrefix?: React.ReactNode` prop; changed helpText guard to `(helpText || helpTextPrefix) && !error`; renders `<div className="flex items-start gap-1">` wrapping prefix + helpText
|
|
- `src/components/ui/FieldRenderer.tsx` - Added `hoverTooltip` state; moved tooltip icon from above-field to `tooltipIcon` element passed as `helpTextPrefix`; tooltip content rendered below TextFieldMD3; select-branch also gains hover support
|
|
- `src/components/ui/PasswordField.tsx` - Same dual-state tooltip fix as FieldRenderer text-branch
|
|
- `src/components/ui/FieldRenderer.test.tsx` - Added `fireEvent` import; added 4 hover behavior tests (hover shows, leave hides, click pins, second-click unpins)
|
|
- `src/components/ui/TextFieldMD3.test.tsx` - Added Tests 9-11 for helpTextPrefix with helpText, without, and prefix-only
|
|
|
|
## Decisions Made
|
|
- Click-to-unpin must explicitly clear `hoverTooltip` because `userEvent.click()` simulates hover before click, leaving `hoverTooltip=true` after second click — required `setShowTooltip(v => { if (v) setHoverTooltip(false); return !v; })`
|
|
- Tooltip content stays outside TextFieldMD3 (rendered after the component in FieldRenderer/PasswordField) — keeps TextFieldMD3 self-contained, tooltip is a consumer concern
|
|
|
|
## Deviations from Plan
|
|
|
|
### Auto-fixed Issues
|
|
|
|
**1. [Rule 1 - Bug] Fixed click-unpin leaving tooltip visible due to hoverTooltip race**
|
|
- **Found during:** Task 1 verification (RemoteConfigStep.test.tsx "hides tooltip panel when clicked again")
|
|
- **Issue:** `userEvent.click()` simulates mouseEnter before click; second click set `showTooltip=false` but `hoverTooltip` stayed true, so tooltip remained visible
|
|
- **Fix:** Changed click handler to `setShowTooltip(v => { if (v) setHoverTooltip(false); return !v; })` — clears hover state when unpinning
|
|
- **Files modified:** src/components/ui/FieldRenderer.tsx, src/components/ui/PasswordField.tsx
|
|
- **Verification:** All 186 tests pass including RemoteConfigStep "hides tooltip panel when clicked again"
|
|
- **Committed in:** 23617c0 (Task 1 commit)
|
|
|
|
---
|
|
|
|
**Total deviations:** 1 auto-fixed (Rule 1 - bug)
|
|
**Impact on plan:** Required for correctness — without this fix, tooltip could not be dismissed by click when mouse was over the button.
|
|
|
|
## Issues Encountered
|
|
- Click-unpin sticky tooltip: `userEvent.click` triggers hover state before click event. Resolved by clearing `hoverTooltip` in the unpin branch of the click handler.
|
|
|
|
## User Setup Required
|
|
None - no external service configuration required.
|
|
|
|
## Next Phase Readiness
|
|
- UAT test 7 (Tooltip Info Buttons Accessibility) now satisfies all criteria: hover shows, mouseLeave hides, click pins, click again unpins, icon beside helpText below field
|
|
- Phase 9 (09-md3-components) fully complete — all must-have truths and requirements satisfied
|
|
- Ready for Phase 10
|
|
|
|
---
|
|
*Phase: 09-md3-components*
|
|
*Completed: 2026-04-01*
|