From cbe522e006e2c30509406451765e3963858e6561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vi=CC=81ctor=20CG?= Date: Mon, 29 Jul 2024 12:57:08 +0200 Subject: [PATCH 01/11] refactor(staggered-fade-and-slide): use Vue native staggered transition --- .../src/components/animations/index.ts | 1 + .../test-staggered-fade-and-slide.vue | 68 +++ packages/_vue3-migration-test/src/router.ts | 8 +- .../staggering-transition-group.spec.ts | 204 -------- .../src/components/animations/index.ts | 1 - .../animations/staggered-fade-and-slide.vue | 95 +++- .../staggering-transition-group.vue | 472 ------------------ .../x-components/src/components/base-grid.vue | 74 ++- packages/x-components/src/views/home/Home.vue | 7 +- 9 files changed, 194 insertions(+), 736 deletions(-) create mode 100644 packages/_vue3-migration-test/src/components/animations/test-staggered-fade-and-slide.vue delete mode 100644 packages/x-components/src/components/animations/__tests__/staggering-transition-group.spec.ts delete mode 100644 packages/x-components/src/components/animations/staggering-transition-group.vue diff --git a/packages/_vue3-migration-test/src/components/animations/index.ts b/packages/_vue3-migration-test/src/components/animations/index.ts index b951da74a4..ca0d8338a1 100644 --- a/packages/_vue3-migration-test/src/components/animations/index.ts +++ b/packages/_vue3-migration-test/src/components/animations/index.ts @@ -5,3 +5,4 @@ export { default as TestCrossFade } from './test-cross-fade.vue'; export { default as TestFade } from './test-fade.vue'; export { default as TestFadeAndSlide } from './test-fade-and-slide.vue'; export { default as TestAnimationFactory } from './test-animation-factory.vue'; +export { default as TestStaggeredFadeAndSlide } from './test-staggered-fade-and-slide.vue'; diff --git a/packages/_vue3-migration-test/src/components/animations/test-staggered-fade-and-slide.vue b/packages/_vue3-migration-test/src/components/animations/test-staggered-fade-and-slide.vue new file mode 100644 index 0000000000..dadcd355f5 --- /dev/null +++ b/packages/_vue3-migration-test/src/components/animations/test-staggered-fade-and-slide.vue @@ -0,0 +1,68 @@ + + + diff --git a/packages/_vue3-migration-test/src/router.ts b/packages/_vue3-migration-test/src/router.ts index d08a611bd9..9dd876ef80 100644 --- a/packages/_vue3-migration-test/src/router.ts +++ b/packages/_vue3-migration-test/src/router.ts @@ -50,7 +50,8 @@ import { TestAnimationFactory, TestIcons, TestDisplayEmitter, - TestBaseSwitch + TestBaseSwitch, + TestStaggeredFadeAndSlide } from './'; const routes = [ @@ -308,6 +309,11 @@ const routes = [ path: '/base-switch', name: 'BaseSwitch', component: TestBaseSwitch + }, + { + path: '/staggered-fade-and-slide', + name: 'StaggeredFadeAndSlide', + component: TestStaggeredFadeAndSlide } ]; diff --git a/packages/x-components/src/components/animations/__tests__/staggering-transition-group.spec.ts b/packages/x-components/src/components/animations/__tests__/staggering-transition-group.spec.ts deleted file mode 100644 index 28b8ff9ed9..0000000000 --- a/packages/x-components/src/components/animations/__tests__/staggering-transition-group.spec.ts +++ /dev/null @@ -1,204 +0,0 @@ -import { mount, Wrapper, WrapperArray } from '@vue/test-utils'; -import Vue, { ComponentOptions } from 'vue'; -import { getDataTestSelector } from '../../../__tests__/utils'; -import StaggeringTransitionGroup from '../staggering-transition-group.vue'; - -describe('testing Staggering Transition Group component', () => { - const wrapper: ComponentOptions = { - components: { - StaggeringTransitionGroup - }, - template: ` - -
- Child {{ index }} -
-
`, - props: { - children: Array, - appear: Boolean, - staggering: Number - } - }; - - function renderStaggeringTransitionGroup( - propsData: StaggeringTransitionGroupWrapper - ): StaggeringTransitionGroupAPI { - const component = mount(wrapper, { - propsData - }); - - return { - component, - getChildren() { - return component.findAll(getDataTestSelector('children')); - }, - setChildren(children) { - component.setProps({ children }); - } - }; - } - - it('applies enter classes when appear is set to true', () => { - const staggering = 100; - // eslint-disable-next-line @typescript-eslint/unbound-method - const { getChildren } = renderStaggeringTransitionGroup({ - appear: true, - children: [1, 2, 3], - staggering - }); - const childrenWrapper = getChildren(); - expect(childrenWrapper).toHaveLength(3); - childrenWrapper.wrappers.forEach((child, index) => { - expect(child.classes()).toContain('staggering-test-enter-active'); - expect(child.element.style.transitionDelay).toEqual(`${staggering * index}ms`); - }); - }); - - it('applies enter classes when a new element enters.', async () => { - const staggering = 100; - // eslint-disable-next-line @typescript-eslint/unbound-method - const { getChildren, setChildren } = renderStaggeringTransitionGroup({ - appear: false, - children: [], - staggering - }); - setChildren([1, 2, 3]); - await Vue.nextTick(); - const childrenWrapper = getChildren(); - expect(childrenWrapper).toHaveLength(3); - childrenWrapper.wrappers.forEach((child, index) => { - expect(child.classes()).toContain('staggering-test-enter-active'); - expect(child.element.style.transitionDelay).toEqual(`${staggering * index}ms`); - }); - }); - - it('applies move classes if child nodes change position', async () => { - const staggering = 100; - // eslint-disable-next-line @typescript-eslint/unbound-method - const { getChildren, setChildren } = renderStaggeringTransitionGroup({ - appear: false, - children: [3], - staggering - }); - const childrenToMove = getChildren().at(0); - fakeIncrementalMovement(childrenToMove.element); - setChildren([1, 2, 3]); - await Vue.nextTick(); - const childrenWrapper = getChildren(); - expect(childrenWrapper).toHaveLength(3); - - childrenWrapper.wrappers.forEach((child, index) => { - if (index < 2) { - expect(child.classes()).toContain('staggering-test-enter-active'); - expect(child.element.style.transitionDelay).toEqual(`${staggering * (index + 1)}ms`); - } - }); - expect(childrenWrapper.at(2).classes()).toContain('staggering-test-move'); - }); - - it('applies leave classes when a node leaves.', async () => { - const staggering = 100; - // eslint-disable-next-line @typescript-eslint/unbound-method - const { getChildren, setChildren } = renderStaggeringTransitionGroup({ - appear: false, - children: [1, 2, 3], - staggering - }); - setChildren([]); - await Vue.nextTick(); - const childrenWrapper = getChildren(); - expect(childrenWrapper).toHaveLength(3); - childrenWrapper.wrappers.forEach((child, index) => { - expect(child.classes()).toContain('staggering-test-leave-active'); - expect(child.element.style.transitionDelay).toEqual(`${staggering * index}ms`); - }); - }); - - it('disables pointer-events when a node leaves.', async () => { - const staggering = 100; - // eslint-disable-next-line @typescript-eslint/unbound-method - const { getChildren, setChildren } = renderStaggeringTransitionGroup({ - appear: false, - children: [1, 2, 3], - staggering - }); - setChildren([]); - await Vue.nextTick(); - const childrenWrapper = getChildren(); - expect(childrenWrapper).toHaveLength(3); - childrenWrapper.wrappers.forEach(child => { - expect(child.element.style.pointerEvents).toEqual('none'); - }); - }); - - it( - 'applies enter classes when a new element enters and one element stay in ' + - 'same position after doing a search', - async () => { - const staggering = 100; - // eslint-disable-next-line @typescript-eslint/unbound-method - const { getChildren, setChildren } = renderStaggeringTransitionGroup({ - appear: true, - children: ['stay', 'move', 'leave0', 'leave1'], - staggering - }); - - // eslint-disable-next-line max-len - // Wait to `after` hooks to be executed. As there are 4 nodes, then after 4 times the staggering - // time they should have finished executing. - await waitFor(4 * staggering); - - const childrenToMove = getChildren().at(1); - fakeIncrementalMovement(childrenToMove.element); - setChildren(['stay', 'enter0', 'move', 'enter1', 'enter2']); - - await Vue.nextTick(); - const childrenWrapper = getChildren(); - expect(childrenWrapper).toHaveLength(5); - const [stay, enter0, move, enter1, enter2] = childrenWrapper.wrappers; - // Note that leave nodes can't be retrieved. That's why the transitionDelay starts at 200ms - // instead of 0ms. - expect(stay.element.style.transitionDelay).toEqual(''); - expect(enter0.element.style.transitionDelay).toEqual(`${staggering * 3}ms`); - expect(move.element.style.transitionDelay).toEqual(`${staggering * 2}ms`); - expect(enter1.element.style.transitionDelay).toEqual(`${staggering * 4}ms`); - expect(enter2.element.style.transitionDelay).toEqual(`${staggering * 5}ms`); - - expect(stay.classes()).toHaveLength(0); - expect(enter0.classes()).toContain('staggering-test-enter-active'); - expect(move.classes()).toContain('staggering-test-move'); - expect(enter1.classes()).toContain('staggering-test-enter-active'); - expect(enter2.classes()).toContain('staggering-test-enter-active'); - } - ); -}); - -// For fake move position and enter in applyTranslation and get new position -function fakeIncrementalMovement(element: HTMLElement): void { - let position = 0; - element.getBoundingClientRect = () => - ({ - left: position++, - top: position++ - } as DOMRect); -} - -// Method for enter in hooks of component afterEnter -function waitFor(ms: number): Promise { - return new Promise(resolve => setTimeout(resolve, ms)); -} - -interface StaggeringTransitionGroupWrapper { - appear: boolean; - children: (string | number)[]; - staggering: number; -} - -interface StaggeringTransitionGroupAPI { - component: Wrapper; - getChildren(): WrapperArray; - setChildren(children: (string | number)[]): void; -} diff --git a/packages/x-components/src/components/animations/index.ts b/packages/x-components/src/components/animations/index.ts index 2c4fb0a84c..b095f0e128 100644 --- a/packages/x-components/src/components/animations/index.ts +++ b/packages/x-components/src/components/animations/index.ts @@ -6,7 +6,6 @@ export { default as Fade } from './fade.vue'; export { default as FadeAndSlide } from './fade-and-slide.vue'; export { default as NoAnimation } from './no-animation.vue'; export { default as StaggeredFadeAndSlide } from './staggered-fade-and-slide.vue'; -export { default as StaggeringTransitionGroup } from './staggering-transition-group.vue'; export { createDirectionalAnimationFactory } from './create-directional-animation-factory'; export { animateClipPath } from './animate-clip-path/animate-clip-path.factory'; export { animateScale } from './animate-scale/animate-scale.factory'; diff --git a/packages/x-components/src/components/animations/staggered-fade-and-slide.vue b/packages/x-components/src/components/animations/staggered-fade-and-slide.vue index ab61530a8f..42b7c25364 100644 --- a/packages/x-components/src/components/animations/staggered-fade-and-slide.vue +++ b/packages/x-components/src/components/animations/staggered-fade-and-slide.vue @@ -1,15 +1,19 @@ diff --git a/packages/x-components/src/components/animations/staggering-transition-group.vue b/packages/x-components/src/components/animations/staggering-transition-group.vue deleted file mode 100644 index 5e84c1b6bd..0000000000 --- a/packages/x-components/src/components/animations/staggering-transition-group.vue +++ /dev/null @@ -1,472 +0,0 @@ - - - - - -## Examples - -### Basic example - -Apart from all the props and events that the classic transition group has, the staggering transition -group also exposes a new `staggering` property, which allows to configure the delay for each one of -the nodes when animating. - -```vue - - - - -``` - diff --git a/packages/x-components/src/components/base-grid.vue b/packages/x-components/src/components/base-grid.vue index 86ed995de2..c89abc01ea 100644 --- a/packages/x-components/src/components/base-grid.vue +++ b/packages/x-components/src/components/base-grid.vue @@ -1,7 +1,6 @@