UNPKG

@amaui/ui-react

Version:
866 lines 56.2 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = __importDefault(require("react")); const utils_1 = require("@amaui/utils"); const style_react_1 = require("@amaui/style-react"); const IconMaterialNavigateBeforeW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialNavigateBeforeW100")); const IconMaterialNavigateNextW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialNavigateNextW100")); const Line_1 = __importDefault(require("../Line")); const Fade_1 = __importDefault(require("../Fade")); const IconButton_1 = __importDefault(require("../IconButton")); const Transitions_1 = __importDefault(require("../Transitions")); const Surface_1 = __importDefault(require("../Surface")); const useMediaQuery_1 = __importDefault(require("../useMediaQuery")); const utils_2 = require("../utils"); const useStyle = (0, style_react_1.style)(theme => ({ root: { position: 'relative', width: '100%', height: '540px', overflow: 'hidden' }, autoHeight: { transition: theme.methods.transitions.make('height') }, item: { width: '100%', height: '100%', flex: '0 0 auto', '& img': { width: 'auto', maxHeight: '100%' } }, item_transition: { position: 'absolute', width: '100%', height: '100%', '& img': { width: 'auto', maxHeight: '100%' } }, item_version_regular_autoHeight: { width: '100%', height: 'unset' }, item_version_transition_autoHeight: { width: '100%', height: 'unset' }, item_itemSize_auto: { width: 'auto', height: 'auto' }, background: { width: '100%', height: '100%', backgroundRepeat: 'no-repeat', backgroundPosition: 'center', backgroundSize: 'cover' }, carousel: { position: 'relative', width: '100%', height: '100%', touchAction: 'none' }, carousel_version_regular: { transition: theme.methods.transitions.make('transform') }, progress: { position: 'absolute' }, progress_orientation_horizontal: { width: '100%', left: '50%', transform: 'translateX(-50%)', bottom: '24px' }, progress_orientation_vertical: { height: '100%', top: '50%', transform: 'translateY(-50%)', right: '24px' }, progress_item: { width: '5px', height: '5px', backgroundColor: 'currentColor', borderRadius: theme.methods.shape.radius.value(40, 'px'), cursor: 'pointer', transition: theme.methods.transitions.make('transform'), '&:hover': { transform: 'scale(1.4)' } }, progress_item_active: { transform: 'scale(1.7)' }, arrow: { position: 'absolute !important' }, arrow_previous: {}, arrow_previous_orientation_horizontal: { top: '50%', transform: 'translateY(-50%)', left: '24px' }, arrow_previous_orientation_vertical: { left: '50%', transform: 'translateX(-50%)', top: '24px' }, arrow_next: {}, arrow_next_orientation_horizontal: { top: '50%', transform: 'translateY(-50%)', right: '24px' }, arrow_next_orientation_vertical: { left: '50%', transform: 'translateX(-50%)', bottom: '24px' }, icon_previous_orientation_vertical: { transform: 'rotate(90deg)' }, icon_next_orientation_vertical: { transform: 'rotate(90deg)' } }), { name: 'amaui-Carousel' }); const Carousel = react_1.default.forwardRef((props_, ref) => { var _a; const theme = (0, style_react_1.useAmauiTheme)(); const props = react_1.default.useMemo(() => { var _a, _b, _c, _d, _e, _f, _g, _h; return (Object.assign(Object.assign(Object.assign({}, (_d = (_c = (_b = (_a = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _a === void 0 ? void 0 : _a.elements) === null || _b === void 0 ? void 0 : _b.all) === null || _c === void 0 ? void 0 : _c.props) === null || _d === void 0 ? void 0 : _d.default), (_h = (_g = (_f = (_e = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _e === void 0 ? void 0 : _e.elements) === null || _f === void 0 ? void 0 : _f.amauiCarousel) === null || _g === void 0 ? void 0 : _g.props) === null || _h === void 0 ? void 0 : _h.default), props_)); }, [props_]); const Line = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Line) || Line_1.default; }, [theme]); const IconButton = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.IconButton) || IconButton_1.default; }, [theme]); const Fade = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Fade) || Fade_1.default; }, [theme]); const Surface = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Surface) || Surface_1.default; }, [theme]); const Transitions = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Transitions) || Transitions_1.default; }, [theme]); const { tonal = true, color = 'default', version: version_, valueDefault, value: value_, onChange, // id if it updates // update items id, // Array of string or object // object having element as a string or element // and a transition element items: items_, orientation: orientation_, itemSize: itemSize_, gap: gap_, move: move_, moveValue: moveValue_, moveItems: moveItems_, moveBeyondEdge: moveBeyondEdge_, free: free_, swipe: swipe_, background: background_, index: index_, autoPlay: autoPlay_, autoHeight: autoHeight_, autoHeightDelay = theme.transitions.duration.rg + 14, autoPlayInterval = 4000, pauseOnHover = true, round: round_, arrows: arrows_, mouseScroll, momentum: momentum_, // AmauiSubscription methods previousSub, nextSub, updateSub, // on mobile visible arrowsVisibility: arrowsVisibility_, arrowHideOnStartEnd: arrowHideOnStartEnd_, renderProgress, renderArrowPrevious, renderArrowNext, progress: progress_, // on mobile visible progressVisibility: progressVisibility_, start: start_, end: end_, noTransition: noTransition_, onUpdatePosition: onUpdatePosition_, onInit, onUpdateItems, onBlur: onBlur_, onFocus: onFocus_, onMouseEnter: onMouseEnter_, onMouseLeave: onMouseLeave_, TransitionComponent: TransitionComponent_ = Fade, ProgressTransitionComponent = Fade, ArrowTransitionComponent = Fade, ArrowPreviousTransitionComponent, ArrowNextTransitionComponent, IconButtonPrevious, IconButtonNext, IconPrevious = IconMaterialNavigateBeforeW100_1.default, IconNext = IconMaterialNavigateNextW100_1.default, ArrowProps, ArrowPreviousProps: ArrowPreviousProps_, ArrowNextProps: ArrowNextProps_, CarouselProps, TransitionsProps, TransitionComponentProps, ArrowTransitionComponentProps, ArrowPreviousTransitionComponentProps, ArrowNextTransitionComponentProps, ProgressTransitionComponentProps, ItemWrapperProps, Component = 'div', className, children } = props, other = __rest(props, ["tonal", "color", "version", "valueDefault", "value", "onChange", "id", "items", "orientation", "itemSize", "gap", "move", "moveValue", "moveItems", "moveBeyondEdge", "free", "swipe", "background", "index", "autoPlay", "autoHeight", "autoHeightDelay", "autoPlayInterval", "pauseOnHover", "round", "arrows", "mouseScroll", "momentum", "previousSub", "nextSub", "updateSub", "arrowsVisibility", "arrowHideOnStartEnd", "renderProgress", "renderArrowPrevious", "renderArrowNext", "progress", "progressVisibility", "start", "end", "noTransition", "onUpdatePosition", "onInit", "onUpdateItems", "onBlur", "onFocus", "onMouseEnter", "onMouseLeave", "TransitionComponent", "ProgressTransitionComponent", "ArrowTransitionComponent", "ArrowPreviousTransitionComponent", "ArrowNextTransitionComponent", "IconButtonPrevious", "IconButtonNext", "IconPrevious", "IconNext", "ArrowProps", "ArrowPreviousProps", "ArrowNextProps", "CarouselProps", "TransitionsProps", "TransitionComponentProps", "ArrowTransitionComponentProps", "ArrowPreviousTransitionComponentProps", "ArrowNextTransitionComponentProps", "ProgressTransitionComponentProps", "ItemWrapperProps", "Component", "className", "children"]); const { classes } = useStyle(); const refs = { root: react_1.default.useRef(undefined), item: react_1.default.useRef(undefined), items: react_1.default.useRef(undefined), value: react_1.default.useRef(undefined), autoPlayTimeout: react_1.default.useRef(undefined), autoPlay: react_1.default.useRef(undefined), carousel: react_1.default.useRef(undefined), mouseDown: react_1.default.useRef(undefined), focus: react_1.default.useRef(undefined), gap: react_1.default.useRef(undefined), previousMouseEvent: react_1.default.useRef(undefined), move: react_1.default.useRef(undefined), moveValue: react_1.default.useRef(undefined), moveItems: react_1.default.useRef(undefined), moveBeyondEdge: react_1.default.useRef(undefined), free: react_1.default.useRef(undefined), swipe: react_1.default.useRef(undefined), mouseDownPosition: react_1.default.useRef(undefined), mouseDownStart: react_1.default.useRef(undefined), mouseDownDuration: react_1.default.useRef(undefined), orientation: react_1.default.useRef(undefined), version: react_1.default.useRef(undefined), itemSize: react_1.default.useRef(undefined), itemsLength: react_1.default.useRef(undefined), momentum: react_1.default.useRef(undefined), round: react_1.default.useRef(undefined), velocity: react_1.default.useRef(undefined), momentumID: react_1.default.useRef(undefined), width: react_1.default.useRef(undefined), onInit: react_1.default.useRef(undefined), ids: { items: react_1.default.useId() } }; const keys = react_1.default.useMemo(() => { const result = []; const properties = [version_, orientation_, itemSize_, gap_, move_, moveValue_, moveItems_, moveBeyondEdge_, swipe_, background_, autoPlay_, autoHeight_, round_, arrows_, arrowsVisibility_, arrowHideOnStartEnd_, progress_, progressVisibility_, noTransition_]; properties.forEach(item => { if ((0, utils_1.is)('object', item)) Object.keys(item).filter(key => theme.breakpoints.media[key]).forEach(key => result.push(key)); }); return (0, utils_1.unique)(result); }, [version_, orientation_, itemSize_, gap_, move_, moveValue_, moveItems_, moveBeyondEdge_, swipe_, background_, autoPlay_, autoHeight_, round_, arrows_, arrowsVisibility_, arrowHideOnStartEnd_, progress_, progressVisibility_, noTransition_]); const breakpoints = {}; keys.forEach(key => { breakpoints[key] = (0, useMediaQuery_1.default)(theme.breakpoints.media[key], { element: refs.root.current }); }); const version = (0, utils_2.valueBreakpoints)(version_, 'regular', breakpoints, theme); const orientation = (0, utils_2.valueBreakpoints)(orientation_, 'horizontal', breakpoints, theme); const itemSize = (0, utils_2.valueBreakpoints)(itemSize_, undefined, breakpoints, theme); const gap = (0, utils_2.valueBreakpoints)(gap_, 4, breakpoints, theme); const move = (0, utils_2.valueBreakpoints)(move_, true, breakpoints, theme); const moveValue = (0, utils_2.valueBreakpoints)(moveValue_, undefined, breakpoints, theme); const moveItems = (0, utils_2.valueBreakpoints)(moveItems_, undefined, breakpoints, theme); const moveBeyondEdge = (0, utils_2.valueBreakpoints)(moveBeyondEdge_, true, breakpoints, theme); const swipe = (0, utils_2.valueBreakpoints)(swipe_, true, breakpoints, theme); const background = (0, utils_2.valueBreakpoints)(background_, true, breakpoints, theme); const autoPlay = (0, utils_2.valueBreakpoints)(autoPlay_, undefined, breakpoints, theme); const autoHeight = (0, utils_2.valueBreakpoints)(autoHeight_, undefined, breakpoints, theme); const round = (0, utils_2.valueBreakpoints)(round_, true, breakpoints, theme); const arrows = (0, utils_2.valueBreakpoints)(arrows_, true, breakpoints, theme); const arrowsVisibility = (0, utils_2.valueBreakpoints)(arrowsVisibility_, 'hover', breakpoints, theme); const arrowHideOnStartEnd = (0, utils_2.valueBreakpoints)(arrowHideOnStartEnd_, undefined, breakpoints, theme); const progress = (0, utils_2.valueBreakpoints)(progress_, true, breakpoints, theme); const progressVisibility = (0, utils_2.valueBreakpoints)(progressVisibility_, 'hover', breakpoints, theme); const noTransition = (0, utils_2.valueBreakpoints)(noTransition_, undefined, breakpoints, theme); let free = (0, utils_2.valueBreakpoints)(free_, undefined, breakpoints, theme); let momentum = (0, utils_2.valueBreakpoints)(momentum_, undefined, breakpoints, theme); if (momentum && version !== 'regular') momentum = false; if (momentum) free = true; if (free && momentum === undefined) momentum = true; const [init, setInit] = react_1.default.useState(); const [items, setItems] = react_1.default.useState(items_ || []); const [value, setValue] = react_1.default.useState(valueDefault !== undefined ? valueDefault : value_); const [hover, setHover] = react_1.default.useState(); const [mouseDown, setMouseDown] = react_1.default.useState(); const [focus, setFocus] = react_1.default.useState(); const styles = { carousel: {} }; refs.items.current = items; refs.value.current = value; refs.gap.current = gap; refs.mouseDown.current = mouseDown; refs.focus.current = focus; refs.move.current = move; refs.moveValue.current = moveValue; refs.moveItems.current = moveItems; refs.moveBeyondEdge.current = moveBeyondEdge; refs.free.current = free; refs.swipe.current = swipe; refs.orientation.current = orientation; refs.version.current = version; refs.itemSize.current = itemSize; refs.momentum.current = momentum; refs.round.current = round; refs.onInit.current = onInit; const { scrollWidth, scrollHeight } = (refs.carousel.current || {}); const { width, height } = (((_a = refs.carousel.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect()) || {}); refs.width.current = width; refs.itemsLength.current = items.length; if (itemSize === 'auto') { if (moveValue) refs.itemsLength.current = orientation === 'horizontal' ? Math.ceil(scrollWidth / moveValue) : Math.ceil(scrollHeight / moveValue); if (moveItems) refs.itemsLength.current = Math.ceil(items.length / (0, utils_1.clamp)(moveItems, 1, items.length)); } const updateValue = (valueNew) => { setValue(valueNew); if ((0, utils_1.is)('function', onChange)) onChange(valueNew); }; const momentumClear = () => { cancelAnimationFrame(refs.momentumID.current); }; const momentumMethod = () => { var _a, _b, _c, _d, _e; const valueNew = refs.orientation.current === 'horizontal' ? (((_a = refs.value.current) === null || _a === void 0 ? void 0 : _a.x) || 0) + refs.velocity.current : (((_b = refs.value.current) === null || _b === void 0 ? void 0 : _b.y) || 0) + refs.velocity.current; const { width: width_, height: height_ } = refs.carousel.current.getBoundingClientRect(); const { scrollWidth: scrollWidth_, scrollHeight: scrollHeight_ } = refs.carousel.current; if (refs.orientation.current === 'horizontal') { const min = 0; let max = ((width_ + (gap * theme.space.unit)) * (refs.itemsLength.current - 1)); if (refs.itemSize.current === 'auto') { max = (scrollWidth_ - (scrollWidth_ / refs.itemsLength.current)) + ((gap * theme.space.unit) * (refs.itemsLength.current - 1)); } refs.value.current = Object.assign(Object.assign({}, refs.value.current), { index: Math.floor(valueNew / (max / (refs.itemsLength.current - 1))), x: valueNew }); if (valueNew <= min || valueNew >= max) { // Done return (_c = refs.carousel.current) === null || _c === void 0 ? void 0 : _c.style.removeProperty('transition'); } else { refs.value.current = Object.assign(Object.assign({}, refs.value.current), { index: Math.floor(valueNew / (max / (refs.itemsLength.current - 1))), x: valueNew }); onUpdatePosition(refs.value.current); } } if (refs.orientation.current === 'vertical') { const min = 0; let max = ((height_ + (gap * theme.space.unit)) * (refs.itemsLength.current - 1)); if (refs.itemSize.current === 'auto') { max = (scrollHeight_ - (scrollHeight_ / refs.itemsLength.current)) + ((gap * theme.space.unit) * (refs.itemsLength.current - 1)); } if (valueNew <= min || valueNew >= max) { // Done return (_d = refs.carousel.current) === null || _d === void 0 ? void 0 : _d.style.removeProperty('transition'); } else { refs.value.current = Object.assign(Object.assign({}, refs.value.current), { index: Math.floor(valueNew / (max / (refs.itemsLength.current - 1))), y: valueNew }); onUpdatePosition(refs.value.current); } } refs.velocity.current *= 0.95; if (Math.abs(refs.velocity.current) > 0.5) refs.momentumID.current = requestAnimationFrame(momentumMethod); else { // Done (_e = refs.carousel.current) === null || _e === void 0 ? void 0 : _e.style.removeProperty('transition'); } }; const momentumStart = () => { refs.momentumID.current = requestAnimationFrame(momentumMethod); }; const onUpdatePosition = (valuePosition_) => { var _a; // Momentum momentumClear(); const valueNew = Object.assign(Object.assign({}, valuePosition_), { additional: 0 }); if (valuePosition_.additional === undefined && refs.version.current === 'regular' && refs.itemSize.current !== 'auto') { const max = refs.width.current / 2; const valuePosition = valueNew[refs.orientation.current === 'horizontal' ? 'x' : 'y']; const part = valuePosition - (((_a = refs.mouseDownPosition.current) === null || _a === void 0 ? void 0 : _a[refs.orientation.current === 'horizontal' ? 'x' : 'y']) || 0); const additional = (part / max) * 100; valueNew.additional = additional; } updateValue(valueNew); if ((0, utils_1.is)('function', onUpdatePosition_)) onUpdatePosition_(valueNew); }; const onUpdate = react_1.default.useCallback((to = 'next', values = refs.items.current) => { var _a, _b; // Momentum momentumClear(); // Momentum clean up (_a = refs.carousel.current) === null || _a === void 0 ? void 0 : _a.style.removeProperty('transition'); let index = (_b = refs.value.current) === null || _b === void 0 ? void 0 : _b.index; if (index === undefined) index = 0; else if ((0, utils_1.is)('number', to)) index = (0, utils_1.clamp)(to, 0, refs.itemsLength.current - 1); else { index = to === 'next' ? index + 1 : index - 1; if (index < 0) index = refs.round.current ? refs.itemsLength.current - 1 : 0; if (index > refs.itemsLength.current - 1) index = refs.round.current ? 0 : refs.itemsLength.current - 1; } // Regular if (version === 'regular' && refs.carousel.current) { if (refs.orientation.current === 'horizontal') { if (refs.itemSize.current === 'auto' && refs.moveValue.current !== undefined) { const x = index * refs.moveValue.current; onUpdatePosition({ index, x, additional: 0 }); } else if (refs.itemSize.current === 'auto' && refs.moveItems.current !== undefined) { let item = index * (0, utils_1.clamp)(moveItems, 1, refs.items.current.length); item = refs.carousel.current.children[item]; if (item) { const x = item.offsetLeft; onUpdatePosition({ index, x, additional: 0 }); } } else { const width_ = refs.carousel.current.getBoundingClientRect().width; const scrollWidth_ = refs.carousel.current.scrollWidth; const part = refs.itemSize.current === 'auto' ? scrollWidth_ / refs.itemsLength.current : width_; const x = (index * part) + (index * (gap * theme.space.unit)); onUpdatePosition({ index, x, additional: 0 }); } } if (refs.orientation.current === 'vertical') { if (refs.itemSize.current === 'auto' && refs.moveValue.current !== undefined) { const y = index * refs.moveValue.current; onUpdatePosition({ index, y, additional: 0 }); } else if (refs.itemSize.current === 'auto' && refs.moveItems.current !== undefined) { let item = index * (0, utils_1.clamp)(moveItems, 1, refs.items.current.length); item = refs.carousel.current.children[item]; if (item) { const y = item.offsetTop; onUpdatePosition({ index, y, additional: 0 }); } } else { const height_ = refs.carousel.current.getBoundingClientRect().height; const scrollHeight_ = refs.carousel.current.scrollHeight; const part = refs.itemSize.current === 'auto' ? scrollHeight_ / refs.itemsLength.current : height_; const y = (index * part) + (index * (gap * theme.space.unit)); onUpdatePosition({ index, y, additional: 0 }); } } } // Transition const itemNew = values[index]; if (itemNew) { if (version === 'transition') updateValue({ index, element: itemNew }); if (autoHeight) { if (version === 'regular') { setTimeout(() => { var _a, _b, _c; const height_ = (_c = (_b = refs.carousel.current.children[(_a = refs.value.current) === null || _a === void 0 ? void 0 : _a.index]) === null || _b === void 0 ? void 0 : _b.children[0]) === null || _c === void 0 ? void 0 : _c.getBoundingClientRect().height; if (height_ > 0) refs.root.current.style.height = `${height_}px`; }, 1); } if (version === 'transition') { setTimeout(() => { var _a, _b; const height_ = (_b = (_a = refs.carousel.current.children[0]) === null || _a === void 0 ? void 0 : _a.children[0]) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect().height; if (height_ > 0) refs.root.current.style.height = `${height_}px`; }, autoHeightDelay); } } } }, [gap, version, autoHeight, autoHeightDelay]); const onMouseUp = react_1.default.useCallback((event) => { var _a, _b, _c, _d, _e, _f; if (refs.mouseDown.current) { if (refs.mouseDown.current && !refs.momentum.current) (_a = refs.carousel.current) === null || _a === void 0 ? void 0 : _a.style.removeProperty('transition'); refs.mouseDownDuration.current = new Date().getTime() - refs.mouseDownStart.current; if (refs.free.current) { setMouseDown(false); if (refs.momentum.current) momentumStart(); refs.previousMouseEvent.current = undefined; return; } // Swipe // less than 140 ms if (refs.swipe.current && refs.mouseDownDuration.current <= 140) { const { clientX: previousClientX, clientY: previousClientY } = ((_b = refs.mouseDown.current.touches) === null || _b === void 0 ? void 0 : _b[0]) || refs.mouseDown.current; const { clientX, clientY } = refs.previousMouseEvent.current || event; refs.previousMouseEvent.current = undefined; setMouseDown(false); if (refs.orientation.current === 'horizontal') { // As move already updates the index // so move to that index if (previousClientX < clientX) return onUpdate((_c = refs.value.current) === null || _c === void 0 ? void 0 : _c.index); if (previousClientX > clientX) return onUpdate('next'); } if (refs.orientation.current === 'vertical') { if (previousClientY < clientY) return onUpdate((_d = refs.value.current) === null || _d === void 0 ? void 0 : _d.index); if (previousClientY > clientY) return onUpdate('next'); } } // Move if (refs.version.current === 'regular' && refs.value.current) { if (refs.orientation.current === 'horizontal') { const { x } = refs.value.current; let index = refs.value.current.index; if (((_e = refs.mouseDownPosition.current) === null || _e === void 0 ? void 0 : _e.x) > x) index++; const width_ = refs.carousel.current.getBoundingClientRect().width; const original = index * width_ + index * (gap * theme.space.unit); const threshold = width_ / 4; const moved = Math.abs(original - x); if (x > 0 && x < original && moved >= threshold) onUpdate(index - 1); else if (x > original && moved >= threshold) onUpdate(index + 1); else onUpdate(index); } if (refs.orientation.current === 'vertical') { const { y } = refs.value.current; let index = refs.value.current.index; if (((_f = refs.mouseDownPosition.current) === null || _f === void 0 ? void 0 : _f.y) > y) index++; const height_ = refs.carousel.current.getBoundingClientRect().height; const original = index * height_ + index * (gap * theme.space.unit); const threshold = height_ / 4; const moved = Math.abs(original - y); if (y > 0 && y < original && moved >= threshold) onUpdate(index - 1); else if (y > original && moved >= threshold) onUpdate(index + 1); else onUpdate(index); } } setMouseDown(false); refs.previousMouseEvent.current = undefined; } }, []); react_1.default.useEffect(() => { var _a; const onKeyDown = (event) => { if (refs.focus.current) { switch (event.key) { case 'ArrowLeft': return onUpdate('previous'); case 'ArrowRight': return onUpdate('next'); default: break; } } }; const onMove = (x_, y_) => { var _a, _b, _c, _d, _e, _f; if (refs.version.current === 'regular' && refs.move.current && refs.mouseDown.current && refs.previousMouseEvent.current) { const incX = x_ - refs.previousMouseEvent.current.clientX; const incY = y_ - refs.previousMouseEvent.current.clientY; const { width: width_, height: height_ } = refs.carousel.current.getBoundingClientRect(); const { scrollWidth: scrollWidth_, scrollHeight: scrollHeight_ } = refs.carousel.current; if (refs.orientation.current === 'horizontal' && incX !== 0) { const min = 0; let max = ((width_ + (gap * theme.space.unit)) * (refs.itemsLength.current - 1)); if (refs.itemSize.current === 'auto') { max = (scrollWidth_ - (scrollWidth_ / refs.itemsLength.current)) + ((gap * theme.space.unit) * (refs.itemsLength.current - 1)); } let x = (((_a = refs.value.current) === null || _a === void 0 ? void 0 : _a.x) || 0) - incX; if (refs.free.current || !refs.moveBeyondEdge.current) x = (0, utils_1.clamp)(x, min, max); // Move beyond min, max if (x < min || x > max) x = (((_b = refs.value.current) === null || _b === void 0 ? void 0 : _b.x) || 0) - (incX / 1.7); refs.velocity.current = x - (((_c = refs.value.current) === null || _c === void 0 ? void 0 : _c.x) || 0); onUpdatePosition({ index: Math.floor(x / (max / (refs.itemsLength.current - 1))), x }); } if (refs.orientation.current === 'vertical' && incY !== 0) { const min = 0; let max = ((height_ + (gap * theme.space.unit)) * (refs.itemsLength.current - 1)); if (refs.itemSize.current === 'auto') { max = (scrollHeight_ - (scrollHeight_ / refs.itemsLength.current)) + ((gap * theme.space.unit) * (refs.itemsLength.current - 1)); } let y = (((_d = refs.value.current) === null || _d === void 0 ? void 0 : _d.y) || 0) - incY; if (refs.free.current || !refs.moveBeyondEdge.current) y = (0, utils_1.clamp)(y, min, max); // Move beyond min, max if (y < min || y > max) y = (((_e = refs.value.current) === null || _e === void 0 ? void 0 : _e.y) || 0) - (incY / 1.7); refs.velocity.current = y - (((_f = refs.value.current) === null || _f === void 0 ? void 0 : _f.y) || 0); onUpdatePosition({ index: Math.floor(y / (max / (refs.itemsLength.current - 1))), y }); } } }; // Mouse move const onMouseMove = (event) => { if (refs.mouseDown.current) { const { clientY, clientX } = event; onMove(clientX, clientY); refs.previousMouseEvent.current = event; } }; // Touch move const onTouchMove = (event) => { if (refs.mouseDown.current) { const { clientY, clientX } = event.touches[0]; onMove(clientX, clientY); refs.previousMouseEvent.current = event; // Normalize for use as a mouseDown value refs.previousMouseEvent.current.clientY = clientY; refs.previousMouseEvent.current.clientX = clientX; } }; const method = () => { var _a; return onUpdate((_a = refs.value.current) === null || _a === void 0 ? void 0 : _a.index); }; const observer = new ResizeObserver(method); method(); observer.observe(refs.root.current); const rootDocument = (0, utils_1.isEnvironment)('browser') ? (((_a = refs.root.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) || window.document) : undefined; rootDocument.addEventListener('keydown', onKeyDown); rootDocument.addEventListener('mouseup', onMouseUp); rootDocument.addEventListener('mousemove', onMouseMove); rootDocument.addEventListener('touchend', onMouseUp); rootDocument.addEventListener('touchmove', onTouchMove, { passive: true }); setInit(true); if ((0, utils_1.is)('function', refs.onInit.current)) refs.onInit.current(); return () => { observer.disconnect(); rootDocument.removeEventListener('keydown', onKeyDown); rootDocument.removeEventListener('mousemove', onMouseMove); rootDocument.removeEventListener('mouseup', onMouseUp); rootDocument.removeEventListener('touchmove', onTouchMove); rootDocument.removeEventListener('touchend', onMouseUp); }; }, []); react_1.default.useEffect(() => { if (value_ !== undefined && !(0, utils_1.equalDeep)(value_, refs.value.current)) setValue((valuePrevious) => (Object.assign(Object.assign({}, valuePrevious), value_))); }, [value_]); react_1.default.useEffect(() => { var _a; if (init) { if (index_ >= 0 && index_ <= refs.itemsLength.current && index_ !== ((_a = refs.value.current) === null || _a === void 0 ? void 0 : _a.index)) onUpdate(index_); } }, [index_]); react_1.default.useEffect(() => { if ((0, utils_1.is)('function', onUpdateItems)) onUpdateItems(); }, [items, onUpdateItems, theme.palette.light]); react_1.default.useEffect(() => { setItems(items_); }, [id, items_]); const onPrevious = () => onUpdate('previous'); const onNext = () => onUpdate('next'); const clear = () => { clearTimeout(refs.autoPlayTimeout.current); refs.autoPlay.current = false; }; const start = () => { clear(); if (!autoPlay || mouseDown || focus) return; if (pauseOnHover && hover) return; refs.autoPlayTimeout.current = setTimeout(onUpdate, autoPlayInterval); refs.autoPlay.current = true; }; // autoPlay react_1.default.useEffect(() => { start(); }, [items, value, autoPlay, autoPlayInterval]); // AmauiSubscription methods react_1.default.useEffect(() => { const method = (...args) => onUpdate(...args); if ((0, utils_1.is)('function', updateSub === null || updateSub === void 0 ? void 0 : updateSub.subscribe)) updateSub === null || updateSub === void 0 ? void 0 : updateSub.subscribe(method); return () => { if ((0, utils_1.is)('function', updateSub === null || updateSub === void 0 ? void 0 : updateSub.unsubscribe)) updateSub === null || updateSub === void 0 ? void 0 : updateSub.unsubscribe(method); }; }, [updateSub]); react_1.default.useEffect(() => { const method = (...args) => onUpdate(...args); if ((0, utils_1.is)('function', previousSub === null || previousSub === void 0 ? void 0 : previousSub.subscribe)) previousSub === null || previousSub === void 0 ? void 0 : previousSub.subscribe(method); return () => { if ((0, utils_1.is)('function', previousSub === null || previousSub === void 0 ? void 0 : previousSub.unsubscribe)) previousSub === null || previousSub === void 0 ? void 0 : previousSub.unsubscribe(method); }; }, [previousSub]); react_1.default.useEffect(() => { const method = (...args) => onUpdate(...args); if ((0, utils_1.is)('function', nextSub === null || nextSub === void 0 ? void 0 : nextSub.subscribe)) nextSub === null || nextSub === void 0 ? void 0 : nextSub.subscribe(method); return () => { if ((0, utils_1.is)('function', nextSub === null || nextSub === void 0 ? void 0 : nextSub.unsubscribe)) nextSub === null || nextSub === void 0 ? void 0 : nextSub.unsubscribe(method); }; }, [nextSub]); react_1.default.useEffect(() => { const values = (0, utils_1.unique)([ ...items_, ...react_1.default.Children.toArray(children) ]) .filter(Boolean); const previous = refs.items.current.reduce((result, item) => result += (0, utils_1.is)('string', item) ? item : item === null || item === void 0 ? void 0 : item.key, ''); const updated = values.reduce((result, item) => result += (0, utils_1.is)('string', item) ? item : item === null || item === void 0 ? void 0 : item.key, ''); if (updated !== previous) { onUpdate('next', values); setItems(values); } }, [items_, background, children]); const onWheel = react_1.default.useCallback((0, utils_1.debounce)((event) => { if ((refs.orientation.current === 'horizontal' && event.deltaX < 0) || (refs.orientation.current === 'vertical' && event.deltaY < 0)) { event.preventDefault(); event.stopPropagation(); return onUpdate('previous'); } if ((refs.orientation.current === 'horizontal' && event.deltaX > 0) || (refs.orientation.current === 'vertical' && event.deltaY > 0)) { event.preventDefault(); event.stopPropagation(); return onUpdate('next'); } }, 40), []); const onBlur = react_1.default.useCallback((event) => { setFocus(false); if ((0, utils_1.is)('function', onBlur_)) onBlur_(event); }, []); const onFocus = react_1.default.useCallback((event) => { setFocus(true); if ((0, utils_1.is)('function', onFocus_)) onFocus_(event); }, []); const onMouseDown = react_1.default.useCallback((event) => { // Momentum momentumClear(); setMouseDown(event); refs.mouseDownPosition.current = Object.assign({}, refs.value.current); refs.mouseDownStart.current = new Date().getTime(); refs.carousel.current.style.transition = 'none'; }, []); const onMouseEnter = react_1.default.useCallback((event) => { setHover(true); if (refs.autoPlay.current) clear(); if ((0, utils_1.is)('function', onMouseEnter_)) onMouseEnter_(event); }, []); const onMouseLeave = react_1.default.useCallback((event) => { setFocus(false); setHover(false); if (!refs.autoPlay.current) start(); if ((0, utils_1.is)('function', onMouseLeave_)) onMouseLeave_(event); }, []); const onArrowMouseEnter = react_1.default.useCallback((event) => { setHover(true); if (refs.autoPlay.current) clear(); }, []); const ArrowPreviousTransitionComponent_ = ArrowPreviousTransitionComponent || ArrowTransitionComponent; const ArrowNextTransitionComponent_ = ArrowNextTransitionComponent || ArrowTransitionComponent; let TransitionComponent = TransitionComponent_; if (noTransition) TransitionComponent = react_1.default.Fragment; if (version === 'regular') { styles.carousel.transform = `translate3d(${orientation === 'horizontal' ? `${-((value === null || value === void 0 ? void 0 : value.x) || 0)}px, 0` : `0, ${-((value === null || value === void 0 ? void 0 : value.y) || 0)}px`}, 0)`; } const indexActive = value === null || value === void 0 ? void 0 : value.index; let arrowPreviousIn = focus || (arrowsVisibility === 'hover' && hover) || arrowsVisibility === 'visible'; let arrowNextIn = focus || (arrowsVisibility === 'hover' && hover) || arrowsVisibility === 'visible'; if (arrowHideOnStartEnd) { const min = 0; let maxX = ((width + (gap * theme.space.unit)) * (refs.itemsLength.current - 1)); let maxY = ((height + (gap * theme.space.unit)) * (refs.itemsLength.current - 1)); if (refs.itemSize.current === 'auto') { maxX = (scrollWidth - (scrollWidth / refs.itemsLength.current)) + ((gap * theme.space.unit) * (refs.itemsLength.current - 1)); maxY = (scrollHeight - (scrollHeight / refs.itemsLength.current)) + ((gap * theme.space.unit) * (refs.itemsLength.current - 1)); } if ((value === null || value === void 0 ? void 0 : value.x) === min || (value === null || value === void 0 ? void 0 : value.y) === min) arrowPreviousIn = false; if (itemSize === 'auto') { if (((value === null || value === void 0 ? void 0 : value.x) !== undefined && (value === null || value === void 0 ? void 0 : value.x) + 1 >= maxX) || ((value === null || value === void 0 ? void 0 : value.y) !== undefined && (value === null || value === void 0 ? void 0 : value.y) + 1 >= maxY)) arrowNextIn = false; } else { if (((value === null || value === void 0 ? void 0 : value.x) !== undefined && (value === null || value === void 0 ? void 0 : value.x) + 1 >= maxX) || ((value === null || value === void 0 ? void 0 : value.y) + 1 !== undefined && (value === null || value === void 0 ? void 0 : value.y) >= maxY)) arrowNextIn = false; } } const ArrowPreviousProps = Object.assign(Object.assign({}, ArrowPreviousProps_), { 'aria-label': 'Arrow previous', 'aria-controls': refs.ids.items }); const ArrowNextProps = Object.assign(Object.assign({}, ArrowNextProps_), { 'aria-label': 'Arrow next', 'aria-controls': refs.ids.items }); const resolveItem = (Item) => { if (!Item) return null; if ((0, utils_1.is)('string', Item)) { if (background) return ((0, jsx_runtime_1.jsx)("div", { className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Carousel', theme) && [ 'amaui-Carousel-background' ], classes.background ]), style: { backgroundImage: `url(${Item})` } })); return ((0, jsx_runtime_1.jsx)("img", { src: Item, alt: '' })); } if ((0, utils_1.is)('function', Item)) return Item(refs.value.current); if (Item === null || Item === void 0 ? void 0 : Item.element) return react_1.default.cloneElement(Item.element); return react_1.default.cloneElement(Item); }; return ((0, jsx_runtime_1.jsxs)(Surface, Object.assign({ ref: item => { if (ref) { if ((0, utils_1.is)('function', ref)) ref(item); else ref.current = item; } refs.root.current = item; }, tabIndex: '0', role: 'region', "aria-roledescription": 'carousel', tonal: tonal, color: color, onFocus: onFocus, onBlur: onBlur, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, Component: Component, className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Carousel', theme) && [ 'amaui-Carousel-root' ], className, classes.root, autoHeight && classes.autoHeight ]) }, other, { children: [start_, version === 'regular' && ((0, jsx_runtime_1.jsx)(Line, Object.assign({ ref: refs.carousel, gap: gap, direction: orientation === 'horizontal' ? theme.direction === 'ltr' ? 'row' : 'row-reverse' : 'column', align: 'center', justify: 'flex-start', onWheel: mouseScroll && onWheel, onMouseDown: onMouseDown, onTouchStart: onMouseDown, onMouseUp: onMouseUp, onTouchEnd: onMouseUp, id: refs.ids.items, "aria-live": 'polite' }, CarouselProps, { className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Carousel', theme) && [ 'amaui-Carousel-carousel' ], CarouselProps === null || CarouselProps === void 0 ? void 0 : CarouselProps.className, classes.carousel, classes[`carousel_version_${version}`] ]), style: Object.assign(Object.assign({}, styles.carousel), CarouselProps === null || CarouselProps === void 0 ? void 0 : CarouselProps.style) }, { children: items.map((item, index) => ((0, jsx_runtime_1.jsx)(Line, Object.assign({ gap: 0, direction: 'column', align: 'center', justify: 'center', role: 'group', "aria-roledescription": 'slide', "aria-label": `${index + 1} out of ${refs.itemsLength.current}` }, ItemWrapperProps, { className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Carousel', theme) && [ 'amaui-Carousel-item' ], ItemWrapperProps === null || ItemWrapperProps === void 0 ? void 0 : ItemWrapperProps.className, classes.item, autoHeight && classes[`item_version_${version}_autoHeight`], itemSize && classes[`item_itemSize_${itemSize}`] ]) }, { children: resolveItem(item) }), index))) }))), version === 'transition' && ((0, jsx_runtime_1.jsx)(Line, Object.assign({ ref: refs.carousel, gap: 0.5, direction: orientation === 'horizontal' ? theme.direction === 'ltr' ? 'row' : 'row-reverse' : 'column', align: 'center', justify: 'center', onWheel: mouseScroll && onWheel, onMouseDown: onMouseDown, onTouchStart: onMouseDown, onMouseUp: onMouseUp, onTouchEnd: onMouseUp, id: refs.ids.items, "aria-live": 'polite' }, CarouselProps, { className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Carousel', theme) && [ 'amaui-Carousel-carousel' ], CarouselProps === null || CarouselProps === void 0 ? void 0 : CarouselProps.className, classes.carousel ]) }, { children: value && ((0, jsx_runtime_1.jsx)(Transitions, Object.assign({ mode: 'in-out-follow', switch: true }, TransitionsProps, { children: (0, jsx_runtime_1.jsx)(TransitionComponent, Object.assign({}, TransitionComponentProps, { children: (0, jsx_runtime_1.jsx)(Line, Object.assign({ ref: refs.item, gap: 0, direction: 'column', align: 'center', justify: 'center', role: 'group', "aria-roledescription": 'slide', "aria-label": `${value.index + 1} out of ${refs.itemsLength.current}`, className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Carousel', theme) && [ 'amaui-Carousel-item-transition' ], classes.item_transition, autoHeight && classes[`item_version_${version}_autoHeight`], ]) }, { children: resolveItem(value.element) })) }), indexActive) }))) }))), progress && ((0, jsx_runtime_1.jsx)(ProgressTransitionComponent, Object.assign({ in: focus || (progressVisibility === 'hover' && hover) || progressVisibility === 'visible' }, ProgressTransitionComponentProps, { children: (0, utils_1.is)('function', renderProgress) ? renderProgress(onUpdate) : (0, jsx_runtime_1.jsx)(Line, Object.assign({ gap: 1, direction: orientation === 'horizontal' ? theme.direction === 'ltr' ? 'row' : 'row-reverse' : 'column', align: 'center', justify: 'center', wrap: 'wrap', className: (0, style_react_1.classNames)