UNPKG

react-floater

Version:
1,079 lines (1,063 loc) 33.6 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.tsx var src_exports = {}; __export(src_exports, { default: () => ReactFloater }); module.exports = __toCommonJS(src_exports); var React8 = __toESM(require("react")); var import_core = require("@popperjs/core"); var import_is_lite5 = __toESM(require("is-lite")); var import_tree_changes_hook = __toESM(require("tree-changes-hook")); // src/components/Floater/index.tsx var React5 = __toESM(require("react")); // src/components/Floater/Arrow.tsx var React = __toESM(require("react")); function FloaterArrow(props) { const { arrowRef, placement, styles } = props; const { arrow: { color, display, length, position, spread } } = styles; const arrowStyles = { display, position }; let points; let x = spread; let y = length; if (placement.startsWith("top")) { points = `0,0 ${x / 2},${y} ${x},0`; } else if (placement.startsWith("bottom")) { points = `${x},${y} ${x / 2},0 0,${y}`; } else if (placement.startsWith("left")) { y = spread; x = length; points = `0,0 ${x},${y / 2} 0,${y}`; } else if (placement.startsWith("right")) { y = spread; x = length; points = `${x},${y} ${x},0 0,${y / 2}`; } return /* @__PURE__ */ React.createElement("span", { ref: arrowRef, className: "__floater__arrow", style: arrowStyles }, /* @__PURE__ */ React.createElement("svg", { height: y, version: "1.1", width: x, xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React.createElement("polygon", { fill: color, points }))); } // src/components/Floater/Container.tsx var React3 = __toESM(require("react")); var import_is_lite = __toESM(require("is-lite")); // src/components/Floater/CloseButton.tsx var React2 = __toESM(require("react")); function FloaterCloseButton({ onClick, styles }) { const { color, height, width, ...style } = styles; return /* @__PURE__ */ React2.createElement("button", { "aria-label": "close", onClick, style, type: "button" }, /* @__PURE__ */ React2.createElement( "svg", { height: `${height}px`, preserveAspectRatio: "xMidYMid", version: "1.1", viewBox: "0 0 18 18", width: `${width}px`, xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React2.createElement("g", null, /* @__PURE__ */ React2.createElement( "path", { d: "M8.13911129,9.00268191 L0.171521827,17.0258467 C-0.0498027049,17.248715 -0.0498027049,17.6098394 0.171521827,17.8327545 C0.28204354,17.9443526 0.427188206,17.9998706 0.572051765,17.9998706 C0.71714958,17.9998706 0.862013139,17.9443526 0.972581703,17.8327545 L9.0000937,9.74924618 L17.0276057,17.8327545 C17.1384085,17.9443526 17.2832721,17.9998706 17.4281356,17.9998706 C17.5729992,17.9998706 17.718097,17.9443526 17.8286656,17.8327545 C18.0499901,17.6098862 18.0499901,17.2487618 17.8286656,17.0258467 L9.86135722,9.00268191 L17.8340066,0.973848225 C18.0553311,0.750979934 18.0553311,0.389855532 17.8340066,0.16694039 C17.6126821,-0.0556467968 17.254037,-0.0556467968 17.0329467,0.16694039 L9.00042166,8.25611765 L0.967006424,0.167268345 C0.745681892,-0.0553188426 0.387317931,-0.0553188426 0.165993399,0.167268345 C-0.0553311331,0.390136635 -0.0553311331,0.751261038 0.165993399,0.974176179 L8.13920499,9.00268191 L8.13911129,9.00268191 Z", fill: color } )) )); } // src/components/Floater/Container.tsx function FloaterContainer(props) { const { content, footer, onClick, open, positionWrapper, showCloseButton, styles, title } = props; const output = { content: React3.isValidElement(content) ? content : /* @__PURE__ */ React3.createElement("div", { className: "__floater__content", style: styles.content }, content) }; if (title) { output.title = React3.isValidElement(title) ? title : /* @__PURE__ */ React3.createElement("div", { className: "__floater__title", style: styles.title }, title); } if (footer) { output.footer = React3.isValidElement(footer) ? footer : /* @__PURE__ */ React3.createElement("div", { className: "__floater__footer", style: styles.footer }, footer); } if ((showCloseButton || positionWrapper) && !import_is_lite.default.boolean(open)) { output.close = /* @__PURE__ */ React3.createElement(FloaterCloseButton, { onClick, styles: styles.close }); } return /* @__PURE__ */ React3.createElement("div", { className: "__floater__container", style: styles.container }, output.close, output.title, output.content, output.footer); } // src/literals.ts var POSITIONING_PROPS = ["position", "top", "right", "bottom", "left"]; var STATUS = { INIT: "init", IDLE: "idle", RENDER: "render", OPENING: "opening", OPEN: "open", CLOSING: "closing", ERROR: "error" }; // src/modules/helpers.ts var React4 = __toESM(require("react")); var import_deepmerge_ts = require("deepmerge-ts"); var import_is_lite2 = __toESM(require("is-lite")); var portalId = "react-floater-portal"; function canUseDOM() { return !!(typeof window !== "undefined" && window.document?.createElement); } function enhanceProps(props) { return { autoOpen: false, debug: false, disableFlip: false, disableHoverToClick: false, event: "click", eventDelay: 0.4, hideArrow: false, offset: 15, placement: "bottom", showCloseButton: false, styles: {}, target: null, wrapperOptions: { position: false }, ...props }; } function getFallbackPlacements(placement) { if (placement.startsWith("left")) { return ["top", "bottom"]; } if (placement.startsWith("right")) { return ["bottom", "top"]; } return void 0; } function getModifiers(modifiers) { const defaultOptions2 = { flip: { name: "flip", enabled: true, options: { padding: 20 } }, preventOverflow: { name: "preventOverflow", enabled: true, options: { padding: 10 } } }; return (0, import_deepmerge_ts.deepmerge)(defaultOptions2, modifiers ?? {}); } function isFixed(el) { if (!el) { return false; } const { nodeName } = el; if (nodeName === "BODY" || nodeName === "HTML") { return false; } if (getComputedStyle(el).position === "fixed") { return true; } return el.parentNode instanceof HTMLElement ? isFixed(el.parentNode) : false; } function isMobile() { return "ontouchstart" in window && /Mobi/.test(navigator.userAgent); } function isValidElement3(object) { return React4.isValidElement(object); } function log({ data, debug = false, title }) { const logFn = console.log; if (debug && title && data) { console.groupCollapsed( `%creact-floater: ${title}`, "color: #9b00ff; font-weight: bold; font-size: 12px;" ); if (Array.isArray(data)) { data.forEach((d) => { if (import_is_lite2.default.plainObject(d) && d.key) { logFn.apply(console, [d.key, d.value]); } else { logFn.apply(console, [d]); } }); } else { logFn.apply(console, [data]); } console.groupEnd(); } } function mergeModifier(modifier, customModifier) { return (0, import_deepmerge_ts.deepmerge)(modifier, customModifier ?? {}); } function off(element, eventType, handler, options = false) { element.removeEventListener(eventType, handler, options); } function on(element, eventType, handler, options = false) { element.addEventListener(eventType, handler, options); } function once(element, eventType, handler, options = false) { let nextCB; nextCB = (event) => { handler(event); off(element, eventType, nextCB); }; on(element, eventType, nextCB, options); } function randomId() { return `rf-${Math.round(Math.random() * 1e5)}`; } // src/components/Floater/index.tsx function Floater(props) { const { component, content, floaterRef, hideArrow, id, onClick: closeFn, placement, status, styles } = props; const style = React5.useMemo(() => { const { arrow: { length }, floater, floaterCentered, floaterClosing, floaterOpening, floaterWithComponent } = styles; let element = { ...floater }; if (!hideArrow) { if (placement.startsWith("top")) { element.padding = `0 0 ${length}px`; } else if (placement.startsWith("bottom")) { element.padding = `${length}px 0 0`; } else if (placement.startsWith("left")) { element.padding = `0 ${length}px 0 0`; } else if (placement.startsWith("right")) { element.padding = `0 0 0 ${length}px`; } } if (status === STATUS.CLOSING) { element = { ...element, ...floaterClosing }; } if (status === STATUS.OPENING || status === STATUS.OPEN) { element = { ...element, ...floaterOpening }; } if (placement === "center") { element = { ...element, ...floaterCentered }; } if (component) { element = { ...element, ...floaterWithComponent }; } return element; }, [component, hideArrow, placement, status, styles]); const shouldRender = ["render", "open", "opening", "closing"].includes(status); const output = {}; const classes = ["__floater"]; const baseProps = { id, role: "tooltip" }; if (component) { const componentProps = { closeFn, ...baseProps }; output.content = isValidElement3(component) ? React5.cloneElement(component, componentProps) : component(componentProps); } else { output.content = /* @__PURE__ */ React5.createElement(FloaterContainer, { ...props, content }); } if (status === STATUS.OPEN) { classes.push("__floater__open"); } if (!hideArrow) { output.arrow = /* @__PURE__ */ React5.createElement(FloaterArrow, { ...props }); } if (!shouldRender) { return null; } return /* @__PURE__ */ React5.createElement("div", { ref: floaterRef, style: { zIndex: styles.options.zIndex } }, /* @__PURE__ */ React5.createElement("div", { className: classes.join(" "), style, ...baseProps }, /* @__PURE__ */ React5.createElement("div", { className: "__floater__body" }, output.content, output.arrow))); } var Floater_default = React5.memo(Floater); // src/components/Portal.tsx var React6 = __toESM(require("react")); var import_react_dom = require("react-dom"); var import_is_lite3 = __toESM(require("is-lite")); // src/modules/hooks.ts var import_react = require("react"); function useEffectOnce(effect) { (0, import_react.useEffect)(effect, []); } function useMount(effect) { useEffectOnce(effect); } function useSingleton(callback) { const hasBeenCalled = (0, import_react.useRef)(false); if (hasBeenCalled.current) { return; } callback(); hasBeenCalled.current = true; } function useUnmount(fn) { const fnRef = (0, import_react.useRef)(fn); fnRef.current = fn; useEffectOnce(() => () => fnRef.current()); } function useUpdateEffect(effect, deps) { const isFirst = (0, import_react.useRef)(true); (0, import_react.useEffect)(() => { if (!isFirst.current) { effect(); } }, deps); if (isFirst.current) { isFirst.current = false; } } // src/components/Portal.tsx function ReactFloaterPortal(props) { const { children, hasChildren, internalId, placement, portalElement, target, zIndex } = props; const node = React6.useRef(null); const initialize = React6.useCallback(() => { if (!canUseDOM()) { return; } if (portalElement) { node.current = import_is_lite3.default.string(portalElement) ? document.querySelector(portalElement) : portalElement; } if (!portalElement || !node.current) { const portal = document.getElementById(portalId); if (portal) { const ids = portal.dataset.ids?.split(",").filter(Boolean) ?? []; if (!ids.includes(internalId) && internalId) { ids.push(internalId); } portal.dataset.ids = ids.join(","); node.current = portal; } else { node.current = document.createElement("div"); node.current.id = portalId; node.current.dataset.ids = internalId; node.current.style.zIndex = `${zIndex}`; document.body.appendChild(node.current); } } if (!portalElement && !document.getElementById(portalId)) { if (node.current) { document.body.appendChild(node.current); } } }, [internalId, portalElement, zIndex]); useMount(() => { if (!canUseDOM) { return; } initialize(); }); React6.useEffect(() => { initialize(); }, [initialize]); useUnmount(() => { if (!canUseDOM() || !node.current) { return; } try { if (node.current.id === portalId) { const ids = node.current.dataset.ids?.split(",") ?? []; if (ids.includes(internalId)) { node.current.dataset.ids = ids.filter((id) => id !== internalId).join(","); } if (ids.length <= 1) { document.body.removeChild(node.current); node.current = null; } } } catch { node.current = null; } }); if (node.current) { if (!hasChildren && !target && placement !== "center") { return null; } return (0, import_react_dom.createPortal)(children, node.current); } return null; } // src/components/Wrapper.tsx var React7 = __toESM(require("react")); var import_is_lite4 = __toESM(require("is-lite")); function FloaterWrapper(props) { const { childRef, children, id, isControlled, onClick, onMount, onMouseEnter, onMouseLeave, status, style, styles, wrapperRef } = props; useMount(() => { onMount(); }); let element; const mergedStyles = { ...styles, ...style, ...React7.isValidElement(children) ? children.props.style : void 0 }; let wrapperProps = { "aria-describedby": [STATUS.OPENING, STATUS.OPEN, STATUS.CLOSING].includes( status ) ? id : void 0, "data-id": id, style: mergedStyles }; if (!isControlled) { wrapperProps = { ...wrapperProps, onClick, onMouseEnter, onMouseLeave }; } if (children) { if (React7.Children.count(children) === 1 && React7.isValidElement(children) && children.type !== React7.Fragment) { if (import_is_lite4.default.function(children.type)) { element = /* @__PURE__ */ React7.createElement("span", { ref: wrapperRef }, React7.cloneElement(React7.Children.only(children), { innerRef: childRef, ...wrapperProps })); } else { element = React7.cloneElement(React7.Children.only(children), { ref: wrapperRef, ...wrapperProps }); } } else { element = /* @__PURE__ */ React7.createElement("span", { ref: wrapperRef, ...wrapperProps }, children); } } return element ?? null; } var Wrapper_default = React7.memo(FloaterWrapper); // src/modules/styles.ts var import_deepmerge_ts2 = require("deepmerge-ts"); var defaultOptions = { zIndex: 100 }; function getStyles(styles) { const { options = {}, ...rest } = styles ?? {}; return (0, import_deepmerge_ts2.deepmerge)( { arrow: { color: "#fff", display: "inline-flex", length: 16, position: "absolute", spread: 32 }, close: { backgroundColor: "transparent", border: 0, borderRadius: 0, color: "#555", fontSize: 0, height: 15, outline: "none", padding: 10, position: "absolute", right: 0, top: 0, width: 15, WebkitAppearance: "none" }, container: { backgroundColor: "#fff", color: "#666", minHeight: 60, minWidth: 200, padding: 20, position: "relative", zIndex: 10 }, content: { fontSize: 15 }, footer: { borderTop: "1px solid #ccc", fontSize: 13, marginTop: 10, paddingTop: 5 }, floater: { display: "inline-block", filter: "drop-shadow(0 0 3px rgba(0, 0, 0, 0.3))", maxWidth: 300, opacity: 0, position: "relative", transition: "opacity 0.3s", visibility: "hidden", zIndex: options.zIndex }, floaterCentered: { left: "50%", position: "fixed", top: "50%", transform: "translate(-50%, -50%)" }, floaterClosing: { opacity: 0, visibility: "visible" }, floaterOpening: { opacity: 1, visibility: "visible" }, floaterWithComponent: { maxWidth: "100%" }, title: { borderBottom: "1px solid #555", color: "#555", fontSize: 18, marginBottom: 5, paddingBottom: 6, paddingRight: 18 }, wrapper: { cursor: "help", zIndex: options.zIndex }, wrapperPosition: { left: -1e3, position: "absolute", top: -1e3, visibility: "hidden" }, options: (0, import_deepmerge_ts2.deepmerge)(defaultOptions, options) }, rest ); } // src/index.tsx function ReactFloater(props) { const { autoOpen = false, callback, children, component, content, debug = false, disableFlip = false, disableHoverToClick = false, event = "click", eventDelay = 0.4, footer, getPopper, hideArrow = false, id, modifiers, offset = 15, open, placement = "bottom", portalElement, showCloseButton = false, style, styles, target, title, wrapperOptions } = enhanceProps(props); const [state, setState] = React8.useReducer( (previousState, nextState) => ({ ...previousState, ...nextState }), { currentPlacement: placement, positionWrapper: !!wrapperOptions?.position && !!target, status: STATUS.INIT, statusWrapper: STATUS.INIT } ); const arrowRef = React8.useRef(null); const childRef = React8.useRef(null); const eventDelayTimer = React8.useRef(); const floaterRef = React8.useRef(null); const internalId = React8.useRef(randomId()); const isMounted = React8.useRef(false); const popperRef = React8.useRef(); const stateRef = React8.useRef(state); const wrapperPopper = React8.useRef(); const wrapperRef = React8.useRef(null); const wrapperStyles = React8.useRef({}); const { currentPlacement, positionWrapper, status, statusWrapper } = state; const { changed } = (0, import_tree_changes_hook.default)(state); const { changed: changedProps } = (0, import_tree_changes_hook.default)(props); const updateState = React8.useCallback( (nextState, callback_) => { if (isMounted.current) { setState(nextState); stateRef.current = { ...state, ...nextState }; if (callback_) { callback_(); } } }, [setState, state] ); const toggle = React8.useCallback( (forceStatus) => { let nextStatus = stateRef.current.status === STATUS.OPEN ? STATUS.CLOSING : STATUS.RENDER; if (!import_is_lite5.default.undefined(forceStatus)) { nextStatus = forceStatus; } updateState({ status: nextStatus, statusWrapper: nextStatus === STATUS.CLOSING ? STATUS.RENDER : STATUS.IDLE }); }, [updateState] ); const targetElement = React8.useRef(() => { if (!canUseDOM()) { return null; } if (target) { if (import_is_lite5.default.domElement(target)) { return target; } return document.querySelector(target); } return childRef.current ?? wrapperRef.current; }); const currentDebug = React8.useMemo(() => { return canUseDOM() && (debug || !!window.ReactFloaterDebug); }, [debug]); const currentEvent = React8.useMemo(() => { if (event === "hover" && isMobile() && !disableHoverToClick) { return "click"; } return event; }, [disableHoverToClick, event]); const currentStyles = React8.useMemo(() => { const nextStyles = getStyles(styles); const element = targetElement.current(); if (positionWrapper) { let wrapperCurrentStyles; if (status !== STATUS.IDLE) { wrapperCurrentStyles = nextStyles.wrapperPosition; } else if (statusWrapper === STATUS.RENDER) { wrapperCurrentStyles = wrapperPopper.current?.state.styles; } nextStyles.wrapper = { ...nextStyles.wrapper, ...wrapperCurrentStyles }; } if (element) { const targetStyles = window.getComputedStyle(element); if (wrapperStyles.current) { nextStyles.wrapper = { ...nextStyles.wrapper, ...wrapperStyles.current }; } else if (!["relative", "static"].includes(targetStyles.position)) { wrapperStyles.current = {}; if (!positionWrapper) { POSITIONING_PROPS.forEach((d) => { if (d === "position") { wrapperStyles.current[d] = targetStyles[d]; } else { wrapperStyles.current[d] = targetStyles[d]; } }); nextStyles.wrapper = { ...nextStyles.wrapper, ...wrapperStyles.current }; } } } return nextStyles; }, [positionWrapper, status, statusWrapper, styles]); const initPopper = React8.useRef(() => { const nextStatus = stateRef.current.status === STATUS.RENDER ? STATUS.OPENING : STATUS.IDLE; const element = targetElement.current(); if (placement === "center") { setTimeout(() => { updateState({ status: nextStatus }); }, 100); } else if (element) { if (floaterRef.current) { const { arrow, flip, offset: offsetModifier, ...rest } = getModifiers(modifiers); popperRef.current = (0, import_core.createPopper)(element, floaterRef.current, { placement, strategy: isFixed(targetElement.current()) ? "fixed" : "absolute", modifiers: [ mergeModifier( { name: "arrow", enabled: !hideArrow, options: { element: arrowRef.current, padding: 8 } }, arrow ), mergeModifier( { name: "flip", enabled: !disableFlip, options: { altAxis: false, fallbackPlacements: getFallbackPlacements(placement || "bottom") } }, flip ), mergeModifier( { name: "offset", enabled: true, options: { offset: [0, offset] } }, offsetModifier ), { name: "updatePlacement", enabled: true, phase: "afterWrite", fn: ({ instance, state: popperState }) => { if (popperState.placement !== stateRef.current.currentPlacement) { popperRef.current = instance; updateState({ currentPlacement: popperState.placement }); } } }, { name: "applyArrowStyle", enabled: true, phase: "write", fn: ({ state: popperState }) => { const { elements: { arrow: stateArrow }, placement: statePlacement } = popperState; if (stateArrow) { if (statePlacement.startsWith("top")) { stateArrow.style.bottom = "0px"; stateArrow.style.right = ""; } else if (statePlacement.startsWith("bottom")) { stateArrow.style.top = "0px"; stateArrow.style.right = ""; } else if (statePlacement.startsWith("left")) { stateArrow.style.right = "0px"; stateArrow.style.bottom = ""; } else if (statePlacement.startsWith("right")) { stateArrow.style.left = "0px"; stateArrow.style.bottom = ""; } } } }, ...Object.values(rest) ], onFirstUpdate: (popperState) => { updateState({ currentPlacement: popperState.placement, status: nextStatus }); if (placement !== popperState.placement) { setTimeout(() => { popperRef.current?.forceUpdate(); }); } } }); if (getPopper && popperRef.current) { getPopper(popperRef.current, "floater"); } } else { updateState({ status: STATUS.IDLE }); } if (wrapperRef.current && !wrapperPopper.current && stateRef.current.positionWrapper) { const wrapperOffset = wrapperOptions?.offset ? wrapperOptions.offset : 0; wrapperPopper.current = (0, import_core.createPopper)(element, wrapperRef.current, { placement: wrapperOptions?.placement ?? placement, modifiers: [ { name: "arrow", enabled: false }, { name: "offset", options: { offset: [0, wrapperOffset] } }, { name: "flip", enabled: false } ], onFirstUpdate: (popperState) => { updateState({ statusWrapper: STATUS.RENDER }); if (placement !== popperState.placement) { setTimeout(() => { wrapperPopper.current?.forceUpdate(); }); } } }); if (getPopper) { getPopper(wrapperPopper.current, "wrapper"); } } } }); const handleLoad = React8.useRef(() => { if (popperRef.current) { popperRef.current.forceUpdate(); } if (wrapperPopper.current) { wrapperPopper.current.forceUpdate(); } }); const handleTransitionEnd = React8.useRef(() => { if (wrapperPopper.current) { wrapperPopper.current.forceUpdate(); } updateState( { status: stateRef.current.status === STATUS.OPENING ? STATUS.OPEN : STATUS.IDLE }, () => { if (callback) { callback(stateRef.current.status === STATUS.OPEN ? "open" : "close", enhanceProps(props)); } } ); }); const handleClick = React8.useCallback(() => { if (import_is_lite5.default.boolean(open)) { return; } if (currentEvent === "click" || currentEvent === "hover" && positionWrapper) { log({ title: "click", data: [{ event, status: status === STATUS.OPEN ? "closing" : "opening" }], debug: currentDebug }); toggle(status === "idle" ? STATUS.RENDER : void 0); } }, [currentDebug, currentEvent, event, open, positionWrapper, status, toggle]); const handleMouseEnter = React8.useCallback(() => { if (import_is_lite5.default.boolean(open) || isMobile() || currentEvent !== "hover") { return; } log({ title: "mouseEnter", data: [{ key: "originalEvent", value: event }], debug: currentDebug }); if (status === STATUS.IDLE) { clearTimeout(eventDelayTimer.current); eventDelayTimer.current = void 0; toggle(STATUS.RENDER); } }, [currentDebug, currentEvent, event, open, status, toggle]); const handleMouseLeave = React8.useCallback(() => { if (import_is_lite5.default.boolean(open) || isMobile()) { return; } if (currentEvent === "hover") { log({ title: "mouseLeave", data: [{ key: "originalEvent", value: event }], debug: currentDebug }); const hasOpenStatus = [STATUS.OPENING, STATUS.OPEN].includes(status); if (!eventDelay) { toggle(status === STATUS.CLOSING ? STATUS.IDLE : STATUS.CLOSING); } else if (!positionWrapper) { if (hasOpenStatus) { clearTimeout(eventDelayTimer.current); eventDelayTimer.current = window.setTimeout(() => { toggle(); eventDelayTimer.current = void 0; }, eventDelay * 1e3); } } } }, [currentDebug, currentEvent, event, eventDelay, open, positionWrapper, status, toggle]); const handleWrapperMount = React8.useCallback(() => { if (positionWrapper) { initPopper.current(); } }, [positionWrapper]); const cleanUp = () => { if (popperRef.current) { popperRef.current.destroy(); popperRef.current = void 0; } if (wrapperPopper.current) { wrapperPopper.current.destroy(); wrapperPopper.current = void 0; } }; useSingleton(() => { if (canUseDOM()) { window.addEventListener("load", handleLoad.current); } }); useMount(() => { isMounted.current = true; log({ title: "init", data: { hasChildren: !!children, hasTarget: !!target, isControlled: import_is_lite5.default.boolean(open), positionWrapper, target: targetElement.current(), floater: floaterRef.current }, debug: currentDebug }); initPopper.current(); }); useUnmount(() => { isMounted.current = false; cleanUp(); window.removeEventListener("load", handleLoad.current); }); useUpdateEffect(() => { if (!canUseDOM()) { return; } if (changedProps("open")) { let forceStatus; if (import_is_lite5.default.boolean(open)) { forceStatus = open ? STATUS.RENDER : STATUS.CLOSING; } toggle(forceStatus); } if (changedProps("wrapperOptions.position") || changedProps("target")) { updateState({ positionWrapper: !!wrapperOptions?.position && !!target }); } if (changed("status", STATUS.IDLE) && open || changed("status", STATUS.IDLE, STATUS.INIT) && autoOpen) { toggle(STATUS.RENDER); } if (changed("status", STATUS.RENDER)) { if (popperRef.current) { popperRef.current.destroy(); } initPopper.current(); } if (floaterRef.current && changed("status", [STATUS.RENDER, STATUS.CLOSING])) { once(floaterRef.current, "transitionend", handleTransitionEnd.current); } if (changed("status", STATUS.IDLE, STATUS.CLOSING) && popperRef.current) { popperRef.current.destroy(); popperRef.current = void 0; if (wrapperPopper.current) { wrapperPopper.current.forceUpdate(); } } }); const wrapper = /* @__PURE__ */ React8.createElement( Wrapper_default, { childRef, id: id ?? internalId.current, isControlled: import_is_lite5.default.boolean(open), onClick: handleClick, onMount: handleWrapperMount, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, status, style, styles: currentStyles.wrapper, wrapperRef }, children ); return /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement( ReactFloaterPortal, { hasChildren: !!children, internalId: internalId.current, placement: currentPlacement, portalElement, target, zIndex: currentStyles.options.zIndex }, /* @__PURE__ */ React8.createElement( Floater_default, { arrowRef, component, content, floaterRef, footer, hideArrow: hideArrow || currentPlacement === "center", id: id ?? internalId.current, onClick: handleClick, placement: currentPlacement, positionWrapper, showCloseButton, status, styles: currentStyles, title } ), positionWrapper && wrapper ), !positionWrapper && wrapper); } //# sourceMappingURL=index.js.map // fix-cjs-exports if (module.exports.default) { Object.assign(module.exports.default, module.exports); module.exports = module.exports.default; delete module.exports.default; }