'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var vue = require('vue');
require('../../../utils/index.cjs');
require('../../../hooks/index.cjs');
var Portal = require('./Portal.cjs');
var canUseDom = require('../../../utils/dom/canUseDom.cjs');
var vueTypes = require('../../../utils/vue/vueTypes.cjs');
var propType = require('../../../utils/vue/propType.cjs');
var index = require('../../../hooks/use-scroll-locker/index.cjs');
var raf = require('../../../utils/vue/raf.cjs');

let openCount = 0;
const supportDom = canUseDom.canUseDom();
function getOpenCount() {
  return process.env.NODE_ENV === "test" ? openCount : 0;
}
function getParent(getContainer) {
  if (!supportDom)
    return null;
  if (getContainer) {
    if (typeof getContainer === "string")
      return document.querySelectorAll(getContainer)[0];
    if (typeof getContainer === "function")
      return getContainer();
    if (typeof getContainer === "object" && getContainer instanceof window.HTMLElement)
      return getContainer;
  }
  return document.body;
}
var PortalWrapper = /* @__PURE__ */ vue.defineComponent({
  compatConfig: {
    MODE: 3
  },
  name: "PortalWrapper",
  inheritAttrs: false,
  props: {
    wrapperClassName: String,
    forceRender: {
      type: Boolean,
      default: void 0
    },
    getContainer: vueTypes.default.any,
    visible: {
      type: Boolean,
      default: void 0
    },
    autoLock: propType.booleanType(),
    didUpdate: Function
  },
  setup(props, {
    slots
  }) {
    const container = vue.shallowRef();
    const componentRef = vue.shallowRef();
    const rafId = vue.shallowRef();
    const triggerUpdate = vue.shallowRef(1);
    const defaultContainer = canUseDom.canUseDom() && document.createElement("div");
    const removeCurrentContainer = () => {
      var _a, _b;
      if (container.value === defaultContainer)
        (_b = (_a = container.value) == null ? void 0 : _a.parentNode) == null ? void 0 : _b.removeChild(container.value);
      container.value = null;
    };
    let parent = null;
    const attachToParent = (force = false) => {
      if (force || container.value && !container.value.parentNode) {
        parent = getParent(props.getContainer);
        if (parent) {
          parent.appendChild(container.value);
          return true;
        }
        return false;
      }
      return true;
    };
    const getContainer = () => {
      if (!supportDom)
        return null;
      if (!container.value) {
        container.value = defaultContainer;
        attachToParent(true);
      }
      setWrapperClassName();
      return container.value;
    };
    const setWrapperClassName = () => {
      const {
        wrapperClassName
      } = props;
      if (container.value && wrapperClassName && wrapperClassName !== container.value.className)
        container.value.className = wrapperClassName;
    };
    vue.onUpdated(() => {
      setWrapperClassName();
      attachToParent();
    });
    index.useScrollLocker(vue.computed(() => {
      return props.autoLock && props.visible && canUseDom.canUseDom() && (container.value === document.body || container.value === defaultContainer);
    }));
    vue.onMounted(() => {
      let init = false;
      vue.watch([() => props.visible, () => props.getContainer], ([visible, _], [prevVisible, prevGetContainer]) => {
        if (supportDom) {
          parent = getParent(props.getContainer);
          if (parent === document.body) {
            if (visible && !prevVisible)
              openCount += 1;
            else if (init)
              openCount -= 1;
          }
        }
        if (init) {
          const getContainerIsFunc = typeof props.getContainer === "function" && typeof prevGetContainer === "function";
          if (getContainerIsFunc ? props.getContainer.toString() !== prevGetContainer.toString() : props.getContainer !== prevGetContainer)
            removeCurrentContainer();
        }
        init = true;
      }, {
        immediate: true,
        flush: "post"
      });
      vue.nextTick(() => {
        if (!attachToParent()) {
          rafId.value = raf.raf(() => {
            triggerUpdate.value += 1;
          });
        }
      });
    });
    vue.onBeforeUnmount(() => {
      const {
        visible
      } = props;
      if (supportDom && parent === document.body) {
        openCount = visible && openCount ? openCount - 1 : openCount;
      }
      removeCurrentContainer();
      raf.raf.cancel(rafId.value);
    });
    return () => {
      const {
        forceRender,
        visible
      } = props;
      let portal = null;
      const childProps = {
        getOpenCount: () => openCount,
        getContainer
      };
      if (triggerUpdate.value && (forceRender || visible || componentRef.value)) {
        portal = vue.createVNode(Portal.default, {
          "getContainer": getContainer,
          "ref": componentRef,
          "didUpdate": props.didUpdate
        }, {
          default: () => {
            var _a;
            return (_a = slots.default) == null ? void 0 : _a.call(slots, childProps);
          }
        });
      }
      return portal;
    };
  }
});

exports.default = PortalWrapper;
exports.getOpenCount = getOpenCount;
//# sourceMappingURL=PortalWrapper.cjs.map
