UNPKG

@workday/canvas-kit-react

Version:

The parent module that contains all Workday Canvas Kit React components

57 lines (56 loc) 2.27 kB
"use strict"; 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 {}; });