'use strict';

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

var vue = require('vue');
var lodashEs = require('lodash-es');
var iconsVue = require('@ant-design/icons-vue');
require('../../../utils/index.cjs');
require('../../../vue-components/vc-overflow/index.cjs');
require('../../../vue-components/transition/index.cjs');
var index = require('../style/index.cjs');
var useConfigInject = require('../../config-provider/src/hooks/useConfigInject.cjs');
var injectionKey = require('../../layout/src/injectionKey.cjs');
var OverrideContext = require('./OverrideContext.cjs');
var useItems = require('./hooks/useItems.cjs');
var useKeyPath = require('./hooks/useKeyPath.cjs');
var SubMenu = require('./SubMenu.cjs');
var MenuItem = require('./MenuItem.cjs');
var useMenuContext = require('./hooks/useMenuContext.cjs');
var props = require('./props.cjs');
var log = require('../../../utils/log.cjs');
var shallowEqual = require('../../../utils/lang/shallowEqual.cjs');
var collapseMotion = require('../../../vue-components/transition/src/collapseMotion.cjs');
var vnode = require('../../../utils/vue/vnode.cjs');
var props$1 = require('../../../utils/vue/props.cjs');
var Overflow = require('../../../vue-components/vc-overflow/src/Overflow.cjs');

const EMPTY_LIST = [];
var AMenu = /* @__PURE__ */ vue.defineComponent({
  compatConfig: {
    MODE: 3
  },
  name: "AMenu",
  inheritAttrs: false,
  props: props.menuProps(),
  slots: Object,
  setup(props, {
    slots,
    emit,
    attrs
  }) {
    const {
      direction,
      getPrefixCls
    } = useConfigInject.default("menu", props);
    const override = OverrideContext.useInjectOverride();
    const prefixCls = vue.computed(() => {
      var _a;
      return getPrefixCls("menu", props.prefixCls || ((_a = override == null ? void 0 : override.prefixCls) == null ? void 0 : _a.value));
    });
    const [wrapSSR, hashId] = index.default(prefixCls, vue.computed(() => {
      return !override;
    }));
    const store = vue.shallowRef(/* @__PURE__ */ new Map());
    const siderCollapsed = vue.inject(injectionKey.SiderCollapsedKey, vue.ref(void 0));
    const inlineCollapsed = vue.computed(() => {
      if (siderCollapsed.value !== void 0)
        return siderCollapsed.value;
      return props.inlineCollapsed;
    });
    const {
      itemsNodes
    } = useItems.default(props);
    const isMounted = vue.shallowRef(false);
    vue.onMounted(() => {
      isMounted.value = true;
    });
    vue.watchEffect(() => {
      log.devWarning(!(props.inlineCollapsed === true && props.mode !== "inline"), "Menu", "`inlineCollapsed` should only be used when `mode` is inline.");
      log.devWarning(!(siderCollapsed.value !== void 0 && props.inlineCollapsed === true), "Menu", "`inlineCollapsed` not control Menu under Sider. Should set `collapsed` on Sider instead.");
    });
    const activeKeys = vue.ref([]);
    const mergedSelectedKeys = vue.ref([]);
    const keyMapStore = vue.ref({});
    vue.watch(store, () => {
      const newKeyMapStore = {};
      for (const menuInfo of store.value.values())
        newKeyMapStore[menuInfo.key] = menuInfo;
      keyMapStore.value = newKeyMapStore;
    }, {
      flush: "post"
    });
    vue.watchEffect(() => {
      if (props.activeKey !== void 0) {
        let keys = [];
        const menuInfo = props.activeKey ? keyMapStore.value[props.activeKey] : void 0;
        if (menuInfo && props.activeKey !== void 0)
          keys = lodashEs.uniq([].concat(vue.unref(menuInfo.parentKeys), props.activeKey));
        else
          keys = [];
        if (!shallowEqual.shallowEqual(activeKeys.value, keys))
          activeKeys.value = keys;
      }
    });
    vue.watch(() => props.selectedKeys, (selectedKeys) => {
      if (selectedKeys)
        mergedSelectedKeys.value = selectedKeys.slice();
    }, {
      immediate: true,
      deep: true
    });
    const selectedSubMenuKeys = vue.ref([]);
    vue.watch([keyMapStore, mergedSelectedKeys], () => {
      let subMenuParentKeys = [];
      mergedSelectedKeys.value.forEach((key) => {
        const menuInfo = keyMapStore.value[key];
        if (menuInfo)
          subMenuParentKeys = subMenuParentKeys.concat(vue.unref(menuInfo.parentKeys));
      });
      subMenuParentKeys = lodashEs.uniq(subMenuParentKeys);
      if (!shallowEqual.shallowEqual(selectedSubMenuKeys.value, subMenuParentKeys))
        selectedSubMenuKeys.value = subMenuParentKeys;
    }, {
      immediate: true
    });
    const mergedOpenKeys = vue.ref([]);
    const mergedMode = vue.ref("vertical");
    const triggerOpenKeys = (keys) => {
      mergedOpenKeys.value = keys;
      emit("update:openKeys", keys);
      emit("openChange", keys);
    };
    const triggerSelection = (info) => {
      if (props.selectable) {
        const {
          key: targetKey
        } = info;
        const exist = mergedSelectedKeys.value.includes(targetKey);
        let newSelectedKeys;
        if (props.multiple) {
          if (exist)
            newSelectedKeys = mergedSelectedKeys.value.filter((key) => key !== targetKey);
          else
            newSelectedKeys = [...mergedSelectedKeys.value, targetKey];
        } else {
          newSelectedKeys = [targetKey];
        }
        const selectInfo = {
          ...info,
          selectedKeys: newSelectedKeys
        };
        if (!shallowEqual.shallowEqual(newSelectedKeys, mergedSelectedKeys.value)) {
          if (props.selectedKeys === void 0)
            mergedSelectedKeys.value = newSelectedKeys;
          emit("update:selectedKeys", newSelectedKeys);
          if (exist && props.multiple)
            emit("deselect", selectInfo);
          else
            emit("select", selectInfo);
        }
      }
      if (mergedMode.value !== "inline" && !props.multiple && mergedOpenKeys.value.length)
        triggerOpenKeys(EMPTY_LIST);
    };
    vue.watch(() => props.openKeys, (openKeys = mergedOpenKeys.value) => {
      if (!shallowEqual.shallowEqual(mergedOpenKeys.value, openKeys))
        mergedOpenKeys.value = openKeys.slice();
    }, {
      immediate: true,
      deep: true
    });
    let timeout;
    const changeActiveKeys = (keys) => {
      clearTimeout(timeout);
      timeout = setTimeout(() => {
        if (props.activeKey === void 0)
          activeKeys.value = keys;
        emit("update:activeKey", keys[keys.length - 1]);
      });
    };
    const disabled = vue.computed(() => !!props.disabled);
    const isRtl = vue.computed(() => direction.value === "rtl");
    const mergedInlineCollapsed = vue.shallowRef(false);
    vue.watchEffect(() => {
      var _a;
      if ((props.mode === "inline" || props.mode === "vertical") && inlineCollapsed.value) {
        mergedMode.value = "vertical";
        mergedInlineCollapsed.value = inlineCollapsed.value;
      } else {
        mergedMode.value = props.mode;
        mergedInlineCollapsed.value = false;
      }
      if ((_a = override == null ? void 0 : override.mode) == null ? void 0 : _a.value)
        mergedMode.value = override.mode.value;
    });
    const isInlineMode = vue.computed(() => mergedMode.value === "inline");
    const inlineCacheOpenKeys = vue.ref(mergedOpenKeys.value);
    const mountRef = vue.shallowRef(false);
    vue.watch(mergedOpenKeys, () => {
      if (isInlineMode.value)
        inlineCacheOpenKeys.value = mergedOpenKeys.value;
    }, {
      immediate: true
    });
    vue.watch(isInlineMode, () => {
      if (!mountRef.value) {
        mountRef.value = true;
        return;
      }
      if (isInlineMode.value) {
        mergedOpenKeys.value = inlineCacheOpenKeys.value;
      } else {
        triggerOpenKeys(EMPTY_LIST);
      }
    }, {
      immediate: true
    });
    const className = vue.computed(() => {
      return {
        [`${prefixCls.value}`]: true,
        [`${prefixCls.value}-root`]: true,
        [`${prefixCls.value}-${mergedMode.value}`]: true,
        [`${prefixCls.value}-inline-collapsed`]: mergedInlineCollapsed.value,
        [`${prefixCls.value}-rtl`]: isRtl.value,
        [`${prefixCls.value}-${props.theme}`]: true
      };
    });
    const rootPrefixCls = vue.computed(() => getPrefixCls());
    const defaultMotions = vue.computed(() => ({
      horizontal: {
        name: `${rootPrefixCls.value}-slide-up`
      },
      inline: collapseMotion.collapseMotion(`${rootPrefixCls.value}-motion-collapse`),
      other: {
        name: `${rootPrefixCls.value}-zoom-big`
      }
    }));
    useMenuContext.useProvideFirstLevel(true);
    const getChildrenKeys = (eventKeys = []) => {
      const keys = [];
      const storeValue = store.value;
      eventKeys.forEach((eventKey) => {
        const {
          key,
          childrenEventKeys
        } = storeValue.get(eventKey);
        keys.push(key, ...getChildrenKeys(vue.unref(childrenEventKeys)));
      });
      return keys;
    };
    const onInternalClick = (info) => {
      var _a;
      emit("click", info);
      triggerSelection(info);
      (_a = override == null ? void 0 : override.onClick) == null ? void 0 : _a.call(override);
    };
    const onInternalOpenChange = (key, open) => {
      var _a;
      const childrenEventKeys = ((_a = keyMapStore.value[key]) == null ? void 0 : _a.childrenEventKeys) || [];
      let newOpenKeys = mergedOpenKeys.value.filter((k) => k !== key);
      if (open) {
        newOpenKeys.push(key);
      } else if (mergedMode.value !== "inline") {
        const subPathKeys = getChildrenKeys(vue.unref(childrenEventKeys));
        newOpenKeys = lodashEs.uniq(newOpenKeys.filter((k) => !subPathKeys.includes(k)));
      }
      if (!shallowEqual.shallowEqual(mergedOpenKeys, newOpenKeys))
        triggerOpenKeys(newOpenKeys);
    };
    const registerMenuInfo = (key, info) => {
      store.value.set(key, info);
      store.value = new Map(store.value);
    };
    const unRegisterMenuInfo = (key) => {
      store.value.delete(key);
      store.value = new Map(store.value);
    };
    const lastVisibleIndex = vue.ref(0);
    const expandIcon = vue.computed(() => {
      var _a;
      return props.expandIcon || slots.expandIcon || ((_a = override == null ? void 0 : override.expandIcon) == null ? void 0 : _a.value) ? (opt) => {
        let icon = props.expandIcon || slots.expandIcon;
        icon = typeof icon === "function" ? icon(opt) : icon;
        return vnode.cloneElement(icon, {
          class: `${prefixCls.value}-submenu-expand-icon`
        }, false);
      } : null;
    });
    useMenuContext.useProvideMenu({
      prefixCls,
      activeKeys,
      openKeys: mergedOpenKeys,
      selectedKeys: mergedSelectedKeys,
      changeActiveKeys,
      disabled,
      rtl: isRtl,
      mode: mergedMode,
      inlineIndent: vue.computed(() => props.inlineIndent),
      subMenuCloseDelay: vue.computed(() => props.subMenuCloseDelay),
      subMenuOpenDelay: vue.computed(() => props.subMenuOpenDelay),
      builtinPlacements: vue.computed(() => props.builtinPlacements),
      triggerSubMenuAction: vue.computed(() => props.triggerSubMenuAction),
      getPopupContainer: vue.computed(() => props.getPopupContainer),
      inlineCollapsed: mergedInlineCollapsed,
      theme: vue.computed(() => props.theme),
      siderCollapsed,
      defaultMotions: vue.computed(() => isMounted.value ? defaultMotions.value : null),
      motion: vue.computed(() => isMounted.value ? props.motion : null),
      overflowDisabled: vue.shallowRef(void 0),
      onOpenChange: onInternalOpenChange,
      onItemClick: onInternalClick,
      registerMenuInfo,
      unRegisterMenuInfo,
      selectedSubMenuKeys,
      expandIcon,
      forceSubMenuRender: vue.computed(() => props.forceSubMenuRender),
      rootClassName: hashId
    });
    return () => {
      var _a, _b;
      const childList = itemsNodes.value || props$1.flattenChildren((_a = slots.default) == null ? void 0 : _a.call(slots));
      const allVisible = lastVisibleIndex.value >= childList.length - 1 || mergedMode.value !== "horizontal" || props.disabledOverflow;
      const wrappedChildList = mergedMode.value !== "horizontal" || props.disabledOverflow ? childList : childList.map((child, index) => {
        return (
          // Always wrap provider to avoid sub node re-mount
          vue.createVNode(useMenuContext.MenuContextProvider, {
            "key": child.key,
            "overflowDisabled": index > lastVisibleIndex.value
          }, {
            default: () => child
          })
        );
      });
      const overflowedIndicator = ((_b = slots.overflowedIndicator) == null ? void 0 : _b.call(slots)) || vue.createVNode(iconsVue.EllipsisOutlined, null, null);
      return wrapSSR(vue.createVNode(Overflow.default, {
        ...attrs,
        "onMousedown": props.onMousedown,
        "prefixCls": `${prefixCls.value}-overflow`,
        "component": "ul",
        "itemComponent": MenuItem.default,
        "class": [className.value, attrs.class, hashId.value],
        "role": "menu",
        "id": props.id,
        "data": wrappedChildList,
        "renderRawItem": (node) => node,
        "renderRawRest": (omitItems) => {
          const len = omitItems.length;
          const originOmitItems = len ? childList.slice(-len) : null;
          return vue.createVNode(vue.Fragment, null, [vue.createVNode(SubMenu.default, {
            "eventKey": useKeyPath.OVERFLOW_KEY,
            "key": useKeyPath.OVERFLOW_KEY,
            "title": overflowedIndicator,
            "disabled": allVisible,
            "internalPopupClose": len === 0
          }, {
            default: () => originOmitItems
          }), vue.createVNode(useKeyPath.PathContext, null, {
            default: () => [vue.createVNode(SubMenu.default, {
              "eventKey": useKeyPath.OVERFLOW_KEY,
              "key": useKeyPath.OVERFLOW_KEY,
              "title": overflowedIndicator,
              "disabled": allVisible,
              "internalPopupClose": len === 0
            }, {
              default: () => originOmitItems
            })]
          })]);
        },
        "maxCount": mergedMode.value !== "horizontal" || props.disabledOverflow ? Overflow.default.INVALIDATE : Overflow.default.RESPONSIVE,
        "ssr": "full",
        "data-menu-list": true,
        "onVisibleChange": (newLastIndex) => {
          lastVisibleIndex.value = newLastIndex;
        }
      }, {
        default: () => [vue.createVNode(vue.Teleport, {
          "to": "body"
        }, {
          default: () => [vue.createVNode("div", {
            "style": {
              display: "none"
            },
            "aria-hidden": true
          }, [vue.createVNode(useKeyPath.PathContext, null, {
            default: () => [wrappedChildList]
          })])]
        })]
      }));
    };
  }
});

exports.default = AMenu;
//# sourceMappingURL=Menu.cjs.map
