import { useEffect, useState, type RefObject } from 'react'; /** * The measured inline size of an element, in px - `undefined` until it has actually been measured. * * CONTAINER, NEVER VIEWPORT, and this is not a preference. We render as a mount inside the practice's * own WordPress page: the window can report 1440 while our column has 900. A viewport media query * therefore answers a question nobody asked, and the patient home had to fix exactly this. * * `undefined` MEANS UNMEASURED AND CALLERS MUST TREAT IT AS "no change". jsdom has no `ResizeObserver` * and neither does an old browser; falling back to *today's* layout is the only safe direction, because * the alternative is a surface that silently rails itself for everyone whose browser we could not ask. * * Layout that is purely visual belongs in a CSS container query instead. This exists for the cases * where width changes BEHAVIOUR - here, whether the queue is a rail with an overlay - which CSS cannot * express. */ export const useContainerWidth = (ref: RefObject): number | undefined => { const [width, setWidth] = useState(undefined); useEffect(() => { const element = ref.current; if (!element) return undefined; if (typeof ResizeObserver === 'undefined') return undefined; const observer = new ResizeObserver(([entry]) => { // `contentRect` rather than `offsetWidth`: the same box a CSS container query measures, so a // threshold expressed in both places cannot land on two different numbers. if (entry) setWidth(entry.contentRect.width); }); observer.observe(element); return () => observer.disconnect(); }, [ref]); return width; };