From e9ba8f30407701aa20991499c1e756f204f3d17a Mon Sep 17 00:00:00 2001 From: Mitch-At-Work Date: Mon, 7 Oct 2024 16:29:28 -0700 Subject: [PATCH 1/6] Working example of carousel modal --- package.json | 1 + .../react-carousel/library/package.json | 3 +- .../src/components/Carousel/Carousel.types.ts | 6 + .../src/components/Carousel/useCarousel.ts | 2 + .../src/components/useEmblaCarousel.ts | 66 +++++--- .../Carousel/CarouselControlled.stories.tsx | 2 +- .../CarouselFirstRunExperience.stories.tsx | 143 ++++++++++++++++++ .../stories/src/Carousel/index.stories.tsx | 1 + yarn.lock | 5 + 9 files changed, 202 insertions(+), 27 deletions(-) create mode 100644 packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx diff --git a/package.json b/package.json index d65bae9514dfa..87fb01ae41488 100644 --- a/package.json +++ b/package.json @@ -220,6 +220,7 @@ "ejs": "3.1.10", "embla-carousel": "8.3.0", "embla-carousel-autoplay": "8.3.0", + "embla-carousel-fade": "8.3.0", "enquirer": "2.3.6", "enzyme": "3.10.0", "enzyme-to-json": "3.6.2", diff --git a/packages/react-components/react-carousel/library/package.json b/packages/react-components/react-carousel/library/package.json index 9a9aadda919a6..25ef69c04195d 100644 --- a/packages/react-components/react-carousel/library/package.json +++ b/packages/react-components/react-carousel/library/package.json @@ -47,7 +47,8 @@ "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1", "embla-carousel": "^8.3.0", - "embla-carousel-autoplay": "^8.3.0" + "embla-carousel-autoplay": "^8.3.0", + "embla-carousel-fade": "^8.3.0" }, "peerDependencies": { "@types/react": ">=16.14.0 <19.0.0", diff --git a/packages/react-components/react-carousel/library/src/components/Carousel/Carousel.types.ts b/packages/react-components/react-carousel/library/src/components/Carousel/Carousel.types.ts index a2a82c9ccf152..945dbaebd455c 100644 --- a/packages/react-components/react-carousel/library/src/components/Carousel/Carousel.types.ts +++ b/packages/react-components/react-carousel/library/src/components/Carousel/Carousel.types.ts @@ -57,6 +57,12 @@ export type CarouselProps = ComponentProps & { */ whitespace?: boolean; + /** + * Sets motion to fade in/out style with minimal movement + * Defaults: false + */ + fade?: boolean; + /** * Localizes the string used to announce carousel page changes * Defaults to: undefined diff --git a/packages/react-components/react-carousel/library/src/components/Carousel/useCarousel.ts b/packages/react-components/react-carousel/library/src/components/Carousel/useCarousel.ts index 192ccc0e4ff5b..80d79823b8ef1 100644 --- a/packages/react-components/react-carousel/library/src/components/Carousel/useCarousel.ts +++ b/packages/react-components/react-carousel/library/src/components/Carousel/useCarousel.ts @@ -33,6 +33,7 @@ export function useCarousel_unstable(props: CarouselProps, ref: React.Ref { diff --git a/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts b/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts index 06ac445240c6f..50d8a7bf424ba 100644 --- a/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts +++ b/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts @@ -1,11 +1,12 @@ import { useControllableState } from '@fluentui/react-utilities'; -import EmblaCarousel, { type EmblaCarouselType, type EmblaOptionsType } from 'embla-carousel'; +import EmblaCarousel, { EmblaPluginType, type EmblaCarouselType, type EmblaOptionsType } from 'embla-carousel'; import * as React from 'react'; import { carouselCardClassNames } from './CarouselCard/useCarouselCardStyles.styles'; import { carouselSliderClassNames } from './CarouselSlider/useCarouselSliderStyles.styles'; import { CarouselUpdateData, CarouselVisibilityEventDetail } from '../Carousel'; import Autoplay from 'embla-carousel-autoplay'; +import Fade from 'embla-carousel-fade'; const sliderClassname = `.${carouselSliderClassNames.root}`; @@ -38,9 +39,10 @@ export function useEmblaCarousel( options: Pick & { defaultActiveIndex: number | undefined; activeIndex: number | undefined; + fade?: boolean; }, ) { - const { align, direction, loop, slidesToScroll, watchDrag, containScroll } = options; + const { align, direction, loop, slidesToScroll, watchDrag, containScroll, fade } = options; const [activeIndex, setActiveIndex] = useControllableState({ defaultState: options.defaultActiveIndex, state: options.activeIndex, @@ -132,6 +134,23 @@ export function useEmblaCarousel( }); }; + const plugins: EmblaPluginType[] = [ + Autoplay({ + playOnInit: autoplayRef.current, + stopOnInteraction: !autoplayRef.current, + stopOnMouseEnter: true, + stopOnFocusIn: true, + rootNode: (emblaRoot: HTMLElement) => { + return emblaRoot.querySelector(sliderClassname) ?? emblaRoot; + }, + }), + ]; + + // Optionally add Fade plugin + if (fade) { + plugins.push(Fade()); + } + return { set current(newElement: HTMLDivElement | null) { if (currentElement) { @@ -149,17 +168,7 @@ export function useEmblaCarousel( ...DEFAULT_EMBLA_OPTIONS, ...emblaOptions.current, }, - [ - Autoplay({ - playOnInit: autoplayRef.current, - stopOnInteraction: !autoplayRef.current, - stopOnMouseEnter: true, - stopOnFocusIn: true, - rootNode: (emblaRoot: HTMLElement) => { - return emblaRoot.querySelector(sliderClassname) ?? emblaRoot; - }, - }), - ], + plugins, ); emblaApi.current?.on('reInit', handleReinit); @@ -209,25 +218,32 @@ export function useEmblaCarousel( }, [activeIndex]); React.useEffect(() => { + const plugins: EmblaPluginType[] = [ + Autoplay({ + playOnInit: autoplayRef.current, + stopOnInteraction: !autoplayRef.current, + stopOnMouseEnter: true, + stopOnFocusIn: true, + rootNode: (emblaRoot: HTMLElement) => { + return emblaRoot.querySelector(sliderClassname) ?? emblaRoot; + }, + }), + ]; + + // Optionally add Fade plugin + if (fade) { + plugins.push(Fade()); + } + emblaOptions.current = { align, direction, loop, slidesToScroll, watchDrag, containScroll }; emblaApi.current?.reInit( { ...DEFAULT_EMBLA_OPTIONS, ...emblaOptions.current, }, - [ - Autoplay({ - playOnInit: autoplayRef.current, - stopOnInteraction: !autoplayRef.current, - stopOnMouseEnter: true, - stopOnFocusIn: true, - rootNode: (emblaRoot: HTMLElement) => { - return emblaRoot.querySelector(sliderClassname) ?? emblaRoot; - }, - }), - ], + plugins, ); - }, [align, direction, loop, slidesToScroll, watchDrag, containScroll]); + }, [align, direction, loop, slidesToScroll, watchDrag, containScroll, fade]); return { activeIndex, diff --git a/packages/react-components/react-carousel/stories/src/Carousel/CarouselControlled.stories.tsx b/packages/react-components/react-carousel/stories/src/Carousel/CarouselControlled.stories.tsx index 310a9ab22aa14..fb2483846fbe4 100644 --- a/packages/react-components/react-carousel/stories/src/Carousel/CarouselControlled.stories.tsx +++ b/packages/react-components/react-carousel/stories/src/Carousel/CarouselControlled.stories.tsx @@ -119,7 +119,7 @@ const WireframeContent: React.FC<{ }; export const Controlled = () => { - const [activeIndex, setActiveIndex] = React.useState(0); + const [activeIndex, setActiveIndex] = React.useState(1); const classes = useClasses(); return ( diff --git a/packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx b/packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx new file mode 100644 index 0000000000000..ed76acde4e2bc --- /dev/null +++ b/packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx @@ -0,0 +1,143 @@ +import * as React from 'react'; +import { + Button, + Carousel, + CarouselAnnouncerFunction, + CarouselCard, + CarouselNav, + CarouselNavButton, + CarouselSlider, + Dialog, + DialogSurface, + DialogTrigger, + Image, + makeStyles, + shorthands, + tokens, + typographyStyles, +} from '@fluentui/react-components'; + +const useStyles = makeStyles({ + surface: { + padding: 0, + ...shorthands.border('none'), + overflow: 'hidden', + }, + carousel: { padding: 0 }, + card: {}, + footer: { + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + width: 'auto', + padding: `${tokens.spacingVerticalS} ${tokens.spacingVerticalXXL} ${tokens.spacingVerticalXXL} ${tokens.spacingVerticalXXL}`, + }, + header: { + display: 'block', + // We use margin instead of padding to avoid messing with the focus indicator in the header + margin: `${tokens.spacingVerticalXXL} ${tokens.spacingVerticalXXL} ${tokens.spacingVerticalS} ${tokens.spacingVerticalXXL}`, + ...typographyStyles.subtitle1, + }, + text: { + display: 'block', + padding: `${tokens.spacingVerticalS} ${tokens.spacingVerticalXXL}`, + ...typographyStyles.body1, + }, +}); + +const PAGES = [ + { + alt: 'Copilot logo', + imgSrc: 'https://fabricweb.azureedge.net/fabric-website/assets/images/swatch-picker/sea-full-img.jpg', + header: 'Discover Copilot, a whole new way to work', + text: 'Explore new ways to work smarter and faster using the power of AI. Copilot in [Word] can help you [get started from scratch], [work from an existing file], [get actionable insights about documents], and more.', + }, + { + alt: 'Copilot logo 2', + imgSrc: 'https://fabricweb.azureedge.net/fabric-website/assets/images/swatch-picker/bridge-full-img.jpg', + header: 'Use your own judgment', + text: 'Copilot can make mistakes so remember to verify the results. To help improve the experience, please share your feedback with us.', + }, +]; + +const getAnnouncement: CarouselAnnouncerFunction = (index: number, totalSlides: number, slideGroupList: number[][]) => { + console.log(`Carousel slide ${index + 1} of ${totalSlides}, ${PAGES[index].header}`); + return `Carousel slide ${index + 1} of ${totalSlides}, ${PAGES[index].header}`; +}; + +export const CarouselFirstRunExperience = () => { + const styles = useStyles(); + const [activeIndex, setActiveIndex] = React.useState(0); + const [open, setModalOpen] = React.useState(false); + const totalPages = PAGES.length; + + const setPage = (page: number) => { + if (page < 0 || page >= totalPages) { + setModalOpen(false); + return; + } + setActiveIndex(page); + }; + // NearButton and FarButton are function components that handle navigation and focus management + const NearButton = () => ( + + ); + + const FarButton = () => ( + + ); + + return ( + { + if (data.open) { + // Reset on open (avoid changing carousel values while Modal is closed) + console.log('Set active index on open:'); + setActiveIndex(0); + // You could restore the previous page on open here to persist state instead + // requestAnimationFrame(() => { + // setActiveIndex(1); + // }); + } + setModalOpen(data.open); + }} + > + + + + + setActiveIndex(data.index)} + > + + {PAGES.map((page, index) => ( + + {page.imgSrc} +

+ {page.header} +

+ {page.text} +
+ ))} +
+
+ {NearButton()} + + {index => } + + {FarButton()} +
+
+
+
+ ); +}; diff --git a/packages/react-components/react-carousel/stories/src/Carousel/index.stories.tsx b/packages/react-components/react-carousel/stories/src/Carousel/index.stories.tsx index 2d7afd762676b..42e651e9e0e34 100644 --- a/packages/react-components/react-carousel/stories/src/Carousel/index.stories.tsx +++ b/packages/react-components/react-carousel/stories/src/Carousel/index.stories.tsx @@ -19,6 +19,7 @@ export { Controlled } from './CarouselControlled.stories'; export { ImageSlideshow } from './CarouselImageBox.stories'; export { AlignmentAndWhitespace } from './CarouselActionCards.stories'; export { Autoplay } from './CarouselAutoplay.stories'; +export { CarouselFirstRunExperience } from './CarouselFirstRunExperience.stories'; export default { title: 'Components/Carousel', diff --git a/yarn.lock b/yarn.lock index 4cbf618c77aaf..a26641d920cf0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10283,6 +10283,11 @@ embla-carousel-autoplay@8.3.0, embla-carousel-autoplay@^8.3.0: resolved "https://registry.yarnpkg.com/embla-carousel-autoplay/-/embla-carousel-autoplay-8.3.0.tgz#2878e7c67c7c6f5c4cb0a06a8cb06e53d8f32f2f" integrity sha512-h7DFJLf9uQD+XDxr1NwA3/oFIjsnj/iED2RjET5u6/svMec46IbF1CYPhmB5Q/1Fc0WkcvhPpsEsrtVXQLxNzA== +embla-carousel-fade@8.3.0, embla-carousel-fade@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/embla-carousel-fade/-/embla-carousel-fade-8.3.0.tgz#44be8f2c00a771828bd02078fed26bce005d1f7a" + integrity sha512-m0NbkNPTAr6ghINhJrCnI0BRgWWoGRIGUd1tYCxTK00Exm9+kzOVL5KBPkrMVzXRXHe6TRgkmsCkb/7npfwRFQ== + embla-carousel@8.3.0, embla-carousel@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/embla-carousel/-/embla-carousel-8.3.0.tgz#dc27c63c405aa98320cb36893e4be2fbdc787ee1" From c638308f6bbf02c4371d14b964118466b0a2ff5b Mon Sep 17 00:00:00 2001 From: Mitch-At-Work Date: Mon, 7 Oct 2024 16:32:46 -0700 Subject: [PATCH 2/6] Change file --- ...eact-carousel-973e8fc6-d327-490f-a135-a9100a53033c.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-react-carousel-973e8fc6-d327-490f-a135-a9100a53033c.json diff --git a/change/@fluentui-react-carousel-973e8fc6-d327-490f-a135-a9100a53033c.json b/change/@fluentui-react-carousel-973e8fc6-d327-490f-a135-a9100a53033c.json new file mode 100644 index 0000000000000..012227e05d072 --- /dev/null +++ b/change/@fluentui-react-carousel-973e8fc6-d327-490f-a135-a9100a53033c.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feat: Add fade motion to carousel as an optional prop", + "packageName": "@fluentui/react-carousel", + "email": "mifraser@microsoft.com", + "dependentChangeType": "patch" +} From 1af7694e00c50e574daf98a658de58602a42087c Mon Sep 17 00:00:00 2001 From: Mitch-At-Work Date: Mon, 7 Oct 2024 17:12:08 -0700 Subject: [PATCH 3/6] Update API --- .../react-carousel/library/etc/react-carousel.api.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-components/react-carousel/library/etc/react-carousel.api.md b/packages/react-components/react-carousel/library/etc/react-carousel.api.md index 6b7207403ee73..bc5c22d59b733 100644 --- a/packages/react-components/react-carousel/library/etc/react-carousel.api.md +++ b/packages/react-components/react-carousel/library/etc/react-carousel.api.md @@ -212,6 +212,7 @@ export type CarouselProps = ComponentProps & { groupSize?: number | 'auto'; draggable?: boolean; whitespace?: boolean; + fade?: boolean; announcement?: CarouselAnnouncerFunction; }; From 688ca23d2a1870c6daa62a53a187bc5c73aaac67 Mon Sep 17 00:00:00 2001 From: Mitch-At-Work Date: Tue, 8 Oct 2024 13:52:24 -0700 Subject: [PATCH 4/6] Add fade memo hook --- .../react-carousel/library/src/components/useEmblaCarousel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts b/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts index 50d8a7bf424ba..a30aa728df663 100644 --- a/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts +++ b/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts @@ -177,7 +177,7 @@ export function useEmblaCarousel( } }, }; - }, [setActiveIndex]); + }, [setActiveIndex, fade]); const carouselApi = React.useMemo( () => ({ From d1b66431155b3801a8602b871f7eaa890c7d3352 Mon Sep 17 00:00:00 2001 From: Mitch-At-Work Date: Thu, 10 Oct 2024 11:46:14 -0700 Subject: [PATCH 5/6] PR Comments --- .../library/etc/react-carousel.api.md | 2 +- .../src/components/Carousel/Carousel.types.ts | 7 +- .../src/components/Carousel/useCarousel.ts | 4 +- .../src/components/useEmblaCarousel.ts | 65 ++++++++----------- .../CarouselFirstRunExperience.stories.tsx | 30 ++++----- 5 files changed, 50 insertions(+), 58 deletions(-) diff --git a/packages/react-components/react-carousel/library/etc/react-carousel.api.md b/packages/react-components/react-carousel/library/etc/react-carousel.api.md index bc5c22d59b733..7a1cc87364999 100644 --- a/packages/react-components/react-carousel/library/etc/react-carousel.api.md +++ b/packages/react-components/react-carousel/library/etc/react-carousel.api.md @@ -212,7 +212,7 @@ export type CarouselProps = ComponentProps & { groupSize?: number | 'auto'; draggable?: boolean; whitespace?: boolean; - fade?: boolean; + motion?: CarouselMotion; announcement?: CarouselAnnouncerFunction; }; diff --git a/packages/react-components/react-carousel/library/src/components/Carousel/Carousel.types.ts b/packages/react-components/react-carousel/library/src/components/Carousel/Carousel.types.ts index 945dbaebd455c..13503bb2f9b95 100644 --- a/packages/react-components/react-carousel/library/src/components/Carousel/Carousel.types.ts +++ b/packages/react-components/react-carousel/library/src/components/Carousel/Carousel.types.ts @@ -10,6 +10,11 @@ export type CarouselSlots = { */ export type CarouselAnnouncerFunction = (index: number, totalSlides: number, slideGroupList: number[][]) => string; +/** + * List of integrated motion types + */ +export type CarouselMotion = 'slide' | 'fade'; + /** * Carousel Props */ @@ -61,7 +66,7 @@ export type CarouselProps = ComponentProps & { * Sets motion to fade in/out style with minimal movement * Defaults: false */ - fade?: boolean; + motion?: CarouselMotion; /** * Localizes the string used to announce carousel page changes diff --git a/packages/react-components/react-carousel/library/src/components/Carousel/useCarousel.ts b/packages/react-components/react-carousel/library/src/components/Carousel/useCarousel.ts index 80d79823b8ef1..10bed09ae8b39 100644 --- a/packages/react-components/react-carousel/library/src/components/Carousel/useCarousel.ts +++ b/packages/react-components/react-carousel/library/src/components/Carousel/useCarousel.ts @@ -33,7 +33,7 @@ export function useCarousel_unstable(props: CarouselProps, ref: React.Ref { diff --git a/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts b/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts index a30aa728df663..9bcbab852be67 100644 --- a/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts +++ b/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts @@ -4,7 +4,7 @@ import * as React from 'react'; import { carouselCardClassNames } from './CarouselCard/useCarouselCardStyles.styles'; import { carouselSliderClassNames } from './CarouselSlider/useCarouselSliderStyles.styles'; -import { CarouselUpdateData, CarouselVisibilityEventDetail } from '../Carousel'; +import { CarouselMotion, CarouselUpdateData, CarouselVisibilityEventDetail } from '../Carousel'; import Autoplay from 'embla-carousel-autoplay'; import Fade from 'embla-carousel-fade'; @@ -39,10 +39,10 @@ export function useEmblaCarousel( options: Pick & { defaultActiveIndex: number | undefined; activeIndex: number | undefined; - fade?: boolean; + motion?: CarouselMotion; }, ) { - const { align, direction, loop, slidesToScroll, watchDrag, containScroll, fade } = options; + const { align, direction, loop, slidesToScroll, watchDrag, containScroll, motion } = options; const [activeIndex, setActiveIndex] = useControllableState({ defaultState: options.defaultActiveIndex, state: options.activeIndex, @@ -81,6 +81,27 @@ export function useEmblaCarousel( [resetAutoplay], ); + const getPlugins = React.useCallback(() => { + const plugins: EmblaPluginType[] = [ + Autoplay({ + playOnInit: autoplayRef.current, + stopOnInteraction: !autoplayRef.current, + stopOnMouseEnter: true, + stopOnFocusIn: true, + rootNode: (emblaRoot: HTMLElement) => { + return emblaRoot.querySelector(sliderClassname) ?? emblaRoot; + }, + }), + ]; + + // Optionally add Fade plugin + if (motion === 'fade') { + plugins.push(Fade()); + } + + return plugins; + }, [motion]); + // Listeners contains callbacks for UI elements that may require state update based on embla changes const listeners = React.useRef(new Set<(data: CarouselUpdateData) => void>()); const subscribeForValues = React.useCallback((listener: (data: CarouselUpdateData) => void) => { @@ -134,22 +155,7 @@ export function useEmblaCarousel( }); }; - const plugins: EmblaPluginType[] = [ - Autoplay({ - playOnInit: autoplayRef.current, - stopOnInteraction: !autoplayRef.current, - stopOnMouseEnter: true, - stopOnFocusIn: true, - rootNode: (emblaRoot: HTMLElement) => { - return emblaRoot.querySelector(sliderClassname) ?? emblaRoot; - }, - }), - ]; - - // Optionally add Fade plugin - if (fade) { - plugins.push(Fade()); - } + const plugins = getPlugins(); return { set current(newElement: HTMLDivElement | null) { @@ -177,7 +183,7 @@ export function useEmblaCarousel( } }, }; - }, [setActiveIndex, fade]); + }, [getPlugins, setActiveIndex]); const carouselApi = React.useMemo( () => ({ @@ -218,22 +224,7 @@ export function useEmblaCarousel( }, [activeIndex]); React.useEffect(() => { - const plugins: EmblaPluginType[] = [ - Autoplay({ - playOnInit: autoplayRef.current, - stopOnInteraction: !autoplayRef.current, - stopOnMouseEnter: true, - stopOnFocusIn: true, - rootNode: (emblaRoot: HTMLElement) => { - return emblaRoot.querySelector(sliderClassname) ?? emblaRoot; - }, - }), - ]; - - // Optionally add Fade plugin - if (fade) { - plugins.push(Fade()); - } + const plugins = getPlugins(); emblaOptions.current = { align, direction, loop, slidesToScroll, watchDrag, containScroll }; emblaApi.current?.reInit( @@ -243,7 +234,7 @@ export function useEmblaCarousel( }, plugins, ); - }, [align, direction, loop, slidesToScroll, watchDrag, containScroll, fade]); + }, [align, direction, loop, slidesToScroll, watchDrag, containScroll, getPlugins]); return { activeIndex, diff --git a/packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx b/packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx index ed76acde4e2bc..4c0f0d0e7d755 100644 --- a/packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx +++ b/packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx @@ -16,6 +16,7 @@ import { tokens, typographyStyles, } from '@fluentui/react-components'; +import { useEffect } from 'react'; const useStyles = makeStyles({ surface: { @@ -47,12 +48,14 @@ const useStyles = makeStyles({ const PAGES = [ { + id: 'Copilot-page-1', alt: 'Copilot logo', imgSrc: 'https://fabricweb.azureedge.net/fabric-website/assets/images/swatch-picker/sea-full-img.jpg', header: 'Discover Copilot, a whole new way to work', text: 'Explore new ways to work smarter and faster using the power of AI. Copilot in [Word] can help you [get started from scratch], [work from an existing file], [get actionable insights about documents], and more.', }, { + id: 'Copilot-page-2', alt: 'Copilot logo 2', imgSrc: 'https://fabricweb.azureedge.net/fabric-website/assets/images/swatch-picker/bridge-full-img.jpg', header: 'Use your own judgment', @@ -89,22 +92,15 @@ export const CarouselFirstRunExperience = () => { ); + useEffect(() => { + // Reset or initialize page on open if nessecary + if (open) { + setActiveIndex(0); + } + }, [open]); + return ( - { - if (data.open) { - // Reset on open (avoid changing carousel values while Modal is closed) - console.log('Set active index on open:'); - setActiveIndex(0); - // You could restore the previous page on open here to persist state instead - // requestAnimationFrame(() => { - // setActiveIndex(1); - // }); - } - setModalOpen(data.open); - }} - > + setModalOpen(data.open)}> @@ -115,12 +111,12 @@ export const CarouselFirstRunExperience = () => { circular announcement={getAnnouncement} activeIndex={activeIndex} - fade + motion="fade" onActiveIndexChange={(e, data) => setActiveIndex(data.index)} > {PAGES.map((page, index) => ( - + {page.imgSrc}

{page.header} From 247b578cf3eb69c5cc41605e783bc72204f91a03 Mon Sep 17 00:00:00 2001 From: Mitch-At-Work Date: Thu, 10 Oct 2024 13:07:47 -0700 Subject: [PATCH 6/6] Remove console log --- .../stories/src/Carousel/CarouselFirstRunExperience.stories.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx b/packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx index 4c0f0d0e7d755..1a6506732813d 100644 --- a/packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx +++ b/packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx @@ -64,7 +64,6 @@ const PAGES = [ ]; const getAnnouncement: CarouselAnnouncerFunction = (index: number, totalSlides: number, slideGroupList: number[][]) => { - console.log(`Carousel slide ${index + 1} of ${totalSlides}, ${PAGES[index].header}`); return `Carousel slide ${index + 1} of ${totalSlides}, ${PAGES[index].header}`; };