diff --git a/change/@fluentui-react-carousel-bf44df36-9898-4ce0-b4d5-decf3c170b35.json b/change/@fluentui-react-carousel-bf44df36-9898-4ce0-b4d5-decf3c170b35.json new file mode 100644 index 00000000000000..92ee57d5223b9d --- /dev/null +++ b/change/@fluentui-react-carousel-bf44df36-9898-4ce0-b4d5-decf3c170b35.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix: autoplay carousel does not trigger live region announcements", + "packageName": "@fluentui/react-carousel", + "email": "sarah.higley@microsoft.com", + "dependentChangeType": "patch" +} 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 1f61ea71e13a9e..00439663bca229 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 @@ -6,10 +6,11 @@ import { useIsomorphicLayoutEffect, useMergedRefs, } from '@fluentui/react-utilities'; +import type { EventHandler } from '@fluentui/react-utilities'; import * as React from 'react'; import type { CarouselProps, CarouselState } from './Carousel.types'; -import type { CarouselContextValue } from '../CarouselContext.types'; +import type { CarouselContextValue, CarouselIndexChangeData } from '../CarouselContext.types'; import { useEmblaCarousel } from '../useEmblaCarousel'; import { useAnnounce } from '@fluentui/react-shared-contexts'; @@ -37,6 +38,12 @@ export function useCarousel_unstable(props: CarouselProps, ref: React.Ref = useEventCallback((event, data) => { + onActiveIndexChange?.(event, data); + updateAnnouncement(data.index); + }); + const { activeIndex, carouselApi, containerRef, viewportRef, subscribeForValues, enableAutoplay, resetAutoplay } = useEmblaCarousel({ align, @@ -48,27 +55,25 @@ export function useCarousel_unstable(props: CarouselProps, ref: React.Ref { const foundIndex = carouselApi.scrollToElement(element, jump); - onActiveIndexChange?.(event, { event, type: 'focus', index: foundIndex }); + onCarouselIndexChange?.(event, { event, type: 'focus', index: foundIndex }); return foundIndex; }); const selectPageByIndex: CarouselContextValue['selectPageByIndex'] = useEventCallback((event, index, jump) => { carouselApi.scrollToIndex(index, jump); - - onActiveIndexChange?.(event, { event, type: 'click', index }); + onCarouselIndexChange?.(event, { event, type: 'click', index }); }); const selectPageByDirection: CarouselContextValue['selectPageByDirection'] = useEventCallback((event, direction) => { const nextPageIndex = carouselApi.scrollInDirection(direction); - onActiveIndexChange?.(event, { event, type: 'click', index: nextPageIndex }); - + onCarouselIndexChange?.(event, { event, type: 'click', index: nextPageIndex }); return nextPageIndex; }); @@ -81,13 +86,13 @@ export function useCarousel_unstable(props: CarouselProps, ref: React.Ref { + const updateAnnouncement = useEventCallback((newIndex: number) => { if (totalNavLength.current <= 0 || !announcement) { // Ignore announcements until slides discovered return; } - const announcementText = announcement(activeIndex, totalNavLength.current, navGroupRef.current); + const announcementText = announcement(newIndex, totalNavLength.current, navGroupRef.current); if (announcementText !== announcementTextRef.current) { announcementTextRef.current = announcementText; @@ -105,14 +110,10 @@ export function useCarousel_unstable(props: CarouselProps, ref: React.Ref { - updateAnnouncement(); - }, [activeIndex, updateAnnouncement]); - return { components: { root: 'div',