Row.utils.ts38 lines · main
1import { useLayoutEffect, useState } from 'react'
2
3export const useMeasuredWidth = <T extends HTMLElement>(ref: React.RefObject<T | null>) => {
4 const [measuredWidth, setMeasuredWidth] = useState<number | null>(null)
5
6 useLayoutEffect(() => {
7 const element = ref.current
8 if (!element) return
9
10 const initial = element.getBoundingClientRect().width
11 setMeasuredWidth((prev) => (prev === initial ? prev : initial))
12
13 if (typeof ResizeObserver !== 'undefined') {
14 let frame = 0
15 const resizeObserver = new ResizeObserver((entries) => {
16 const width = entries[0]?.contentRect.width ?? 0
17 if (frame) cancelAnimationFrame(frame)
18 frame = requestAnimationFrame(() => {
19 setMeasuredWidth((prev) => (prev === width ? prev : width))
20 })
21 })
22 resizeObserver.observe(element)
23 return () => {
24 if (frame) cancelAnimationFrame(frame)
25 resizeObserver.disconnect()
26 }
27 } else {
28 const handleResize = () => {
29 const width = element.getBoundingClientRect().width
30 setMeasuredWidth((prev) => (prev === width ? prev : width))
31 }
32 window.addEventListener('resize', handleResize)
33 return () => window.removeEventListener('resize', handleResize)
34 }
35 }, [ref])
36
37 return measuredWidth
38}