@@ -14,10 +14,12 @@ import {
1414 isImageSlide ,
1515 makeInertWhen ,
1616 parseLengthPercentage ,
17+ translateLabel ,
18+ translateSlideCounter ,
1719} from "../utils.js" ;
1820import { ImageSlide } from "../components/index.js" ;
1921import { useController } from "./Controller/index.js" ;
20- import { useDocumentContext , useLightboxProps , useLightboxState } from "../contexts/index.js" ;
22+ import { useA11yContext , useDocumentContext , useLightboxProps , useLightboxState } from "../contexts/index.js" ;
2123import { CLASS_FLEX_CENTER , CLASS_SLIDE , MODULE_CAROUSEL } from "../consts.js" ;
2224
2325function cssPrefix ( value ?: string ) {
@@ -36,13 +38,14 @@ type CarouselSlideProps = {
3638function CarouselSlide ( { slide, offset } : CarouselSlideProps ) {
3739 const containerRef = React . useRef < HTMLDivElement > ( null ) ;
3840
39- const { currentIndex } = useLightboxState ( ) ;
41+ const { currentIndex, slides } = useLightboxState ( ) ;
4042 const { slideRect, focus } = useController ( ) ;
4143 const {
4244 render,
4345 carousel : { imageFit, imageProps } ,
4446 on : { click : onClick } ,
4547 styles : { slide : style } ,
48+ labels,
4649 } = useLightboxProps ( ) ;
4750 const { getOwnerDocument } = useDocumentContext ( ) ;
4851
@@ -90,8 +93,9 @@ function CarouselSlide({ slide, offset }: CarouselSlideProps) {
9093 ) }
9194 { ...makeInertWhen ( offscreen ) }
9295 style = { style }
93- role = "region"
94- aria-roledescription = "slide"
96+ role = "group"
97+ aria-roledescription = { translateLabel ( labels , "Slide" ) }
98+ aria-label = { translateSlideCounter ( labels , slides , currentIndex + offset ) }
9599 >
96100 { renderSlide ( ) }
97101 </ div >
@@ -103,9 +107,10 @@ function Placeholder() {
103107 return < div className = { cssClass ( CLASS_SLIDE ) } style = { style } /> ;
104108}
105109
106- export function Carousel ( { carousel } : ComponentProps ) {
110+ export function Carousel ( { carousel, labels } : ComponentProps ) {
107111 const { slides, currentIndex, globalIndex } = useLightboxState ( ) ;
108112 const { setCarouselRef } = useController ( ) ;
113+ const { autoPlaying, focusWithin } = useA11yContext ( ) ;
109114
110115 const spacingValue = parseLengthPercentage ( carousel . spacing ) ;
111116 const paddingValue = parseLengthPercentage ( carousel . padding ) ;
@@ -142,6 +147,10 @@ export function Carousel({ carousel }: ComponentProps) {
142147 [ `${ cssVar ( cssPrefix ( "padding_px" ) ) } ` ] : paddingValue . pixel || 0 ,
143148 [ `${ cssVar ( cssPrefix ( "padding_percent" ) ) } ` ] : paddingValue . percent || 0 ,
144149 } }
150+ role = "region"
151+ aria-live = { autoPlaying && ! focusWithin ? "off" : "polite" }
152+ aria-roledescription = { translateLabel ( labels , "Carousel" ) }
153+ aria-label = { translateLabel ( labels , "Photo gallery" ) }
145154 >
146155 { items . map ( ( { key, slide, offset } ) =>
147156 slide ? < CarouselSlide key = { key } slide = { slide } offset = { offset } /> : < Placeholder key = { key } /> ,
0 commit comments