UNPKG

@mantine/carousel

Version:
271 lines (265 loc) 8.82 kB
'use client'; 'use strict'; var jsxRuntime = require('react/jsx-runtime'); var react = require('react'); var useEmblaCarousel = require('embla-carousel-react'); var core = require('@mantine/core'); var hooks = require('@mantine/hooks'); var Carousel_context = require('./Carousel.context.cjs'); var CarouselSlide = require('./CarouselSlide/CarouselSlide.cjs'); var CarouselVariables = require('./CarouselVariables/CarouselVariables.cjs'); var getChevronRotation = require('./get-chevron-rotation.cjs'); var Carousel_module = require('./Carousel.module.css.cjs'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var useEmblaCarousel__default = /*#__PURE__*/_interopDefault(useEmblaCarousel); 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 = core.createVarsResolver( (_, { height, controlSize, controlsOffset }) => ({ root: { "--carousel-height": core.rem(height), "--carousel-control-size": core.rem(controlSize), "--carousel-controls-offset": core.getSpacing(controlsOffset) } }) ); const Carousel = core.factory((_props, ref) => { const props = 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, ...others } = props; const getStyles = core.useStyles({ name: "Carousel", classes: Carousel_module, props, className, style, classNames, styles, unstyled, attributes, vars, varsResolver }); const responsiveClassName = core.useRandomClassName(); const { dir } = core.useDirection(); const [emblaRefElement, embla] = useEmblaCarousel__default.default( { axis: orientation === "horizontal" ? "x" : "y", direction: orientation === "horizontal" ? dir : void 0, startIndex: initialSlide, ...defaultEmblaOptions, ...emblaOptions }, plugins ); const [selected, setSelected] = react.useState(0); const [slidesCount, setSlidesCount] = react.useState(0); const handleScroll = react.useCallback((index) => embla && embla.scrollTo(index), [embla]); const handleSelect = react.useCallback(() => { if (!embla) { return; } const slide = embla.selectedScrollSnap(); setSelected(slide); slide !== selected && onSlideChange?.(slide); }, [embla, setSelected, onSlideChange, selected]); const handlePrevious = react.useCallback(() => { embla?.scrollPrev(); onPreviousSlide?.(); }, [embla]); const handleNext = react.useCallback(() => { embla?.scrollNext(); onNextSlide?.(); }, [embla]); const handleKeydown = react.useCallback( (event) => { if (withKeyboardEvents) { if (event.key === "ArrowRight") { event.preventDefault(); handleNext(); } if (event.key === "ArrowLeft") { event.preventDefault(); handlePrevious(); } } }, [embla] ); react.useEffect(() => { if (embla) { getEmblaApi?.(embla); handleSelect(); setSlidesCount(embla.scrollSnapList().length); embla.on("select", handleSelect); return () => { embla.off("select", handleSelect); }; } return void 0; }, [embla, emblaOptions?.slidesToScroll, handleSelect]); react.useEffect(() => { if (embla) { embla.reInit(); setSlidesCount(embla.scrollSnapList().length); setSelected( (currentSelected) => 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 indicators = Array(slidesCount).fill(0).map((_, index) => /* @__PURE__ */ react.createElement( core.UnstyledButton, { ...getStyles("indicator"), key: index, "data-active": index === selected || void 0, "aria-hidden": true, tabIndex: -1, onClick: () => handleScroll(index), "data-orientation": orientation, onMouseDown: (event) => event.preventDefault() } )); return /* @__PURE__ */ jsxRuntime.jsxs(Carousel_context.CarouselProvider, { value: { getStyles, orientation }, children: [ type === "container" ? /* @__PURE__ */ jsxRuntime.jsx(CarouselVariables.CarouselContainerVariables, { ...props, selector: `.${responsiveClassName}` }) : /* @__PURE__ */ jsxRuntime.jsx(CarouselVariables.CarouselVariables, { ...props, selector: `.${responsiveClassName}` }), /* @__PURE__ */ jsxRuntime.jsxs( core.Box, { ref, ...getStyles("root", { className: "responsiveClassName" }), ...others, mod: [{ orientation, "include-gap-in-size": includeGapInSize }, mod], onKeyDownCapture: handleKeydown, children: [ /* @__PURE__ */ jsxRuntime.jsx("div", { ...getStyles("viewport"), ref: emblaRefElement, "data-type": type, children: /* @__PURE__ */ jsxRuntime.jsx( "div", { ...getStyles("container", { className: responsiveClassName }), "data-orientation": orientation, children } ) }), withIndicators && /* @__PURE__ */ jsxRuntime.jsx("div", { ...getStyles("indicators"), "data-orientation": orientation, children: indicators }), withControls && /* @__PURE__ */ jsxRuntime.jsxs("div", { ...getStyles("controls"), "data-orientation": orientation, children: [ /* @__PURE__ */ jsxRuntime.jsx( core.UnstyledButton, { ...previousControlProps, ...getStyles("control", { className: previousControlProps?.className, style: previousControlProps?.style }), onClick: (event) => { handlePrevious(); previousControlProps?.onClick?.(event); }, "data-inactive": !canScrollPrev || void 0, tabIndex: canScrollPrev ? 0 : -1, children: typeof previousControlIcon !== "undefined" ? previousControlIcon : /* @__PURE__ */ jsxRuntime.jsx( core.AccordionChevron, { style: { transform: `rotate(${getChevronRotation.getChevronRotation({ dir, orientation, direction: "previous" })}deg)` } } ) } ), /* @__PURE__ */ jsxRuntime.jsx( core.UnstyledButton, { ...getStyles("control", { className: nextControlProps?.className, style: nextControlProps?.style }), ...nextControlProps, onClick: (event) => { handleNext(); nextControlProps?.onClick?.(event); }, "data-inactive": !canScrollNext || void 0, tabIndex: canScrollNext ? 0 : -1, children: typeof nextControlIcon !== "undefined" ? nextControlIcon : /* @__PURE__ */ jsxRuntime.jsx( core.AccordionChevron, { style: { transform: `rotate(${getChevronRotation.getChevronRotation({ dir, orientation, direction: "next" })}deg)` } } ) } ) ] }) ] } ) ] }); }); Carousel.classes = Carousel_module; Carousel.displayName = "@mantine/carousel/Carousel"; Carousel.Slide = CarouselSlide.CarouselSlide; exports.Carousel = Carousel; //# sourceMappingURL=Carousel.cjs.map