From 969a3e569e7e64f8f31b15a192373898e73a6366 Mon Sep 17 00:00:00 2001 From: Vitaly Rtishchev Date: Fri, 12 Aug 2022 17:44:37 +0300 Subject: [PATCH] [@mantine/carousel] Add dynamic slides handling (#2074) --- src/mantine-carousel/src/Carousel.story.tsx | 25 ++++++++++++++++++++- src/mantine-carousel/src/Carousel.tsx | 13 ++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/mantine-carousel/src/Carousel.story.tsx b/src/mantine-carousel/src/Carousel.story.tsx index 2370d4d0b85..d42bbcebfbf 100644 --- a/src/mantine-carousel/src/Carousel.story.tsx +++ b/src/mantine-carousel/src/Carousel.story.tsx @@ -1,4 +1,5 @@ -import React, { useRef } from 'react'; +import React, { useRef, useState } from 'react'; +import { Button } from '@mantine/core'; import Autoplay from 'embla-carousel-autoplay'; import { Carousel } from './Carousel'; @@ -70,3 +71,25 @@ export function AutoPlay() { ); } + +export function DynamicSlides() { + const [count, setCount] = useState(1); + + const _slides = Array(count) + .fill(0) + .map((_, index) => ( + + {index} + + )); + + return ( +
+ + {_slides} + + + +
+ ); +} diff --git a/src/mantine-carousel/src/Carousel.tsx b/src/mantine-carousel/src/Carousel.tsx index 225a0bafbdf..109b4831ae3 100644 --- a/src/mantine-carousel/src/Carousel.tsx +++ b/src/mantine-carousel/src/Carousel.tsx @@ -1,5 +1,5 @@ /* eslint-disable react/no-unused-prop-types */ -import React, { forwardRef, useEffect, useCallback, useState } from 'react'; +import React, { forwardRef, useEffect, useCallback, useState, Children } from 'react'; import { useComponentDefaultProps, Box, @@ -10,6 +10,7 @@ import { StylesApiProvider, Selectors, } from '@mantine/core'; +import { clamp } from '@mantine/hooks'; import useEmblaCarousel, { EmblaPluginType } from 'embla-carousel-react'; import { ForwardRefWithStaticComponents } from '@mantine/utils'; import { CarouselSlide, CarouselSlideStylesNames } from './CarouselSlide/CarouselSlide'; @@ -231,6 +232,16 @@ export const _Carousel = forwardRef((props, ref) return undefined; }, [embla]); + useEffect(() => { + if (embla) { + embla.reInit(); + setSlidesCount(embla.scrollSnapList().length); + setSelected((currentSelected) => + clamp(currentSelected, 0, Children.toArray(children).length - 1) + ); + } + }, [Children.toArray(children).length]); + const canScrollPrev = embla?.canScrollPrev() || false; const canScrollNext = embla?.canScrollNext() || false;