UNPKG

@transkripid/flowbite-react

Version:

Official React components built for Flowbite and Tailwind CSS - Transkrip.id fork

1 lines 13.1 kB
{"version":3,"file":"Carousel.mjs","sources":["../../../src/components/Carousel/Carousel.tsx"],"sourcesContent":["'use client';\n\nimport type { ComponentProps, FC, ReactElement, ReactNode } from 'react';\nimport { Children, cloneElement, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { HiOutlineChevronLeft, HiOutlineChevronRight } from 'react-icons/hi';\nimport ScrollContainer from 'react-indiana-drag-scroll';\nimport { twMerge } from 'tailwind-merge';\nimport { isClient } from '../../helpers/is-client';\nimport { mergeDeep } from '../../helpers/merge-deep';\nimport { getTheme } from '../../theme-store';\nimport type { DeepPartial } from '../../types';\nimport type { FlowbiteBoolean } from '../Flowbite';\n\nexport interface FlowbiteCarouselTheme {\n root: FlowbiteCarouselRootTheme;\n indicators: FlowbiteCarouselIndicatorsTheme;\n item: FlowbiteCarouselItemTheme;\n control: FlowbiteCarouselControlTheme;\n scrollContainer: FlowbiteCarouselScrollContainer;\n}\n\nexport interface FlowbiteCarouselRootTheme {\n base: string;\n leftControl: string;\n rightControl: string;\n}\n\nexport interface FlowbiteCarouselIndicatorsTheme {\n active: FlowbiteBoolean;\n base: string;\n wrapper: string;\n}\n\nexport interface FlowbiteCarouselItemTheme {\n base: string;\n wrapper: FlowbiteBoolean;\n}\n\nexport interface FlowbiteCarouselControlTheme {\n base: string;\n icon: string;\n}\n\nexport interface FlowbiteCarouselScrollContainer {\n base: string;\n snap: string;\n}\n\nexport interface CarouselProps extends ComponentProps<'div'> {\n indicators?: boolean;\n leftControl?: ReactNode;\n rightControl?: ReactNode;\n draggable?: boolean;\n slide?: boolean;\n slideInterval?: number;\n theme?: DeepPartial<FlowbiteCarouselTheme>;\n onSlideChange?: (slide: number) => void;\n pauseOnHover?: boolean;\n}\n\nexport interface DefaultLeftRightControlProps extends ComponentProps<'div'> {\n theme?: DeepPartial<FlowbiteCarouselTheme>;\n}\n\nexport const Carousel: FC<CarouselProps> = ({\n children,\n indicators = true,\n leftControl,\n rightControl,\n slide = true,\n draggable = true,\n slideInterval,\n className,\n theme: customTheme = {},\n onSlideChange = null,\n pauseOnHover = false,\n ...props\n}) => {\n const theme = mergeDeep(getTheme().carousel, customTheme);\n\n const isDeviceMobile = isClient() && navigator.userAgent.indexOf('IEMobile') !== -1;\n const carouselContainer = useRef<HTMLDivElement>(null);\n const [activeItem, setActiveItem] = useState(0);\n const [isDragging, setIsDragging] = useState(false);\n const [isHovering, setIsHovering] = useState(false);\n\n const didMountRef = useRef(false);\n\n const items = useMemo(\n () =>\n Children.map(children as ReactElement[], (child: ReactElement) =>\n cloneElement(child, {\n className: twMerge(theme.item.base, child.props.className),\n }),\n ),\n [children, theme.item.base],\n );\n\n const navigateTo = useCallback(\n (item: number) => () => {\n if (!items) return;\n item = (item + items.length) % items.length;\n if (carouselContainer.current) {\n carouselContainer.current.scrollLeft = carouselContainer.current.clientWidth * item;\n }\n setActiveItem(item);\n },\n [items],\n );\n\n useEffect(() => {\n if (carouselContainer.current && !isDragging && carouselContainer.current.scrollLeft !== 0) {\n setActiveItem(Math.round(carouselContainer.current.scrollLeft / carouselContainer.current.clientWidth));\n }\n }, [isDragging]);\n\n useEffect(() => {\n if (slide && !(pauseOnHover && isHovering)) {\n const intervalId = setInterval(() => !isDragging && navigateTo(activeItem + 1)(), slideInterval ?? 3000);\n\n return () => clearInterval(intervalId);\n }\n }, [activeItem, isDragging, navigateTo, slide, slideInterval, pauseOnHover, isHovering]);\n\n useEffect(() => {\n if (didMountRef.current) {\n onSlideChange && onSlideChange(activeItem);\n } else {\n didMountRef.current = true;\n }\n }, [onSlideChange, activeItem]);\n\n const handleDragging = (dragging: boolean) => () => setIsDragging(dragging);\n\n const setHoveringTrue = useCallback(() => setIsHovering(true), [setIsHovering]);\n const setHoveringFalse = useCallback(() => setIsHovering(false), [setIsHovering]);\n\n return (\n <div\n className={twMerge(theme.root.base, className)}\n data-testid=\"carousel\"\n onMouseEnter={setHoveringTrue}\n onMouseLeave={setHoveringFalse}\n onTouchStart={setHoveringTrue}\n onTouchEnd={setHoveringFalse}\n {...props}\n >\n <ScrollContainer\n className={twMerge(theme.scrollContainer.base, (isDeviceMobile || !isDragging) && theme.scrollContainer.snap)}\n draggingClassName=\"cursor-grab\"\n innerRef={carouselContainer}\n onEndScroll={handleDragging(false)}\n onStartScroll={handleDragging(draggable)}\n vertical={false}\n horizontal={draggable}\n >\n {items?.map((item, index) => (\n <div\n key={index}\n className={theme.item.wrapper[draggable ? 'on' : 'off']}\n data-active={activeItem === index}\n data-testid=\"carousel-item\"\n >\n {item}\n </div>\n ))}\n </ScrollContainer>\n {indicators && (\n <div className={theme.indicators.wrapper}>\n {items?.map((_, index) => (\n <button\n key={index}\n className={twMerge(theme.indicators.base, theme.indicators.active[index === activeItem ? 'on' : 'off'])}\n onClick={navigateTo(index)}\n data-testid=\"carousel-indicator\"\n aria-label={`Slide ${index + 1}`}\n />\n ))}\n </div>\n )}\n\n {items && (\n <>\n <div className={theme.root.leftControl}>\n <button\n className=\"group\"\n data-testid=\"carousel-left-control\"\n onClick={navigateTo(activeItem - 1)}\n type=\"button\"\n aria-label=\"Previous slide\"\n >\n {leftControl ? leftControl : <DefaultLeftControl theme={customTheme} />}\n </button>\n </div>\n <div className={theme.root.rightControl}>\n <button\n className=\"group\"\n data-testid=\"carousel-right-control\"\n onClick={navigateTo(activeItem + 1)}\n type=\"button\"\n aria-label=\"Next slide\"\n >\n {rightControl ? rightControl : <DefaultRightControl theme={customTheme} />}\n </button>\n </div>\n </>\n )}\n </div>\n );\n};\n\nconst DefaultLeftControl: FC<DefaultLeftRightControlProps> = ({ theme: customTheme = {} }) => {\n const theme = mergeDeep(getTheme().carousel, customTheme);\n return (\n <span className={theme.control.base}>\n <HiOutlineChevronLeft className={theme.control.icon} />\n </span>\n );\n};\n\nconst DefaultRightControl: FC<DefaultLeftRightControlProps> = ({ theme: customTheme = {} }) => {\n const theme = mergeDeep(getTheme().carousel, customTheme);\n return (\n <span className={theme.control.base}>\n <HiOutlineChevronRight className={theme.control.icon} />\n </span>\n );\n};\n\nCarousel.displayName = 'Carousel';\n"],"names":["Carousel","children","indicators","leftControl","rightControl","slide","draggable","slideInterval","className","theme","customTheme","onSlideChange","pauseOnHover","props","mergeDeep","getTheme","carousel","isDeviceMobile","isClient","navigator","userAgent","indexOf","carouselContainer","useRef","activeItem","setActiveItem","useState","isDragging","setIsDragging","isHovering","setIsHovering","didMountRef","items","useMemo","Children","map","child","cloneElement","twMerge","item","base","navigateTo","useCallback","length","current","scrollLeft","clientWidth","useEffect","Math","round","intervalId","setInterval","clearInterval","handleDragging","dragging","setHoveringTrue","setHoveringFalse","jsxs","root","jsx","ScrollContainer","scrollContainer","snap","index","wrapper","_","active","Fragment","DefaultLeftControl","DefaultRightControl","t0","$","_c","t1","t2","undefined","t3","t4","control","icon","HiOutlineChevronLeft","t5","HiOutlineChevronRight","displayName"],"mappings":"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"}