Skip to content

Instantly share code, notes, and snippets.

@manix84
Last active June 28, 2024 11:14
Show Gist options
  • Save manix84/e0a93f98ddef155b12edaf70b29a5090 to your computer and use it in GitHub Desktop.
Save manix84/e0a93f98ddef155b12edaf70b29a5090 to your computer and use it in GitHub Desktop.
A React+Typescript hook for resizing a line of text, so it fits on X lines.
/**
This code is licensed under the terms of the MIT license
*/
import { useCallback, useState } from "react";
export const useTextResize = () => {
const [originalFontSize, setOriginalFontSize] = useState<number>(null);
const [originalLineHeight, setOriginalLineHeight] = useState<number>(null);
const resizeText = (textElement: HTMLElement, maxLines: number = 3) => {
if (!textElement) return;
const style = getComputedStyle(textElement);
const divHeight = textElement.offsetHeight;
let lineHeight = parseInt(style.lineHeight);
let fontSize = parseInt(style.fontSize);
setOriginalFontSize((prevValue) => prevValue || fontSize);
setOriginalLineHeight((prevValue) => prevValue || lineHeight);
const lines = divHeight / lineHeight;
if (lines > maxLines) {
fontSize--;
lineHeight--;
textElement.style.fontSize = fontSize + "px";
textElement.style.lineHeight = lineHeight + "px";
resizeText(textElement, maxLines);
} else if (fontSize < originalFontSize && lines < maxLines) {
fontSize = originalFontSize;
lineHeight = originalLineHeight;
textElement.style.fontSize = fontSize + "px";
textElement.style.lineHeight = lineHeight + "px";
resizeText(textElement, maxLines);
}
};
// Just in case you need to use the state as a dependency in another hook. Here are the exposed states.
resizeText.originalFontSize = originalFontSize;
resizeText.originalLineHeight = originalLineHeight;
return useCallback(resizeText, [originalFontSize, originalLineHeight]);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment