@workday/canvas-kit-react
Version:
The parent module that contains all Workday Canvas Kit React components
57 lines (56 loc) • 2.27 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useCloseOnTargetHidden = void 0;
const react_1 = __importDefault(require("react"));
const common_1 = require("@workday/canvas-kit-react/common");
const usePopupModel_1 = require("./usePopupModel");
function getScrollParent(element) {
if (element === document.body || !element.parentElement) {
return element;
}
const styles = getComputedStyle(element);
if (styles.overflowY === 'scroll' ||
styles.overflowY === 'auto' ||
styles.overflowX === 'scroll' ||
styles.overflowX === 'auto') {
return element;
}
return getScrollParent(element.parentElement);
}
/**
* Sets up an
* [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
* for the target element. When the target is detected as being less than 50% visible, the popup
* will close. Most likely, this will happen if the user scrolls an overflowed content area of the
* page and the target is no longer visible.
*
* This should be used with popup elements that are transitory like Tooltips and dropdown menus.
*/
exports.useCloseOnTargetHidden = (0, common_1.createElemPropsHook)(usePopupModel_1.usePopupModel)(model => {
const visible = model.state.visibility !== 'hidden';
const callback = react_1.default.useCallback(entries => {
if (entries[0].intersectionRatio < 0.5) {
model.events.hide();
}
}, [model.events]);
react_1.default.useLayoutEffect(() => {
if (!visible || !model.state.targetRef.current) {
return;
}
const target = model.state.targetRef.current;
const scrollParent = getScrollParent(target);
// eslint-disable-next-line compat/compat
const observer = new IntersectionObserver(callback, {
root: scrollParent,
threshold: 0.5,
});
observer.observe(model.state.targetRef.current);
return () => {
observer.disconnect();
};
}, [callback, model.state.targetRef, visible]);
return {};
});
;