/** * earth-now.co * Author: Simon-Pierre Boucher * Contact: contact@spboucher.ai * File: apps/web/components/FitValue.tsx * Purpose: Overflow-proof ticking value — measures and scales the digit line to always fit its container (mobile and desktop) */ "use client"; import { useEffect, useRef } from "react"; export interface FitValueProps { text: string; className?: string; } /** * Renders a single-line value that NEVER overflows: the inner span is scaled * down (transform, left-anchored) whenever it is wider than the container. * With tabular-nums the width only depends on the character count, so we * re-measure on length changes and container resizes — not on every rAF tick. */ export default function FitValue({ text, className = "" }: FitValueProps) { const containerRef = useRef(null); const spanRef = useRef(null); const lastLength = useRef(-1); useEffect(() => { const container = containerRef.current; const span = spanRef.current; if (container === null || span === null) return; const fit = () => { // scale = min(1, available / natural); measured unscaled via scrollWidth. const natural = span.scrollWidth; const available = container.clientWidth; const scale = natural > 0 ? Math.min(1, available / natural) : 1; span.style.transform = scale < 1 ? `scale(${scale})` : ""; }; fit(); const observer = new ResizeObserver(fit); observer.observe(container); // Re-fit when the digit count changes (value crossed a power of ten). const id = window.setInterval(() => { const len = span.textContent?.length ?? 0; if (len !== lastLength.current) { lastLength.current = len; fit(); } }, 500); return () => { observer.disconnect(); window.clearInterval(id); }; }, []); return (
{text}
); }