You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1 line
23 KiB

11 months ago
{"version":3,"file":"sub-menu.mjs","sources":["../../../../../../packages/components/menu/src/sub-menu.ts"],"sourcesContent":["import {\n defineComponent,\n computed,\n ref,\n provide,\n inject,\n getCurrentInstance,\n watch,\n onMounted,\n onBeforeUnmount,\n withDirectives,\n Fragment,\n vShow,\n h,\n reactive,\n} from 'vue'\nimport { useTimeoutFn } from '@vueuse/core'\nimport ElCollapseTransition from '@element-plus/components/collapse-transition'\nimport ElTooltip from '@element-plus/components/tooltip'\nimport { buildProps } from '@element-plus/utils/props'\nimport { throwError } from '@element-plus/utils/error'\nimport { ArrowDown, ArrowRight } from '@element-plus/icons-vue'\nimport { ElIcon } from '@element-plus/components/icon'\nimport useMenu from './use-menu'\nimport { useMenuCssVar } from './use-menu-css-var'\n\nimport type { Placement } from '@element-plus/components/popper'\nimport type { ExtractPropTypes, VNodeArrayChildren, CSSProperties } from 'vue'\nimport type { MenuProvider, SubMenuProvider } from './types'\n\nexport const subMenuProps = buildProps({\n index: {\n type: String,\n required: true,\n },\n showTimeout: {\n type: Number,\n default: 300,\n },\n hideTimeout: {\n type: Number,\n default: 300,\n },\n popperClass: String,\n disabled: Boolean,\n popperAppendToBody: {\n type: Boolean,\n default: undefined,\n },\n} as const)\nexport type SubMenuProps = ExtractPropTypes<typeof subMenuProps>\n\nconst COMPONENT_NAME = 'ElSubMenu'\nexport default defineComponent({\n name: COMPONENT_NAME,\n props: subMenuProps,\n\n setup(props, { slots, expose }) {\n const instance = getCurrentInstance()!\n const { paddingStyle, indexPath, parentMenu } = useMenu(\n instance,\n computed(() => props.index)\n )\n\n // inject\n const rootMenu = inject<MenuProvider>('rootMenu')\n if (!rootMenu) throwError(COMPONENT_NAME, 'can not inject root menu')\n\n const subMenu = inject<SubMenuProvider>(`subMenu:${parentMenu.value!.uid}`)\n if (!subMenu) throwError(COMPONENT_NAME, 'can not inject sub menu')\n\n const items = ref<MenuProvider['items']>({})\n const subMenus = ref<MenuProvider['subMenus']>({})\n\n let timeout: (() => void) | undefined\n const mouseInChild = ref(false)\n const verticalTitleRef = ref<HTMLDivElement>()\n const vPopper = ref<InstanceType<typeof ElTooltip> | null>(null)\n\n // computed\n const currentPlacement = computed<Placement>(() =>\n mode.value === 'horizontal' && isFirstLevel.value\n ? 'bottom-start'\n : 'right-start'\n )\n const subMenuTitleIcon = computed(() => {\n return (mode.value === 'horizontal' && isFirstLevel.value) ||\n (mode.value === 'vertical' && !rootMenu.props.collapse)\n ? ArrowDown\n : ArrowRight\n })\n const isFirstLevel = computed(() => {\n let isFirstLevel = true\n let parent = instance.parent\n while (parent && parent.type.name !== 'ElMenu') {\n if (['ElSubMenu', 'ElMenuItemGroup'].includes(parent.type.name!)) {\n isFirstLevel = false\n break\n } else {\n parent = parent.parent\n }\n }\n return isFirstLevel\n })\n const appendToBody = computed(() => {\n return props.popperAppendToBody === undefined\n ? isFirstLevel.value\n : Boolean(props.popperAppendToBody)\n })\n const menuTransitionName = computed(() =>\n rootMenu.props.collapse ? 'el-zoom-in-left' : 'el-zoom-in-top'\n )\n const fallbackPlacements = computed<Placement[]>(() =>\n mode.value === 'horizontal' && isFirstLevel.value\n ? [\n 'bottom-start',\n 'bottom-end',\n 'top-start',\n 'top-end',\n 'right-start',\n 'left-start',\n ]\n : [\n 'right-start',\n 'left-start',\n 'bottom-start',\n 'bottom-end',\n 'top-start',\n 'top-end',\n ]\n )\n const opened = computed(() => rootMenu.opened