Files
web/components/Carousel/CarouselDots.tsx
Chuma Mcphoy (We Ahead) 38cce4b136 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
2025-02-14 10:53:14 +00:00

46 lines
1.1 KiB
TypeScript

"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>
)
}