@codeworker.br/govbr-tw-react
Version:
Biblioteca de componentes React usando Tailwind CSS que implementa o Padrão Digital de Governo.
402 lines (401 loc) • 27.8 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
import { createPortal } from "react-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faChevronLeft, faChevronRight, faPlay, faXmark } from "@fortawesome/free-solid-svg-icons";
import { cn } from "../../libs/utils";
import { Button } from "../Button";
const VARIANT_STYLES = {
light: {
container: "border-govbr-gray-20 bg-govbr-gray-2 text-govbr-gray-80",
emptyState: {
border: "border-govbr-gray-20",
background: "bg-govbr-pure-0",
text: "text-govbr-gray-50",
},
mainImageWrapper: "border-govbr-gray-20 bg-govbr-pure-0",
navButtonVariant: "ghost",
captionContainer: "border-govbr-gray-20 bg-govbr-pure-0/95",
captionTitle: "text-govbr-blue-warm-vivid-70 text-sm",
captionDescription: "text-govbr-gray-60 text-xs",
captionAttribution: "text-govbr-blue-warm-vivid-70",
captionLink: "text-govbr-blue-warm-vivid-70 hover:text-govbr-blue-warm-vivid-50 decoration-govbr-blue-warm-vivid-70 decoration-1",
gradientLeft: "from-govbr-gray-2",
gradientRight: "from-govbr-gray-2",
thumbnailActive: "border-[3px] border-govbr-blue-warm-vivid-70 shadow-sm",
thumbnailInactive: "border border-govbr-gray-20 hover:border-govbr-blue-warm-vivid-70/60",
overlayBackdrop: "bg-govbr-gray-80/90",
overlayContainer: "border border-govbr-gray-20 bg-govbr-pure-0 text-govbr-gray-80",
overlayButtonVariant: "default",
overlayCaptionBackground: "bg-govbr-gray-10/60 text-govbr-gray-80",
overlayTitle: "text-govbr-blue-warm-vivid-70 text-sm",
overlayDescription: "text-govbr-gray-60 text-xs",
overlayAttribution: "text-govbr-blue-warm-vivid-70 text-xs",
overlayLink: "text-govbr-blue-warm-vivid-70 hover:text-govbr-blue-warm-vivid-50 decoration-1",
overlayLinkDecoration: "decoration-govbr-blue-warm-vivid-70 decoration-1",
},
dark: {
container: "border-govbr-blue-warm-20 bg-govbr-blue-warm-vivid-95 text-govbr-pure-0",
emptyState: {
border: "border-govbr-blue-warm-20",
background: "bg-govbr-blue-warm-vivid-90",
text: "text-govbr-blue-warm-20",
},
mainImageWrapper: "border-govbr-blue-warm-20 bg-govbr-blue-warm-vivid-90",
navButtonVariant: "ghost-dark",
captionContainer: "border-govbr-blue-warm-20 bg-govbr-blue-warm-vivid-90/95",
captionTitle: "text-govbr-pure-0 text-sm",
captionDescription: "text-govbr-blue-warm-20 text-xs",
captionAttribution: "text-govbr-blue-warm-10",
captionLink: "text-govbr-blue-warm-10 hover:text-govbr-pure-0 decoration-govbr-blue-warm-10 decoration-1",
gradientLeft: "from-govbr-blue-warm-vivid-95",
gradientRight: "from-govbr-blue-warm-vivid-95",
thumbnailActive: "border-[3px] border-govbr-blue-warm-10 shadow-sm",
thumbnailInactive: "border border-govbr-blue-warm-40 hover:border-govbr-blue-warm-10/70",
overlayBackdrop: "bg-govbr-gray-90/95",
overlayContainer: "border border-govbr-blue-warm-20 bg-govbr-blue-warm-vivid-95/95 text-govbr-pure-0",
overlayButtonVariant: "ghost-dark",
overlayCaptionBackground: "bg-govbr-blue-warm-vivid-90 text-govbr-pure-0",
overlayTitle: "text-govbr-pure-0",
overlayDescription: "text-govbr-blue-warm-10",
overlayAttribution: "text-govbr-blue-warm-20",
overlayLink: "text-govbr-blue-warm-20 hover:text-govbr-pure-0 decoration-1",
overlayLinkDecoration: "decoration-govbr-blue-warm-20 decoration-1",
},
};
const DEFAULT_FIELD_MAP = {
image: "imageUrl",
thumbnail: "thumbnailUrl",
title: "title",
description: "description",
attributionLabel: "attributionLabel",
attributionUrl: "attributionUrl",
mediaType: "mediaType",
videoUrl: "videoUrl",
videoId: "videoId",
videoProvider: "videoProvider",
};
const DEFAULT_LABELS = {
galleryLabel: "Galeria de fotos",
emptyState: "Nenhuma imagem disponivel.",
previousImageButton: "Imagem anterior",
nextImageButton: "Proxima imagem",
scrollThumbnailsLeft: "Deslocar miniaturas para a esquerda",
scrollThumbnailsRight: "Deslocar miniaturas para a direita",
creditPrefix: "Credito:",
closeLightbox: "Fechar visualizacao em tela cheia",
openLightbox: "Ver imagem em tela cheia",
selectedImageAlt: "Imagem selecionada da galeria {{title}}",
fullscreenImageAlt: "Imagem em tela cheia {{title}}",
thumbnailAlt: "Miniatura {{index}} {{title}}",
thumbnailButton: "Selecionar imagem {{index}} {{title}}",
openVideoLightbox: "Assistir video {{title}} em tela cheia",
videoPreviewAlt: "Miniatura do video {{title}}",
videoIframeTitle: "Player do video {{title}}",
};
const formatLabel = (template, replacements) => {
return template
.replace(/\{\{(\w+)\}\}/g, (_, key) => {
const value = replacements[key];
if (value === undefined || value === null) {
return "";
}
return String(value);
})
.replace(/\s{2,}/g, " ")
.trim();
};
const truncateText = (value, maxLength) => {
if (!value) {
return undefined;
}
if (!Number.isFinite(maxLength) || maxLength <= 0) {
return "...";
}
if (value.length <= maxLength) {
return value;
}
if (maxLength <= 3) {
return "...".slice(0, maxLength);
}
return `${value.slice(0, maxLength - 3).trimEnd()}...`;
};
const YOUTUBE_ID_REGEX = /^[a-zA-Z0-9_-]{11}$/;
const extractYouTubeId = (value) => {
if (!value) {
return undefined;
}
const trimmed = value.trim();
if (YOUTUBE_ID_REGEX.test(trimmed)) {
return trimmed;
}
const url = new URL(trimmed, "https://youtube.com");
const directId = url.searchParams.get("v");
if (directId && YOUTUBE_ID_REGEX.test(directId)) {
return directId;
}
const path = url.pathname;
const embedMatch = path.match(/\/embed\/([a-zA-Z0-9_-]{11})/);
if (embedMatch === null || embedMatch === void 0 ? void 0 : embedMatch[1]) {
return embedMatch[1];
}
const shortMatch = path.match(/\/([a-zA-Z0-9_-]{11})$/);
if (shortMatch === null || shortMatch === void 0 ? void 0 : shortMatch[1]) {
return shortMatch[1];
}
return undefined;
};
const splitPath = (path) => path
.replace(/\[(\d+)\]/g, ".$1")
.split(".")
.filter(Boolean);
const resolvePathValue = (item, path) => {
if (!path) {
return undefined;
}
return splitPath(path).reduce((acc, key) => {
if (acc == null) {
return undefined;
}
if (typeof acc === "object" && key in acc) {
return acc[key];
}
if (Array.isArray(acc)) {
const index = Number.parseInt(key, 10);
return Number.isNaN(index) ? undefined : acc[index];
}
return undefined;
}, item);
};
const resolveFieldValue = (item, selector) => {
if (!selector) {
return undefined;
}
if (typeof selector === "function") {
return selector(item);
}
if (typeof selector === "string") {
return resolvePathValue(item, selector);
}
return undefined;
};
export function PhotoGallery(_a) {
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
var { items, fieldMap, className, ariaLabel, emptyStateLabel, variant = "light", captionMaxLength = 140, fullscreenFit = "contain", labels: labelsProp } = _a, rest = __rest(_a, ["items", "fieldMap", "className", "ariaLabel", "emptyStateLabel", "variant", "captionMaxLength", "fullscreenFit", "labels"]);
const styles = VARIANT_STYLES[variant];
const resolvedLabels = useMemo(() => (Object.assign(Object.assign({}, DEFAULT_LABELS), labelsProp)), [labelsProp]);
const resolvedAriaLabel = ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : resolvedLabels.galleryLabel;
const resolvedEmptyState = emptyStateLabel !== null && emptyStateLabel !== void 0 ? emptyStateLabel : resolvedLabels.emptyState;
const resolvedCaptionLength = Math.max(1, Math.floor(captionMaxLength));
const overlayImageClass = fullscreenFit === "cover"
? "h-full w-full object-cover"
: "h-auto max-h-full w-auto max-w-full object-contain";
const mountedRef = useRef(false);
const scrollContainerRef = useRef(null);
const [currentIndex, setCurrentIndex] = useState(0);
const [isLightboxOpen, setIsLightboxOpen] = useState(false);
const map = useMemo(() => (Object.assign(Object.assign({}, DEFAULT_FIELD_MAP), fieldMap)), [fieldMap]);
const normalizedItems = useMemo(() => {
return items.reduce((acc, item) => {
var _a;
const mediaTypeValue = resolveFieldValue(item, map.mediaType);
const mediaType = mediaTypeValue === "video" || mediaTypeValue === "Video" ? "video" : "image";
const imageValue = resolveFieldValue(item, map.image);
const thumbnailValue = resolveFieldValue(item, map.thumbnail);
const titleValue = resolveFieldValue(item, map.title);
const descriptionValue = resolveFieldValue(item, map.description);
const attributionLabelValue = resolveFieldValue(item, map.attributionLabel);
const attributionUrlValue = resolveFieldValue(item, map.attributionUrl);
const baseTitle = typeof titleValue === "string" ? titleValue : undefined;
const baseDescription = typeof descriptionValue === "string" ? descriptionValue : undefined;
const baseAttributionLabel = typeof attributionLabelValue === "string" ? attributionLabelValue : undefined;
const baseAttributionUrl = typeof attributionUrlValue === "string" ? attributionUrlValue : undefined;
if (mediaType === "video") {
const providerValue = resolveFieldValue(item, map.videoProvider);
const provider = typeof providerValue === "string" ? providerValue.toLowerCase().trim() : "youtube";
if (provider !== "youtube") {
return acc;
}
const videoUrlValue = resolveFieldValue(item, map.videoUrl);
const videoIdValue = resolveFieldValue(item, map.videoId);
const resolvedVideoUrl = typeof videoUrlValue === "string" ? videoUrlValue.trim() : undefined;
const videoIdFromField = typeof videoIdValue === "string" && videoIdValue.trim().length > 0
? videoIdValue.trim()
: undefined;
const videoId = videoIdFromField !== null && videoIdFromField !== void 0 ? videoIdFromField : extractYouTubeId(resolvedVideoUrl);
if (!videoId) {
return acc;
}
const thumbnailCandidate = typeof thumbnailValue === "string" && thumbnailValue.trim().length > 0
? thumbnailValue.trim()
: undefined;
const imageCandidate = typeof imageValue === "string" && imageValue.trim().length > 0
? imageValue.trim()
: undefined;
const thumbnail = (_a = thumbnailCandidate !== null && thumbnailCandidate !== void 0 ? thumbnailCandidate : imageCandidate) !== null && _a !== void 0 ? _a : `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`;
const image = imageCandidate !== null && imageCandidate !== void 0 ? imageCandidate : thumbnail;
if (!thumbnail) {
return acc;
}
const embedBase = `https://www.youtube.com/embed/${videoId}`;
const embedUrl = `${embedBase}?rel=0`;
const embedAutoplayUrl = `${embedBase}?autoplay=1&rel=0`;
acc.push({
mediaType: "video",
image,
thumbnail,
title: baseTitle,
description: baseDescription,
attributionLabel: baseAttributionLabel,
attributionUrl: baseAttributionUrl,
video: {
provider: "youtube",
videoId,
url: resolvedVideoUrl !== null && resolvedVideoUrl !== void 0 ? resolvedVideoUrl : `https://www.youtube.com/watch?v=${videoId}`,
embedUrl,
embedAutoplayUrl,
},
});
return acc;
}
const resolvedImage = typeof imageValue === "string" && imageValue.trim().length > 0
? imageValue.trim()
: undefined;
if (!resolvedImage) {
return acc;
}
const thumbnail = typeof thumbnailValue === "string" && thumbnailValue.trim().length > 0
? thumbnailValue.trim()
: resolvedImage;
acc.push({
mediaType: "image",
image: resolvedImage,
thumbnail,
title: baseTitle,
description: baseDescription,
attributionLabel: baseAttributionLabel,
attributionUrl: baseAttributionUrl,
});
return acc;
}, []);
}, [items, map]);
useEffect(() => {
if (currentIndex >= normalizedItems.length) {
setCurrentIndex(0);
}
}, [currentIndex, normalizedItems.length]);
useEffect(() => {
mountedRef.current = true;
return () => {
mountedRef.current = false;
};
}, []);
const activeItem = normalizedItems[currentIndex];
const hasImages = normalizedItems.length > 0;
const truncatedDescription = (activeItem === null || activeItem === void 0 ? void 0 : activeItem.description) != null
? truncateText(activeItem.description, resolvedCaptionLength)
: undefined;
const mainImageAlt = (activeItem === null || activeItem === void 0 ? void 0 : activeItem.mediaType) === "image"
? formatLabel(resolvedLabels.selectedImageAlt, { title: (_b = activeItem.title) !== null && _b !== void 0 ? _b : "" })
: undefined;
const videoPreviewAlt = (activeItem === null || activeItem === void 0 ? void 0 : activeItem.mediaType) === "video"
? formatLabel(resolvedLabels.videoPreviewAlt, { title: (_c = activeItem.title) !== null && _c !== void 0 ? _c : "" })
: undefined;
const fullscreenImageAlt = (activeItem === null || activeItem === void 0 ? void 0 : activeItem.mediaType) === "image"
? formatLabel(resolvedLabels.fullscreenImageAlt, { title: (_d = activeItem.title) !== null && _d !== void 0 ? _d : "" })
: undefined;
const videoIframeTitle = (activeItem === null || activeItem === void 0 ? void 0 : activeItem.mediaType) === "video"
? formatLabel(resolvedLabels.videoIframeTitle, {
title: (_g = (_e = activeItem.title) !== null && _e !== void 0 ? _e : (_f = activeItem.video) === null || _f === void 0 ? void 0 : _f.videoId) !== null && _g !== void 0 ? _g : "",
})
: undefined;
const openLightboxLabel = (activeItem === null || activeItem === void 0 ? void 0 : activeItem.mediaType) === "video"
? formatLabel(resolvedLabels.openVideoLightbox, { title: (_h = activeItem.title) !== null && _h !== void 0 ? _h : "" })
: formatLabel(resolvedLabels.openLightbox, { title: (_j = activeItem === null || activeItem === void 0 ? void 0 : activeItem.title) !== null && _j !== void 0 ? _j : "" });
const goToIndex = useCallback((index) => {
if (!hasImages) {
return;
}
const nextIndex = (index + normalizedItems.length) % normalizedItems.length;
setCurrentIndex(nextIndex);
}, [hasImages, normalizedItems.length]);
const goNext = useCallback(() => {
goToIndex(currentIndex + 1);
}, [currentIndex, goToIndex]);
const goPrevious = useCallback(() => {
goToIndex(currentIndex - 1);
}, [currentIndex, goToIndex]);
const scrollThumbnails = useCallback((direction) => {
const container = scrollContainerRef.current;
if (!container) {
return;
}
const amount = direction === "left" ? -240 : 240;
container.scrollBy({
left: amount,
behavior: "smooth",
});
}, []);
const closeLightbox = useCallback(() => {
setIsLightboxOpen(false);
}, []);
useEffect(() => {
if (!isLightboxOpen) {
return;
}
const onKeyDown = (event) => {
if (event.key === "Escape") {
event.preventDefault();
closeLightbox();
}
else if (event.key === "ArrowRight") {
goNext();
}
else if (event.key === "ArrowLeft") {
goPrevious();
}
};
const originalOverflow = document.body.style.overflow;
document.body.style.overflow = "hidden";
document.addEventListener("keydown", onKeyDown);
return () => {
document.body.style.overflow = originalOverflow;
document.removeEventListener("keydown", onKeyDown);
};
}, [closeLightbox, goNext, goPrevious, isLightboxOpen]);
const lightbox = isLightboxOpen && activeItem && mountedRef.current && typeof document !== "undefined"
? createPortal(_jsx("div", { className: cn("fixed inset-0 z-[60] flex items-center justify-center backdrop-blur-sm px-4 py-8", styles.overlayBackdrop), children: _jsxs("div", { className: cn("relative flex h-full w-full max-w-5xl min-h-0 flex-col items-stretch justify-center rounded-lg shadow-2xl", styles.overlayContainer), children: [_jsx("div", { className: "absolute right-4 top-4", children: _jsx(Button, { size: "icon", variant: styles.overlayButtonVariant, "aria-label": resolvedLabels.closeLightbox, onClick: closeLightbox, children: _jsx(FontAwesomeIcon, { icon: faXmark }) }) }), _jsx("div", { className: "flex h-full w-full min-h-0 flex-1 items-center justify-center p-4 sm:p-6", children: activeItem.mediaType === "video" && activeItem.video ? (_jsx("div", { className: "relative w-full max-w-4xl overflow-hidden rounded-md bg-black shadow-lg", style: { aspectRatio: "16 / 9", maxHeight: "65vh" }, children: _jsx("iframe", { src: activeItem.video.embedAutoplayUrl, title: videoIframeTitle !== null && videoIframeTitle !== void 0 ? videoIframeTitle : activeItem.video.videoId, allow: "autoplay; encrypted-media; fullscreen; picture-in-picture", allowFullScreen: true, className: "absolute inset-0 h-full w-full border-0" }, activeItem.video.videoId) })) : (_jsx("img", { src: (_k = activeItem.image) !== null && _k !== void 0 ? _k : activeItem.thumbnail, alt: fullscreenImageAlt, className: cn("max-h-[65vh] max-w-full rounded-md", overlayImageClass) })) }), _jsx("div", { className: "relative w-full min-h-0", children: _jsxs("div", { className: cn("w-full max-h-[35vh] overflow-y-auto px-4 py-5 sm:px-6", styles.overlayCaptionBackground), children: [activeItem.title ? (_jsx("h3", { className: cn("text-lg font-semibold", styles.overlayTitle), children: activeItem.title })) : null, activeItem.description ? (_jsx("p", { className: cn("mt-2 text-sm", styles.overlayDescription), children: activeItem.description })) : null, activeItem.attributionLabel ? (_jsxs("p", { className: cn("mt-3 text-sm", styles.overlayAttribution), children: [resolvedLabels.creditPrefix, " ", activeItem.attributionUrl ? (_jsx("a", { href: activeItem.attributionUrl, target: "_blank", rel: "noreferrer", className: cn("underline decoration-2 underline-offset-4", styles.overlayLinkDecoration, styles.overlayLink), children: activeItem.attributionLabel })) : (activeItem.attributionLabel)] })) : null] }) })] }) }), document.body)
: null;
return (_jsxs(_Fragment, { children: [_jsx("div", Object.assign({ className: cn("flex w-full flex-col gap-4 rounded-lg border p-4 sm:gap-6 sm:p-6", styles.container, className), "aria-label": resolvedAriaLabel }, rest, { children: !hasImages ? (_jsx("div", { className: cn("flex h-48 items-center justify-center rounded-md border border-dashed", styles.emptyState.border, styles.emptyState.background), children: _jsx("p", { className: cn("text-sm text-center", styles.emptyState.text), children: resolvedEmptyState }) })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: cn("relative overflow-hidden rounded-lg border", styles.mainImageWrapper), children: [_jsx("div", { className: "absolute left-4 top-1/2 z-10 -translate-y-1/2", children: _jsx(Button, { size: "icon", variant: styles.navButtonVariant, onClick: goPrevious, "aria-label": resolvedLabels.previousImageButton, children: _jsx(FontAwesomeIcon, { icon: faChevronLeft }) }) }), _jsx("div", { className: "absolute right-4 top-1/2 z-10 -translate-y-1/2", children: _jsx(Button, { size: "icon", variant: styles.navButtonVariant, onClick: goNext, "aria-label": resolvedLabels.nextImageButton, children: _jsx(FontAwesomeIcon, { icon: faChevronRight }) }) }), _jsxs("div", { className: "flex w-full flex-col", children: [_jsxs("div", { className: cn("group relative overflow-hidden rounded-lg", activeItem.mediaType === "video" ? "aspect-video" : undefined), style: activeItem.mediaType === "video" ? { maxHeight: "55vh" } : undefined, children: [activeItem.mediaType === "video" ? (_jsx("img", { src: (_l = activeItem.image) !== null && _l !== void 0 ? _l : activeItem.thumbnail, alt: videoPreviewAlt !== null && videoPreviewAlt !== void 0 ? videoPreviewAlt : "", className: "h-full w-full object-cover transition-transform duration-300 group-hover:scale-[1.01]" })) : (_jsx("img", { src: (_m = activeItem.image) !== null && _m !== void 0 ? _m : activeItem.thumbnail, alt: mainImageAlt, className: "max-h-[55vh] w-full object-cover transition-transform duration-300 group-hover:scale-[1.01] sm:max-h-[480px]" })), _jsx("button", { type: "button", className: cn("absolute inset-0 focus:outline-none focus-visible:ring-2 focus-visible:ring-govbr-blue-warm-vivid-50", activeItem.mediaType === "video" ? "cursor-pointer" : "cursor-zoom-in"), onClick: () => setIsLightboxOpen(true), "aria-label": openLightboxLabel, children: _jsx("span", { className: "sr-only", children: openLightboxLabel }) }), activeItem.mediaType === "video" ? (_jsx("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-center", children: _jsx("div", { className: "flex h-16 w-16 items-center justify-center rounded-full bg-black/60 text-white shadow-lg transition-transform duration-300 group-hover:scale-105", children: _jsx(FontAwesomeIcon, { icon: faPlay, className: "text-2xl" }) }) })) : null] }), _jsxs("div", { className: cn("w-full border-t px-4 py-4 text-left sm:px-6 sm:py-4", styles.captionContainer), children: [activeItem.title ? (_jsx("h3", { className: cn("text-base font-semibold", styles.captionTitle), children: activeItem.title })) : null, truncatedDescription ? (_jsx("p", { className: cn("mt-1 text-sm", styles.captionDescription), children: truncatedDescription })) : null, activeItem.attributionLabel ? (_jsxs("p", { className: cn("mt-2 text-xs", styles.captionAttribution), children: [resolvedLabels.creditPrefix, " ", activeItem.attributionUrl ? (_jsx("a", { href: activeItem.attributionUrl, target: "_blank", rel: "noreferrer", className: cn("underline decoration-2 underline-offset-4", styles.captionLink), onClick: (event) => event.stopPropagation(), children: activeItem.attributionLabel })) : (activeItem.attributionLabel)] })) : null] })] })] }), _jsxs("div", { className: "relative", children: [_jsx("div", { className: cn("pointer-events-none absolute left-0 top-0 h-full w-10 bg-gradient-to-r to-transparent", styles.gradientLeft) }), _jsx("div", { className: cn("pointer-events-none absolute right-0 top-0 h-full w-10 bg-gradient-to-l to-transparent", styles.gradientRight) }), _jsx("div", { className: "absolute left-2 top-1/2 z-10 -translate-y-1/2", children: _jsx(Button, { size: "icon", variant: styles.navButtonVariant, onClick: () => scrollThumbnails("left"), "aria-label": resolvedLabels.scrollThumbnailsLeft, children: _jsx(FontAwesomeIcon, { icon: faChevronLeft }) }) }), _jsx("div", { className: "absolute right-2 top-1/2 z-10 -translate-y-1/2", children: _jsx(Button, { size: "icon", variant: styles.navButtonVariant, onClick: () => scrollThumbnails("right"), "aria-label": resolvedLabels.scrollThumbnailsRight, children: _jsx(FontAwesomeIcon, { icon: faChevronRight }) }) }), _jsx("div", { ref: scrollContainerRef, className: "flex gap-3 overflow-x-auto px-8 py-2 sm:px-14", children: normalizedItems.map((item, index) => {
var _a, _b, _c;
const isActive = index === currentIndex;
const displayIndex = index + 1;
const thumbnailLabel = formatLabel(resolvedLabels.thumbnailButton, {
index: displayIndex,
title: (_a = item.title) !== null && _a !== void 0 ? _a : "",
});
const thumbnailAltBase = item.mediaType === "video"
? formatLabel(resolvedLabels.videoPreviewAlt, {
index: displayIndex,
title: (_b = item.title) !== null && _b !== void 0 ? _b : "",
})
: formatLabel(resolvedLabels.thumbnailAlt, {
index: displayIndex,
title: (_c = item.title) !== null && _c !== void 0 ? _c : "",
});
const fallbackThumbnailAlt = thumbnailAltBase || item.title || `Miniatura ${displayIndex}`;
return (_jsxs("button", { type: "button", onClick: () => goToIndex(index), className: cn("relative flex h-20 w-24 flex-shrink-0 overflow-hidden rounded-md border transition-all duration-200 sm:w-32", isActive ? styles.thumbnailActive : styles.thumbnailInactive), "aria-label": thumbnailLabel || `Selecionar imagem ${displayIndex}`, children: [_jsx("img", { src: item.thumbnail, alt: fallbackThumbnailAlt, className: "h-full w-full object-cover" }), item.mediaType === "video" ? (_jsx("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-center", children: _jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-black/60 text-white shadow-md", children: _jsx(FontAwesomeIcon, { icon: faPlay, className: "text-lg" }) }) })) : null] }, `${item.thumbnail}-${index}`));
}) })] })] })) })), lightbox] }));
}
export default PhotoGallery;