nuka-carousel
Version:
Pure React Carousel
1 lines • 31 kB
Source Map (JSON)
{"version":3,"sources":["../src/hooks/use-carousel.tsx","../src/Carousel/Carousel.tsx","../src/hooks/use-interval.tsx","../src/hooks/use-paging.tsx","../src/hooks/use-measurement.tsx","../src/utils/array.ts","../src/utils/browser.ts","../src/utils/css.ts","../src/utils/mouse.ts","../src/hooks/use-resize-observer.tsx","../src/hooks/use-hover.tsx","../src/hooks/use-keyboard.tsx","../src/hooks/use-reduced-motion.tsx","../src/Carousel/NavButtons.tsx","../src/Carousel/PageIndicators.tsx","#style-inject:#style-inject","../src/Carousel/Carousel.css"],"sourcesContent":["import React, { useContext } from 'react';\n\nimport { CarouselProps } from '../types';\n\ntype CarouselContextType = CarouselProps & {\n currentPage: number;\n scrollOffset: number[];\n totalPages: number;\n goToPage: (idx: number) => void;\n goForward: () => void;\n goBack: () => void;\n};\n\nconst CarouselContext = React.createContext<CarouselContextType>(\n {} as unknown as CarouselContextType,\n);\nexport const CarouselProvider = CarouselContext.Provider;\n\nexport const useCarousel = () => {\n const context = useContext(CarouselContext);\n return context;\n};\n","import {\n MouseEvent,\n TouchEvent,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\n\nimport { useInterval } from '../hooks/use-interval';\nimport { usePaging } from '../hooks/use-paging';\nimport { useMeasurement } from '../hooks/use-measurement';\nimport { useHover } from '../hooks/use-hover';\nimport { useKeyboard } from '../hooks/use-keyboard';\nimport { useReducedMotion } from '../hooks/use-reduced-motion';\nimport { CarouselProvider } from '../hooks/use-carousel';\nimport { CarouselProps, SlideHandle } from '../types';\nimport { cls, isMouseEvent } from '../utils';\nimport { NavButtons } from './NavButtons';\nimport { PageIndicators } from './PageIndicators';\n\nimport './Carousel.css';\n\nconst defaults = {\n arrows: <NavButtons />,\n autoplay: false,\n autoplayInterval: 3000,\n dots: <PageIndicators />,\n id: 'nuka-carousel',\n keyboard: true,\n minSwipeDistance: 50,\n scrollDistance: 'screen',\n showArrows: false,\n showDots: false,\n swiping: true,\n wrapMode: 'nowrap',\n} satisfies Partial<CarouselProps>;\n\nexport const Carousel = forwardRef<SlideHandle, CarouselProps>(\n (props: CarouselProps, ref) => {\n const options = { ...defaults, ...props };\n\n const {\n afterSlide,\n arrows,\n autoplay,\n autoplayInterval,\n beforeSlide,\n children,\n className,\n dots,\n id,\n keyboard,\n minSwipeDistance,\n scrollDistance,\n showArrows,\n showDots,\n swiping,\n title,\n wrapMode,\n initialPage,\n } = options;\n\n const carouselRef = useRef<HTMLDivElement | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const previousPageRef = useRef<number>(-1);\n const arrowsContainerRef = useRef<HTMLDivElement | null>(null);\n\n // -- update page count and scroll offset based on scroll distance\n const { totalPages, scrollOffset } = useMeasurement({\n element: containerRef,\n scrollDistance,\n });\n\n // -- paging\n const { currentPage, goBack, goForward, goToPage } = usePaging({\n totalPages,\n wrapMode,\n initialPage,\n });\n\n // -- handle touch scroll events\n const [touchStart, setTouchStart] = useState<null | number>(null);\n const [touchEnd, setTouchEnd] = useState<null | number>(null);\n\n const onTouchStart = (e: MouseEvent | TouchEvent) => {\n if (!swiping) return;\n setTouchEnd(null);\n setTouchStart(isMouseEvent(e) ? e.clientX : e.targetTouches[0].clientX);\n };\n\n const onTouchMove = (e: MouseEvent | TouchEvent) => {\n if (!swiping) return;\n setTouchEnd(isMouseEvent(e) ? e.clientX : e.targetTouches[0].clientX);\n };\n\n const onTouchEnd = () => {\n if (!swiping) return;\n if (!containerRef.current) return;\n if (!touchStart || !touchEnd) return;\n\n const distance = touchStart - touchEnd;\n const isLeftSwipe = distance > minSwipeDistance;\n const isRightSwipe = distance < -minSwipeDistance;\n if (isLeftSwipe || isRightSwipe) {\n if (isLeftSwipe) {\n goForward();\n } else {\n goBack();\n }\n }\n };\n\n // -- keyboard nav\n useKeyboard({\n element: carouselRef,\n enabled: keyboard,\n goForward,\n goBack,\n });\n\n // -- forward events to ref\n useImperativeHandle(ref, () => ({ goForward, goBack, goToPage }), [\n goForward,\n goBack,\n goToPage,\n ]);\n\n // -- autoplay\n const isHovered = useHover({ element: containerRef, enabled: autoplay });\n const isArrowHovered = useHover({\n element: arrowsContainerRef,\n enabled: autoplay && showArrows === true,\n });\n const prefersReducedMotion = useReducedMotion({ enabled: autoplay });\n const autoplayEnabled =\n autoplay && !(isHovered || prefersReducedMotion || isArrowHovered);\n useInterval(goForward, autoplayInterval, autoplayEnabled);\n\n // -- scroll container when page index changes\n useEffect(() => {\n if (containerRef.current) {\n const currentSlideIndex = previousPageRef.current;\n const endSlideIndex = currentPage;\n beforeSlide && beforeSlide(currentSlideIndex, endSlideIndex);\n containerRef.current.scrollLeft = scrollOffset[currentPage];\n afterSlide && setTimeout(() => afterSlide(endSlideIndex), 0);\n previousPageRef.current = currentPage;\n if (initialPage === undefined || currentPage === initialPage) {\n containerRef.current.classList.remove('scroll-auto');\n containerRef.current.classList.add('scroll-smooth');\n }\n }\n }, [currentPage, scrollOffset, beforeSlide, afterSlide, initialPage]);\n\n const containerClassName = cls(\n 'nuka-container',\n showArrows === 'hover' && 'nuka-container-auto-hide',\n className,\n );\n\n const providerValues = {\n ...options,\n totalPages,\n currentPage,\n scrollOffset,\n goBack,\n goForward,\n goToPage,\n };\n\n return (\n <CarouselProvider value={providerValues}>\n <div\n className={containerClassName}\n aria-labelledby=\"nuka-carousel-heading\"\n tabIndex={keyboard ? 0 : undefined}\n ref={carouselRef}\n id={id}\n >\n {title && (\n <h3 id=\"nuka-carousel-heading\" className=\"nuka-hidden\">\n {title}\n </h3>\n )}\n <div className=\"nuka-slide-container\">\n <div\n className=\"nuka-overflow\"\n ref={containerRef}\n onTouchEnd={onTouchEnd}\n onTouchMove={onTouchMove}\n onTouchStart={onTouchStart}\n id=\"nuka-overflow\"\n data-testid=\"nuka-overflow\"\n style={{ touchAction: 'pan-y' }}\n >\n <div\n className=\"nuka-wrapper\"\n id=\"nuka-wrapper\"\n data-testid=\"nuka-wrapper\"\n >\n {children}\n </div>\n </div>\n {showArrows && <div ref={arrowsContainerRef}>{arrows}</div>}\n </div>\n </div>\n {showDots && dots}\n </CarouselProvider>\n );\n },\n);\n\nCarousel.displayName = 'Carousel';\n","import { useEffect, useRef } from 'react';\n\ntype CallbackFunction = (...args: never[]) => void;\n\nexport function useInterval(\n callback: CallbackFunction,\n delay: number,\n enabled = true,\n) {\n const _callback = useRef<CallbackFunction>();\n\n useEffect(() => {\n _callback.current = callback;\n }, [callback]);\n\n useEffect(() => {\n if (enabled && delay !== null) {\n const id = setInterval(() => {\n if (_callback.current) _callback.current();\n }, delay);\n return () => clearInterval(id);\n }\n }, [delay, enabled]);\n}\n","import { useEffect, useState } from 'react';\n\nimport { CarouselProps } from '../types';\n\ntype UsePagingReturnType = {\n currentPage: number;\n goToPage: (idx: number) => void;\n goForward: () => void;\n goBack: () => void;\n};\n\ntype PagingProps = {\n totalPages: number;\n wrapMode: CarouselProps['wrapMode'];\n initialPage?: number;\n};\n\nexport function usePaging({\n totalPages,\n wrapMode,\n initialPage,\n}: PagingProps): UsePagingReturnType {\n const [currentPage, setCurrentPage] = useState(0);\n\n useEffect(() => {\n if (initialPage) {\n setCurrentPage(Math.max(0, Math.min(initialPage, totalPages)));\n }\n }, [initialPage, totalPages]);\n\n const goToPage = (idx: number) => {\n if (idx < 0 || idx >= totalPages) return;\n setCurrentPage(idx);\n };\n\n const goForward = () => {\n if (wrapMode === 'wrap') {\n setCurrentPage((prev) => (prev + 1) % totalPages);\n } else {\n setCurrentPage((prev) => Math.min(prev + 1, totalPages - 1));\n }\n };\n\n const goBack = () => {\n if (wrapMode === 'wrap') {\n setCurrentPage((prev) => (prev - 1 + totalPages) % totalPages);\n } else {\n setCurrentPage((prev) => Math.max(prev - 1, 0));\n }\n };\n\n return { currentPage, goToPage, goForward, goBack };\n}\n","import { useEffect, useState } from 'react';\n\nimport { arraySeq, arraySum } from '../utils';\nimport { useResizeObserver } from './use-resize-observer';\n\ntype MeasurementProps = {\n element: React.RefObject<HTMLDivElement>;\n scrollDistance: number | 'slide' | 'screen';\n};\n\nexport function useMeasurement({ element, scrollDistance }: MeasurementProps) {\n const [totalPages, setTotalPages] = useState(0);\n const [scrollOffset, setScrollOffset] = useState(arraySeq(totalPages, 0));\n const dimensions = useResizeObserver(element);\n\n useEffect(() => {\n const container = element.current;\n if (!(container && dimensions)) return;\n\n // determine the width of the content that is not visible (overflow)\n // we ignore the bounding box width because its a float\n // and scrollWidth is an integer, so it creates an imperfect\n // calculation when the scrollWidth is a few pixels larger\n const scrollWidth = container.scrollWidth;\n const visibleWidth = container.offsetWidth;\n const remainder = scrollWidth - visibleWidth;\n\n if (visibleWidth === 0) return;\n\n switch (scrollDistance) {\n case 'screen': {\n const pageCount = Math.round(scrollWidth / visibleWidth);\n\n setTotalPages(pageCount);\n setScrollOffset(arraySeq(pageCount, visibleWidth));\n break;\n }\n case 'slide': {\n // creates an array of slide widths in order to support\n // slides of varying widths as children\n const children =\n container.querySelector('#nuka-wrapper')?.children || [];\n const offsets = Array.from(children).map(\n (child) => (child as HTMLElement).offsetWidth,\n );\n\n // shift the scroll offsets by one to account for the first slide\n const scrollOffsets = arraySum([0, ...offsets.slice(0, -1)]);\n\n // find the index of the scroll offset that is greater than\n // the remainder of the full width and window width\n const pageCount =\n scrollOffsets.findIndex((offset) => offset >= remainder) + 1;\n\n setTotalPages(pageCount);\n setScrollOffset(scrollOffsets);\n break;\n }\n default: {\n if (typeof scrollDistance === 'number' && scrollDistance > 0) {\n // find the number of pages required to scroll all the slides\n // to the end of the container\n const pageCount = Math.ceil(remainder / scrollDistance) + 1;\n\n setTotalPages(pageCount);\n setScrollOffset(arraySeq(pageCount, scrollDistance));\n }\n }\n }\n }, [element, scrollDistance, dimensions]);\n\n return { totalPages, scrollOffset };\n}\n","/**\n * Creates an zero based array of numbers each multiplied by initialValue\n * @param length The length of the array\n * @param initialValue The seed value that each element will be multiplied by\n * @returns An array of numbers\n */\nexport function arraySeq(length: number, initialValue: number): number[] {\n return new Array(length).fill(0).map((_, i) => i * initialValue);\n}\n\n/**\n * Creates an array where each element is the sum of all previous elements\n * @param values The seed array\n * @returns An array of numbers\n */\nexport function arraySum(values: number[]): number[] {\n let sum = 0;\n return values.map((value) => (sum += value));\n}\n","export const isBrowser = () => typeof window !== 'undefined';\n","type ClassName = string | boolean | undefined;\n\nexport function cls(...classes: ClassName[]) {\n return classes.filter(Boolean).join(' ');\n}\n","export function isMouseEvent(\n e: React.MouseEvent | React.TouchEvent,\n): e is React.MouseEvent {\n return 'clientX' && 'clientY' in e;\n}\n","import { RefObject, useEffect, useState } from 'react';\n\nexport function useResizeObserver(element: RefObject<HTMLElement>) {\n const [dimensions, setDimensions] = useState<DOMRect>();\n\n useEffect(() => {\n if (!element.current) return;\n\n const target = element.current;\n\n const observer = new ResizeObserver(() =>\n setDimensions(target.getBoundingClientRect()),\n );\n\n observer.observe(target);\n return () => {\n observer.unobserve(target);\n };\n }, [element]);\n\n return dimensions;\n}\n","import { useEffect, useState } from 'react';\nimport type { RefObject } from 'react';\n\nexport function useHover<T extends HTMLElement>({\n element,\n enabled,\n}: {\n element: RefObject<T>;\n enabled: boolean;\n}) {\n const [hovered, setHovered] = useState(false);\n\n const target = element?.current;\n\n useEffect(() => {\n if (!(target && target.addEventListener)) return;\n\n if (enabled) {\n const onMouseOver = () => setHovered(true);\n const onMouseOut = () => setHovered(false);\n\n target.addEventListener('mouseover', onMouseOver);\n target.addEventListener('mouseout', onMouseOut);\n\n return () => {\n target.removeEventListener('mouseover', onMouseOver);\n target.removeEventListener('mouseout', onMouseOut);\n };\n }\n }, [target, enabled]);\n\n return hovered;\n}\n","import { useEffect } from 'react';\nimport type { RefObject } from 'react';\n\nexport function useKeyboard<T extends HTMLElement>({\n element,\n enabled,\n goForward,\n goBack,\n}: {\n element: RefObject<T>;\n enabled: boolean;\n goForward: () => void;\n goBack: () => void;\n}) {\n const target = element?.current;\n\n useEffect(() => {\n if (target && enabled) {\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'ArrowLeft') {\n goBack();\n } else if (e.key === 'ArrowRight') {\n goForward();\n }\n };\n target.addEventListener('keydown', onKeyDown);\n return () => target.removeEventListener('keydown', onKeyDown);\n }\n }, [enabled, goBack, goForward, target]);\n}\n","import { useEffect, useState } from 'react';\n\nimport { isBrowser } from '../utils';\n\nconst QUERY = '(prefers-reduced-motion: no-preference)';\nconst getInitialState = () =>\n isBrowser() ? !window.matchMedia(QUERY).matches : true;\n\nexport function useReducedMotion({ enabled }: { enabled: boolean }) {\n const [reduceMotion, setReducedMotion] = useState(getInitialState);\n\n useEffect(() => {\n if (!(isBrowser() && enabled)) return;\n\n const mediaQueryList = window.matchMedia(QUERY);\n\n const listener = (event: MediaQueryListEvent) => {\n setReducedMotion(!event.matches);\n };\n\n mediaQueryList.addEventListener('change', listener);\n\n return () => {\n mediaQueryList.removeEventListener('change', listener);\n };\n }, [enabled]);\n return reduceMotion;\n}\n","import { useCarousel } from '../hooks/use-carousel';\nimport { cls } from '../utils';\n\nexport function NavButtons() {\n const { currentPage, totalPages, wrapMode, goBack, goForward } =\n useCarousel();\n\n const allowWrap = wrapMode !== 'nowrap';\n\n const enablePrevNavButton = allowWrap || currentPage > 0;\n const enableNextNavButton = allowWrap || currentPage < totalPages - 1;\n\n const prevNavClassName = cls(\n 'nuka-nav-button',\n 'nuka-nav-button-prev',\n enablePrevNavButton && 'nuka-nav-button-enabled',\n );\n\n const nextNavClassName = cls(\n 'nuka-nav-button',\n 'nuka-nav-button-next',\n enableNextNavButton && 'nuka-nav-button-enabled',\n );\n\n return (\n <>\n <div className={prevNavClassName} onClick={goBack}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentcolor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M11.78 5.22a.75.75 0 0 1 0 1.06L8.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </div>\n <div className={nextNavClassName} onClick={goForward}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentcolor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M8.22 5.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L11.94 10 8.22 6.28a.75.75 0 0 1 0-1.06Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </div>\n </>\n );\n}\n","import { useCarousel } from '../hooks/use-carousel';\nimport { cls } from '../utils';\n\nexport const PageIndicators = () => {\n const { totalPages, currentPage, goToPage } = useCarousel();\n\n const className = (index: number) =>\n cls(\n 'nuka-page-indicator',\n currentPage === index ? 'nuka-page-indicator-active' : '',\n );\n\n return (\n <div className=\"nuka-page-container\" data-testid=\"pageIndicatorContainer\">\n {[...Array(totalPages)].map((_, index) => (\n <button\n key={index}\n onClick={() => goToPage(index)}\n className={className(index)}\n >\n <span className=\"nuka-hidden\">{index + 1}</span>\n </button>\n ))}\n </div>\n );\n};\n","\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\".nuka-hidden {\\n position: absolute;\\n width: 1px;\\n height: 1px;\\n padding: 0;\\n margin: -1px;\\n overflow: hidden;\\n clip: rect(0, 0, 0, 0);\\n white-space: nowrap;\\n border-width: 0;\\n}\\n.nuka-container {\\n position: relative;\\n}\\n.nuka-slide-container {\\n position: relative;\\n}\\n.nuka-overflow {\\n overflow: scroll;\\n -ms-overflow-style: none;\\n scrollbar-width: none;\\n}\\n.nuka-overflow.scroll-smooth {\\n scroll-behavior: smooth;\\n}\\n.nuka-overflow.scroll-auto {\\n scroll-behavior: auto;\\n}\\n.nuka-overflow::-webkit-scrollbar {\\n display: none;\\n}\\n.nuka-wrapper {\\n display: flex;\\n}\\n.nuka-nav-button {\\n position: absolute;\\n top: calc(50% - 2rem);\\n margin: 1rem;\\n display: none;\\n height: 2rem;\\n width: 2rem;\\n cursor: pointer;\\n background-color: rgba(146, 148, 151, 0.5);\\n color: white;\\n border-radius: 9999px;\\n font-size: 1rem;\\n user-select: none;\\n}\\n.nuka-nav-button.nuka-nav-button-prev {\\n left: 0;\\n margin-right: 1rem;\\n}\\n.nuka-nav-button.nuka-nav-button-next {\\n right: 0;\\n margin-left: 1rem;\\n}\\n.nuka-nav-button:hover {\\n background-color: rgba(146, 148, 151, 0.65);\\n}\\n.nuka-nav-button-enabled {\\n display: block;\\n}\\n.nuka-container-auto-hide .nuka-nav-button {\\n display: none;\\n}\\n.nuka-container-auto-hide:hover .nuka-nav-button-enabled {\\n display: block;\\n}\\n.nuka-page-container {\\n padding-top: 1rem;\\n padding-bottom: 1rem;\\n display: flex;\\n gap: 0.5rem;\\n justify-content: center;\\n align-items: center;\\n}\\n.nuka-page-indicator {\\n width: 0.75rem;\\n height: 0.75rem;\\n cursor: pointer;\\n border-radius: 9999px;\\n border-style: none;\\n background-color: rgba(146, 148, 151, 0.65);\\n}\\n.nuka-page-indicator.nuka-page-indicator-active,\\n.nuka-page-indicator.nuka-page-indicator-active:hover {\\n background-color: rgb(229 231 235 / 1);\\n}\\n.nuka-page-indicator:hover {\\n background-color: rgb(229 231 235 / 1);\\n}\\n\")"],"mappings":"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","names":["useEffect","useRef","useState","useEffect","useEffect","useState","useEffect","useState","useState","useEffect","useEffect","useState","useEffect","useEffect","useState","useState","useEffect","jsx","jsx","jsxs","useRef","useState","useEffect"]}