refactor: menu
parent
a887ec5b8f
commit
9bb16977a9
|
@ -3,6 +3,7 @@ import {
|
||||||
CSSProperties,
|
CSSProperties,
|
||||||
defineComponent,
|
defineComponent,
|
||||||
nextTick,
|
nextTick,
|
||||||
|
Ref,
|
||||||
Transition as T,
|
Transition as T,
|
||||||
TransitionGroup as TG,
|
TransitionGroup as TG,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
|
@ -91,17 +92,17 @@ export declare type MotionEvent = (TransitionEvent | AnimationEvent) & {
|
||||||
deadline?: boolean;
|
deadline?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export declare type MotionEventHandler = (
|
export declare type MotionEventHandler = (element: Element, done?: () => void) => CSSProperties;
|
||||||
element: Element,
|
|
||||||
done?: () => void,
|
|
||||||
) => CSSProperties | void;
|
|
||||||
|
|
||||||
export declare type MotionEndEventHandler = (element: Element, done?: () => void) => boolean | void;
|
export declare type MotionEndEventHandler = (element: Element, done?: () => void) => boolean | void;
|
||||||
|
|
||||||
// ================== Collapse Motion ==================
|
// ================== Collapse Motion ==================
|
||||||
const getCollapsedHeight: MotionEventHandler = () => ({ height: 0, opacity: 0 });
|
const getCollapsedHeight: MotionEventHandler = () => ({ height: 0, opacity: 0 });
|
||||||
const getRealHeight: MotionEventHandler = node => ({ height: node.scrollHeight, opacity: 1 });
|
const getRealHeight: MotionEventHandler = node => ({
|
||||||
const getCurrentHeight: MotionEventHandler = (node: any) => ({ height: node.offsetHeight });
|
height: `${node.scrollHeight}px`,
|
||||||
|
opacity: 1,
|
||||||
|
});
|
||||||
|
const getCurrentHeight: MotionEventHandler = (node: any) => ({ height: `${node.offsetHeight}px` });
|
||||||
// const skipOpacityTransition: MotionEndEventHandler = (_, event) =>
|
// const skipOpacityTransition: MotionEndEventHandler = (_, event) =>
|
||||||
// (event as TransitionEvent).propertyName === 'height';
|
// (event as TransitionEvent).propertyName === 'height';
|
||||||
|
|
||||||
|
@ -110,14 +111,38 @@ export interface CSSMotionProps extends Partial<BaseTransitionProps<Element>> {
|
||||||
css?: boolean;
|
css?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const collapseMotion: CSSMotionProps = {
|
const collapseMotion = (style: Ref<CSSProperties>, className: Ref<string>): CSSMotionProps => {
|
||||||
|
return {
|
||||||
name: 'ant-motion-collapse',
|
name: 'ant-motion-collapse',
|
||||||
appear: true,
|
appear: true,
|
||||||
// onAppearStart: getCollapsedHeight,
|
css: true,
|
||||||
onBeforeEnter: getCollapsedHeight,
|
onBeforeEnter: node => {
|
||||||
onEnter: getRealHeight,
|
className.value = 'ant-motion-collapse';
|
||||||
onBeforeLeave: getCurrentHeight,
|
style.value = getCollapsedHeight(node);
|
||||||
onLeave: getCollapsedHeight,
|
},
|
||||||
|
onEnter: node => {
|
||||||
|
nextTick(() => {
|
||||||
|
style.value = getRealHeight(node);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onAfterEnter: () => {
|
||||||
|
className.value = '';
|
||||||
|
style.value = {};
|
||||||
|
},
|
||||||
|
onBeforeLeave: node => {
|
||||||
|
className.value = 'ant-motion-collapse';
|
||||||
|
style.value = getCurrentHeight(node);
|
||||||
|
},
|
||||||
|
onLeave: node => {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
style.value = getCollapsedHeight(node);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onAfterLeave: () => {
|
||||||
|
className.value = '';
|
||||||
|
style.value = {};
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export { Transition, TransitionGroup, collapseMotion };
|
export { Transition, TransitionGroup, collapseMotion };
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { computed, defineComponent, ref, watch } from '@vue/runtime-core';
|
import { computed, defineComponent, reactive, 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 { MenuMode } from './interface';
|
||||||
|
@ -31,12 +31,13 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
{ flush: 'post' },
|
{ flush: 'post' },
|
||||||
);
|
);
|
||||||
|
const style = ref({});
|
||||||
const mergedMotion = computed(() => ({
|
const className = ref('');
|
||||||
...(motion.value || defaultMotions.value?.[fixedMode]),
|
const mergedMotion = computed(() => {
|
||||||
appear: props.keyPath.length <= 1,
|
const m = motion.value || defaultMotions.value?.[fixedMode];
|
||||||
}));
|
const res = typeof m === 'function' ? m(style, className) : m;
|
||||||
|
return { ...res, appear: props.keyPath.length <= 1 };
|
||||||
|
});
|
||||||
return () => {
|
return () => {
|
||||||
if (destroy.value) {
|
if (destroy.value) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -49,7 +50,12 @@ export default defineComponent({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Transition {...mergedMotion.value}>
|
<Transition {...mergedMotion.value}>
|
||||||
<SubMenuList v-show={mergedOpen.value} id={props.id}>
|
<SubMenuList
|
||||||
|
v-show={mergedOpen.value}
|
||||||
|
id={props.id}
|
||||||
|
style={style.value}
|
||||||
|
class={className.value}
|
||||||
|
>
|
||||||
{slots.default?.()}
|
{slots.default?.()}
|
||||||
</SubMenuList>
|
</SubMenuList>
|
||||||
</Transition>
|
</Transition>
|
||||||
|
|
|
@ -88,7 +88,6 @@ export default defineComponent({
|
||||||
watch(
|
watch(
|
||||||
() => props.openKeys,
|
() => props.openKeys,
|
||||||
(openKeys = mergedOpenKeys.value) => {
|
(openKeys = mergedOpenKeys.value) => {
|
||||||
console.log('mergedOpenKeys', openKeys);
|
|
||||||
mergedOpenKeys.value = openKeys;
|
mergedOpenKeys.value = openKeys;
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
import { Key } from '../../../_util/type';
|
import { Key } from '../../../_util/type';
|
||||||
import { ComputedRef, defineComponent, inject, InjectionKey, provide, Ref, UnwrapRef } from 'vue';
|
import {
|
||||||
|
ComputedRef,
|
||||||
|
CSSProperties,
|
||||||
|
defineComponent,
|
||||||
|
inject,
|
||||||
|
InjectionKey,
|
||||||
|
provide,
|
||||||
|
Ref,
|
||||||
|
UnwrapRef,
|
||||||
|
} from 'vue';
|
||||||
import { BuiltinPlacements, MenuMode, MenuTheme, TriggerSubMenuAction } from '../interface';
|
import { BuiltinPlacements, MenuMode, MenuTheme, TriggerSubMenuAction } from '../interface';
|
||||||
import { CSSMotionProps } from '../../../_util/transition';
|
import { CSSMotionProps } from '../../../_util/transition';
|
||||||
|
|
||||||
|
@ -48,7 +57,13 @@ export interface MenuContextProps {
|
||||||
|
|
||||||
// // Motion
|
// // Motion
|
||||||
motion?: ComputedRef<CSSMotionProps | null>;
|
motion?: ComputedRef<CSSMotionProps | null>;
|
||||||
defaultMotions?: ComputedRef<Partial<{ [key in MenuMode | 'other']: CSSMotionProps }> | null>;
|
defaultMotions?: ComputedRef<Partial<
|
||||||
|
{
|
||||||
|
[key in MenuMode | 'other']:
|
||||||
|
| CSSMotionProps
|
||||||
|
| ((style: Ref<CSSProperties>, className: Ref<string>) => CSSMotionProps);
|
||||||
|
}
|
||||||
|
> | null>;
|
||||||
|
|
||||||
// // Popup
|
// // Popup
|
||||||
subMenuOpenDelay: ComputedRef<number>;
|
subMenuOpenDelay: ComputedRef<number>;
|
||||||
|
|
|
@ -239,7 +239,6 @@ a {
|
||||||
&[disabled] {
|
&[disabled] {
|
||||||
color: @disabled-color;
|
color: @disabled-color;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
pointer-events: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
@import 'motion/move';
|
@import 'motion/move';
|
||||||
@import 'motion/other';
|
@import 'motion/other';
|
||||||
@import 'motion/slide';
|
@import 'motion/slide';
|
||||||
@import 'motion/swing';
|
|
||||||
@import 'motion/zoom';
|
@import 'motion/zoom';
|
||||||
|
|
||||||
// For common/openAnimation
|
// For common/openAnimation
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
.fade-motion(@className, @keyframeName) {
|
.fade-motion(@className, @keyframeName) {
|
||||||
.make-motion(@className, @keyframeName);
|
@name: ~'@{ant-prefix}-@{className}';
|
||||||
.@{className}-enter,
|
.make-motion(@name, @keyframeName);
|
||||||
.@{className}-appear {
|
.@{name}-enter,
|
||||||
|
.@{name}-appear {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation-timing-function: linear;
|
animation-timing-function: linear;
|
||||||
}
|
}
|
||||||
.@{className}-leave {
|
.@{name}-leave {
|
||||||
animation-timing-function: linear;
|
animation-timing-function: linear;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
.move-motion(@className, @keyframeName) {
|
.move-motion(@className, @keyframeName) {
|
||||||
.make-motion(@className, @keyframeName);
|
@name: ~'@{ant-prefix}-@{className}';
|
||||||
.@{className}-enter,
|
.make-motion(@name, @keyframeName);
|
||||||
.@{className}-appear {
|
.@{name}-enter,
|
||||||
|
.@{name}-appear {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation-timing-function: @ease-out-circ;
|
animation-timing-function: @ease-out-circ;
|
||||||
}
|
}
|
||||||
.@{className}-leave {
|
.@{name}-leave {
|
||||||
animation-timing-function: @ease-in-circ;
|
animation-timing-function: @ease-in-circ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,17 +4,23 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[ant-click-animating='true'],
|
@click-animating-true: ~"[@{ant-prefix}-click-animating='true']";
|
||||||
[ant-click-animating-without-extra-node='true'] {
|
@click-animating-with-extra-node-true: ~"[@{ant-prefix}-click-animating-without-extra-node='true']";
|
||||||
|
|
||||||
|
@{click-animating-true},
|
||||||
|
@{click-animating-with-extra-node-true} {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
--antd-wave-shadow-color: @primary-color;
|
--antd-wave-shadow-color: @primary-color;
|
||||||
|
--scroll-bar: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[ant-click-animating-without-extra-node='true']::after,
|
@click-animating-with-extra-node-true-after: ~'@{click-animating-with-extra-node-true}::after';
|
||||||
.ant-click-animating-node {
|
|
||||||
|
@{click-animating-with-extra-node-true-after},
|
||||||
|
.@{ant-prefix}-click-animating-node {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
.slide-motion(@className, @keyframeName) {
|
.slide-motion(@className, @keyframeName) {
|
||||||
.make-motion(@className, @keyframeName);
|
@name: ~'@{ant-prefix}-@{className}';
|
||||||
.@{className}-enter,
|
.make-motion(@name, @keyframeName);
|
||||||
.@{className}-appear {
|
.@{name}-enter,
|
||||||
|
.@{name}-appear {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation-timing-function: @ease-out-quint;
|
animation-timing-function: @ease-out-quint;
|
||||||
}
|
}
|
||||||
.@{className}-leave {
|
.@{name}-leave {
|
||||||
animation-timing-function: @ease-in-quint;
|
animation-timing-function: @ease-in-quint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
.swing-motion(@className, @keyframeName) {
|
|
||||||
.@{className}-enter,
|
|
||||||
.@{className}-appear {
|
|
||||||
.motion-common();
|
|
||||||
|
|
||||||
animation-play-state: paused;
|
|
||||||
}
|
|
||||||
.@{className}-enter.@{className}-enter-active,
|
|
||||||
.@{className}-appear.@{className}-appear-active {
|
|
||||||
animation-name: ~'@{keyframeName}In';
|
|
||||||
animation-play-state: running;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.swing-motion(swing, antSwing);
|
|
||||||
|
|
||||||
@keyframes antSwingIn {
|
|
||||||
0%,
|
|
||||||
100% {
|
|
||||||
transform: translateX(0);
|
|
||||||
}
|
|
||||||
20% {
|
|
||||||
transform: translateX(-10px);
|
|
||||||
}
|
|
||||||
40% {
|
|
||||||
transform: translateX(10px);
|
|
||||||
}
|
|
||||||
60% {
|
|
||||||
transform: translateX(-5px);
|
|
||||||
}
|
|
||||||
80% {
|
|
||||||
transform: translateX(5px);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +1,17 @@
|
||||||
.zoom-motion(@className, @keyframeName, @duration: @animation-duration-base) {
|
.zoom-motion(@className, @keyframeName, @duration: @animation-duration-base) {
|
||||||
.make-motion(@className, @keyframeName, @duration);
|
@name: ~'@{ant-prefix}-@{className}';
|
||||||
.@{className}-enter,
|
.make-motion(@name, @keyframeName, @duration);
|
||||||
.@{className}-appear {
|
.@{name}-enter,
|
||||||
|
.@{name}-appear {
|
||||||
transform: scale(0); // need this by yiminghe
|
transform: scale(0); // need this by yiminghe
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation-timing-function: @ease-out-circ;
|
animation-timing-function: @ease-out-circ;
|
||||||
|
|
||||||
&-prepare {
|
&-prepare {
|
||||||
transform: none;
|
transform: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.@{className}-leave {
|
.@{name}-leave {
|
||||||
animation-timing-function: @ease-in-out-circ;
|
animation-timing-function: @ease-in-out-circ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +56,7 @@
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
5% {
|
5% {
|
||||||
transform: scale(0.2);
|
transform: scale(0.8);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
|
|
|
@ -67,15 +67,15 @@ export default defineComponent({
|
||||||
const selectedKeys = ref<string[]>(['1']);
|
const selectedKeys = ref<string[]>(['1']);
|
||||||
const openKeys = ref<string[]>(['sub1']);
|
const openKeys = ref<string[]>(['sub1']);
|
||||||
const handleClick = (e: Event) => {
|
const handleClick = (e: Event) => {
|
||||||
console.log('click', e);
|
// console.log('click', e);
|
||||||
};
|
};
|
||||||
const titleClick = (e: Event) => {
|
const titleClick = (e: Event) => {
|
||||||
console.log('titleClick', e);
|
// console.log('titleClick', e);
|
||||||
};
|
};
|
||||||
watch(
|
watch(
|
||||||
() => openKeys,
|
() => openKeys,
|
||||||
val => {
|
val => {
|
||||||
console.log('openKeys', val);
|
// console.log('openKeys', val);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
|
|
2
v2-doc
2
v2-doc
|
@ -1 +1 @@
|
||||||
Subproject commit d197053285b81e77718621c0b5b94cb3b21831a2
|
Subproject commit a7013ae87f69dcbcf547f4b023255b8a7a775557
|
Loading…
Reference in New Issue