diff --git a/src/design-system/composites/ThemedChart/ChartTooltip.module.css b/src/design-system/composites/ThemedChart/ChartTooltip.module.css new file mode 100644 index 0000000..5b6006c --- /dev/null +++ b/src/design-system/composites/ThemedChart/ChartTooltip.module.css @@ -0,0 +1,47 @@ +.tooltip { + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: var(--radius-sm); + box-shadow: var(--shadow-md); + padding: 6px 10px; + font-size: 12px; +} + +.time { + font-family: var(--font-mono); + font-size: 10px; + color: var(--text-muted); + margin-bottom: 4px; + padding-bottom: 3px; + border-bottom: 1px solid var(--border-subtle); +} + +.row { + display: flex; + align-items: center; + gap: 5px; + margin-bottom: 2px; +} + +.row:last-child { + margin-bottom: 0; +} + +.dot { + width: 6px; + height: 6px; + border-radius: 50%; + flex-shrink: 0; +} + +.label { + color: var(--text-muted); + font-size: 11px; +} + +.value { + font-family: var(--font-mono); + font-weight: 600; + font-size: 11px; + color: var(--text-primary); +} diff --git a/src/design-system/composites/ThemedChart/ChartTooltip.tsx b/src/design-system/composites/ThemedChart/ChartTooltip.tsx new file mode 100644 index 0000000..56b9abc --- /dev/null +++ b/src/design-system/composites/ThemedChart/ChartTooltip.tsx @@ -0,0 +1,41 @@ +import type { TooltipProps } from 'recharts' +import styles from './ChartTooltip.module.css' + +function formatValue(val: number): string { + if (val >= 1_000_000) return `${(val / 1_000_000).toFixed(1)}M` + if (val >= 1000) return `${(val / 1000).toFixed(1)}k` + if (Number.isInteger(val)) return String(val) + return val.toFixed(1) +} + +function formatTimestamp(val: unknown): string | null { + if (val == null) return null + const str = String(val) + const ms = typeof val === 'number' && val > 1e12 ? val + : typeof val === 'number' && val > 1e9 ? val * 1000 + : Date.parse(str) + if (isNaN(ms)) return str + return new Date(ms).toLocaleString([], { + month: 'short', day: 'numeric', + hour: '2-digit', minute: '2-digit', second: '2-digit', + }) +} + +export function ChartTooltip({ active, payload, label }: TooltipProps) { + if (!active || !payload?.length) return null + + const timeLabel = formatTimestamp(label) + + return ( +
+ {timeLabel &&
{timeLabel}
} + {payload.map((entry) => ( +
+ + {entry.name}: + {formatValue(entry.value as number)} +
+ ))} +
+ ) +}