refactor(ui): MetricTooltip delegates to InfoPopover (circled ? glyph)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Tudor
2026-07-22 15:37:33 +01:00
co-authored by Claude Opus 4.8
parent 1d9d2eb5ae
commit 15b7493b85
3 changed files with 40 additions and 161 deletions
+8 -47
View File
@@ -1,8 +1,7 @@
'use client';
import { useEffect, useRef, useState } from 'react';
import { METRIC_EXPLANATIONS } from '@/lib/metrics';
import styles from './MetricTooltip.module.css';
import { InfoPopover } from './InfoPopover';
interface MetricTooltipProps {
metricKey?: string;
@@ -13,51 +12,13 @@ interface MetricTooltipProps {
export function MetricTooltip({ metricKey, label, plain, detail }: MetricTooltipProps) {
const explanation = metricKey ? METRIC_EXPLANATIONS[metricKey] : undefined;
const tooltipLabel = label ?? explanation?.label;
const tooltipPlain = plain ?? explanation?.plain;
const tooltipDetail = detail ?? explanation?.detail;
// Tap/click/keyboard toggle so the definition is reachable on touch devices
// and by keyboard, not just mouse hover (hover still works on desktop).
const [open, setOpen] = useState(false);
const wrapperRef = useRef<HTMLSpanElement>(null);
useEffect(() => {
if (!open) return;
const dismiss = (e: Event) => {
if (wrapperRef.current && e.target instanceof Node && !wrapperRef.current.contains(e.target)) {
setOpen(false);
}
};
const onKey = (e: KeyboardEvent) => {
if (e.key === 'Escape') setOpen(false);
};
document.addEventListener('click', dismiss);
document.addEventListener('keydown', onKey);
return () => {
document.removeEventListener('click', dismiss);
document.removeEventListener('keydown', onKey);
};
}, [open]);
if (!tooltipPlain) return null;
const resolvedLabel = label ?? explanation?.label;
return (
<span className={styles.wrapper} ref={wrapperRef}>
<button
type="button"
className={styles.icon}
aria-expanded={open}
aria-label={`What does ${tooltipLabel ?? 'this metric'} mean?`}
onClick={() => setOpen((o) => !o)}
>
</button>
<span className={`${styles.tooltip}${open ? ` ${styles.tooltipOpen}` : ''}`} role="tooltip">
{tooltipLabel && <span className={styles.tooltipLabel}>{tooltipLabel}</span>}
<span className={styles.tooltipPlain}>{tooltipPlain}</span>
{tooltipDetail && <span className={styles.tooltipDetail}>{tooltipDetail}</span>}
</span>
</span>
<InfoPopover
label={resolvedLabel}
plain={plain ?? explanation?.plain}
detail={detail ?? explanation?.detail}
ariaLabel={resolvedLabel ? `What does ${resolvedLabel} mean?` : undefined}
/>
);
}