ultisuite-client/hooks/use-match-media.ts
2026-05-25 13:52:40 +02:00

29 lines
724 B
TypeScript

import { useLayoutEffect, useState } from "react"
/** matchMedia with rAF batching — avoids resize storms re-rendering every pixel. */
export function useMatchMedia(query: string): boolean {
const [matches, setMatches] = useState(false)
useLayoutEffect(() => {
const mql = window.matchMedia(query)
let raf = 0
const sync = () => {
cancelAnimationFrame(raf)
raf = requestAnimationFrame(() => {
const next = mql.matches
setMatches((prev) => (prev === next ? prev : next))
})
}
sync()
mql.addEventListener("change", sync)
return () => {
mql.removeEventListener("change", sync)
cancelAnimationFrame(raf)
}
}, [query])
return matches
}