Skip to content

Commit 914ee93

Browse files
Carousel: Ensure buttons are disabled if not enough content to loop (#34427)
1 parent 8edf93c commit 914ee93

File tree

4 files changed

+20
-1
lines changed

4 files changed

+20
-1
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "fix: Ensure buttons are disabled when not enough content for circular",
4+
"packageName": "@fluentui/react-carousel",
5+
"email": "mifraser@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}

packages/react-components/react-carousel/library/src/components/Carousel/Carousel.types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,8 @@ export interface CarouselUpdateData {
121121
* An array of the card DOM elements after render
122122
*/
123123
slideNodes: HTMLElement[];
124+
/**
125+
* Whether the carousel has enough cards present to enable looping without issues.
126+
*/
127+
canLoop?: boolean;
124128
}

packages/react-components/react-carousel/library/src/components/CarouselButton/useCarouselButton.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,14 @@ export const useCarouselButton_unstable = (
3737
const { dir } = useFluent();
3838
const buttonRef = React.useRef<HTMLButtonElement>();
3939
const circular = useCarouselContext(ctx => ctx.circular);
40+
const [canLoop, setCanLoop] = React.useState(circular);
4041
const containerRef = useCarouselContext(ctx => ctx.containerRef);
4142
const selectPageByDirection = useCarouselContext(ctx => ctx.selectPageByDirection);
4243
const subscribeForValues = useCarouselContext(ctx => ctx.subscribeForValues);
4344
const resetAutoplay = useCarouselContext(ctx => ctx.resetAutoplay);
4445

4546
const isTrailing = useCarouselContext(ctx => {
46-
if (circular) {
47+
if (circular && canLoop) {
4748
return false;
4849
}
4950

@@ -85,6 +86,10 @@ export const useCarouselButton_unstable = (
8586

8687
useIsomorphicLayoutEffect(() => {
8788
return subscribeForValues((data: CarouselUpdateData) => {
89+
if (data.canLoop !== undefined) {
90+
// Only update canLoop if it has been defined by the carousel engine
91+
setCanLoop(data.canLoop);
92+
}
8893
setTotalSlides(data.navItemsCount);
8994
});
9095
}, [subscribeForValues]);

packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,14 @@ export function useEmblaCarousel(
172172
const nodes: HTMLElement[] = emblaApi.current?.slideNodes() ?? [];
173173
const groupIndexList: number[][] = emblaApi.current?.internalEngine().slideRegistry ?? [];
174174
const navItemsCount = groupIndexList.length > 0 ? groupIndexList.length : nodes.length;
175+
const canLoop = emblaApi.current?.internalEngine().slideLooper.canLoop();
176+
175177
const data: CarouselUpdateData = {
176178
navItemsCount,
177179
activeIndex: emblaApi.current?.selectedScrollSnap() ?? 0,
178180
groupIndexList,
179181
slideNodes: nodes,
182+
canLoop,
180183
};
181184

182185
updateIndex();

0 commit comments

Comments
 (0)