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 @@
+
+ Dinamic content:
+
+
+
+
+
+ {{ item.id }} - {{ item.name }}
+
+
+
+
+
+ Animation as prop
+
+
+ {{ suggestion.query }}
+
+
+
+
+ Static content:
+
+ Element to animate
+ Element to animate
+ Element to animate
+
+
+
+
diff --git a/packages/_vue3-migration-test/src/router.ts b/packages/_vue3-migration-test/src/router.ts
index c188737156..b6a8ec7597 100644
--- a/packages/_vue3-migration-test/src/router.ts
+++ b/packages/_vue3-migration-test/src/router.ts
@@ -49,7 +49,8 @@ import {
TestRenderlessExtraParam,
TestAnimationFactory,
TestIcons,
- TestDisplayEmitter
+ TestDisplayEmitter,
+ TestStaggeredFadeAndSlide
} from './';
const routes = [
@@ -302,6 +303,11 @@ const routes = [
path: '/display-emitter',
name: 'DisplayEmitter',
component: TestDisplayEmitter
+ },
+ {
+ 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 26240a7f04..e2f252cff4 100644
--- a/packages/x-components/src/components/animations/index.ts
+++ b/packages/x-components/src/components/animations/index.ts
@@ -5,7 +5,6 @@ export { default as CrossFade } from './cross-fade.vue';
export { default as Fade } from './fade.vue';
export { default as FadeAndSlide } from './fade-and-slide.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 bc2a484abd..86dc978b32 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 @@
();
+ /**
+ * ResizeObserver instance to keep track of the number of columns rendered inside the grid.
+ */
+ let resizeObserver: { stop: () => void };
+
/**
* It injects {@link ListItem} provided by an ancestor.
*
@@ -124,9 +130,6 @@
undefined
);
- const gridEl = ref(null);
-
- let renderedColumnsNumber = ref(0);
/**
* Emits the {@link XEventsTypes.RenderedColumnsNumberChanged}
* event whenever the number of columns rendered inside the grid changes.
@@ -136,9 +139,7 @@
watch(
renderedColumnsNumber,
() => xBus.emit('RenderedColumnsNumberChanged', renderedColumnsNumber.value),
- {
- immediate: false
- }
+ { immediate: false }
);
/**
@@ -205,49 +206,38 @@
})
);
- /**
- * Checks if a given value is an `ElementRef` object.
- *
- * @param value - The value to check.
- * @returns `true` if the value is an `ElementRef` object, `false` otherwise.
- *
- * @internal
- */
- const isElementRef = (value: any): value is ElementRef => {
- return value && value.$el instanceof HTMLElement;
- };
-
/**
* Updates the number of columns rendered inside the grid.
- *
- * @internal
*/
const updateRenderedColumnsNumber = (): void => {
- const { gridTemplateColumns } = getComputedStyle(
- isElementRef(gridEl.value) ? gridEl.value.$el : (gridEl.value as Element)
- );
- renderedColumnsNumber.value = gridTemplateColumns.split(' ').length;
+ if (rootEl.value) {
+ const { gridTemplateColumns } = getComputedStyle(rootEl.value);
+ renderedColumnsNumber.value = gridTemplateColumns.split(' ').length;
+ }
};
/**
* Initialises the rendered columns number and sets a ResizeObserver to keep it updated.
- *
- * @internal
*/
- let resizeObserver: UseResizeObserverReturn;
onMounted(() => {
- resizeObserver = useResizeObserver(
- gridEl as MaybeComputedElementRef,
- updateRenderedColumnsNumber
- );
+ rootEl.value = getCurrentInstance()?.proxy?.$el as HTMLElement | undefined;
+ if (rootEl.value) {
+ resizeObserver = useResizeObserver(
+ rootEl as MaybeComputedElementRef,
+ updateRenderedColumnsNumber
+ );
+ }
});
+
+ /**
+ * Stops the ResizeObserver when the component is unmounted.
+ */
onBeforeUnmount(() => resizeObserver?.stop());
return {
gridItems,
cssClasses,
style,
- gridEl,
slots
};
}
diff --git a/packages/x-components/src/views/home/Home.vue b/packages/x-components/src/views/home/Home.vue
index 306700b313..1ff3881863 100644
--- a/packages/x-components/src/views/home/Home.vue
+++ b/packages/x-components/src/views/home/Home.vue
@@ -459,7 +459,7 @@
/* eslint-disable max-len */
import { computed, ComputedRef, defineComponent, provide } from 'vue';
// import { animateClipPath } from '../../components/animations/animate-clip-path/animate-clip-path.factory';
- // import StaggeredFadeAndSlide from '../../components/animations/staggered-fade-and-slide.vue';
+ import StaggeredFadeAndSlide from '../../components/animations/staggered-fade-and-slide.vue';
import AutoProgressBar from '../../components/auto-progress-bar.vue';
import BaseDropdown from '../../components/base-dropdown.vue';
import BaseGrid from '../../components/base-grid.vue';
@@ -586,6 +586,7 @@
SortPickerList,
Spellcheck,
SpellcheckButton,
+ StaggeredFadeAndSlide,
Tagging,
UrlHandler
},
@@ -600,7 +601,7 @@
'Find sunglasses'
];
const columnPickerValues = [0, 2, 4];
- // const resultsAnimation = StaggeredFadeAndSlide;
+ const resultsAnimation = StaggeredFadeAndSlide;
// const modalAnimation = animateClipPath();
const selectedColumns = 4;
const sortValues = ['', 'price asc', 'price desc'];
@@ -662,7 +663,7 @@
adapterConfig.e2e = !adapterConfig.e2e;
};
return {
- resultsAnimation: undefined,
+ resultsAnimation,
modalAnimation: undefined,
queriesPreviewInfo,
stores,