refactor: resize performance

This commit is contained in:
2026-03-12 18:28:31 +01:00
parent a0bf9c6b70
commit e9ed508bfc
3 changed files with 64 additions and 35 deletions

View File

@@ -1,32 +1,30 @@
import { useEffect, useRef, useState } from 'react'
import { observeResize } from '@/lib/sharedResizeObserver'
/**
* Returns the height of the observed element, updating when it resizes (e.g. node resize).
* Used to give CodeMirror and other components an explicit height that tracks their container.
* Uses a shared ResizeObserver to reduce memory (one observer for all elements).
* @param defaultHeight - Height used until the element is measured.
* @param deps - Optional dependency array; when the ref is attached to a conditionally mounted element, pass deps (e.g. [viewMode]) so the effect re-runs when the element appears.
*/
export function useResizeHeight(
defaultHeight: number,
deps?: React.DependencyList
defaultHeight: number,
deps?: React.DependencyList
): [number, React.RefObject<HTMLDivElement | null>] {
const ref = useRef<HTMLDivElement | null>(null)
const [height, setHeight] = useState(defaultHeight)
const ref = useRef<HTMLDivElement | null>(null)
const [height, setHeight] = useState(defaultHeight)
useEffect(() => {
const el = ref.current
if (!el) return
useEffect(() => {
const el = ref.current
if (!el) return
const ro = new ResizeObserver((entries) => {
const entry = entries[0]
if (entry?.contentRect.height != null && entry.contentRect.height > 0) {
setHeight(entry.contentRect.height)
}
})
ro.observe(el)
setHeight(el.getBoundingClientRect().height)
return () => ro.disconnect()
}, deps ?? [])
const unobserve = observeResize(el, (size) => {
if (size.height > 0) setHeight(size.height)
})
const initial = el.getBoundingClientRect().height
if (initial > 0) setHeight(initial)
return unobserve
}, deps ?? [])
return [height, ref]
return [height, ref]
}