UNPKG

@atlaskit/spotlight

Version:

A spotlight introduces users to points of interest, from focused messages to multi-step tours.

65 lines (63 loc) 1.94 kB
import { useEffect, useState } from 'react'; import { bind } from 'bind-event-listener'; /** * Future improvements to this might be to check if the target resizes with: * ``` * const ro = new ResizeObserver(read); * ro.observe(targetRef.current); * ``` * * No need to do this for the PopoverContent, as it has static height/width. */ export const usePositionArea = ref => { const [positionArea, setPositionArea] = useState(undefined); useEffect(() => { const el = ref.current; if (!el) { return; } const readPositionArea = () => { try { var _el$computedStyleMap$; return (_el$computedStyleMap$ = el.computedStyleMap().get('position-area')) === null || _el$computedStyleMap$ === void 0 ? void 0 : _el$computedStyleMap$.toString(); } catch { // Some old browsers do not support computedStyleMap, so fall back to getPropertyValue return window.getComputedStyle(el).getPropertyValue('position-area').trim(); } }; const read = () => { const positionArea = readPositionArea(); setPositionArea(positionArea); }; read(); /** * requestAnimationFrame ensures that initial renders are in a different position * to the supplied prop value (e.g. the viewport is too small so the position is * recalculated) are rendered correctly. */ const rafId = window.requestAnimationFrame(read); // Check if the viewport resizes const unbindResize = bind(window, { type: 'resize', listener: read, options: { passive: true } }); // Check if the viewport scrolls const unbindScroll = bind(window, { type: 'scroll', listener: read, options: { passive: true, capture: true } }); return () => { window.cancelAnimationFrame(rafId); unbindResize(); unbindScroll(); }; }, [ref]); return positionArea; };