import { CopilotChatConfigurationProvider, CopilotChatDefaultLabels, useCopilotChatConfiguration } from "../../providers/CopilotChatConfigurationProvider.mjs"; import { cn } from "../../lib/utils.mjs"; import { renderSlot } from "../../lib/slots.mjs"; import CopilotChatView_default from "./CopilotChatView.mjs"; import CopilotChatToggleButton from "./CopilotChatToggleButton.mjs"; import { CopilotModalHeader } from "./CopilotModalHeader.mjs"; import React, { useEffect, useMemo, useRef, useState } from "react"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; //#region src/components/chat/CopilotPopupView.tsx const DEFAULT_POPUP_WIDTH = 420; const DEFAULT_POPUP_HEIGHT = 560; const dimensionToCss = (value, fallback) => { if (typeof value === "number" && Number.isFinite(value)) return `${value}px`; if (typeof value === "string" && value.trim().length > 0) return value; return `${fallback}px`; }; function CopilotPopupView({ header, toggleButton, width, height, clickOutsideToClose, defaultOpen = true, className, ...restProps }) { return /* @__PURE__ */ jsx(CopilotChatConfigurationProvider, { isModalDefaultOpen: defaultOpen, children: /* @__PURE__ */ jsx(CopilotPopupViewInternal, { header, toggleButton, width, height, clickOutsideToClose, className, ...restProps }) }); } function CopilotPopupViewInternal({ header, toggleButton, width, height, clickOutsideToClose, className, ...restProps }) { const configuration = useCopilotChatConfiguration(); const isPopupOpen = configuration?.isModalOpen ?? false; const setModalOpen = configuration?.setModalOpen; const labels = configuration?.labels ?? CopilotChatDefaultLabels; const containerRef = useRef(null); const [isRendered, setIsRendered] = useState(isPopupOpen); const [isAnimatingOut, setIsAnimatingOut] = useState(false); useEffect(() => { if (isPopupOpen) { setIsRendered(true); setIsAnimatingOut(false); return; } if (!isRendered) return; setIsAnimatingOut(true); const timeout = setTimeout(() => { setIsRendered(false); setIsAnimatingOut(false); }, 200); return () => clearTimeout(timeout); }, [isPopupOpen, isRendered]); useEffect(() => { if (!isPopupOpen) return; if (typeof window === "undefined") return; const handleKeyDown = (event) => { if (event.key === "Escape") { event.preventDefault(); setModalOpen?.(false); } }; window.addEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown); }, [isPopupOpen, setModalOpen]); useEffect(() => { if (!isPopupOpen) return; const focusTimer = setTimeout(() => { const container = containerRef.current; if (container && !container.contains(document.activeElement)) container.focus({ preventScroll: true }); }, 200); return () => clearTimeout(focusTimer); }, [isPopupOpen]); useEffect(() => { if (!isPopupOpen || !clickOutsideToClose) return; if (typeof document === "undefined") return; const handlePointerDown = (event) => { const target = event.target; if (!target) return; if (containerRef.current?.contains(target)) return; const toggleButton = document.querySelector("[data-slot='chat-toggle-button']"); if (toggleButton && toggleButton.contains(target)) return; setModalOpen?.(false); }; document.addEventListener("pointerdown", handlePointerDown); return () => document.removeEventListener("pointerdown", handlePointerDown); }, [ isPopupOpen, clickOutsideToClose, setModalOpen ]); const headerElement = useMemo(() => renderSlot(header, CopilotModalHeader, {}), [header]); const toggleButtonElement = useMemo(() => renderSlot(toggleButton, CopilotChatToggleButton, {}), [toggleButton]); const resolvedWidth = dimensionToCss(width, DEFAULT_POPUP_WIDTH); const resolvedHeight = dimensionToCss(height, DEFAULT_POPUP_HEIGHT); const popupStyle = useMemo(() => ({ "--copilot-popup-width": resolvedWidth, "--copilot-popup-height": resolvedHeight, "--copilot-popup-max-width": "calc(100vw - 3rem)", "--copilot-popup-max-height": "calc(100dvh - 7.5rem)", paddingTop: "env(safe-area-inset-top)", paddingBottom: "env(safe-area-inset-bottom)", paddingLeft: "env(safe-area-inset-left)", paddingRight: "env(safe-area-inset-right)" }), [resolvedHeight, resolvedWidth]); const popupAnimationClass = isPopupOpen && !isAnimatingOut ? "cpk:pointer-events-auto cpk:translate-y-0 cpk:opacity-100 cpk:md:scale-100" : "cpk:pointer-events-none cpk:translate-y-4 cpk:opacity-0 cpk:md:translate-y-5 cpk:md:scale-[0.95]"; return /* @__PURE__ */ jsxs(Fragment, { children: [toggleButtonElement, isRendered ? /* @__PURE__ */ jsx("div", { "data-copilotkit": true, className: cn("cpk:fixed cpk:inset-0 cpk:z-[1200] cpk:flex cpk:max-w-full cpk:flex-col cpk:items-stretch", "cpk:md:inset-auto cpk:md:bottom-24 cpk:md:right-6 cpk:md:items-end cpk:md:gap-4"), children: /* @__PURE__ */ jsxs("div", { ref: containerRef, tabIndex: -1, role: "dialog", "aria-label": labels.modalHeaderTitle, "data-testid": "copilot-popup", "data-copilot-popup": true, className: cn("copilotKitPopup copilotKitWindow", "cpk:relative cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden cpk:bg-background cpk:text-foreground", "cpk:origin-bottom cpk:focus:outline-none cpk:transform-gpu cpk:transition-transform cpk:transition-opacity cpk:duration-200 cpk:ease-out", "cpk:md:transition-transform cpk:md:transition-opacity", "cpk:rounded-none cpk:border cpk:border-border/0 cpk:shadow-none cpk:ring-0", "cpk:md:h-[var(--copilot-popup-height)] cpk:md:w-[var(--copilot-popup-width)]", "cpk:md:max-h-[var(--copilot-popup-max-height)] cpk:md:max-w-[var(--copilot-popup-max-width)]", "cpk:md:origin-bottom-right cpk:md:rounded-2xl cpk:md:border-border cpk:md:shadow-xl cpk:md:ring-1 cpk:md:ring-border/40", popupAnimationClass), style: popupStyle, children: [headerElement, /* @__PURE__ */ jsx("div", { className: "cpk:flex-1 cpk:overflow-hidden", "data-popup-chat": true, children: /* @__PURE__ */ jsx(CopilotChatView_default, { ...restProps, className: cn("cpk:h-full cpk:min-h-0", className) }) })] }) }) : null] }); } CopilotPopupView.displayName = "CopilotPopupView"; (function(_CopilotPopupView) { _CopilotPopupView.WelcomeScreen = ({ welcomeMessage, input, suggestionView, className, children, ...props }) => { const BoundWelcomeMessage = renderSlot(welcomeMessage, CopilotChatView_default.WelcomeMessage, {}); if (children) return /* @__PURE__ */ jsx("div", { "data-copilotkit": true, style: { display: "contents" }, children: children({ welcomeMessage: BoundWelcomeMessage, input, suggestionView, className, ...props }) }); return /* @__PURE__ */ jsxs("div", { className: cn("cpk:h-full cpk:flex cpk:flex-col", className), ...props, children: [/* @__PURE__ */ jsx("div", { className: "cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4", children: BoundWelcomeMessage }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", { className: "cpk:mb-4 cpk:flex cpk:justify-center cpk:px-4", children: suggestionView }), input] })] }); }; })(CopilotPopupView || (CopilotPopupView = {})); var CopilotPopupView_default = CopilotPopupView; //#endregion export { CopilotPopupView, CopilotPopupView_default as default }; //# sourceMappingURL=CopilotPopupView.mjs.map