---
phase: 07-validation-ux-polish
plan: "02"
type: execute
wave: 3
depends_on:
- "07-01"
files_modified:
- src/schemas/registry.ts
- src/components/ui/FieldRenderer.tsx
- src/components/ui/PasswordField.tsx
- src/components/wizard/SftpAuthToggle.tsx
- src/components/wizard/AzureAuthToggle.tsx
autonomous: false
requirements:
- UX-01
must_haves:
truths:
- "User can click ⓘ next to the SAS URL label and read an explanation of SAS URL vs access key"
- "User can click ⓘ next to the Access Key label and read an explanation of full account key access"
- "User can click ⓘ on the SFTP authentication method section and read the difference between password and key-based auth"
- "User can click ⓘ next to the OneDrive token label and read how to obtain the JSON token"
- "Clicking ⓘ again hides the tooltip panel (toggle behavior)"
- "All 147+ tests (including VALID-01 from Plan 01) pass after tooltip implementation"
artifacts:
- path: "src/schemas/registry.ts"
provides: "tooltipText populated for azureblob.sas_url, azureblob.key, onedrive.token"
contains: "tooltipText:"
- path: "src/components/ui/FieldRenderer.tsx"
provides: "ⓘ button + inline tooltip panel when field.tooltipText is present"
contains: "showTooltip"
- path: "src/components/ui/PasswordField.tsx"
provides: "ⓘ button + inline tooltip panel when tooltipText prop is present"
contains: "tooltipText"
- path: "src/components/wizard/SftpAuthToggle.tsx"
provides: "ⓘ button above auth method toggle with inline explanation"
contains: "showAuthTip"
- path: "src/components/wizard/AzureAuthToggle.tsx"
provides: "Passes tooltipText from registry to PasswordField for sas_url and key"
contains: "tooltipText"
key_links:
- from: "BACKEND_REGISTRY azureblob.sas_url.tooltipText"
to: "AzureAuthToggle → PasswordField tooltipText prop"
via: "BACKEND_REGISTRY.azureblob.fields.find(f => f.key === 'sas_url')?.tooltipText"
pattern: "BACKEND_REGISTRY\\.azureblob\\.fields\\.find"
- from: "BACKEND_REGISTRY onedrive.token.tooltipText"
to: "FieldRenderer ⓘ button rendered"
via: "field.tooltipText present → useState showTooltip"
- from: "SftpAuthToggle showAuthTip state"
to: "inline explanation panel"
via: "useState + conditional render"
---
Implement UX-01: add tooltipText data to 3 registry fields, render ⓘ toggle buttons in FieldRenderer and PasswordField, wire AzureAuthToggle to pass tooltipText from the registry, and add a standalone auth-method tooltip to SftpAuthToggle.
Purpose: Users can access plain-language explanations of sensitive or confusing credential fields without leaving the wizard.
Output: 5 modified files; ⓘ buttons visible on sas_url, key, onedrive token, and SFTP auth method.
@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/phases/07-validation-ux-polish/07-CONTEXT.md
@.planning/phases/07-validation-ux-polish/07-RESEARCH.md
@.planning/phases/07-validation-ux-polish/07-01-SUMMARY.md
After Plan 01, FieldDef in src/schemas/registry.ts:
```typescript
export interface FieldDef {
key: string;
label: string;
inputType: 'text' | 'password' | 'select' | 'toggle';
required: boolean;
placeholder?: string;
helpText?: string;
options?: { value: string; label: string }[];
validate?: { regex: RegExp; message: string };
tooltipText?: string; // Added in Plan 01 — now populate it for tooltip fields
}
```
Current PasswordField props (src/components/ui/PasswordField.tsx) — to add tooltipText?:
```typescript
interface PasswordFieldProps {
id: string;
label: string;
error?: FieldError;
registration: UseFormRegisterReturn;
placeholder?: string;
helpText?: string;
// tooltipText?: string ← add this
}
```
CRITICAL pitfall: azureblob.sas_url and azureblob.key are NOT rendered through the FieldRenderer registry loop.
They are rendered inside AzureAuthToggle.tsx which calls PasswordField with hardcoded props.
To wire the tooltip, AzureAuthToggle must read from BACKEND_REGISTRY:
BACKEND_REGISTRY.azureblob.fields.find(f => f.key === 'sas_url')?.tooltipText
BACKEND_REGISTRY.azureblob.fields.find(f => f.key === 'key')?.tooltipText
Then pass those strings as tooltipText prop to the respective PasswordField calls.
SFTP auth method tooltip is NOT field-level — it's a standalone explanation above the segmented control.
SftpAuthToggle manages its own useState for showAuthTip.
The PasswordField calls inside SftpAuthToggle for 'pass' and 'key_pem' do NOT get tooltipText.
CSS-hidden toggle pattern is established project convention (AzureAuthToggle, SftpAuthToggle use div.block/div.hidden).
CONTEXT.md decision: use CSS-hidden pattern (div.hidden / div.block) for tooltip panel visibility — not conditional render with &&.
Actually re-read: CONTEXT.md says "toggle state is local to the field component (no global state needed)" and research shows
both CSS-hidden and conditional render work; CSS-hidden is the project convention. Use div.hidden / div.block OR useState + conditional render ({showTooltip &&
...}).
Research Pattern 3 shows conditional render. Either is fine — use Claude's discretion for tooltip panel; CSS-hidden for SftpAuthToggle to stay consistent with its existing pattern.
Accessibility: the ⓘ button MUST be outside (sibling to, not inside) the