UNPKG

@hitachivantara/uikit-react-core

Version:

Core React components for the NEXT Design System.

228 lines (227 loc) 8.42 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const jsxRuntime = require("react/jsx-runtime"); const React = require("react"); const useCarousel = require("embla-carousel-react"); const uikitReactUtils = require("@hitachivantara/uikit-react-utils"); const useLabels = require("../hooks/useLabels.cjs"); const icons = require("../icons.cjs"); const Carousel_styles = require("./Carousel.styles.cjs"); const CarouselControls = require("./CarouselControls.cjs"); const CarouselThumbnails = require("./CarouselThumbnails.cjs"); const Container = require("../Container/Container.cjs"); const Button = require("../Button/Button.cjs"); const IconButton = require("../IconButton/IconButton.cjs"); const Typography = require("../Typography/Typography.cjs"); const _interopDefault = (e) => e && e.__esModule ? e : { default: e }; const useCarousel__default = /* @__PURE__ */ _interopDefault(useCarousel); const DEFAULT_LABELS = { close: "Close", fullscreen: "Fullscreen", backwards: "Backwards", forwards: "Forwards" }; const HvCarousel = React.forwardRef(function HvCarousel2(props, ref) { const { className, classes: classesProp, height: heightProp = "auto", thumbnailWidth = 90, title, children, actions: actionsProp, xs, showDots: showDotsProp, showCounter: showCounterProp, showSlideControls, showFullscreen: showFullscreenProp, hideThumbnails: hideThumbnailsProp, controlsPosition: controlsPositionProp, thumbnailsPosition: thumbnailsPositionProp, labels: labelsProps, carouselOptions, renderThumbnail, onChange, onFullscreen, ...others } = uikitReactUtils.useDefaultProps("HvCarousel", props); const { activeTheme } = uikitReactUtils.useTheme(); const { classes, css, cx } = Carousel_styles.useClasses(classesProp); const labels = useLabels.useLabels(DEFAULT_LABELS, labelsProps); const thumbnailsRef = React.useRef(null); const [isFullscreen, setIsFullscreen] = React.useState(false); const isDs3 = activeTheme?.base === "ds3"; const actionsPosition = isDs3 ? "header" : "controls"; const controlsPosition = controlsPositionProp ?? (isDs3 ? "bottom" : "top"); const thumbnailsPosition = thumbnailsPositionProp ?? "bottom"; const [containerRef, controller] = useCarousel__default.default({ align: "start", loop: true, ...carouselOptions }); const [selectedIndex, setSelectedIndex] = React.useState( carouselOptions?.startIndex ?? 0 ); const numSlides = React.Children.count(children); const handlePrevious = React.useCallback(() => { controller?.scrollPrev(); }, [controller]); const handleNext = React.useCallback(() => { controller?.scrollNext(); }, [controller]); const handleScroll = (index) => { controller?.scrollTo(index); }; const handleSelect = React.useCallback(() => { if (!controller) return; const slideIndex = controller.selectedScrollSnap(); setSelectedIndex(slideIndex); thumbnailsRef.current?.querySelectorAll("button")?.[slideIndex]?.scrollIntoView({ behavior: "smooth", block: "nearest" }); onChange?.(slideIndex); }, [controller, onChange]); React.useEffect(() => { if (!controller) return; controller.on("select", handleSelect); return () => { controller.off("select", handleSelect); }; }, [controller, handleSelect]); React.useEffect(() => { if (!controller) return; controller.reInit(); setSelectedIndex((currentIndex) => uikitReactUtils.clamp(currentIndex, numSlides)); }, [numSlides, controller]); const handleFullscreen = (event) => { onFullscreen?.(event, !isFullscreen); setIsFullscreen((curr) => !curr); }; const canPrev = controller?.canScrollPrev() ?? false; const canNext = controller?.canScrollNext() ?? false; const showTitle = !!title && (!xs || isFullscreen); const showFullscreen = showFullscreenProp ?? xs; const height = isFullscreen ? "100%" : heightProp ?? "auto"; const showCounter = xs; const hideThumbnails = hideThumbnailsProp ?? (xs && !isFullscreen); const showThumbnails = !hideThumbnails && !!renderThumbnail; const showDots = showDotsProp ?? numSlides <= 5; const actions = /* @__PURE__ */ jsxRuntime.jsxs( "div", { className: cx( classes.actions, actionsPosition === "header" ? css({ position: "relative", top: -40, height: 0 }) : css({ position: "absolute" }) ), children: [ actionsProp, showFullscreen && /* @__PURE__ */ jsxRuntime.jsx( IconButton.HvIconButton, { title: isFullscreen ? labels.close : labels.fullscreen, onClick: handleFullscreen, className: classes.closeButton, children: /* @__PURE__ */ jsxRuntime.jsx(icons.HvIcon, { name: isFullscreen ? "Close" : "Fullscreen" }) } ) ] } ); const controls = /* @__PURE__ */ jsxRuntime.jsx( CarouselControls.HvCarouselControls, { classes, showDots, page: selectedIndex, pages: numSlides, canPrevious: canPrev, canNext, onPreviousClick: handlePrevious, onNextClick: handleNext, actions: actionsPosition === "controls" && actions, labels: { backwards: labels.backwards, forwards: labels.forwards } } ); const thumbnails = showThumbnails && /* @__PURE__ */ jsxRuntime.jsx( CarouselThumbnails.HvCarouselThumbnails, { classes, ref: thumbnailsRef, page: selectedIndex, pages: numSlides, width: thumbnailWidth, onThumbnailClick: (evt, i) => handleScroll(i), renderThumbnail } ); return /* @__PURE__ */ jsxRuntime.jsxs( Container.HvContainer, { ref, className: cx(classes.root, className, { [classes.xs]: xs, [classes.fullscreen]: isFullscreen }), ...others, children: [ showTitle && /* @__PURE__ */ jsxRuntime.jsx(Typography.HvTypography, { variant: "title2", className: classes.title, children: title }), actionsPosition === "header" && actions, thumbnailsPosition === "top" && thumbnails, controlsPosition === "top" && controls, /* @__PURE__ */ jsxRuntime.jsxs( "div", { className: cx(classes.main, { [classes.mainXs]: xs, [classes.mainFullscreen]: isFullscreen }), children: [ showCounter && /* @__PURE__ */ jsxRuntime.jsx("div", { className: classes.counterContainer, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: classes.counter, children: `${selectedIndex + 1}/${numSlides}` }) }), showSlideControls && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: classes.slideControls, children: [ /* @__PURE__ */ jsxRuntime.jsx( Button.HvButton, { icon: true, disabled: !canPrev, variant: "secondarySubtle", "aria-label": labels.backwards, onClick: handlePrevious, children: /* @__PURE__ */ jsxRuntime.jsx(icons.HvIcon, { name: "Backwards", size: "xs" }) } ), /* @__PURE__ */ jsxRuntime.jsx( Button.HvButton, { icon: true, disabled: !canNext, variant: "secondarySubtle", "aria-label": labels.forwards, onClick: handleNext, children: /* @__PURE__ */ jsxRuntime.jsx(icons.HvIcon, { name: "Forwards", size: "xs" }) } ) ] }), /* @__PURE__ */ jsxRuntime.jsx( "div", { ref: containerRef, style: { height }, className: classes.slidesViewport, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: classes.slidesContainer, children }) } ) ] } ), controlsPosition === "bottom" && controls, thumbnailsPosition === "bottom" && thumbnails ] } ); }); exports.carouselClasses = Carousel_styles.staticClasses; exports.HvCarousel = HvCarousel;