Skip to content

Instantly share code, notes, and snippets.

@alvarogfn
Created May 6, 2024 21:09
Show Gist options
  • Save alvarogfn/61076546ccaad269746a395348a4faee to your computer and use it in GitHub Desktop.
Save alvarogfn/61076546ccaad269746a395348a4faee to your computer and use it in GitHub Desktop.
Hook que computa quantidade de linhas de um element com lineClamp
import { useEffect, useRef, useState } from 'react'
const countElementLines = (target: HTMLElement) => {
const style = window.getComputedStyle(target, null)
const fontSize = parseInt(style.getPropertyValue('font-size'))
let height = parseInt(style.getPropertyValue('height'))
const boxSizing = style.getPropertyValue('box-sizing')
if (boxSizing === 'border-box') {
const paddingTop = parseInt(style.getPropertyValue('padding-top'))
const paddingBottom = parseInt(style.getPropertyValue('padding-bottom'))
const borderTop = parseInt(style.getPropertyValue('border-top-width'))
const borderBottom = parseInt(style.getPropertyValue('border-bottom-width'))
height = height - paddingTop - paddingBottom - borderTop - borderBottom
}
let lineHeight = parseInt(style.getPropertyValue('line-height'))
if (isNaN(lineHeight)) lineHeight = fontSize * 1.2
return Math.floor(height / lineHeight)
}
export const useElementLineCount = () => {
const ref = useRef<HTMLDivElement>(null)
const [lines, setLines] = useState(0)
useEffect(() => {
const element = ref.current
if (element === null) return
const clonedElement = element.cloneNode(true) as HTMLElement
element.insertAdjacentElement('afterend', clonedElement)
clonedElement.style.setProperty('-webkit-line-clamp', 'unset')
clonedElement.style.setProperty('visibility', 'hidden')
clonedElement.style.setProperty('position', 'absolute')
const observer = new ResizeObserver(() => {
setLines(countElementLines(clonedElement))
})
observer.observe(element)
return () => {
observer.disconnect()
clonedElement.remove()
}
}, [ref, setLines])
return { lines, ref }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment