UNPKG

analytica-frontend-lib

Version:

Repositório público dos componentes utilizados nas plataformas da Analytica Ensino

232 lines (230 loc) 8.28 kB
import { getYouTubeEmbedUrl, getYouTubeVideoId, isYouTubeUrl } from "./chunk-Z2G5TBXF.mjs"; import { Button_default } from "./chunk-LAYB7IKW.mjs"; import { cn } from "./chunk-53ICLDGS.mjs"; // src/components/Modal/Modal.tsx import { useEffect, useId } from "react"; import { XIcon } from "@phosphor-icons/react/dist/csr/X"; import { jsx, jsxs } from "react/jsx-runtime"; var SIZE_CLASSES = { xs: "max-w-[360px]", sm: "max-w-[420px]", md: "max-w-[510px]", lg: "max-w-[640px]", xl: "max-w-[970px]" }; var Modal = ({ isOpen, onClose, title, children, size = "md", className = "", closeOnEscape = true, footer, hideCloseButton = false, variant = "default", description, image, imageAlt, actionLink, actionLabel, contentClassName = "" }) => { const titleId = useId(); useEffect(() => { if (!isOpen || !closeOnEscape) return; const handleEscape = (event) => { if (event.key === "Escape") { onClose(); } }; document.addEventListener("keydown", handleEscape); return () => document.removeEventListener("keydown", handleEscape); }, [isOpen, closeOnEscape, onClose]); useEffect(() => { if (!isOpen) return; const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth; const originalOverflow = document.body.style.overflow; const originalPaddingRight = document.body.style.paddingRight; document.body.style.overflow = "hidden"; if (scrollbarWidth > 0) { document.body.style.paddingRight = `${scrollbarWidth}px`; const overlay = document.createElement("div"); overlay.id = "modal-scrollbar-overlay"; overlay.style.cssText = ` position: fixed; top: 0; right: 0; width: ${scrollbarWidth}px; height: 100vh; background-color: rgb(0 0 0 / 0.6); z-index: 40; pointer-events: none; `; document.body.appendChild(overlay); } return () => { document.body.style.overflow = originalOverflow; document.body.style.paddingRight = originalPaddingRight; const overlay = document.getElementById("modal-scrollbar-overlay"); if (overlay) { overlay.remove(); } }; }, [isOpen]); if (!isOpen) return null; const sizeClasses = SIZE_CLASSES[size]; const baseClasses = "bg-secondary-50 rounded-3xl shadow-hard-shadow-2 border border-border-100 w-full mx-4 max-h-[calc(100dvh-2rem)] flex flex-col overflow-hidden"; const dialogResetClasses = "p-0 m-0 border-none outline-none static"; const modalClasses = cn( baseClasses, sizeClasses, dialogResetClasses, className ); const normalizeUrl = (href) => /^https?:\/\//i.test(href) ? href : `https://${href}`; const handleActionClick = () => { if (actionLink) { window.open(normalizeUrl(actionLink), "_blank", "noopener,noreferrer"); } }; if (variant === "activity") { return /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-xs border-none p-0 m-0 w-full cursor-default", children: /* @__PURE__ */ jsxs( "dialog", { className: modalClasses, "aria-labelledby": titleId, "aria-modal": "true", open: true, children: [ /* @__PURE__ */ jsx("div", { className: "flex justify-end p-6 pb-0", children: !hideCloseButton && /* @__PURE__ */ jsx( "button", { onClick: onClose, className: "p-1 text-text-500 hover:text-text-700 hover:bg-background-50 rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-indicator-info focus:ring-offset-2", "aria-label": "Fechar modal", children: /* @__PURE__ */ jsx(XIcon, { size: 18 }) } ) }), /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center px-6 pb-6 gap-5 flex-1 min-h-0 overflow-y-auto", children: [ image && /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx( "img", { src: image, alt: imageAlt ?? "", className: "w-[122px] h-[122px] object-contain" } ) }), /* @__PURE__ */ jsx( "h2", { id: titleId, className: "text-lg font-semibold text-text-950 text-center", children: title } ), description && /* @__PURE__ */ jsx("p", { className: "text-sm font-normal text-text-400 text-center max-w-md leading-[21px]", children: description }), actionLink && /* @__PURE__ */ jsxs("div", { className: "w-full", children: [ (() => { const normalized = normalizeUrl(actionLink); const isYT = isYouTubeUrl(normalized); if (!isYT) return null; const id = getYouTubeVideoId(normalized); if (!id) { return /* @__PURE__ */ jsx( Button_default, { variant: "solid", action: "primary", size: "large", className: "w-full", onClick: handleActionClick, children: actionLabel || "Iniciar Atividade" } ); } return /* @__PURE__ */ jsx( "iframe", { src: getYouTubeEmbedUrl(id), className: "w-full aspect-video rounded-lg", allowFullScreen: true, allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture", title: "V\xEDdeo YouTube" } ); })(), !isYouTubeUrl(normalizeUrl(actionLink)) && /* @__PURE__ */ jsx( Button_default, { variant: "solid", action: "primary", size: "large", className: "w-full", onClick: handleActionClick, children: actionLabel || "Iniciar Atividade" } ) ] }) ] }) ] } ) }); } return /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-xs border-none p-0 m-0 w-full cursor-default", children: /* @__PURE__ */ jsxs( "dialog", { className: modalClasses, "aria-labelledby": titleId, "aria-modal": "true", open: true, children: [ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-6 py-6", children: [ /* @__PURE__ */ jsx("h2", { id: titleId, className: "text-lg font-semibold text-text-950", children: title }), !hideCloseButton && /* @__PURE__ */ jsx( "button", { onClick: onClose, className: "p-1 text-text-500 hover:text-text-700 hover:bg-background-50 rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-indicator-info focus:ring-offset-2", "aria-label": "Fechar modal", children: /* @__PURE__ */ jsx(XIcon, { size: 18 }) } ) ] }), children && /* @__PURE__ */ jsx( "div", { className: cn( "px-6 pb-6 flex-1 min-h-0 overflow-y-auto", contentClassName ), children: /* @__PURE__ */ jsx( "div", { className: cn( "text-text-500 font-normal text-sm leading-6", contentClassName?.includes("flex") && "flex flex-col flex-1 min-h-0" ), children } ) } ), footer && /* @__PURE__ */ jsx("div", { className: "flex justify-end gap-3 px-6 pb-6", children: footer }) ] } ) }); }; var Modal_default = Modal; export { Modal_default }; //# sourceMappingURL=chunk-TNLGS7SB.mjs.map