diff --git a/packages/ui/primitives/auto-sized-text.tsx b/packages/ui/primitives/auto-sized-text.tsx deleted file mode 100644 index 04535974f..000000000 --- a/packages/ui/primitives/auto-sized-text.tsx +++ /dev/null @@ -1,143 +0,0 @@ -import { useLayoutEffect, useRef } from 'react'; - -import { cn } from '../lib/utils'; - -export type Dimensions = { - height: number; - width: number; -}; - -export type AutoSizedTextProps = { - children: React.ReactNode; - className?: string; - maxHeight?: number; - useRem?: boolean; -}; - -const ITERATION_LIMIT = 20; -const MAXIMUM_DIFFERENCE = 1; // px - -function getElementDimensions(element: HTMLElement): Dimensions { - const bbox = element.getBoundingClientRect(); - - return { - width: bbox.width, - height: bbox.height, - }; -} - -function getBaseFontSize(): number { - try { - const fontSize = getComputedStyle(document.documentElement).fontSize; - const parsed = parseFloat(fontSize); - - // Check if we got a valid number - if (!Number.isFinite(parsed)) { - return 16; - } - - return parsed; - } catch (error) { - // Fallback to browser default if anything goes wrong - return 16; - } -} - -function pxToRem(px: number): number { - return px / getBaseFontSize(); -} - -export function AutoSizedText({ children, className, maxHeight, useRem = false }: AutoSizedTextProps) { - const childRef = useRef(null); - - const fontSize = useRef(0); - const fontSizeLowerBound = useRef(0); - const fontSizeUpperBound = useRef(0); - - const adjustFontSize = (childDimensions: Dimensions, parentDimensions: Dimensions) => { - const childElement = childRef.current; - - if (!childElement) { - return; - } - - let newFontSize: number; - - const targetHeight = maxHeight && maxHeight < parentDimensions.height ? maxHeight : parentDimensions.height; - - const isElementTooBig = childDimensions.width > parentDimensions.width || childDimensions.height > targetHeight; - - if (isElementTooBig) { - // Scale down if element is bigger than target - newFontSize = (fontSizeLowerBound.current + fontSize.current) / 2; - fontSizeUpperBound.current = fontSize.current; - } else if (childDimensions.width < parentDimensions.width || childDimensions.height < parentDimensions.height) { - // Scale up if element is smaller than target - newFontSize = (fontSizeUpperBound.current + fontSize.current) / 2; - fontSizeLowerBound.current = fontSize.current; - } - - fontSize.current = newFontSize; - - // Convert to rem if useRem is true - const displayFontSize = useRem ? `${pxToRem(newFontSize)}rem` : `${newFontSize}px`; - childElement.style.fontSize = displayFontSize; - }; - - useLayoutEffect(() => { - const childElement = childRef.current; - const parentElement = childRef.current?.parentElement; - - if (!childElement || !parentElement) { - return; - } - - const observer = new ResizeObserver((entries) => { - const entry = entries[0]; - - if (!entry) { - return; - } - - const parentDimensions = entry.contentRect; - - // Reset iteration parameters - fontSizeLowerBound.current = 0; - fontSizeUpperBound.current = parentDimensions.height; - - let iterationCount = 0; - - while (iterationCount <= ITERATION_LIMIT) { - const childDimensions = getElementDimensions(childElement); - - const targetHeight = maxHeight && maxHeight < parentDimensions.height ? maxHeight : parentDimensions.height; - - const widthDifference = parentDimensions.width - childDimensions.width; - const heightDifference = targetHeight - childDimensions.height; - - const childFitsIntoParent = heightDifference >= 0 && widthDifference >= 0; - const isWithinTolerance = - Math.abs(widthDifference) <= MAXIMUM_DIFFERENCE || Math.abs(heightDifference) <= MAXIMUM_DIFFERENCE; - - if (childFitsIntoParent && isWithinTolerance) { - break; - } - - adjustFontSize(childDimensions, parentDimensions); - iterationCount += 1; - } - }); - - observer.observe(parentElement); - - return () => { - observer.disconnect(); - }; - }, [maxHeight, useRem]); - - return ( -
- {children} -
- ); -}