@atlaskit/spotlight
Version:
A spotlight introduces users to points of interest, from focused messages to multi-step tours.
69 lines (67 loc) • 2.16 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
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 var usePositionArea = function usePositionArea(ref) {
var _useState = useState(undefined),
_useState2 = _slicedToArray(_useState, 2),
positionArea = _useState2[0],
setPositionArea = _useState2[1];
useEffect(function () {
var el = ref.current;
if (!el) {
return;
}
var readPositionArea = function readPositionArea() {
try {
var _el$computedStyleMap$;
return (_el$computedStyleMap$ = el.computedStyleMap().get('position-area')) === null || _el$computedStyleMap$ === void 0 ? void 0 : _el$computedStyleMap$.toString();
} catch (_unused) {
// Some old browsers do not support computedStyleMap, so fall back to getPropertyValue
return window.getComputedStyle(el).getPropertyValue('position-area').trim();
}
};
var read = function read() {
var 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.
*/
var rafId = window.requestAnimationFrame(read);
// Check if the viewport resizes
var unbindResize = bind(window, {
type: 'resize',
listener: read,
options: {
passive: true
}
});
// Check if the viewport scrolls
var unbindScroll = bind(window, {
type: 'scroll',
listener: read,
options: {
passive: true,
capture: true
}
});
return function () {
window.cancelAnimationFrame(rafId);
unbindResize();
unbindScroll();
};
}, [ref]);
return positionArea;
};