Merged in feat/SW-1542-carousel-functionality (pull request #1311)
feat(SW-1542): Carousel component * feat(SW-1542): add Embla Carousel component and use in CarouselCards * fix(SW-1542): remove max-width constraint for card on ipad * fix(SW-1542): Add padding to start page content container * refactor(SW-1542): Improve Embla Carousel type imports * refactor(SW-1542): Remove unnecessary carousel wrapper div * refactor(SW-1542): Modularize Carousel component structure * refactor(SW-1542): Remove carousel dots display * feat(SW-1542): Add carousel dots navigation * refactor(SW-1542): Update Carousel component styling and types * refactor(SW-1542): Remove uneeded useCallback from Carousel navigation methods * refactor(SW-1542): Modify CarouselContextProps type to exclude className * refactor(SW-1542): Optimize React imports in Carousel components * refactor(SW-1542): Consolidate Carousel component and remove CarouselRoot * refactor(SW-1542): Update Carousel navigation methods to use function-based scroll checks * refactor(SW-1542): Add explicit children prop support to CarouselContent component * refactor(SW-1542): Add children prop support to CarouselItem component Approved-by: Christian Andolf
This commit is contained in:
45
components/Carousel/CarouselDots.tsx
Normal file
45
components/Carousel/CarouselDots.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
"use client"
|
||||
|
||||
import { cx } from "class-variance-authority"
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
import { useCarousel } from "./CarouselContext"
|
||||
|
||||
import styles from "./carousel.module.css"
|
||||
|
||||
export function CarouselDots({ className }: { className?: string }) {
|
||||
const { selectedIndex, api } = useCarousel()
|
||||
const [scrollSnaps, setScrollSnaps] = useState<number[]>([])
|
||||
|
||||
// Update scroll snaps when the carousel is initialized or viewport changes
|
||||
useEffect(() => {
|
||||
if (!api) return
|
||||
|
||||
const onInit = () => {
|
||||
setScrollSnaps(api.scrollSnapList())
|
||||
}
|
||||
|
||||
onInit()
|
||||
api.on("reInit", onInit)
|
||||
|
||||
return () => {
|
||||
api.off("reInit", onInit)
|
||||
}
|
||||
}, [api])
|
||||
|
||||
// Don't render dots if we have 1 or fewer scroll positions
|
||||
if (scrollSnaps.length <= 1) return null
|
||||
|
||||
return (
|
||||
<div className={cx(styles.dots, className)}>
|
||||
{scrollSnaps.map((_, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={styles.dot}
|
||||
data-active={index === selectedIndex}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user