diff --git a/packages/components/transition/__tests__/index.spec.tsx b/packages/components/transition/__tests__/index.spec.tsx
index c189cc6..1c94c77 100644
--- a/packages/components/transition/__tests__/index.spec.tsx
+++ b/packages/components/transition/__tests__/index.spec.tsx
@@ -1,15 +1,21 @@
// @vitest-environment jsdom
-import { Transition } from '@deot/vc-components';
-import { mount } from '@vue/test-utils';
+import {
+ Transition,
+ TransitionCollapse,
+ TransitionFade,
+ TransitionScale,
+ TransitionSlide,
+ TransitionZoom
+} from '@deot/vc-components';
describe('index.ts', () => {
it('basic', () => {
expect(typeof Transition).toBe('object');
- });
- it('create', async () => {
- const wrapper = mount(() => ());
-
- expect(wrapper.classes()).toContain('vc-transition');
+ expect(typeof TransitionCollapse).toBe('object');
+ expect(typeof TransitionFade).toBe('object');
+ expect(typeof TransitionScale).toBe('object');
+ expect(typeof TransitionSlide).toBe('object');
+ expect(typeof TransitionZoom).toBe('object');
});
});
diff --git a/packages/components/transition/__tests__/transition-collapse.spec.tsx b/packages/components/transition/__tests__/transition-collapse.spec.tsx
new file mode 100644
index 0000000..e9013fa
--- /dev/null
+++ b/packages/components/transition/__tests__/transition-collapse.spec.tsx
@@ -0,0 +1,65 @@
+// @vitest-environment jsdom
+
+import { ref, withDirectives, vShow, createApp } from 'vue';
+import { TransitionCollapse } from '@deot/vc-components';
+import { Utils } from '@deot/dev-test';
+
+describe('transition.ts', () => {
+ const root = document.createElement('div');
+ document.body.appendChild(root);
+
+ it('create', async () => {
+ const isVisible = ref(false);
+ const isGroup = ref(false);
+ const mode = ref('none');
+ const methods = {
+ onEnter: vi.fn(),
+ onBeforeEnter: vi.fn(),
+ onAfterEnter: vi.fn(),
+ onBeforeLeave: vi.fn(),
+ onLeave: vi.fn(),
+ onAfterLeave: vi.fn()
+ };
+ const app = createApp(
+ () => (
+
+ { withDirectives(, [[vShow, isVisible.value]])}
+
+ )
+ );
+
+
+ app.mount(root);
+
+ isVisible.value = true;
+ await Utils.sleep(10);
+ let el = root.querySelector('div')!;
+ expect(el.classList.contains('v-enter-from')).toBeTruthy();
+ await Utils.sleep(100);
+ expect(el.classList.contains('v-enter-to')).toBeTruthy();
+
+ isGroup.value = true;
+ await Utils.sleep(30);
+ expect(root.innerHTML).toBe(`
`);
+
+ isVisible.value = false;
+ await Utils.sleep(30);
+ expect(methods.onBeforeEnter).toHaveBeenCalledTimes(1);
+ expect(methods.onAfterEnter).toHaveBeenCalledTimes(1);
+ expect(methods.onBeforeLeave).toHaveBeenCalledTimes(1);
+ expect(methods.onAfterLeave).toHaveBeenCalledTimes(1);
+ expect(methods.onEnter).toHaveBeenCalledTimes(1);
+ expect(methods.onLeave).toHaveBeenCalledTimes(1);
+
+ mode.value = 'left-part';
+ await Utils.sleep(30);
+ });
+});
diff --git a/packages/components/transition/__tests__/transition-fade.spec.tsx b/packages/components/transition/__tests__/transition-fade.spec.tsx
new file mode 100644
index 0000000..4c03f48
--- /dev/null
+++ b/packages/components/transition/__tests__/transition-fade.spec.tsx
@@ -0,0 +1,35 @@
+// @vitest-environment jsdom
+
+import { ref, withDirectives, vShow } from 'vue';
+import { TransitionFade } from '@deot/vc-components';
+import { mount } from '@vue/test-utils';
+import { Utils } from '@deot/dev-test';
+
+describe('transition-fade.ts', () => {
+ it('create', async () => {
+ const isVisible = ref(false);
+ const isGroup = ref(false);
+ const mode = ref('none');
+
+ const wrapper = mount(
+ () => (
+
+ { withDirectives(, [[vShow, isVisible.value]])}
+
+ )
+ );
+ let vm = wrapper.getComponent({ name: 'transition' });
+ expect(vm.props('enterActiveClass')).toBe('vc-transition-fade is-in');
+ expect(vm.props('leaveActiveClass')).toBe('vc-transition-fade is-out');
+
+ isGroup.value = true;
+ await Utils.sleep(1);
+ vm = wrapper.getComponent({ name: 'transition-group' });
+ expect(vm.props('moveClass')).toBe('vc-transition-fade is-move');
+ });
+});
diff --git a/packages/components/transition/__tests__/transition-scale.spec.tsx b/packages/components/transition/__tests__/transition-scale.spec.tsx
new file mode 100644
index 0000000..4fedf19
--- /dev/null
+++ b/packages/components/transition/__tests__/transition-scale.spec.tsx
@@ -0,0 +1,35 @@
+// @vitest-environment jsdom
+
+import { ref, withDirectives, vShow } from 'vue';
+import { TransitionScale } from '@deot/vc-components';
+import { mount } from '@vue/test-utils';
+import { Utils } from '@deot/dev-test';
+
+describe('transition-scale.ts', () => {
+ it('create', async () => {
+ const isVisible = ref(false);
+ const isGroup = ref(false);
+ const mode = ref('none');
+
+ const wrapper = mount(
+ () => (
+
+ { withDirectives(, [[vShow, isVisible.value]])}
+
+ )
+ );
+ let vm = wrapper.getComponent({ name: 'transition' });
+ expect(vm.props('enterActiveClass')).toBe('vc-transition-scale is-in');
+ expect(vm.props('leaveActiveClass')).toBe('vc-transition-scale is-out');
+
+ isGroup.value = true;
+ await Utils.sleep(1);
+ vm = wrapper.getComponent({ name: 'transition-group' });
+ expect(vm.props('moveClass')).toBe('vc-transition-scale is-move');
+ });
+});
diff --git a/packages/components/transition/__tests__/transition-slide.spec.tsx b/packages/components/transition/__tests__/transition-slide.spec.tsx
new file mode 100644
index 0000000..17ac71d
--- /dev/null
+++ b/packages/components/transition/__tests__/transition-slide.spec.tsx
@@ -0,0 +1,35 @@
+// @vitest-environment jsdom
+
+import { ref, withDirectives, vShow } from 'vue';
+import { TransitionSlide } from '@deot/vc-components';
+import { mount } from '@vue/test-utils';
+import { Utils } from '@deot/dev-test';
+
+describe('transition-slide.ts', () => {
+ it('create', async () => {
+ const isVisible = ref(false);
+ const isGroup = ref(false);
+ const mode = ref('none');
+
+ const wrapper = mount(
+ () => (
+
+ { withDirectives(, [[vShow, isVisible.value]])}
+
+ )
+ );
+ let vm = wrapper.getComponent({ name: 'transition' });
+ expect(vm.props('enterActiveClass')).toBe('vc-transition-slide is-in');
+ expect(vm.props('leaveActiveClass')).toBe('vc-transition-slide is-out');
+
+ isGroup.value = true;
+ await Utils.sleep(1);
+ vm = wrapper.getComponent({ name: 'transition-group' });
+ expect(vm.props('moveClass')).toBe('vc-transition-slide is-move');
+ });
+});
diff --git a/packages/components/transition/__tests__/transition-zoom.spec.tsx b/packages/components/transition/__tests__/transition-zoom.spec.tsx
new file mode 100644
index 0000000..fc01609
--- /dev/null
+++ b/packages/components/transition/__tests__/transition-zoom.spec.tsx
@@ -0,0 +1,35 @@
+// @vitest-environment jsdom
+
+import { ref, withDirectives, vShow } from 'vue';
+import { TransitionZoom } from '@deot/vc-components';
+import { mount } from '@vue/test-utils';
+import { Utils } from '@deot/dev-test';
+
+describe('transition-zoom.ts', () => {
+ it('create', async () => {
+ const isVisible = ref(false);
+ const isGroup = ref(false);
+ const mode = ref('none');
+
+ const wrapper = mount(
+ () => (
+
+ { withDirectives(, [[vShow, isVisible.value]])}
+
+ )
+ );
+ let vm = wrapper.getComponent({ name: 'transition' });
+ expect(vm.props('enterActiveClass')).toBe('vc-transition-zoom is-in');
+ expect(vm.props('leaveActiveClass')).toBe('vc-transition-zoom is-out');
+
+ isGroup.value = true;
+ await Utils.sleep(1);
+ vm = wrapper.getComponent({ name: 'transition-group' });
+ expect(vm.props('moveClass')).toBe('vc-transition-zoom is-move');
+ });
+});
diff --git a/packages/components/transition/__tests__/transition.spec.tsx b/packages/components/transition/__tests__/transition.spec.tsx
new file mode 100644
index 0000000..60720cb
--- /dev/null
+++ b/packages/components/transition/__tests__/transition.spec.tsx
@@ -0,0 +1,66 @@
+// @vitest-environment jsdom
+
+import { ref, withDirectives, vShow, createApp } from 'vue';
+import { Transition as VTransition } from '@deot/vc-components';
+// import { mount } from '@vue/test-utils';
+import { Utils } from '@deot/dev-test';
+
+describe('transition.ts', () => {
+ const root = document.createElement('div');
+ document.body.appendChild(root);
+
+ it('create', async () => {
+ const isVisible = ref(false);
+ const isGroup = ref(false);
+ const mode = ref('none');
+ const methods = {
+ onEnter: vi.fn(),
+ onBeforeEnter: vi.fn(),
+ onAfterEnter: vi.fn(),
+ onBeforeLeave: vi.fn(),
+ onLeave: vi.fn(),
+ onAfterLeave: vi.fn()
+ };
+ const app = createApp(
+ () => (
+
+ { withDirectives(, [[vShow, isVisible.value]])}
+
+ )
+ );
+
+
+ app.mount(root);
+
+ isVisible.value = true;
+ await Utils.sleep(10);
+ let el = root.querySelector('div')!;
+ expect(el.classList.contains('v-enter-from')).toBeTruthy();
+ await Utils.sleep(30);
+ expect(el.classList.contains('v-enter-to')).toBeTruthy();
+
+ isGroup.value = true;
+ await Utils.sleep(30);
+ expect(root.innerHTML).toBe(``);
+
+ isVisible.value = false;
+ await Utils.sleep(30);
+ expect(methods.onBeforeEnter).toHaveBeenCalledTimes(1);
+ expect(methods.onAfterEnter).toHaveBeenCalledTimes(1);
+ expect(methods.onBeforeLeave).toHaveBeenCalledTimes(1);
+ expect(methods.onAfterLeave).toHaveBeenCalledTimes(1);
+ expect(methods.onEnter).toHaveBeenCalledTimes(1);
+ expect(methods.onLeave).toHaveBeenCalledTimes(1);
+
+ mode.value = 'left-part';
+ await Utils.sleep(30);
+ });
+});
diff --git a/packages/components/transition/examples/index.vue b/packages/components/transition/examples/index.vue
index ee5300b..f9ae0d7 100644
--- a/packages/components/transition/examples/index.vue
+++ b/packages/components/transition/examples/index.vue
@@ -92,6 +92,7 @@
diff --git a/packages/components/transition/transition-collapse.ts b/packages/components/transition/transition-collapse.ts
index d92800e..a104e8b 100644
--- a/packages/components/transition/transition-collapse.ts
+++ b/packages/components/transition/transition-collapse.ts
@@ -1,4 +1,4 @@
-import { defineComponent, h, toHandlers, mergeProps } from 'vue';
+import { defineComponent, h } from 'vue';
import { props as transitionProps } from './transition-props';
import { useTransition } from './use-transition';
@@ -11,12 +11,12 @@ export const TransitionCollapse = defineComponent({
inheritAttrs: false,
setup(props, { slots, attrs: _attrs }) {
const attrs = _attrs as any;
- const { Wrapper, resetStyles, resetAbsolute } = useTransition();
- const getTransitionStyle = (duration = 0.3) => {
+ const { Wrapper, resetStyles, resetAbsolute, createNext } = useTransition();
+ const getTransitionStyle = (duration) => {
let style = `
- ${duration}s height ease-in-out,
- ${duration}s padding-top ease-in-out,
- ${duration}s padding-bottom ease-in-out
+ ${duration}ms height ease-in-out,
+ ${duration}ms padding-top ease-in-out,
+ ${duration}ms padding-bottom ease-in-out
`;
return style;
};
@@ -25,8 +25,11 @@ export const TransitionCollapse = defineComponent({
let duration = (props.duration as any).enter || props.duration;
el.style.transition = getTransitionStyle(duration);
- // @ts-ignore
- if (!el.dataset) el.dataset = {};
+ /* istanbul ignore next -- @preserve */
+ if (!el.dataset) {
+ // @ts-ignore
+ el.dataset = {};
+ }
el.dataset.oldPaddingTop = el.style.paddingTop;
el.dataset.oldPaddingBottom = el.style.paddingBottom;
@@ -39,21 +42,27 @@ export const TransitionCollapse = defineComponent({
attrs.onBeforeEnter?.(el);
};
- const handleEnter = (el: HTMLElement) => {
- el.dataset.oldOverflow = el.style.overflow;
- if (el.scrollHeight !== 0) {
- el.style.height = el.scrollHeight + 'px';
- el.style.paddingTop = el.dataset.oldPaddingTop + 'px';
- el.style.paddingBottom = el.dataset.oldPaddingBottom + 'px';
- } else {
- el.style.height = '';
- el.style.paddingTop = el.dataset.oldPaddingTop + 'px';
- el.style.paddingBottom = el.dataset.oldPaddingBottom + 'px';
+ const handleEnter = async (el: HTMLElement, done?: () => any) => {
+ let next = createNext(done);
+ try {
+ el.dataset.oldOverflow = el.style.overflow;
+ /* istanbul ignore next -- @preserve */
+ if (el.scrollHeight !== 0) {
+ el.style.height = el.scrollHeight + 'px';
+ el.style.paddingTop = el.dataset.oldPaddingTop + 'px';
+ el.style.paddingBottom = el.dataset.oldPaddingBottom + 'px';
+ } else {
+ el.style.height = '';
+ el.style.paddingTop = el.dataset.oldPaddingTop + 'px';
+ el.style.paddingBottom = el.dataset.oldPaddingBottom + 'px';
+ }
+
+ el.style.overflow = 'hidden';
+
+ attrs.onEnter?.(el);
+ } finally {
+ next();
}
-
- el.style.overflow = 'hidden';
-
- attrs.onEnter?.(el);
};
const handleAfterEnter = (el: HTMLElement) => {
@@ -66,8 +75,11 @@ export const TransitionCollapse = defineComponent({
};
const handleBeforeLeave = (el: HTMLElement) => {
- // @ts-ignore
- if (!el.dataset) el.dataset = {};
+ /* istanbul ignore next -- @preserve */
+ if (!el.dataset) {
+ // @ts-ignore
+ el.dataset = {};
+ }
el.dataset.oldPaddingTop = el.style.paddingTop;
el.dataset.oldPaddingBottom = el.style.paddingBottom;
el.dataset.oldOverflow = el.style.overflow;
@@ -79,24 +91,30 @@ export const TransitionCollapse = defineComponent({
attrs.onBeforeLeave?.(el);
};
- const handleLeave = (el: HTMLElement) => {
- let leaveDuration = (props.duration as any).leave || props.duration;
- if (el.scrollHeight !== 0) {
+ const handleLeave = (el: HTMLElement, done?: () => any) => {
+ let next = createNext(done);
+ try {
+ let leaveDuration = (props.duration as any).leave || props.duration;
+ /* istanbul ignore next -- @preserve */
+ if (el.scrollHeight !== 0) {
+ /**
+ * for safari:
+ * 在设置高度之后添加,否则它会突然跳到零高度
+ */
+ el.style.transition = getTransitionStyle(leaveDuration);
+ el.style.height = '0px';
+ el.style.paddingTop = '0px';
+ el.style.paddingBottom = '0px';
+ }
/**
- * for safari:
- * 在设置高度之后添加,否则它会突然跳到零高度
+ * for group
*/
- el.style.transition = getTransitionStyle(leaveDuration);
- el.style.height = '0px';
- el.style.paddingTop = '0px';
- el.style.paddingBottom = '0px';
- }
- /**
- * for group
- */
- resetAbsolute(el);
+ resetAbsolute(el);
- attrs.onLeave?.(el);
+ attrs.onLeave?.(el);
+ } finally {
+ next();
+ }
};
const handleAfterLeave = (el: HTMLElement) => {
@@ -109,26 +127,24 @@ export const TransitionCollapse = defineComponent({
attrs.onAfterLeave?.(el);
};
- const listeners = toHandlers({
- 'before-enter': handleBeforeEnter,
- 'after-enter': handleAfterEnter,
- 'enter': handleEnter,
- 'before-leave': handleBeforeLeave,
- 'leave': handleLeave,
- 'after-leave': handleAfterLeave
- });
+ const listeners = {
+ onBeforeEnter: handleBeforeEnter,
+ onEnter: handleEnter,
+ onAfterEnter: handleAfterEnter,
+ onBeforeLeave: handleBeforeLeave,
+ onLeave: handleLeave,
+ onAfterLeave: handleAfterLeave
+ };
return () => {
return h(
Wrapper.value,
- mergeProps(
- {
- tag: props.tag,
- moveClass: props.group ? `vc-transition-collapse is-move` : undefined
- },
- attrs,
- listeners
- ),
+ {
+ ...attrs,
+ ...listeners,
+ tag: props.tag,
+ moveClass: props.group ? `${attrs.moveClass || ''} vc-transition-collapse is-move` : undefined
+ },
slots
);
};
diff --git a/packages/components/transition/transition-fade.ts b/packages/components/transition/transition-fade.ts
index 425df4c..14606f9 100644
--- a/packages/components/transition/transition-fade.ts
+++ b/packages/components/transition/transition-fade.ts
@@ -1,4 +1,4 @@
-import { defineComponent, h, mergeProps } from 'vue';
+import { defineComponent, h } from 'vue';
import { props as transitionProps } from './transition-props';
import { useTransition } from './use-transition';
@@ -27,14 +27,12 @@ export const TransitionFade = defineComponent({
return () => {
return h(
Wrapper.value,
- mergeProps(
- {
- tag: props.tag,
- },
- classes.value,
- attrs,
- listeners
- ),
+ {
+ ...attrs,
+ ...listeners,
+ ...classes.value,
+ tag: props.tag
+ },
slots
);
};
diff --git a/packages/components/transition/transition-props.ts b/packages/components/transition/transition-props.ts
index eff7e99..72f23e5 100644
--- a/packages/components/transition/transition-props.ts
+++ b/packages/components/transition/transition-props.ts
@@ -3,11 +3,11 @@ import type { ExtractPropTypes } from 'vue';
export const props = {
/**
* 进入/离开持续时间
- * {enter: .3, leave: .3}
+ * {enter: 300, leave: 300}
*/
duration: {
type: [Number, Object],
- default: 0.3
+ default: 300
},
/**
* 进入/离开延迟时间
@@ -48,7 +48,7 @@ export const props = {
},
prefix: {
type: String,
- default: ''
+ default: 'vc-transition'
},
mode: {
type: String,
diff --git a/packages/components/transition/transition-scale.ts b/packages/components/transition/transition-scale.ts
index 934f1b5..0590b35 100644
--- a/packages/components/transition/transition-scale.ts
+++ b/packages/components/transition/transition-scale.ts
@@ -1,4 +1,4 @@
-import { defineComponent, h, mergeProps } from 'vue';
+import { defineComponent, h } from 'vue';
import type { PropType } from 'vue';
import { props as transitionProps } from './transition-props';
import { useTransition } from './use-transition';
@@ -10,7 +10,7 @@ export const TransitionScale = defineComponent({
props: {
...transitionProps,
mode: {
- type: String as PropType<'x' | 'y' | 'part' | 'both' | 'none'>,
+ type: String as PropType<'x' | 'y' | 'part' | 'both' | 'none' | string>,
default: 'both',
validator: (v: string) => /(part|both|y|x|none)/.test(v)
},
@@ -34,14 +34,12 @@ export const TransitionScale = defineComponent({
return () => {
return h(
Wrapper.value,
- mergeProps(
- {
- tag: props.tag,
- },
- classes.value,
- attrs,
- listeners
- ),
+ {
+ ...attrs,
+ ...listeners,
+ ...classes.value,
+ tag: props.tag
+ },
slots
);
};
diff --git a/packages/components/transition/transition-slide.ts b/packages/components/transition/transition-slide.ts
index d824729..71c5390 100644
--- a/packages/components/transition/transition-slide.ts
+++ b/packages/components/transition/transition-slide.ts
@@ -1,4 +1,4 @@
-import { defineComponent, h, mergeProps } from 'vue';
+import { defineComponent, h } from 'vue';
import { props as transitionProps } from './transition-props';
import { useTransition } from './use-transition';
@@ -33,14 +33,12 @@ export const TransitionSlide = defineComponent({
return () => {
return h(
Wrapper.value,
- mergeProps(
- {
- tag: props.tag,
- },
- classes.value,
- attrs,
- listeners
- ),
+ {
+ ...attrs,
+ ...listeners,
+ ...classes.value,
+ tag: props.tag
+ },
slots
);
};
diff --git a/packages/components/transition/transition-zoom.ts b/packages/components/transition/transition-zoom.ts
index 32d24d6..21820a0 100644
--- a/packages/components/transition/transition-zoom.ts
+++ b/packages/components/transition/transition-zoom.ts
@@ -1,4 +1,4 @@
-import { defineComponent, h, mergeProps } from 'vue';
+import { defineComponent, h } from 'vue';
import type { PropType } from 'vue';
import { props as transitionProps } from './transition-props';
import { useTransition } from './use-transition';
@@ -10,7 +10,7 @@ export const TransitionZoom = defineComponent({
props: {
...transitionProps,
mode: {
- type: String as PropType<'x' | 'y' | 'center' | 'none'>,
+ type: String as PropType<'x' | 'y' | 'center' | 'none' | string>,
default: 'x',
validator: (v: string) => /^(x|y|center|none)$/.test(v)
},
@@ -34,14 +34,12 @@ export const TransitionZoom = defineComponent({
return () => {
return h(
Wrapper.value,
- mergeProps(
- {
- tag: props.tag,
- },
- classes.value,
- attrs,
- listeners
- ),
+ {
+ ...attrs,
+ ...listeners,
+ ...classes.value,
+ tag: props.tag
+ },
slots
);
};
diff --git a/packages/components/transition/transition.ts b/packages/components/transition/transition.ts
index 0fff9d1..b1d15bc 100644
--- a/packages/components/transition/transition.ts
+++ b/packages/components/transition/transition.ts
@@ -1,4 +1,4 @@
-import { defineComponent, h, mergeProps } from 'vue';
+import { defineComponent, h } from 'vue';
import { props as transitionProps } from './transition-props';
import { useTransition } from './use-transition';
@@ -13,15 +13,13 @@ export const Transition = defineComponent({
const { Wrapper, listeners, classes } = useTransition();
return () => {
return h(
- Wrapper,
- mergeProps(
- {
- tag: props.tag
- },
- classes.value,
- attrs,
- listeners
- ),
+ Wrapper.value,
+ {
+ ...attrs,
+ ...listeners,
+ ...classes.value,
+ tag: props.tag
+ },
slots
);
};
diff --git a/packages/components/transition/use-transition.ts b/packages/components/transition/use-transition.ts
index 42aafd0..682ed53 100644
--- a/packages/components/transition/use-transition.ts
+++ b/packages/components/transition/use-transition.ts
@@ -2,12 +2,12 @@ import {
getCurrentInstance,
computed,
Transition,
- TransitionGroup,
- toHandlers
+ TransitionGroup
} from 'vue';
import type { ComponentInternalInstance, Component } from 'vue';
import type { Props } from './transition-props';
+const trim = (str: string) => str.trim().replace(/\s+/g, " ");
export const useTransition = () => {
const instance = getCurrentInstance() as ComponentInternalInstance;
const attrs = instance.attrs as any;
@@ -20,9 +20,9 @@ export const useTransition = () => {
const classes = computed(() => {
let modeClass = props.mode !== 'none' ? `-${props.mode}`.split('-').join(' is-') : '';
return {
- enterActiveClass: `${props.prefix} ${modeClass} is-in`,
- moveClass: `${props.prefix} ${modeClass} is-move`,
- leaveActiveClass: `${props.prefix} ${modeClass} is-out`
+ enterActiveClass: trim(`${attrs.enterActiveClass || ''} ${props.prefix} ${modeClass} is-in`),
+ leaveActiveClass: trim(`${attrs.leaveActiveClass || ''} ${props.prefix} ${modeClass} is-out`),
+ moveClass: props.group ? trim(`${attrs.moveClass || ''} ${props.prefix} ${modeClass} is-move`) : undefined,
};
});
@@ -59,18 +59,30 @@ export const useTransition = () => {
// hooks
const handleBeforeEnter = (el: HTMLElement) => {
let duration = (props.duration as any).enter || props.duration;
- el.style.animationDuration = `${duration}s`;
+ el.style.animationDuration = `${duration}ms`;
let delay = (props.delay as any).enter || props.delay;
- el.style.animationDelay = `${delay}s`;
+ el.style.animationDelay = `${delay}ms`;
resetStyles(el);
attrs.onBeforeEnter?.(el);
};
- const handleEnter = (el: HTMLElement) => {
- attrs.onEnter?.(el);
+ const createNext = (callback?: () => any) => {
+ let hasDone = false;
+ return () => {
+ !hasDone && callback?.();
+ hasDone = true;
+ };
+ };
+ const handleEnter = async (el: HTMLElement, done?: () => any) => {
+ let next = createNext(done);
+ try {
+ await attrs.onEnter?.(el, next);
+ } finally {
+ next();
+ }
};
const handleAfterEnter = (el: HTMLElement) => {
@@ -81,22 +93,25 @@ export const useTransition = () => {
const handleBeforeLeave = (el: HTMLElement) => {
let duration = (props.duration as any).leave || props.duration;
- el.style.animationDuration = `${duration}s`;
+ el.style.animationDuration = `${duration}ms`;
let delay = (props.delay as any).leave || props.delay;
- el.style.animationDelay = `${delay}s`;
+ el.style.animationDelay = `${delay}ms`;
resetStyles(el);
attrs.onBeforeLeave?.(el);
};
- // 特殊处理: 如果第二个参数为done, 且接收的话, 由用户管理结束
- const handleLeave = (el: HTMLElement) => {
- resetAbsolute(el);
-
- attrs.onLeave?.(el);
-
+ // 如果第二个参数为done, 且接收的话, 由用户管理结束
+ const handleLeave = async (el: HTMLElement, done?: () => any) => {
+ let next = createNext(done);
+ try {
+ resetAbsolute(el);
+ await attrs.onLeave?.(el, next);
+ } finally {
+ next();
+ }
};
const handleAfterLeave = (el: HTMLElement) => {
clearStyles(el);
@@ -109,13 +124,14 @@ export const useTransition = () => {
resetStyles,
resetAbsolute,
classes,
- listeners: toHandlers({
- 'before-enter': handleBeforeEnter,
- 'enter': handleEnter,
- 'after-enter': handleAfterEnter,
- 'before-leave': handleBeforeLeave,
- 'leave': handleLeave,
- 'after-leave': handleAfterLeave
- })
+ createNext,
+ listeners: {
+ onBeforeEnter: handleBeforeEnter,
+ onEnter: handleEnter,
+ onAfterEnter: handleAfterEnter,
+ onBeforeLeave: handleBeforeLeave,
+ onLeave: handleLeave,
+ onAfterLeave: handleAfterLeave
+ }
};
};