refactor: menu
parent
572ebc8f1a
commit
11c742b772
|
@ -1,7 +1,6 @@
|
||||||
import { computed, defineComponent, ref, watch } from '@vue/runtime-core';
|
import { computed, defineComponent, ref, watch } from '@vue/runtime-core';
|
||||||
import Transition from 'ant-design-vue/es/_util/transition';
|
import Transition from 'ant-design-vue/es/_util/transition';
|
||||||
import { useInjectMenu, MenuContextProvider } from './hooks/useMenuContext';
|
import { useInjectMenu, MenuContextProvider } from './hooks/useMenuContext';
|
||||||
import { MenuMode } from './interface';
|
|
||||||
import SubMenuList from './SubMenuList';
|
import SubMenuList from './SubMenuList';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
@ -13,9 +12,9 @@ export default defineComponent({
|
||||||
keyPath: Array,
|
keyPath: Array,
|
||||||
},
|
},
|
||||||
setup(props, { slots }) {
|
setup(props, { slots }) {
|
||||||
const fixedMode: MenuMode = 'inline';
|
const fixedMode = computed(() => 'inline');
|
||||||
const { motion, mode, defaultMotions } = useInjectMenu();
|
const { motion, mode, defaultMotions } = useInjectMenu();
|
||||||
const sameModeRef = computed(() => mode.value === fixedMode);
|
const sameModeRef = computed(() => mode.value === fixedMode.value);
|
||||||
const destroy = ref(!sameModeRef.value);
|
const destroy = ref(!sameModeRef.value);
|
||||||
|
|
||||||
const mergedOpen = computed(() => (sameModeRef.value ? props.open : false));
|
const mergedOpen = computed(() => (sameModeRef.value ? props.open : false));
|
||||||
|
@ -34,7 +33,8 @@ export default defineComponent({
|
||||||
const style = ref({});
|
const style = ref({});
|
||||||
const className = ref('');
|
const className = ref('');
|
||||||
const mergedMotion = computed(() => {
|
const mergedMotion = computed(() => {
|
||||||
const m = motion.value || defaultMotions.value?.[fixedMode];
|
const m =
|
||||||
|
motion.value || defaultMotions.value?.[fixedMode.value] || defaultMotions.value?.other;
|
||||||
const res = typeof m === 'function' ? m(style, className) : m;
|
const res = typeof m === 'function' ? m(style, className) : m;
|
||||||
return { ...res, appear: props.keyPath.length <= 1 };
|
return { ...res, appear: props.keyPath.length <= 1 };
|
||||||
});
|
});
|
||||||
|
|
|
@ -251,8 +251,8 @@ export default defineComponent({
|
||||||
const getChildrenKeys = (eventKeys: string[] = []): Key[] => {
|
const getChildrenKeys = (eventKeys: string[] = []): Key[] => {
|
||||||
const keys = [];
|
const keys = [];
|
||||||
eventKeys.forEach(eventKey => {
|
eventKeys.forEach(eventKey => {
|
||||||
const { key, childrenEventKeys } = store[eventKey] as any;
|
const { key, childrenEventKeys } = store[eventKey];
|
||||||
keys.push(key, ...getChildrenKeys(childrenEventKeys.value));
|
keys.push(key, ...getChildrenKeys(childrenEventKeys));
|
||||||
});
|
});
|
||||||
return keys;
|
return keys;
|
||||||
};
|
};
|
||||||
|
@ -267,14 +267,15 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
|
|
||||||
const onInternalOpenChange = (eventKey: Key, open: boolean) => {
|
const onInternalOpenChange = (eventKey: Key, open: boolean) => {
|
||||||
const { key, childrenEventKeys } = store[eventKey] as any;
|
const { key, childrenEventKeys } = store[eventKey];
|
||||||
let newOpenKeys = mergedOpenKeys.value.filter(k => k !== key);
|
let newOpenKeys = mergedOpenKeys.value.filter(k => k !== key);
|
||||||
|
|
||||||
if (open) {
|
if (open) {
|
||||||
newOpenKeys.push(key);
|
newOpenKeys.push(key);
|
||||||
} else if (mergedMode.value !== 'inline') {
|
} else if (mergedMode.value !== 'inline') {
|
||||||
// We need find all related popup to close
|
// We need find all related popup to close
|
||||||
const subPathKeys = getChildrenKeys(childrenEventKeys.value);
|
const subPathKeys = getChildrenKeys(childrenEventKeys);
|
||||||
|
console.log('subPathKeys', eventKey, childrenEventKeys, subPathKeys);
|
||||||
newOpenKeys = newOpenKeys.filter(k => !subPathKeys.includes(k));
|
newOpenKeys = newOpenKeys.filter(k => !subPathKeys.includes(k));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ export default defineComponent({
|
||||||
role: String,
|
role: String,
|
||||||
disabled: Boolean,
|
disabled: Boolean,
|
||||||
danger: Boolean,
|
danger: Boolean,
|
||||||
title: { type: [String, Boolean] },
|
title: { type: [String, Boolean], default: undefined },
|
||||||
icon: PropTypes.VNodeChild,
|
icon: PropTypes.VNodeChild,
|
||||||
},
|
},
|
||||||
emits: ['mouseenter', 'mouseleave', 'click'],
|
emits: ['mouseenter', 'mouseleave', 'click'],
|
||||||
|
@ -46,6 +46,7 @@ export default defineComponent({
|
||||||
return [...parentEventKeys.value.map(eK => store[eK].key), key];
|
return [...parentEventKeys.value.map(eK => store[eK].key), key];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const keysPath = computed(() => [...parentEventKeys.value, eventKey]);
|
||||||
const menuInfo = {
|
const menuInfo = {
|
||||||
eventKey,
|
eventKey,
|
||||||
key,
|
key,
|
||||||
|
@ -102,7 +103,8 @@ export default defineComponent({
|
||||||
|
|
||||||
const onMouseEnter = (event: MouseEvent) => {
|
const onMouseEnter = (event: MouseEvent) => {
|
||||||
if (!mergedDisabled.value) {
|
if (!mergedDisabled.value) {
|
||||||
changeActiveKeys([...parentEventKeys.value, key]);
|
changeActiveKeys(keysPath.value);
|
||||||
|
console.log('item mouseenter', keysPath.value);
|
||||||
emit('mouseenter', event);
|
emit('mouseenter', event);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,7 +50,6 @@ export default defineComponent({
|
||||||
parentEventKeys,
|
parentEventKeys,
|
||||||
childrenEventKeys,
|
childrenEventKeys,
|
||||||
};
|
};
|
||||||
|
|
||||||
parentInfo.childrenEventKeys?.value.push(eventKey);
|
parentInfo.childrenEventKeys?.value.push(eventKey);
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
if (parentInfo.childrenEventKeys) {
|
if (parentInfo.childrenEventKeys) {
|
||||||
|
@ -195,13 +194,20 @@ export default defineComponent({
|
||||||
|
|
||||||
const renderMode = computed(() => (mode.value === 'horizontal' ? 'vertical' : mode.value));
|
const renderMode = computed(() => (mode.value === 'horizontal' ? 'vertical' : mode.value));
|
||||||
|
|
||||||
|
const style = ref({});
|
||||||
|
const className = ref('');
|
||||||
|
const mergedMotion = computed(() => {
|
||||||
|
const m = motion.value || defaultMotions.value?.[mode.value] || defaultMotions.value?.other;
|
||||||
|
const res = typeof m === 'function' ? m(style, className) : m;
|
||||||
|
return res ? getTransitionProps(res.name) : undefined;
|
||||||
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
const icon = getPropsSlot(slots, props, 'icon');
|
const icon = getPropsSlot(slots, props, 'icon');
|
||||||
const title = renderTitle(getPropsSlot(slots, props, 'title'), icon);
|
const title = renderTitle(getPropsSlot(slots, props, 'title'), icon);
|
||||||
const subMenuPrefixClsValue = subMenuPrefixCls.value;
|
const subMenuPrefixClsValue = subMenuPrefixCls.value;
|
||||||
let titleNode = (
|
let titleNode = (
|
||||||
<div
|
<div
|
||||||
role="menuitem"
|
|
||||||
style={directionStyle.value}
|
style={directionStyle.value}
|
||||||
class={`${subMenuPrefixClsValue}-title`}
|
class={`${subMenuPrefixClsValue}-title`}
|
||||||
tabindex={mergedDisabled.value ? null : -1}
|
tabindex={mergedDisabled.value ? null : -1}
|
||||||
|
@ -214,8 +220,6 @@ export default defineComponent({
|
||||||
aria-disabled={mergedDisabled.value}
|
aria-disabled={mergedDisabled.value}
|
||||||
onClick={onInternalTitleClick}
|
onClick={onInternalTitleClick}
|
||||||
onFocus={onInternalFocus}
|
onFocus={onInternalFocus}
|
||||||
onMouseenter={onMouseEnter}
|
|
||||||
onMouseleave={onMouseLeave}
|
|
||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
|
|
||||||
|
@ -230,13 +234,6 @@ export default defineComponent({
|
||||||
|
|
||||||
if (!overflowDisabled.value) {
|
if (!overflowDisabled.value) {
|
||||||
const triggerMode = triggerModeRef.value;
|
const triggerMode = triggerModeRef.value;
|
||||||
const style = ref({});
|
|
||||||
const className = ref('');
|
|
||||||
const mergedMotion = computed(() => {
|
|
||||||
const m = motion.value || defaultMotions.value?.[mode.value];
|
|
||||||
const res = typeof m === 'function' ? m(style, className) : m;
|
|
||||||
return res ? getTransitionProps(res.name) : undefined;
|
|
||||||
});
|
|
||||||
titleNode = (
|
titleNode = (
|
||||||
<PopupTrigger
|
<PopupTrigger
|
||||||
mode={triggerMode}
|
mode={triggerMode}
|
||||||
|
@ -278,11 +275,13 @@ export default defineComponent({
|
||||||
[`${subMenuPrefixClsValue}-disabled`]: mergedDisabled.value,
|
[`${subMenuPrefixClsValue}-disabled`]: mergedDisabled.value,
|
||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
|
onMouseenter={onMouseEnter}
|
||||||
|
onMouseleave={onMouseLeave}
|
||||||
>
|
>
|
||||||
{titleNode}
|
{titleNode}
|
||||||
|
|
||||||
{/* Inline mode */}
|
{/* Inline mode */}
|
||||||
{!overflowDisabled.value && (
|
{!overflowDisabled.value && mode.value !== 'vertical' && (
|
||||||
<InlineSubMenuList id={popupId} open={open.value} keyPath={keysPath.value}>
|
<InlineSubMenuList id={popupId} open={open.value} keyPath={keysPath.value}>
|
||||||
{slots.default?.()}
|
{slots.default?.()}
|
||||||
</InlineSubMenuList>
|
</InlineSubMenuList>
|
||||||
|
|
|
@ -21,8 +21,8 @@ import { CSSMotionProps } from '../../../_util/transition';
|
||||||
export interface StoreMenuInfo {
|
export interface StoreMenuInfo {
|
||||||
eventKey: string;
|
eventKey: string;
|
||||||
key: Key;
|
key: Key;
|
||||||
parentEventKeys: ComputedRef<Key[]>;
|
parentEventKeys: ComputedRef<string[]>;
|
||||||
childrenEventKeys?: Ref<Key[]>;
|
childrenEventKeys?: Ref<string[]>;
|
||||||
isLeaf?: boolean;
|
isLeaf?: boolean;
|
||||||
}
|
}
|
||||||
export interface MenuContextProps {
|
export interface MenuContextProps {
|
||||||
|
|
|
@ -530,7 +530,7 @@
|
||||||
text-overflow: clip;
|
text-overflow: clip;
|
||||||
|
|
||||||
.@{menu-prefix-cls}-submenu-arrow {
|
.@{menu-prefix-cls}-submenu-arrow {
|
||||||
opacity: 0;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.@{menu-prefix-cls}-item-icon,
|
.@{menu-prefix-cls}-item-icon,
|
||||||
|
|
|
@ -11,16 +11,22 @@
|
||||||
theme="dark"
|
theme="dark"
|
||||||
:inline-collapsed="collapsed"
|
:inline-collapsed="collapsed"
|
||||||
>
|
>
|
||||||
<a-menu-item key="1">
|
<!-- <a-menu-item key="1">
|
||||||
<PieChartOutlined />
|
<template #icon>
|
||||||
|
<PieChartOutlined />
|
||||||
|
</template>
|
||||||
<span>Option 1</span>
|
<span>Option 1</span>
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
<a-menu-item key="2">
|
<a-menu-item key="2">
|
||||||
<DesktopOutlined />
|
<template #icon>
|
||||||
|
<DesktopOutlined />
|
||||||
|
</template>
|
||||||
<span>Option 2</span>
|
<span>Option 2</span>
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
<a-menu-item key="3">
|
<a-menu-item key="3">
|
||||||
<InboxOutlined />
|
<template #icon>
|
||||||
|
<InboxOutlined />
|
||||||
|
</template>
|
||||||
<span>Option 3</span>
|
<span>Option 3</span>
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
<a-sub-menu key="sub1">
|
<a-sub-menu key="sub1">
|
||||||
|
@ -34,7 +40,7 @@
|
||||||
<a-menu-item key="6">Option 6</a-menu-item>
|
<a-menu-item key="6">Option 6</a-menu-item>
|
||||||
<a-menu-item key="7">Option 7</a-menu-item>
|
<a-menu-item key="7">Option 7</a-menu-item>
|
||||||
<a-menu-item key="8">Option 8</a-menu-item>
|
<a-menu-item key="8">Option 8</a-menu-item>
|
||||||
</a-sub-menu>
|
</a-sub-menu> -->
|
||||||
<a-sub-menu key="sub2">
|
<a-sub-menu key="sub2">
|
||||||
<template #title>
|
<template #title>
|
||||||
<span>
|
<span>
|
||||||
|
|
2
v2-doc
2
v2-doc
|
@ -1 +1 @@
|
||||||
Subproject commit a7013ae87f69dcbcf547f4b023255b8a7a775557
|
Subproject commit d197053285b81e77718621c0b5b94cb3b21831a2
|
Loading…
Reference in New Issue