UNPKG

@vectara/vectara-ui

Version:

Vectara's design system, codified as a React and Sass component library

70 lines (69 loc) 5.7 kB
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; import { useEffect, useRef, useState } from "react"; import { FocusOn } from "react-focus-on"; import { BiX, BiChevronLeft, BiChevronRight } from "react-icons/bi"; import { VuiIconButton } from "../button/IconButton"; import { VuiIcon } from "../icon/Icon"; import { VuiPortal } from "../portal/Portal"; import { VuiFlexContainer } from "../flex/FlexContainer"; import { VuiFlexItem } from "../flex/FlexItem"; import { VuiText } from "../typography/Text"; import { VuiTextColor } from "../typography/TextColor"; import { getOverlayProps } from "../../utils/getOverlayProps"; export const VuiImagePreview = ({ images, initialIndex = 0, isOpen, onClose, className }) => { const returnFocusElRef = useRef(null); const [currentIndex, setCurrentIndex] = useState(initialIndex); const isCarousel = images.length > 1; useEffect(() => { var _a; if (isOpen) { returnFocusElRef.current = document.activeElement; setCurrentIndex(initialIndex); } else { (_a = returnFocusElRef.current) === null || _a === void 0 ? void 0 : _a.focus(); returnFocusElRef.current = null; } }, [isOpen, initialIndex]); useEffect(() => { if (!isOpen) return; const handleKeyDown = (e) => { if (e.key === "ArrowLeft") { e.preventDefault(); handlePrevious(); } else if (e.key === "ArrowRight") { e.preventDefault(); handleNext(); } }; window.addEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown); }, [isOpen, currentIndex]); const handlePrevious = () => { setCurrentIndex((prev) => (prev > 0 ? prev - 1 : images.length - 1)); }; const handleNext = () => { setCurrentIndex((prev) => (prev < images.length - 1 ? prev + 1 : 0)); }; const handleOnClose = () => { onClose === null || onClose === void 0 ? void 0 : onClose(); }; return (_jsx(VuiPortal, { children: isOpen && (_jsx(FocusOn, Object.assign({ onEscapeKey: handleOnClose, returnFocus: false, autoFocus: isOpen }, { children: _jsx("figure", Object.assign({ className: className }, getOverlayProps("imagePreviewTitle"), { children: _jsx("div", Object.assign({ className: "vuiImagePreview__container" }, { children: _jsxs("div", Object.assign({ className: "vuiImagePreview__mask", onClick: handleOnClose }, { children: [_jsx("div", Object.assign({ onClick: (e) => e.stopPropagation() }, { children: _jsxs(VuiFlexContainer, Object.assign({ alignItems: "center", justifyContent: "spaceBetween", className: "vuiImagePreview__header" }, { children: [_jsx(VuiFlexItem, { children: _jsxs(VuiFlexContainer, Object.assign({ alignItems: "center", spacing: "xs" }, { children: [isCarousel && (_jsxs(_Fragment, { children: [_jsx(VuiFlexItem, { children: _jsx(VuiIconButton, { "aria-label": "Previous image", onClick: (e) => { e.stopPropagation(); handlePrevious(); }, color: "neutral", size: "s", icon: _jsx(VuiIcon, Object.assign({ size: "m", color: "empty" }, { children: _jsx(BiChevronLeft, {}) })), tooltip: { darkTheme: true, position: "bottom-end" } }) }), _jsx(VuiFlexItem, { children: _jsx(VuiIconButton, { "aria-label": "Next image", onClick: (e) => { e.stopPropagation(); handleNext(); }, color: "neutral", size: "s", icon: _jsx(VuiIcon, Object.assign({ size: "m", color: "empty" }, { children: _jsx(BiChevronRight, {}) })), tooltip: { darkTheme: true, position: "bottom" } }) })] })), _jsx(VuiFlexItem, { children: _jsx(VuiText, Object.assign({ size: "s" }, { children: _jsx(VuiTextColor, Object.assign({ color: "empty" }, { children: _jsxs("figcaption", Object.assign({ id: "imagePreviewTitle" }, { children: [isCarousel && `Image ${currentIndex + 1} of ${images.length}: `, images[currentIndex].caption] })) })) })) })] })) }), _jsx(VuiFlexItem, Object.assign({ grow: false }, { children: _jsx("div", Object.assign({ className: "vuiImagePreview__closeButton" }, { children: _jsx(VuiIconButton, { "aria-label": "Close preview", onClick: handleOnClose, color: "neutral", icon: _jsx(VuiIcon, Object.assign({ size: "l", color: "empty" }, { children: _jsx(BiX, {}) })), tooltip: { darkTheme: true, position: "bottom-end" } }) })) }))] })) })), _jsx("div", Object.assign({ className: "vuiImagePreview__imageContainer" }, { children: _jsx("img", { src: images[currentIndex].src, alt: images[currentIndex].alt, className: "vuiImagePreview__image", draggable: false }) }))] })) })) })) }))) })); };