import { MutableRefObject, useEffect, useState } from "react" /** * Returns the up-to-date value of an element's attribute. * Useful when dealing with Radix components where the uncontrolled state is not exposed * and is instead only derived from the data attributes */ export const useElementAttribute = ( ref: MutableRefObject, attributeName: string, ): T | null => { const [dataState, setDataState] = useState( (ref.current?.getAttribute(attributeName) ?? null) as T | null, ) useEffect(() => { if (!ref.current) { return } setDataState((ref.current?.getAttribute(attributeName) || "") as T | null) const observer = new MutationObserver(mutationsList => { for (const mutation of mutationsList) { if (mutation.attributeName === attributeName) { setDataState( ((mutation.target as HTMLElement).getAttribute(attributeName) ?? null) as T | null, ) } } }) const element = ref.current observer.observe(element, { attributes: true }) return () => { observer.disconnect() } }, [attributeName, ref]) return dataState }