Files
buzz/components/fit.tsx
T
dmgnr a31c8fbb54
Build and Push Image / build-backend (push) Successful in 52s
Build and Push Image / build-frontend (push) Successful in 2m8s
Build and Push Image / push (push) Successful in 1m24s
chore: oxc
2026-06-10 01:44:11 +07:00

62 lines
1.5 KiB
TypeScript
Executable File

"use client";
import { useEffect, useRef, useState } from "react";
export default function AutoFitText({
children,
className,
}: {
children: string;
className?: string;
}) {
const containerRef = useRef<HTMLDivElement>(null);
const textRef = useRef<HTMLDivElement>(null);
const [fontSize, setFontSize] = useState(10); // will update instantly
// biome-ignore lint/correctness/useExhaustiveDependencies: it needs children
useEffect(() => {
function resize() {
const container = containerRef.current;
const text = textRef.current;
if (!container || !text) return;
// start large and shrink until it fits
let size = 300;
text.style.fontSize = `${size}px`;
const { width: cw, height: ch } = container.getBoundingClientRect();
while ((text.scrollWidth > cw || text.scrollHeight > ch) && size > 5) {
size -= 2;
text.style.fontSize = `${size}px`;
}
setFontSize(size - 5);
}
resize();
window.addEventListener("resize", resize);
return () => window.removeEventListener("resize", resize);
}, [children]);
return (
<div
ref={containerRef}
className="grid h-full w-full place-content-center overflow-hidden"
>
<div
ref={textRef}
className={className}
style={{
fontSize,
lineHeight: 1,
whiteSpace: "nowrap",
userSelect: "none",
}}
>
{children}
</div>
</div>
);
}