{"version":3,"file":"submenu.mjs","sources":["../../../../../src/components/ivue-menu/submenu.vue"],"sourcesContent":["<template>\r\n  <li\r\n    :class=\"wrapperClasses\"\r\n    @mouseenter=\"handleMouseenter\"\r\n    @mouseleave=\"handleMouseleave\"\r\n  >\r\n    <div\r\n      :class=\"`${prefixCls}--title`\"\r\n      ref=\"reference\"\r\n      @click.stop=\"handleTitleClick\"\r\n      :style=\"titleStyle\"\r\n    >\r\n      <!-- title -->\r\n      <slot name=\"title\"></slot>\r\n      <!-- 箭头 -->\r\n      <ivue-icon :class=\"iconClasses\">expand_more</ivue-icon>\r\n    </div>\r\n    <!-- 垂直打开 -->\r\n    <collapse-transition v-if=\"Menu.mode === 'vertical'\">\r\n      <ul class=\"ivue-menu\" v-show=\"data.opened\">\r\n        <slot></slot>\r\n      </ul>\r\n    </collapse-transition>\r\n    <!-- 水平打开 -->\r\n    <drop-down\r\n      :visible=\"data.opened\"\r\n      placement=\"bottom\"\r\n      transition-name=\"slide-up\"\r\n      :styles=\"dropDownStyle\"\r\n      ref=\"dropDown\"\r\n      v-if=\"Menu.mode === 'horizontal'\"\r\n    >\r\n      <ul class=\"ivue-menu-dropdown--list\">\r\n        <slot></slot>\r\n      </ul>\r\n    </drop-down>\r\n  </li>\r\n</template>\r\n\r\n<script lang=\"ts\">\r\nimport {\r\n  computed,\r\n  getCurrentInstance,\r\n  inject,\r\n  onBeforeUnmount,\r\n  onMounted,\r\n  reactive,\r\n  ref,\r\n  watch,\r\n  ComponentInternalInstance,\r\n  provide,\r\n} from 'vue';\r\nimport CollapseTransition from '../../utils/collapse-transition';\r\nimport { getStyle } from '../../utils/assist';\r\nimport { findComponentUpward, findComponentsUpward } from '../../utils/helpers';\r\n\r\n// 下拉框\r\nimport DropDown from './drop-down.vue';\r\nimport IvueIcon from '../ivue-icon/index.vue';\r\n\r\n// ts\r\nimport { MenuContextKey, SubmenuProxy } from './types/menu';\r\nimport { SubmenuContextKey, Data, Props } from './types/submenu';\r\n\r\nconst prefixCls = 'ivue-menu-submenu';\r\n\r\nexport default {\r\n  name: prefixCls,\r\n  props: {\r\n    /**\r\n     * 菜单项的唯一标识，必填\r\n     *\r\n     * @type {String | NUmber}\r\n     */\r\n    name: {\r\n      type: [String, Number],\r\n      required: true,\r\n    },\r\n    /**\r\n     * 禁用\r\n     *\r\n     * @type {Boolean}\r\n     */\r\n    disabled: {\r\n      type: Boolean,\r\n      default: false,\r\n    },\r\n  },\r\n  setup(props: Props) {\r\n    // vm\r\n    const { proxy, uid } = getCurrentInstance() as ComponentInternalInstance;\r\n\r\n    // dom\r\n    const reference = ref<HTMLDivElement>();\r\n    const dropDown = ref();\r\n\r\n    // inject\r\n    const Menu = inject(MenuContextKey, {\r\n      default: null,\r\n    });\r\n\r\n    const Submenu = inject(SubmenuContextKey, {\r\n      default: null,\r\n    });\r\n\r\n    // data\r\n    const data = reactive<Data>({\r\n      /**\r\n       * 展开\r\n       *\r\n       * @type {Boolean}\r\n       */\r\n      opened: false,\r\n      /**\r\n       * 下拉框宽度\r\n       *\r\n       * @type {Number}\r\n       */\r\n      dropWidth: parseFloat(getStyle(proxy.$el, 'width')),\r\n      /**\r\n       * 延迟\r\n       *\r\n       * @type {Function}\r\n       */\r\n      timeout: null,\r\n      /**\r\n       * 子菜单列表\r\n       *\r\n       * @type {Array}\r\n       */\r\n      childSubmenuList: [],\r\n      /**\r\n       * 是否激活\r\n       *\r\n       * @type {Boolean}\r\n       */\r\n      active: false,\r\n    });\r\n\r\n    // computed\r\n\r\n    // 外部样式\r\n    const wrapperClasses = computed(() => {\r\n      return [\r\n        prefixCls,\r\n        {\r\n          // 激活\r\n          [`${prefixCls}--active`]: data.active && !Submenu.default,\r\n          // 子菜单激活\r\n          [`${prefixCls}--child-active`]: data.active,\r\n          // 打开下拉框\r\n          [`${prefixCls}--opened`]: data.opened,\r\n        },\r\n      ];\r\n    });\r\n\r\n    // 标题样式\r\n    const titleStyle = computed(() => {\r\n      const styles: {\r\n        paddingLeft?: string;\r\n      } = {};\r\n\r\n      const len = findComponentsUpward(proxy, 'ivue-menu-submenu').length;\r\n\r\n      if (Submenu.default !== null && Menu.mode !== 'horizontal') {\r\n        styles.paddingLeft = `${43 + (len - 1) * 24}px`;\r\n      }\r\n\r\n      return styles;\r\n    });\r\n\r\n    // 下拉框样式\r\n    const dropDownStyle = computed(() => {\r\n      const style = {\r\n        minWidth: 'auto',\r\n      };\r\n\r\n      if (data.dropWidth) {\r\n        style.minWidth = `${data.dropWidth}px`;\r\n      }\r\n\r\n      return style;\r\n    });\r\n\r\n    // icon样式\r\n    const iconClasses = computed(() => {\r\n      return [\r\n        `${prefixCls}--icon`,\r\n        {\r\n          // 打开下拉框\r\n          [`${prefixCls}--opened__icon`]: data.opened,\r\n        },\r\n      ];\r\n    });\r\n\r\n    // methods\r\n\r\n    // 标题点击\r\n    const handleTitleClick = () => {\r\n      // 禁用\r\n      if (props.disabled) {\r\n        return;\r\n      }\r\n\r\n      // 水平\r\n      if (Menu.mode === 'horizontal') {\r\n        return;\r\n      }\r\n\r\n      const opened = data.opened;\r\n\r\n      data.opened = !opened;\r\n\r\n      // 更新打开的菜单名称\r\n      Menu.updateOpenKeys(props.name);\r\n    };\r\n\r\n    // 鼠标进入\r\n    const handleMouseenter = () => {\r\n      // 禁用\r\n      if (props.disabled) {\r\n        return;\r\n      }\r\n\r\n      // 垂直\r\n      if (Menu.mode === 'vertical') {\r\n        return;\r\n      }\r\n\r\n      clearTimeout(data.timeout);\r\n\r\n      data.timeout = setTimeout(() => {\r\n        // 更新打开的菜单名称\r\n        Menu.updateOpenKeys(props.name);\r\n\r\n        data.opened = true;\r\n      }, 250);\r\n    };\r\n\r\n    // 鼠标离开\r\n    const handleMouseleave = () => {\r\n      // 禁用\r\n      if (props.disabled) {\r\n        return;\r\n      }\r\n\r\n      // 垂直\r\n      if (Menu.mode === 'vertical') {\r\n        return;\r\n      }\r\n\r\n      clearTimeout(data.timeout);\r\n      data.timeout = setTimeout(() => {\r\n        // 更新打开的菜单名称\r\n        Menu.updateOpenKeys(props.name);\r\n\r\n        data.opened = false;\r\n      }, 150);\r\n    };\r\n\r\n    // 添加子菜单\r\n    const addSubmenu = () => {\r\n      const { submenuList } = Menu.data;\r\n\r\n      // 插入当前子菜单\r\n      if (submenuList) {\r\n        submenuList.push({\r\n          uid: uid,\r\n          submenu: proxy as unknown as SubmenuProxy,\r\n        });\r\n      }\r\n\r\n      // 查找父子菜单\r\n      const parentSubmenu = findComponentUpward(proxy, prefixCls);\r\n\r\n      if (parentSubmenu) {\r\n        if (!parentSubmenu.data.childSubmenuList) {\r\n          parentSubmenu.data.childSubmenuList = [];\r\n        }\r\n\r\n        parentSubmenu.data.childSubmenuList.push({\r\n          uid: uid,\r\n          submenu: proxy as unknown as SubmenuProxy,\r\n        });\r\n      }\r\n    };\r\n\r\n    // 删除子菜单\r\n    const removeSubmenu = () => {\r\n      const { submenuList } = Menu.data;\r\n\r\n      if (submenuList && submenuList.length) {\r\n        const index = submenuList.findIndex((item) => item.uid === uid);\r\n\r\n        submenuList.splice(index, 1);\r\n      }\r\n    };\r\n\r\n    // 更新激活的名称\r\n    const activeName = (status: boolean | string | number) => {\r\n      if (findComponentUpward(proxy, 'ivue-menu-submenu')) {\r\n        Submenu.activeName(status);\r\n      }\r\n\r\n      // 子菜单列表\r\n      if (data.childSubmenuList && data.childSubmenuList.length) {\r\n        data.childSubmenuList\r\n          .map((item) => item.submenu)\r\n          .forEach((item) => {\r\n            item.data.active = false;\r\n          });\r\n      }\r\n\r\n      // 激活\r\n      data.active = status;\r\n    };\r\n\r\n    // 菜单选择\r\n    const handleMenuItemSelect = (name) => {\r\n      // 水平\r\n      if (Menu.mode === 'horizontal') {\r\n        data.opened = false;\r\n      }\r\n\r\n      Menu.handleMenuItemSelect(name);\r\n    };\r\n\r\n    // watch\r\n\r\n    // 监听模式变化\r\n    watch(\r\n      () => Menu.mode,\r\n      (value) => {\r\n        // 水平\r\n        if (value === 'horizontal') {\r\n          dropDown.value.update();\r\n        }\r\n      }\r\n    );\r\n\r\n    // 监听打开\r\n    watch(\r\n      () => data.opened,\r\n      (value) => {\r\n        // 垂直打开\r\n        if (Menu.mode === 'vertical') {\r\n          return;\r\n        }\r\n\r\n        // 打开下拉框\r\n        if (value) {\r\n          // 下拉框宽度\r\n          data.dropWidth = parseFloat(getStyle(proxy.$el, 'width'));\r\n\r\n          dropDown.value.update();\r\n        }\r\n        // 销毁下拉框\r\n        else {\r\n          dropDown.value.destroy();\r\n        }\r\n      }\r\n    );\r\n\r\n    // provide\r\n\r\n    provide(\r\n      SubmenuContextKey,\r\n      reactive({\r\n        activeName,\r\n        handleMenuItemSelect,\r\n      })\r\n    );\r\n\r\n    // onMounted\r\n    onMounted(() => {\r\n      addSubmenu();\r\n    });\r\n\r\n    // onBeforeUnmount\r\n    onBeforeUnmount(() => {\r\n      removeSubmenu();\r\n    });\r\n\r\n    return {\r\n      prefixCls,\r\n\r\n      // dom\r\n      reference,\r\n      dropDown,\r\n\r\n      // data\r\n      data,\r\n\r\n      // inject\r\n      Menu,\r\n\r\n      // computed\r\n      wrapperClasses,\r\n      titleStyle,\r\n      dropDownStyle,\r\n      iconClasses,\r\n\r\n      // methods\r\n      activeName,\r\n      handleTitleClick,\r\n      handleMouseenter,\r\n      handleMouseleave,\r\n      handleMenuItemSelect,\r\n    };\r\n  },\r\n  components: {\r\n    CollapseTransition,\r\n    DropDown,\r\n    IvueIcon,\r\n  },\r\n};\r\n</script>\r\n"],"names":["_resolveComponent","_openBlock","_createElementBlock","_normalizeClass","_createElementVNode","_withModifiers","_normalizeStyle","_createCommentVNode","_renderSlot","_createVNode","_createBlock","_withCtx","_withDirectives"],"mappings":";;;;;;;;;+BACEA,iBAmCK,WAAA,CAAA,CAAA;EAjCF,OAAAC,SAAA,EAAU,EAAAC,kBAAA,CAAA,IAAA,EAAA;AAAA,IACV,KAAA,EAAUC,cAAA,CAAA,MAAA,CAAA,cAAA,CAAA;AAAA,IAAA,YAAA,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,MAAA,CAAA,gBAAA,IAAA,MAAA,CAAA,gBAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IAEX,YAUM,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,MAAA,CAAA,gBAAA,IAAA,MAAA,CAAA,gBAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,GAAA,EAAA;AAAA,IARWC,mBAAA,KAAA,EAAA;AAAA,MACd,KAAK,EAAAD,cAAA,CAAA,CAAA,EAAA,MAAA,CAAA,SAAA,CAAA,OAAA,CAAA,CAAA;AAAA,MACL,GAAK,EAAA,WAAA;AAAA,MAAA,SAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAAE,cAAA,CAAA,GAAA,IAAA,KAAA,MAAA,CAAA,gBAAA,IAAA,OAAA,gBAAA,CAAA,GAAA,IAAA,CAAA,EAAA,CAAA,MAAA,CAAA,CAAA,CAAA;AAAA,MAEN,KAAA,EAAcC,cAAA,CAAA,MAAA,CAAA,UAAA,CAAA;AAAA,KACd,EAAA;AAAA,MACAC,mBAAW,SAAA,CAAA;AAAA,MACXC,UAAA,CAAuD,IAAA,CAAA,MAAA,EAAA,OAAA,CAAA;AAAA,MAAAD,mBAAtC,gBAAE,CAAA;AAAA,MAAAE,YAAA,oBAAA,EAAA;AAAA,QAAwB,KAAA,EAAAN,cAAA,CAAA,MAAA,CAAA,WAAA,CAAA;AAAA,OAAA,EAAA;AAAA;;;;OAEhC,EAAA,CAAA,EAAA,CAAA,OAAA,CAAA,CAAA;AAAA,OACc,CAAS,CAAA;AAAA,IAApCI,mBAAA,4BAAA,CAAA;AAAA,IAAA,MAAA,CAAA,IAAA,CAAA,IAAA,KAAA,UAAA,IAAAN,SAAA,EAAA,EAAAS,WAAA,CACE,8BAEK,EAAA,EAAA,GAAA,EAAA,CAAA,EAAA,EAAA;AAAA,MAAA,OAAA,EADHC,QAAa,MAAA;AAAA,QAAAC,cAAA,CAAAR,kBAAA,CAAA,IAAA,EAAA,UAAA,EAAA;AAAA,UADeI,UAAA,CAAA,IAAA,CAAA,MAAA,EAAK,SAAM,CAAA;AAAA,SAAA,EAAA,GAAA,CAAA,EAAA;AAAA;;;;KAI3C,CAAA,IAOQD,kBAAS,CAAA,MAAA,EAAA,IAAA,CAAA;AAAA,IANjBA,mBAAA,4BAAA,CAAA;AAAA,IAAA,OAAA,IAAA,CAAA,IAAA,KAAA,gBAAAN,SACY,EAAA,cAAK,oBAAM,EAAA;AAAA,MACrB,GAAA,EAAA,CAAA;AAAA,MACA,OAAA,EAAgB,OAAA,IAAA,CAAA,MAAA;AAAA,MACf,SAAQ,EAAA,QAAA;AAAA,MACT,iBAAc,EAAA,UAAA;AAAA,MAAA,QAAA,MAAA,CAAA,aAAA;AAAA;;eAIZU,QAAa,MAAA;AAAA,QAAAP,kBAAA,CAAA,MAAA,UAAA,EAAA;AAAA;;;;;;;;;;;"}