UNPKG

@mantine/carousel

Version:
287 lines (286 loc) 10.3 kB
"use client"; const require_runtime = require("./_virtual/_rolldown/runtime.cjs"); const require_Carousel_context = require("./Carousel.context.cjs"); const require_Carousel_module = require("./Carousel.module.cjs"); const require_CarouselSlide = require("./CarouselSlide/CarouselSlide.cjs"); const require_CarouselVariables = require("./CarouselVariables/CarouselVariables.cjs"); const require_get_chevron_rotation = require("./get-chevron-rotation.cjs"); let react = require("react"); let embla_carousel_react = require("embla-carousel-react"); embla_carousel_react = require_runtime.__toESM(embla_carousel_react); let _mantine_core = require("@mantine/core"); let _mantine_hooks = require("@mantine/hooks"); let react_jsx_runtime = require("react/jsx-runtime"); //#region packages/@mantine/carousel/src/Carousel.tsx const defaultProps = { controlSize: 26, controlsOffset: "sm", slideSize: "100%", slideGap: 0, orientation: "horizontal", includeGapInSize: true, initialSlide: 0, withControls: true, withIndicators: false, withKeyboardEvents: true, type: "media" }; const defaultEmblaOptions = { align: "center", loop: false, slidesToScroll: 1, dragFree: false, inViewThreshold: 0, skipSnaps: false, containScroll: "trimSnaps" }; const varsResolver = (0, _mantine_core.createVarsResolver)((_, { height, controlSize, controlsOffset }) => ({ root: { "--carousel-height": (0, _mantine_core.rem)(height), "--carousel-control-size": (0, _mantine_core.rem)(controlSize), "--carousel-controls-offset": (0, _mantine_core.getSpacing)(controlsOffset) } })); const Carousel = (0, _mantine_core.factory)((_props) => { const props = (0, _mantine_core.useProps)("Carousel", defaultProps, _props); const { classNames, className, style, styles, unstyled, vars, children, getEmblaApi, onNextSlide, onPreviousSlide, onSlideChange, nextControlProps, previousControlProps, controlSize, controlsOffset, slideSize, slideGap, orientation, height, includeGapInSize, draggable, initialSlide, withControls, withIndicators, plugins, nextControlIcon, previousControlIcon, withKeyboardEvents, mod, type, emblaOptions, attributes, getIndicatorProps, id, ...others } = props; const getStyles = (0, _mantine_core.useStyles)({ name: "Carousel", classes: require_Carousel_module.default, props, className, style, classNames, styles, unstyled, attributes, vars, varsResolver }); const _id = (0, _mantine_hooks.useId)(id); const responsiveClassName = (0, _mantine_core.useRandomClassName)(); const { dir } = (0, _mantine_core.useDirection)(); const [emblaRefElement, embla] = (0, embla_carousel_react.default)({ axis: orientation === "horizontal" ? "x" : "y", direction: orientation === "horizontal" ? dir : void 0, startIndex: initialSlide, ...defaultEmblaOptions, ...emblaOptions }, plugins); const [selected, setSelected] = (0, react.useState)(0); const [slidesCount, setSlidesCount] = (0, react.useState)(0); const handleScroll = (0, react.useCallback)((index) => embla && embla.scrollTo(index), [embla]); const handleSelect = (0, react.useCallback)(() => { if (!embla) return; const slide = embla.selectedScrollSnap(); setSelected(slide); slide !== selected && onSlideChange?.(slide); }, [ embla, setSelected, onSlideChange, selected ]); const handlePrevious = (0, react.useCallback)(() => { embla?.scrollPrev(); onPreviousSlide?.(); }, [embla]); const handleNext = (0, react.useCallback)(() => { embla?.scrollNext(); onNextSlide?.(); }, [embla]); const handleKeydown = (0, react.useCallback)((event) => { if (withKeyboardEvents) { if (event.key === "ArrowRight") { event.preventDefault(); handleNext(); } if (event.key === "ArrowLeft") { event.preventDefault(); handlePrevious(); } if (event.key === "Home") { event.preventDefault(); embla?.scrollTo(0); } if (event.key === "End") { event.preventDefault(); embla?.scrollTo(embla.scrollSnapList().length - 1); } } }, [ embla, handleNext, handlePrevious ]); (0, react.useEffect)(() => { if (embla) { getEmblaApi?.(embla); handleSelect(); setSlidesCount(embla.scrollSnapList().length); embla.on("select", handleSelect); return () => { embla.off("select", handleSelect); }; } }, [ embla, emblaOptions?.slidesToScroll, handleSelect ]); (0, react.useEffect)(() => { if (embla) { embla.reInit(); setSlidesCount(embla.scrollSnapList().length); setSelected((currentSelected) => (0, _mantine_hooks.clamp)(currentSelected, 0, react.Children.toArray(children).length - 1)); } }, [react.Children.toArray(children).length, emblaOptions?.slidesToScroll]); const canScrollPrev = embla?.canScrollPrev() || false; const canScrollNext = embla?.canScrollNext() || false; const handleIndicatorKeyDown = (0, react.useCallback)((event, index) => { const isHorizontal = orientation === "horizontal"; const nextKey = isHorizontal ? "ArrowRight" : "ArrowDown"; const prevKey = isHorizontal ? "ArrowLeft" : "ArrowUp"; if (event.key === nextKey) { event.preventDefault(); const nextIndex = index < slidesCount - 1 ? index + 1 : 0; handleScroll(nextIndex); (event.currentTarget.parentElement?.children[nextIndex])?.focus(); } if (event.key === prevKey) { event.preventDefault(); const prevIndex = index > 0 ? index - 1 : slidesCount - 1; handleScroll(prevIndex); (event.currentTarget.parentElement?.children[prevIndex])?.focus(); } if (event.key === "Home") { event.preventDefault(); handleScroll(0); (event.currentTarget.parentElement?.children[0])?.focus(); } if (event.key === "End") { event.preventDefault(); handleScroll(slidesCount - 1); (event.currentTarget.parentElement?.children[slidesCount - 1])?.focus(); } }, [ orientation, slidesCount, handleScroll ]); const indicators = Array(slidesCount).fill(0).map((_, index) => /* @__PURE__ */ (0, react.createElement)(_mantine_core.UnstyledButton, { ...getStyles("indicator"), key: index, role: "tab", "aria-label": `Go to slide ${index + 1}`, "aria-selected": index === selected, tabIndex: index === selected ? 0 : -1, "data-active": index === selected || void 0, onClick: () => handleScroll(index), onKeyDown: (event) => handleIndicatorKeyDown(event, index), "data-orientation": orientation, onMouseDown: (event) => event.preventDefault(), ...getIndicatorProps?.(index) })); return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Carousel_context.CarouselProvider, { value: { getStyles, orientation }, children: [type === "container" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_CarouselVariables.CarouselContainerVariables, { ...props, selector: `.${responsiveClassName}` }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_CarouselVariables.CarouselVariables, { ...props, selector: `.${responsiveClassName}` }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mantine_core.Box, { role: "region", "aria-roledescription": "carousel", ...getStyles("root", { className: responsiveClassName }), ...others, id: _id, mod: [{ orientation, "include-gap-in-size": includeGapInSize }, mod], onKeyDownCapture: handleKeydown, children: [ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mantine_core.VisuallyHidden, { role: "status", "aria-live": "polite", "aria-atomic": "true", children: slidesCount > 0 && `Slide ${selected + 1} of ${slidesCount}` }), withControls && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { ...getStyles("controls"), "data-orientation": orientation, children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mantine_core.UnstyledButton, { "aria-controls": _id, "aria-label": "Previous slide", "aria-disabled": !canScrollPrev, "data-inactive": !canScrollPrev || void 0, "data-type": "previous", tabIndex: canScrollPrev ? 0 : -1, ...previousControlProps, ...getStyles("control", { className: previousControlProps?.className, style: previousControlProps?.style }), onClick: (event) => { handlePrevious(); previousControlProps?.onClick?.(event); }, children: typeof previousControlIcon !== "undefined" ? previousControlIcon : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mantine_core.AccordionChevron, { style: { transform: `rotate(${require_get_chevron_rotation.getChevronRotation({ dir, orientation, direction: "previous" })}deg)` } }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mantine_core.UnstyledButton, { "aria-controls": _id, "aria-label": "Next slide", "aria-disabled": !canScrollNext, "data-inactive": !canScrollNext || void 0, "data-type": "next", tabIndex: canScrollNext ? 0 : -1, ...getStyles("control", { className: nextControlProps?.className, style: nextControlProps?.style }), ...nextControlProps, onClick: (event) => { handleNext(); nextControlProps?.onClick?.(event); }, children: typeof nextControlIcon !== "undefined" ? nextControlIcon : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mantine_core.AccordionChevron, { style: { transform: `rotate(${require_get_chevron_rotation.getChevronRotation({ dir, orientation, direction: "next" })}deg)` } }) })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { ...getStyles("viewport"), ref: emblaRefElement, "data-type": type, children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { ...getStyles("container", { className: responsiveClassName }), "data-orientation": orientation, children }) }), withIndicators && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { ...getStyles("indicators"), role: "tablist", "aria-label": "Slides", "data-orientation": orientation, children: indicators }) ] })] }); }); Carousel.classes = require_Carousel_module.default; Carousel.varsResolver = varsResolver; Carousel.displayName = "@mantine/carousel/Carousel"; Carousel.Slide = require_CarouselSlide.CarouselSlide; //#endregion exports.Carousel = Carousel; //# sourceMappingURL=Carousel.cjs.map