@vectara/vectara-ui
Version:
Vectara's design system, codified as a React and Sass component library
70 lines (69 loc) • 5.7 kB
JavaScript
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 }) }))] })) })) })) }))) }));
};