@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
173 lines (172 loc) • 5.78 kB
JavaScript
;
"use client";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _componentHelper = require("../../shared/component-helper.js");
var _useMountEffect = _interopRequireDefault(require("../../shared/helpers/useMountEffect.js"));
var _useMounted = _interopRequireDefault(require("../../shared/helpers/useMounted.js"));
var _index = require("../../shared/index.js");
var _Theme = require("../../shared/Theme.js");
var _PortalRoot = _interopRequireDefault(require("../PortalRoot.js"));
var _ModalContext = _interopRequireDefault(require("../modal/ModalContext.js"));
var _PopoverContainer = _interopRequireDefault(require("./PopoverContainer.js"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
let popoverPortal;
if (typeof globalThis !== 'undefined') {
globalThis.popoverPortal = globalThis.popoverPortal || {};
popoverPortal = globalThis.popoverPortal;
} else {
popoverPortal = {};
}
function PopoverPortal(props) {
const {
baseClassNames = ['dnb-popover'],
active,
targetElement,
showDelay,
hideDelay,
keepInDOM,
noAnimation,
portalRootClass,
children,
attributes,
arrowPosition,
placement,
alignOnTarget,
horizontalOffset,
arrowPositionSelector,
fixedPosition,
contentRef,
triggerOffset,
autoAlignMode,
hideArrow,
arrowEdgeOffset,
targetRefreshKey
} = props;
const [id] = (0, _react.useState)(() => (0, _componentHelper.makeUniqueId)());
const modalContext = (0, _react.useContext)(_ModalContext.default);
const theme = (0, _index.useTheme)();
const {
isActive: portalActive,
shouldRenderPortal
} = usePopoverPortalLifecycle({
id,
active,
hideDelay,
keepInDOM,
noAnimation
});
if (!shouldRenderPortal) {
return null;
}
return _react.default.createElement(_PortalRoot.default, null, _react.default.createElement("div", {
className: (0, _classnames.default)(baseClassNames.map(base => `${base}__portal`), portalRootClass, theme && (0, _Theme.getThemeClasses)(theme), (modalContext === null || modalContext === void 0 ? void 0 : modalContext.id) && baseClassNames.map(base => `${base}--inside-modal`))
}, _react.default.createElement(_PopoverContainer.default, {
baseClassNames: baseClassNames,
active: portalActive,
targetElement: targetElement || null,
showDelay: showDelay,
hideDelay: hideDelay,
keepInDOM: keepInDOM,
noAnimation: noAnimation,
arrowPosition: arrowPosition,
placement: placement,
alignOnTarget: alignOnTarget,
horizontalOffset: horizontalOffset,
arrowPositionSelector: arrowPositionSelector,
fixedPosition: fixedPosition,
attributes: attributes,
contentRef: contentRef,
triggerOffset: triggerOffset,
autoAlignMode: autoAlignMode,
hideArrow: hideArrow,
arrowEdgeOffset: arrowEdgeOffset,
targetRefreshKey: targetRefreshKey
}, children)));
}
var _default = exports.default = PopoverPortal;
function usePopoverPortalLifecycle({
id,
active,
hideDelay,
keepInDOM,
noAnimation
}) {
const [isActive, setIsActive] = (0, _react.useState)(active);
const [isInDOM, setIsInDOM] = (0, _react.useState)(() => keepInDOM || active);
const isMountedRef = (0, _useMounted.default)();
const ensurePortalEntry = (0, _react.useCallback)(() => {
if (!popoverPortal[id]) {
popoverPortal[id] = {
count: 0
};
}
return popoverPortal[id];
}, [id]);
const clearTimers = (0, _react.useCallback)(() => {
const entry = popoverPortal[id];
if (entry) {
clearTimeout(entry.delayTimeout);
clearTimeout(entry.hiddenTimeout);
}
}, [id]);
(0, _react.useEffect)(() => {
const entry = ensurePortalEntry();
if (active) {
clearTimers();
setIsActive(true);
setIsInDOM(true);
if (!isMountedRef.current) {
entry.count++;
}
return () => {
clearTimers();
};
}
if (keepInDOM) {
clearTimers();
setIsActive(false);
setIsInDOM(true);
return () => {
clearTimers();
};
}
if (!isMountedRef.current) {
return () => {
clearTimers();
};
}
const delayRender = () => setIsActive(false);
const delayHidden = () => {
setIsInDOM(false);
};
if (noAnimation || globalThis.IS_TEST) {
delayRender();
delayHidden();
return () => {
clearTimers();
};
}
const delay = parseFloat(String(hideDelay));
entry.delayTimeout = setTimeout(delayRender, delay);
entry.hiddenTimeout = setTimeout(delayHidden, delay + 300);
return () => {
clearTimers();
};
}, [active, clearTimers, ensurePortalEntry, hideDelay, isMountedRef, keepInDOM, noAnimation]);
(0, _useMountEffect.default)(() => {
if (keepInDOM) {
ensurePortalEntry();
}
});
return {
isActive,
shouldRenderPortal: isInDOM || keepInDOM
};
}
//# sourceMappingURL=PopoverPortal.js.map