Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 1x 1x 1x | import { useLayoutEffect, useRef, useState } from 'react';
export const useLongText = (text: string, maxLines = 20) => {
const textRef = useRef<HTMLSpanElement>(null);
const [isLongText, setIsLongText] = useState(false);
// 20줄이 넘어가면 longText로 판단.
useLayoutEffect(() => {
if (!textRef.current) return;
const el = textRef.current;
// 클론 생성
const clone = el.cloneNode(true) as HTMLSpanElement;
// 오프스크린 스타일 적용
clone.style.position = 'absolute';
clone.style.visibility = 'hidden';
clone.style.pointerEvents = 'none';
clone.style.display = 'block';
clone.style.webkitLineClamp = 'unset';
clone.style.overflow = 'visible';
clone.style.width = `${el.offsetWidth}px`;
// DOM에 추가
document.body.appendChild(clone);
// 측정
const lineHeight = parseFloat(getComputedStyle(clone).lineHeight);
const fullHeight = clone.scrollHeight;
setIsLongText(fullHeight > lineHeight * maxLines);
// 정리
document.body.removeChild(clone);
}, [text, maxLines]);
return { textRef, isLongText };
};
|