File size: 1,502 Bytes
00a912e | 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 42 43 44 45 46 | import { useCallback, useRef, useState } from 'react'
/**
* Measures the minimum dimension (min of width/height) of a container element.
* Used to constrain sibling elements (info bar, controls) to match cover width.
*
* @param paused - When true, stops updating the width (e.g. during lyric mode
* where the container shrinks to compact height and would produce a misleading value).
*/
export function useCoverWidth(paused: boolean) {
const [width, setWidth] = useState(0)
const observerRef = useRef<ResizeObserver | null>(null)
const ref = useCallback(
(node: HTMLDivElement | null) => {
observerRef.current?.disconnect()
observerRef.current = null
if (!node) return
const update = (w: number, h: number) => {
if (paused) return
const newDimension = Math.floor(Math.min(w, h))
setWidth((prev) => {
// Hysteresis dead-zone: Ignore sub 3px changes to prevent ResizeObserver infinite loops
// when the zoom scaling below changes the actual pixel height of the controls.
if (Math.abs(prev - newDimension) <= 3) return prev
return newDimension
})
}
const rect = node.getBoundingClientRect()
update(rect.width, rect.height)
const ro = new ResizeObserver(([entry]) => {
update(entry.contentRect.width, entry.contentRect.height)
})
ro.observe(node)
observerRef.current = ro
},
[paused],
)
return { ref, coverWidth: width }
}
|