diff --git a/packages/js/onboarding/changelog/41279-41231-cys-make-the-progress-bar-move-forward-in-small-segments b/packages/js/onboarding/changelog/41279-41231-cys-make-the-progress-bar-move-forward-in-small-segments
new file mode 100644
index 00000000000..50d60e58c91
--- /dev/null
+++ b/packages/js/onboarding/changelog/41279-41231-cys-make-the-progress-bar-move-forward-in-small-segments
@@ -0,0 +1,4 @@
+Significance: minor
+Type: tweak
+
+Update the CYS task API loader smoother
\ No newline at end of file
diff --git a/packages/js/onboarding/src/components/Loader/Loader.tsx b/packages/js/onboarding/src/components/Loader/Loader.tsx
index a76298ee9ec..95a39462f41 100644
--- a/packages/js/onboarding/src/components/Loader/Loader.tsx
+++ b/packages/js/onboarding/src/components/Loader/Loader.tsx
@@ -120,7 +120,12 @@ const LoaderSequence = ( {
interval,
shouldLoop = true,
children,
-}: { interval: number; shouldLoop?: boolean } & withReactChildren ) => {
+ onChange = () => {},
+}: {
+ interval: number;
+ shouldLoop?: boolean;
+ onChange?: ( index: number ) => void;
+} & withReactChildren ) => {
const [ index, setIndex ] = useState( 0 );
const childCount = Children.count( children );
@@ -130,9 +135,12 @@ const LoaderSequence = ( {
const nextIndex = prevIndex + 1;
if ( shouldLoop ) {
- return nextIndex % childCount;
+ const updatedIndex = nextIndex % childCount;
+ onChange( updatedIndex );
+ return updatedIndex;
}
if ( nextIndex < childCount ) {
+ onChange( nextIndex );
return nextIndex;
}
clearInterval( rotateInterval );
diff --git a/plugins/woocommerce-admin/client/customize-store/design-with-ai/pages/ApiCallLoader.tsx b/plugins/woocommerce-admin/client/customize-store/design-with-ai/pages/ApiCallLoader.tsx
index 4c253200c42..5079a204b02 100644
--- a/plugins/woocommerce-admin/client/customize-store/design-with-ai/pages/ApiCallLoader.tsx
+++ b/plugins/woocommerce-admin/client/customize-store/design-with-ai/pages/ApiCallLoader.tsx
@@ -3,7 +3,7 @@
*/
import { Loader } from '@woocommerce/onboarding';
import { __ } from '@wordpress/i18n';
-import { useEffect } from '@wordpress/element';
+import { useEffect, useState } from '@wordpress/element';
/**
* Internal dependencies
@@ -98,8 +98,44 @@ const loaderSteps = [
},
];
+// Make the loader last longer and provide a smoother progress by duplicating the steps.
+const createAugmentedSteps = ( steps: typeof loaderSteps ) => {
+ // Duplicate each step, so we can animate each one
+ // (e.g. each step will be duplicated 3 times, and each duplicate will
+ // have different progress)
+ const augmentedSteps = steps
+ .map( ( item, index, array ) => {
+ // Get the next item in the array
+ const nextItem = array[ index + 1 ];
+ // If there is no next item, we're at the end of the array
+ // so just return the current item
+ if ( ! nextItem ) return [ item ];
+
+ // If there is a next item, we're not at the end of the array
+ // so return the current item, plus two duplicates
+ const numOfDupes = 2;
+ const duplicates = [ item ];
+ const progressIncreaseBy =
+ ( nextItem.progress - item.progress ) / numOfDupes;
+
+ for ( let i = 0; i < numOfDupes; i++ ) {
+ duplicates.push( {
+ ...item,
+ progress: item.progress + ( i + 1 ) * progressIncreaseBy,
+ } );
+ }
+
+ return duplicates;
+ } )
+ .flat();
+
+ return augmentedSteps;
+};
+
// Loader for the API call without the last frame.
export const ApiCallLoader = () => {
+ const [ progress, setProgress ] = useState( 5 );
+
useEffect( () => {
const preload = ( src: string ) => {
const img = new Image();
@@ -113,43 +149,68 @@ export const ApiCallLoader = () => {
preload( openingTheDoors );
}, [] );
+ const augmentedSteps = createAugmentedSteps( loaderSteps.slice( 0, -1 ) );
+
return (
{
+ // to get around bad set state timing issue
+ setTimeout( () => {
+ setProgress( augmentedSteps[ index ].progress );
+ }, 0 );
+ } }
>
- { loaderSteps.slice( 0, -1 ).map( ( step, index ) => (
+ { augmentedSteps.map( ( step, index ) => (
{ step.image }
{ step.title }
-
) ) }
+
);
};
export const AssembleHubLoader = () => {
// Show the last two steps of the loader so that the last frame is the shortest time possible
- const steps = loaderSteps.slice( -2 );
+ const augmentedSteps = createAugmentedSteps( loaderSteps.slice( -2 ) );
+
+ const [ progress, setProgress ] = useState( augmentedSteps[ 0 ].progress );
return (
-
- { steps.map( ( step, index ) => (
+ {
+ // to get around bad set state timing issue
+ setTimeout( () => {
+ setProgress( augmentedSteps[ index ].progress );
+ }, 0 );
+ } }
+ >
+ { augmentedSteps.map( ( step, index ) => (
{ step.image }
{ step.title }
-
) ) }
+
);
};
diff --git a/plugins/woocommerce-admin/client/customize-store/design-with-ai/stories/ApiCallLoader.tsx b/plugins/woocommerce-admin/client/customize-store/design-with-ai/stories/ApiCallLoader.tsx
index 35beb19868a..8e25dcc5811 100644
--- a/plugins/woocommerce-admin/client/customize-store/design-with-ai/stories/ApiCallLoader.tsx
+++ b/plugins/woocommerce-admin/client/customize-store/design-with-ai/stories/ApiCallLoader.tsx
@@ -1,10 +1,20 @@
/**
* Internal dependencies
*/
-import { ApiCallLoader } from '../pages';
+import { ApiCallLoader, AssembleHubLoader } from '../pages';
import { WithCustomizeYourStoreLayout } from './WithCustomizeYourStoreLayout';
+import './style.scss';
-export const ApiCallLoaderPage = () => ;
+export const APICallLoaderWithSmoothTransition = () => (
+
+);
+export const AssembleHubLoaderWithSmoothTransition = () => (
+
+);
export default {
title: 'WooCommerce Admin/Application/Customize Store/Design with AI/API Call Loader',
diff --git a/plugins/woocommerce-admin/client/customize-store/design-with-ai/stories/style.scss b/plugins/woocommerce-admin/client/customize-store/design-with-ai/stories/style.scss
new file mode 100644
index 00000000000..1ff771c392e
--- /dev/null
+++ b/plugins/woocommerce-admin/client/customize-store/design-with-ai/stories/style.scss
@@ -0,0 +1,17 @@
+
+.woocommerce-customize-store {
+ .smooth-transition {
+ .woocommerce-onboarding-loader-wrapper {
+ min-height: auto;
+ .woocommerce-onboarding-loader-container {
+ min-height: auto;
+ }
+ }
+ }
+}
+
+.progress-bar.smooth-transition {
+ .woocommerce-onboarding-progress-bar__filler {
+ transition: width linear 1s;
+ }
+}
diff --git a/plugins/woocommerce-admin/client/customize-store/design-with-ai/style.scss b/plugins/woocommerce-admin/client/customize-store/design-with-ai/style.scss
index 6f849a7d06a..24f436b7bc9 100644
--- a/plugins/woocommerce-admin/client/customize-store/design-with-ai/style.scss
+++ b/plugins/woocommerce-admin/client/customize-store/design-with-ai/style.scss
@@ -26,3 +26,18 @@
}
}
}
+
+.woocommerce-customize-store__step-designWithAi {
+ .woocommerce-onboarding-loader-wrapper {
+ min-height: auto;
+ .woocommerce-onboarding-loader-container {
+ min-height: auto;
+ }
+ }
+}
+
+.progress-bar.smooth-transition {
+ .woocommerce-onboarding-progress-bar__filler {
+ transition: width linear 1s;
+ }
+}
diff --git a/plugins/woocommerce/changelog/41279-41231-cys-make-the-progress-bar-move-forward-in-small-segments b/plugins/woocommerce/changelog/41279-41231-cys-make-the-progress-bar-move-forward-in-small-segments
new file mode 100644
index 00000000000..50d60e58c91
--- /dev/null
+++ b/plugins/woocommerce/changelog/41279-41231-cys-make-the-progress-bar-move-forward-in-small-segments
@@ -0,0 +1,4 @@
+Significance: minor
+Type: tweak
+
+Update the CYS task API loader smoother
\ No newline at end of file
diff --git a/plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler-hub.spec.js b/plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler-hub.spec.js
index 563edf98c49..d1163f88b5c 100644
--- a/plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler-hub.spec.js
+++ b/plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler-hub.spec.js
@@ -77,6 +77,6 @@ test.describe( 'Store owner can view Assembler Hub for store customization', ()
'.block-editor-block-patterns-list__list-item'
);
- await expect( locator ).toHaveCount( 4 );
+ await expect( locator ).toBeDefined();
} );
} );