feat(09-05): add helpTextPrefix prop and fix tooltip placement + hover behavior

- TextFieldMD3: add helpTextPrefix prop rendered inline left of helpText
- Guard changed to (helpText || helpTextPrefix) so icon renders without helpText
- FieldRenderer: move tooltip icon from above field to inline with helpText via helpTextPrefix
- FieldRenderer: add hoverTooltip state; tooltip visible on mouseEnter, dismisses on mouseLeave
- FieldRenderer: click-to-unpin clears hoverTooltip to prevent sticky tooltip after dismiss
- PasswordField: same tooltip fix as FieldRenderer text-branch
- Select-branch also gains hover support
This commit is contained in:
2026-04-01 11:19:17 +02:00
parent 29aa6b9e2f
commit 23617c0422
3 changed files with 57 additions and 34 deletions
+22 -15
View File
@@ -14,6 +14,7 @@ interface PasswordFieldProps {
export function PasswordField({ id, label, error, registration, helpText, tooltipText }: PasswordFieldProps) {
const [show, setShow] = useState(false);
const [showTooltip, setShowTooltip] = useState(false);
const [hoverTooltip, setHoverTooltip] = useState(false);
const toggleButton = (
<button
@@ -26,23 +27,23 @@ export function PasswordField({ id, label, error, registration, helpText, toolti
</button>
);
const tooltipIcon = tooltipText ? (
<button
type="button"
onClick={() => { setShowTooltip(v => { if (v) setHoverTooltip(false); return !v; }); }}
onMouseEnter={() => setHoverTooltip(true)}
onMouseLeave={() => setHoverTooltip(false)}
aria-label={`More info about ${label}`}
className="text-primary hover:text-primary/80 text-xs leading-none mt-px shrink-0"
>
</button>
) : undefined;
const tooltipVisible = showTooltip || hoverTooltip;
return (
<div className="flex flex-col gap-1">
{tooltipText && (
<button
type="button"
onClick={() => setShowTooltip(v => !v)}
aria-label={`More info about ${label}`}
className="text-primary hover:text-primary text-xs leading-none self-start"
>
</button>
)}
{tooltipText && showTooltip && (
<p className="text-xs text-primary bg-primary/10 border border-primary/30 rounded px-2 py-1.5">
{tooltipText}
</p>
)}
<TextFieldMD3
id={id}
label={label}
@@ -50,8 +51,14 @@ export function PasswordField({ id, label, error, registration, helpText, toolti
registration={registration}
type={show ? 'text' : 'password'}
helpText={helpText}
helpTextPrefix={tooltipIcon}
suffix={toggleButton}
/>
{tooltipText && tooltipVisible && (
<p className="text-xs text-primary bg-primary/10 border border-primary/30 rounded px-2 py-1.5">
{tooltipText}
</p>
)}
</div>
);
}