UNPKG

@itwin/itwinui-react

Version:

A react component library for iTwinUI

168 lines (167 loc) 5.37 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true, }); Object.defineProperty(exports, 'CarouselDotsList', { enumerable: true, get: function () { return CarouselDotsList; }, }); const _interop_require_default = require('@swc/helpers/_/_interop_require_default'); const _interop_require_wildcard = require('@swc/helpers/_/_interop_require_wildcard'); const _react = /*#__PURE__*/ _interop_require_wildcard._(require('react')); const _classnames = /*#__PURE__*/ _interop_require_default._( require('classnames'), ); const _CarouselContext = require('./CarouselContext.js'); const _index = require('../../utils/index.js'); const _CarouselDot = require('./CarouselDot.js'); const CarouselDotsList = _react.forwardRef((props, ref) => { let { currentIndex: userCurrentIndex, length, className, onSlideChange, children, ...rest } = props; let context = _react.useContext(_CarouselContext.CarouselContext); let slideCount = length ?? context?.slideCount ?? _react.Children.count(children); let currentIndex = userCurrentIndex ?? context?.currentIndex ?? 0; let idPrefix = props.id ?? context?.idPrefix; let handleSlideChange = _react.useCallback( (index) => { if (context) { context.setCurrentIndex(index); context.scrollToSlide.current(index); } listRef.current?.children[index]?.focus(); onSlideChange?.(index); }, [context, onSlideChange], ); let justMounted = _react.useRef(true); let [visibleCount, setVisibleCount] = _react.useState(slideCount); let listRef = _react.useRef(null); let [width, setWidth] = _react.useState(); let [resizeRef, resizeObserver] = (0, _index.useResizeObserver)( ({ width }) => { if (!listRef.current) return; setWidth(width); let dotWidth = listRef.current.children[0].offsetWidth; setVisibleCount(Math.floor(width / dotWidth)); }, ); _react.useEffect(() => resizeObserver?.disconnect(), [resizeObserver]); let refs = (0, _index.useMergedRefs)(ref, resizeRef, listRef); let firstVisibleDotIndex = _react.useMemo( () => (0, _index.getBoundedValue)( currentIndex - Math.ceil(visibleCount / 2) + 1, 0, slideCount - visibleCount, ), [currentIndex, slideCount, visibleCount], ); let lastVisibleDotIndex = _react.useMemo( () => (0, _index.getBoundedValue)( currentIndex + Math.floor(visibleCount / 2), visibleCount - 1, slideCount - 1, ), [currentIndex, slideCount, visibleCount], ); let dots = _react.useMemo( () => Array(slideCount) .fill(null) .map((_, index) => { let isFirstSmallDot = (index === firstVisibleDotIndex && 0 !== index) || (index === lastVisibleDotIndex && index !== slideCount - 1); let isSecondSmallDot = (index === firstVisibleDotIndex + 1 && 1 !== index) || (index === lastVisibleDotIndex - 1 && index !== slideCount - 2); let isClipped = index < firstVisibleDotIndex || index > lastVisibleDotIndex; return _react.createElement(_CarouselDot.CarouselDot, { key: index, 'aria-label': `Slide ${index + 1}`, isActive: index === currentIndex, onClick: () => handleSlideChange(index), isSmall: isSecondSmallDot, isSmaller: isFirstSmallDot || isClipped, id: idPrefix && `${idPrefix}--dot-${index}`, }); }), [ slideCount, firstVisibleDotIndex, lastVisibleDotIndex, currentIndex, idPrefix, handleSlideChange, ], ); let motionOk = (0, _index.useMediaQuery)( '(prefers-reduced-motion: no-preference)', ); _react.useEffect(() => { let firstDot = listRef.current?.children[firstVisibleDotIndex]; if (!listRef.current || !firstDot) return; listRef.current.scrollTo({ left: firstDot.offsetLeft - listRef.current.offsetLeft, behavior: motionOk && !justMounted.current ? 'smooth' : 'auto', }); if (justMounted.current) justMounted.current = false; }, [ currentIndex, firstVisibleDotIndex, motionOk, slideCount, visibleCount, width, ]); let handleKeyDown = (event) => { if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return; let key = event.key; if ('ArrowLeft' === key || 'ArrowRight' === key) event.preventDefault(); }; let handleKeyUp = (event) => { switch (event.key) { case 'ArrowLeft': handleSlideChange((slideCount + currentIndex - 1) % slideCount); break; case 'ArrowRight': handleSlideChange((slideCount + currentIndex + 1) % slideCount); break; } }; return _react.createElement( _react.Fragment, null, _react.createElement( _index.Box, { className: (0, _classnames.default)( 'iui-carousel-navigation-dots', className, ), role: 'tablist', 'aria-label': 'Slides', ref: refs, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, tabIndex: -1, ...rest, }, children ?? dots, ), ); }); if ('development' === process.env.NODE_ENV) CarouselDotsList.displayName = 'Carousel.DotsList';