UNPKG

@arco-design/web-vue

Version:

Arco Design Vue 2.0: A Vue.js 3 UI Library

274 lines (273 loc) 8.11 kB
import { defineComponent, toRefs, reactive, computed, provide, resolveComponent, openBlock, createElementBlock, mergeProps, createElementVNode, normalizeClass, renderSlot, createBlock, createCommentVNode } from "vue"; import { getPrefixCls } from "../_utils/global-config.js"; import IconMenuFold from "../icon/icon-menu-fold/index.js"; import IconMenuUnfold from "../icon/icon-menu-unfold/index.js"; import useMergeState from "../_hooks/use-merge-state.js"; import { provideLevel } from "./hooks/use-level.js"; import { MenuInjectionKey } from "./context.js"; import usePickSlots from "../_hooks/use-pick-slots.js"; import { omit } from "../_utils/omit.js"; import useMenuDataCollector from "./hooks/use-menu-data-collector.js"; import useMenuOpenState from "./hooks/use-menu-open-state.js"; import { useResponsive } from "../_hooks/use-responsive.js"; import { isNumber, isObject } from "../_utils/is.js"; import _export_sfc from "../_virtual/plugin-vue_export-helper.js"; const _sfc_main = defineComponent({ name: "BaseMenu", components: { IconMenuFold, IconMenuUnfold }, inheritAttrs: false, props: { style: { type: Object }, theme: { type: String, default: "light" }, mode: { type: String, default: "vertical" }, levelIndent: { type: Number }, autoOpen: { type: Boolean }, collapsed: { type: Boolean, default: void 0 }, defaultCollapsed: { type: Boolean }, collapsedWidth: { type: Number }, accordion: { type: Boolean }, autoScrollIntoView: { type: Boolean }, showCollapseButton: { type: Boolean }, selectedKeys: { type: Array }, defaultSelectedKeys: { type: Array, default: () => [] }, openKeys: { type: Array }, defaultOpenKeys: { type: Array, default: () => [] }, scrollConfig: { type: Object }, triggerProps: { type: Object }, tooltipProps: { type: Object }, autoOpenSelected: { type: Boolean }, breakpoint: { type: String }, popupMaxHeight: { type: [Boolean, Number], default: true }, prefixCls: { type: String }, inTrigger: { type: Boolean }, siderCollapsed: { type: Boolean }, isRoot: { type: Boolean } }, emits: [ "update:collapsed", "update:selectedKeys", "update:openKeys", "collapse", "menu-item-click", "sub-menu-click" ], setup(props, { emit, slots }) { const { style, mode, theme, levelIndent, accordion, showCollapseButton, scrollConfig, autoScrollIntoView, collapsedWidth, autoOpen, collapsed: propCollapsed, defaultCollapsed, selectedKeys: propSelectedKeys, defaultSelectedKeys, openKeys: propOpenKeys, defaultOpenKeys, triggerProps, tooltipProps, autoOpenSelected, breakpoint, popupMaxHeight, prefixCls, inTrigger, siderCollapsed, isRoot } = toRefs(props); const { subMenuKeys, menuData } = useMenuDataCollector({ type: isRoot.value ? "menu" : "popupMenu" }); const [selectedKeys, setSelectedKeys] = useMergeState( defaultSelectedKeys.value, reactive({ value: propSelectedKeys }) ); const { openKeys, setOpenKeys, open } = useMenuOpenState( reactive({ modelValue: propOpenKeys, defaultValue: defaultOpenKeys, autoOpen, autoOpenSelected, selectedKeys, subMenuKeys, menuData, accordion }) ); const [collapsed, setCollapsed] = useMergeState( defaultCollapsed.value, reactive({ value: propCollapsed }) ); const computedCollapsed = computed( () => siderCollapsed.value || collapsed.value || mode.value === "popButton" ); const computedHasCollapseButton = computed( () => ["horizontal", "popButton"].indexOf(mode.value) < 0 && !inTrigger.value && showCollapseButton.value ); const changeCollapsed = (newVal, type) => { if (newVal === collapsed.value) return; setCollapsed(newVal); emit("update:collapsed", newVal); emit("collapse", newVal, type); }; const onCollapseBtnClick = () => { changeCollapsed(!collapsed.value, "clickTrigger"); }; useResponsive(breakpoint, (checked) => { changeCollapsed(!checked, "responsive"); }); const computedPrefixCls = computed( () => (prefixCls == null ? void 0 : prefixCls.value) || getPrefixCls("menu") ); const classNames = computed(() => [ computedPrefixCls.value, `${computedPrefixCls.value}-${theme == null ? void 0 : theme.value}`, { [`${computedPrefixCls.value}-horizontal`]: mode.value === "horizontal", [`${computedPrefixCls.value}-vertical`]: mode.value !== "horizontal", [`${computedPrefixCls.value}-collapsed`]: computedCollapsed.value, [`${computedPrefixCls.value}-pop`]: mode.value === "pop" || computedCollapsed.value, [`${computedPrefixCls.value}-pop-button`]: mode.value === "popButton" } ]); const computedStyle = computed(() => { const pxCollapsedWidth = isNumber(collapsedWidth.value) ? `${collapsedWidth.value}px` : void 0; const objectStyle = isObject(style.value) ? style.value : void 0; const width = computedCollapsed.value ? pxCollapsedWidth : objectStyle == null ? void 0 : objectStyle.width; return [ objectStyle ? omit(objectStyle, ["width"]) : style.value, { width } ]; }); const expandIconDown = usePickSlots(slots, "expand-icon-down"); const expandIconRight = usePickSlots(slots, "expand-icon-right"); const menuContext = reactive({ theme, mode, levelIndent, autoScrollIntoView, selectedKeys, openKeys, prefixCls: computedPrefixCls, scrollConfig, inTrigger, collapsed: computedCollapsed, triggerProps, tooltipProps, popupMaxHeight, expandIconDown, expandIconRight, onMenuItemClick: (key) => { setSelectedKeys([key]); emit("update:selectedKeys", [key]); emit("menu-item-click", key); }, onSubMenuClick: (key, level) => { const newOpenKeys = open(key, level); setOpenKeys(newOpenKeys); emit("update:openKeys", newOpenKeys); emit("sub-menu-click", key, newOpenKeys); } }); provide(MenuInjectionKey, menuContext); provideLevel(1); return { computedPrefixCls, classNames, computedStyle, computedCollapsed, computedHasCollapseButton, onCollapseBtnClick }; } }); function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_IconMenuUnfold = resolveComponent("IconMenuUnfold"); const _component_IconMenuFold = resolveComponent("IconMenuFold"); return openBlock(), createElementBlock("div", mergeProps({ class: _ctx.classNames }, _ctx.$attrs, { style: _ctx.computedStyle }), [ createElementVNode("div", { class: normalizeClass(`${_ctx.computedPrefixCls}-inner`) }, [ renderSlot(_ctx.$slots, "default") ], 2), _ctx.computedHasCollapseButton ? (openBlock(), createElementBlock("div", { key: 0, class: normalizeClass(`${_ctx.computedPrefixCls}-collapse-button`), onClick: _cache[0] || (_cache[0] = (...args) => _ctx.onCollapseBtnClick && _ctx.onCollapseBtnClick(...args)) }, [ renderSlot(_ctx.$slots, "collapse-icon", { collapsed: _ctx.computedCollapsed }, () => [ _ctx.computedCollapsed ? (openBlock(), createBlock(_component_IconMenuUnfold, { key: 0 })) : (openBlock(), createBlock(_component_IconMenuFold, { key: 1 })) ]) ], 2)) : createCommentVNode("v-if", true) ], 16); } var BaseMenu = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]); export { BaseMenu as default };