@copilotkitnext/react 1.52.0-next.7 → 1.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/components/chat/CopilotChatAssistantMessage.cjs +7 -0
  2. package/dist/components/chat/CopilotChatAssistantMessage.cjs.map +1 -1
  3. package/dist/components/chat/CopilotChatAssistantMessage.d.cts.map +1 -1
  4. package/dist/components/chat/CopilotChatAssistantMessage.d.mts.map +1 -1
  5. package/dist/components/chat/CopilotChatAssistantMessage.mjs +7 -0
  6. package/dist/components/chat/CopilotChatAssistantMessage.mjs.map +1 -1
  7. package/dist/components/chat/CopilotChatInput.cjs +7 -0
  8. package/dist/components/chat/CopilotChatInput.cjs.map +1 -1
  9. package/dist/components/chat/CopilotChatInput.d.cts.map +1 -1
  10. package/dist/components/chat/CopilotChatInput.d.mts.map +1 -1
  11. package/dist/components/chat/CopilotChatInput.mjs +7 -0
  12. package/dist/components/chat/CopilotChatInput.mjs.map +1 -1
  13. package/dist/components/chat/CopilotChatMessageView.cjs +2 -0
  14. package/dist/components/chat/CopilotChatMessageView.cjs.map +1 -1
  15. package/dist/components/chat/CopilotChatMessageView.d.cts.map +1 -1
  16. package/dist/components/chat/CopilotChatMessageView.d.mts.map +1 -1
  17. package/dist/components/chat/CopilotChatMessageView.mjs +2 -0
  18. package/dist/components/chat/CopilotChatMessageView.mjs.map +1 -1
  19. package/dist/components/chat/CopilotChatSuggestionPill.cjs +1 -0
  20. package/dist/components/chat/CopilotChatSuggestionPill.cjs.map +1 -1
  21. package/dist/components/chat/CopilotChatSuggestionPill.mjs +1 -0
  22. package/dist/components/chat/CopilotChatSuggestionPill.mjs.map +1 -1
  23. package/dist/components/chat/CopilotChatSuggestionView.cjs +1 -0
  24. package/dist/components/chat/CopilotChatSuggestionView.cjs.map +1 -1
  25. package/dist/components/chat/CopilotChatSuggestionView.d.cts.map +1 -1
  26. package/dist/components/chat/CopilotChatSuggestionView.d.mts.map +1 -1
  27. package/dist/components/chat/CopilotChatSuggestionView.mjs +1 -0
  28. package/dist/components/chat/CopilotChatSuggestionView.mjs.map +1 -1
  29. package/dist/components/chat/CopilotChatToggleButton.cjs +1 -0
  30. package/dist/components/chat/CopilotChatToggleButton.cjs.map +1 -1
  31. package/dist/components/chat/CopilotChatToggleButton.mjs +1 -0
  32. package/dist/components/chat/CopilotChatToggleButton.mjs.map +1 -1
  33. package/dist/components/chat/CopilotChatUserMessage.cjs +5 -0
  34. package/dist/components/chat/CopilotChatUserMessage.cjs.map +1 -1
  35. package/dist/components/chat/CopilotChatUserMessage.d.cts.map +1 -1
  36. package/dist/components/chat/CopilotChatUserMessage.d.mts.map +1 -1
  37. package/dist/components/chat/CopilotChatUserMessage.mjs +5 -0
  38. package/dist/components/chat/CopilotChatUserMessage.mjs.map +1 -1
  39. package/dist/components/chat/CopilotChatView.cjs +6 -0
  40. package/dist/components/chat/CopilotChatView.cjs.map +1 -1
  41. package/dist/components/chat/CopilotChatView.d.cts.map +1 -1
  42. package/dist/components/chat/CopilotChatView.d.mts.map +1 -1
  43. package/dist/components/chat/CopilotChatView.mjs +6 -0
  44. package/dist/components/chat/CopilotChatView.mjs.map +1 -1
  45. package/dist/components/chat/CopilotModalHeader.cjs +3 -0
  46. package/dist/components/chat/CopilotModalHeader.cjs.map +1 -1
  47. package/dist/components/chat/CopilotModalHeader.d.cts.map +1 -1
  48. package/dist/components/chat/CopilotModalHeader.d.mts.map +1 -1
  49. package/dist/components/chat/CopilotModalHeader.mjs +3 -0
  50. package/dist/components/chat/CopilotModalHeader.mjs.map +1 -1
  51. package/dist/components/chat/CopilotPopupView.cjs +1 -0
  52. package/dist/components/chat/CopilotPopupView.cjs.map +1 -1
  53. package/dist/components/chat/CopilotPopupView.d.cts.map +1 -1
  54. package/dist/components/chat/CopilotPopupView.d.mts.map +1 -1
  55. package/dist/components/chat/CopilotPopupView.mjs +1 -0
  56. package/dist/components/chat/CopilotPopupView.mjs.map +1 -1
  57. package/dist/components/chat/CopilotSidebarView.cjs +1 -0
  58. package/dist/components/chat/CopilotSidebarView.cjs.map +1 -1
  59. package/dist/components/chat/CopilotSidebarView.d.cts.map +1 -1
  60. package/dist/components/chat/CopilotSidebarView.d.mts.map +1 -1
  61. package/dist/components/chat/CopilotSidebarView.mjs +1 -0
  62. package/dist/components/chat/CopilotSidebarView.mjs.map +1 -1
  63. package/dist/index.umd.js +35 -0
  64. package/dist/index.umd.js.map +1 -1
  65. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"CopilotPopupView.d.mts","names":[],"sources":["../../../src/components/chat/CopilotPopupView.tsx"],"mappings":";;;;;;;;KAkBY,qBAAA,GAAwB,oBAAA;EAClC,MAAA,GAAS,SAAA,QAAiB,kBAAA;EAC1B,YAAA,GAAe,SAAA,QAAiB,uBAAA;EAChC,KAAA;EACA,MAAA;EACA,mBAAA;EACA,WAAA;AAAA;AAAA,iBAkBc,gBAAA,CAAA;EACd,MAAA;EACA,YAAA;EACA,KAAA;EACA,MAAA;EACA,mBAAA;EACA,WAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,qBAAA,GAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBATR,gBAAA;EAAA,IAAgB,WAAA;AAAA;AAAA,kBAqNf,gBAAA;EA7OmB;;;;;;EAAA,MAoPrB,aAAA,EAAe,KAAA,CAAM,EAAA,CAAG,kBAAA;AAAA"}
1
+ {"version":3,"file":"CopilotPopupView.d.mts","names":[],"sources":["../../../src/components/chat/CopilotPopupView.tsx"],"mappings":";;;;;;;;KAkBY,qBAAA,GAAwB,oBAAA;EAClC,MAAA,GAAS,SAAA,QAAiB,kBAAA;EAC1B,YAAA,GAAe,SAAA,QAAiB,uBAAA;EAChC,KAAA;EACA,MAAA;EACA,mBAAA;EACA,WAAA;AAAA;AAAA,iBAkBc,gBAAA,CAAA;EACd,MAAA;EACA,YAAA;EACA,KAAA;EACA,MAAA;EACA,mBAAA;EACA,WAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,qBAAA,GAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBATR,gBAAA;EAAA,IAAgB,WAAA;AAAA;AAAA,kBAsNf,gBAAA;EA9OmB;;;;;;EAAA,MAqPrB,aAAA,EAAe,KAAA,CAAM,EAAA,CAAG,kBAAA;AAAA"}
@@ -112,6 +112,7 @@ function CopilotPopupViewInternal({ header, toggleButton, width, height, clickOu
112
112
  tabIndex: -1,
113
113
  role: "dialog",
114
114
  "aria-label": labels.modalHeaderTitle,
115
+ "data-testid": "copilot-popup",
115
116
  "data-copilot-popup": true,
116
117
  className: cn("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),
117
118
  style: popupStyle,
@@ -1 +1 @@
1
- {"version":3,"file":"CopilotPopupView.mjs","names":["CopilotChatView"],"sources":["../../../src/components/chat/CopilotPopupView.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport CopilotChatView, {\n CopilotChatViewProps,\n WelcomeScreenProps,\n} from \"./CopilotChatView\";\nimport CopilotChatToggleButton from \"./CopilotChatToggleButton\";\nimport { CopilotModalHeader } from \"./CopilotModalHeader\";\nimport { cn } from \"@/lib/utils\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotChatDefaultLabels,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\n\nconst DEFAULT_POPUP_WIDTH = 420;\nconst DEFAULT_POPUP_HEIGHT = 560;\n\nexport type CopilotPopupViewProps = CopilotChatViewProps & {\n header?: SlotValue<typeof CopilotModalHeader>;\n toggleButton?: SlotValue<typeof CopilotChatToggleButton>;\n width?: number | string;\n height?: number | string;\n clickOutsideToClose?: boolean;\n defaultOpen?: boolean;\n};\n\nconst dimensionToCss = (\n value: number | string | undefined,\n fallback: number,\n): string => {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return `${value}px`;\n }\n\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n\n return `${fallback}px`;\n};\n\nexport function CopilotPopupView({\n header,\n toggleButton,\n width,\n height,\n clickOutsideToClose,\n defaultOpen = true,\n className,\n ...restProps\n}: CopilotPopupViewProps) {\n return (\n <CopilotChatConfigurationProvider isModalDefaultOpen={defaultOpen}>\n <CopilotPopupViewInternal\n header={header}\n toggleButton={toggleButton}\n width={width}\n height={height}\n clickOutsideToClose={clickOutsideToClose}\n className={className}\n {...restProps}\n />\n </CopilotChatConfigurationProvider>\n );\n}\n\nfunction CopilotPopupViewInternal({\n header,\n toggleButton,\n width,\n height,\n clickOutsideToClose,\n className,\n ...restProps\n}: Omit<CopilotPopupViewProps, \"defaultOpen\">) {\n const configuration = useCopilotChatConfiguration();\n const isPopupOpen = configuration?.isModalOpen ?? false;\n const setModalOpen = configuration?.setModalOpen;\n const labels = configuration?.labels ?? CopilotChatDefaultLabels;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [isRendered, setIsRendered] = useState(isPopupOpen);\n const [isAnimatingOut, setIsAnimatingOut] = useState(false);\n\n useEffect(() => {\n if (isPopupOpen) {\n setIsRendered(true);\n setIsAnimatingOut(false);\n return;\n }\n\n if (!isRendered) {\n return;\n }\n\n setIsAnimatingOut(true);\n const timeout = setTimeout(() => {\n setIsRendered(false);\n setIsAnimatingOut(false);\n }, 200);\n\n return () => clearTimeout(timeout);\n }, [isPopupOpen, isRendered]);\n\n useEffect(() => {\n if (!isPopupOpen) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setModalOpen?.(false);\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [isPopupOpen, setModalOpen]);\n\n useEffect(() => {\n if (!isPopupOpen) {\n return;\n }\n\n const focusTimer = setTimeout(() => {\n const container = containerRef.current;\n // Don't steal focus if something inside the popup (like the input) is already focused\n if (container && !container.contains(document.activeElement)) {\n container.focus({ preventScroll: true });\n }\n }, 200);\n\n return () => clearTimeout(focusTimer);\n }, [isPopupOpen]);\n\n useEffect(() => {\n if (!isPopupOpen || !clickOutsideToClose) {\n return;\n }\n\n if (typeof document === \"undefined\") {\n return;\n }\n\n const handlePointerDown = (event: PointerEvent) => {\n const target = event.target as Node | null;\n if (!target) {\n return;\n }\n\n const container = containerRef.current;\n if (container?.contains(target)) {\n return;\n }\n\n const toggleButton = document.querySelector(\n \"[data-slot='chat-toggle-button']\",\n );\n if (toggleButton && toggleButton.contains(target)) {\n return;\n }\n\n setModalOpen?.(false);\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDown);\n return () => document.removeEventListener(\"pointerdown\", handlePointerDown);\n }, [isPopupOpen, clickOutsideToClose, setModalOpen]);\n\n const headerElement = useMemo(\n () => renderSlot(header, CopilotModalHeader, {}),\n [header],\n );\n const toggleButtonElement = useMemo(\n () => renderSlot(toggleButton, CopilotChatToggleButton, {}),\n [toggleButton],\n );\n\n const resolvedWidth = dimensionToCss(width, DEFAULT_POPUP_WIDTH);\n const resolvedHeight = dimensionToCss(height, DEFAULT_POPUP_HEIGHT);\n\n const popupStyle = useMemo(\n () =>\n ({\n \"--copilot-popup-width\": resolvedWidth,\n \"--copilot-popup-height\": resolvedHeight,\n \"--copilot-popup-max-width\": \"calc(100vw - 3rem)\",\n \"--copilot-popup-max-height\": \"calc(100dvh - 7.5rem)\",\n paddingTop: \"env(safe-area-inset-top)\",\n paddingBottom: \"env(safe-area-inset-bottom)\",\n paddingLeft: \"env(safe-area-inset-left)\",\n paddingRight: \"env(safe-area-inset-right)\",\n }) as React.CSSProperties,\n [resolvedHeight, resolvedWidth],\n );\n\n const popupAnimationClass =\n isPopupOpen && !isAnimatingOut\n ? \"cpk:pointer-events-auto cpk:translate-y-0 cpk:opacity-100 cpk:md:scale-100\"\n : \"cpk:pointer-events-none cpk:translate-y-4 cpk:opacity-0 cpk:md:translate-y-5 cpk:md:scale-[0.95]\";\n\n const popupContent = isRendered ? (\n <div\n data-copilotkit\n className={cn(\n \"cpk:fixed cpk:inset-0 cpk:z-[1200] cpk:flex cpk:max-w-full cpk:flex-col cpk:items-stretch\",\n \"cpk:md:inset-auto cpk:md:bottom-24 cpk:md:right-6 cpk:md:items-end cpk:md:gap-4\",\n )}\n >\n <div\n ref={containerRef}\n tabIndex={-1}\n role=\"dialog\"\n aria-label={labels.modalHeaderTitle}\n data-copilot-popup\n className={cn(\n \"cpk:relative cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden cpk:bg-background cpk:text-foreground\",\n \"cpk:origin-bottom cpk:focus:outline-none cpk:transform-gpu cpk:transition-transform cpk:transition-opacity cpk:duration-200 cpk:ease-out\",\n \"cpk:md:transition-transform cpk:md:transition-opacity\",\n \"cpk:rounded-none cpk:border cpk:border-border/0 cpk:shadow-none cpk:ring-0\",\n \"cpk:md:h-[var(--copilot-popup-height)] cpk:md:w-[var(--copilot-popup-width)]\",\n \"cpk:md:max-h-[var(--copilot-popup-max-height)] cpk:md:max-w-[var(--copilot-popup-max-width)]\",\n \"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\",\n popupAnimationClass,\n )}\n style={popupStyle}\n >\n {headerElement}\n <div className=\"cpk:flex-1 cpk:overflow-hidden\" data-popup-chat>\n <CopilotChatView\n {...restProps}\n className={cn(\"cpk:h-full cpk:min-h-0\", className)}\n />\n </div>\n </div>\n </div>\n ) : null;\n\n return (\n <>\n {toggleButtonElement}\n {popupContent}\n </>\n );\n}\n\nCopilotPopupView.displayName = \"CopilotPopupView\";\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotPopupView {\n /**\n * Popup-specific welcome screen layout:\n * - Welcome message centered vertically\n * - Suggestions just above input\n * - Input fixed at the bottom\n */\n export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({\n welcomeMessage,\n input,\n suggestionView,\n className,\n children,\n ...props\n }) => {\n // Render the welcomeMessage slot internally\n const BoundWelcomeMessage = renderSlot(\n welcomeMessage,\n CopilotChatView.WelcomeMessage,\n {},\n );\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n welcomeMessage: BoundWelcomeMessage,\n input,\n suggestionView,\n className,\n ...props,\n })}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\"cpk:h-full cpk:flex cpk:flex-col\", className)}\n {...props}\n >\n {/* Welcome message - centered vertically */}\n <div className=\"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\">\n {BoundWelcomeMessage}\n </div>\n\n {/* Suggestions and input at bottom */}\n <div>\n {/* Suggestions above input */}\n <div className=\"cpk:mb-4 cpk:flex cpk:justify-center cpk:px-4\">\n {suggestionView}\n </div>\n {input}\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotPopupView;\n"],"mappings":"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"}
1
+ {"version":3,"file":"CopilotPopupView.mjs","names":["CopilotChatView"],"sources":["../../../src/components/chat/CopilotPopupView.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport CopilotChatView, {\n CopilotChatViewProps,\n WelcomeScreenProps,\n} from \"./CopilotChatView\";\nimport CopilotChatToggleButton from \"./CopilotChatToggleButton\";\nimport { CopilotModalHeader } from \"./CopilotModalHeader\";\nimport { cn } from \"@/lib/utils\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotChatDefaultLabels,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\n\nconst DEFAULT_POPUP_WIDTH = 420;\nconst DEFAULT_POPUP_HEIGHT = 560;\n\nexport type CopilotPopupViewProps = CopilotChatViewProps & {\n header?: SlotValue<typeof CopilotModalHeader>;\n toggleButton?: SlotValue<typeof CopilotChatToggleButton>;\n width?: number | string;\n height?: number | string;\n clickOutsideToClose?: boolean;\n defaultOpen?: boolean;\n};\n\nconst dimensionToCss = (\n value: number | string | undefined,\n fallback: number,\n): string => {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return `${value}px`;\n }\n\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n\n return `${fallback}px`;\n};\n\nexport function CopilotPopupView({\n header,\n toggleButton,\n width,\n height,\n clickOutsideToClose,\n defaultOpen = true,\n className,\n ...restProps\n}: CopilotPopupViewProps) {\n return (\n <CopilotChatConfigurationProvider isModalDefaultOpen={defaultOpen}>\n <CopilotPopupViewInternal\n header={header}\n toggleButton={toggleButton}\n width={width}\n height={height}\n clickOutsideToClose={clickOutsideToClose}\n className={className}\n {...restProps}\n />\n </CopilotChatConfigurationProvider>\n );\n}\n\nfunction CopilotPopupViewInternal({\n header,\n toggleButton,\n width,\n height,\n clickOutsideToClose,\n className,\n ...restProps\n}: Omit<CopilotPopupViewProps, \"defaultOpen\">) {\n const configuration = useCopilotChatConfiguration();\n const isPopupOpen = configuration?.isModalOpen ?? false;\n const setModalOpen = configuration?.setModalOpen;\n const labels = configuration?.labels ?? CopilotChatDefaultLabels;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [isRendered, setIsRendered] = useState(isPopupOpen);\n const [isAnimatingOut, setIsAnimatingOut] = useState(false);\n\n useEffect(() => {\n if (isPopupOpen) {\n setIsRendered(true);\n setIsAnimatingOut(false);\n return;\n }\n\n if (!isRendered) {\n return;\n }\n\n setIsAnimatingOut(true);\n const timeout = setTimeout(() => {\n setIsRendered(false);\n setIsAnimatingOut(false);\n }, 200);\n\n return () => clearTimeout(timeout);\n }, [isPopupOpen, isRendered]);\n\n useEffect(() => {\n if (!isPopupOpen) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setModalOpen?.(false);\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [isPopupOpen, setModalOpen]);\n\n useEffect(() => {\n if (!isPopupOpen) {\n return;\n }\n\n const focusTimer = setTimeout(() => {\n const container = containerRef.current;\n // Don't steal focus if something inside the popup (like the input) is already focused\n if (container && !container.contains(document.activeElement)) {\n container.focus({ preventScroll: true });\n }\n }, 200);\n\n return () => clearTimeout(focusTimer);\n }, [isPopupOpen]);\n\n useEffect(() => {\n if (!isPopupOpen || !clickOutsideToClose) {\n return;\n }\n\n if (typeof document === \"undefined\") {\n return;\n }\n\n const handlePointerDown = (event: PointerEvent) => {\n const target = event.target as Node | null;\n if (!target) {\n return;\n }\n\n const container = containerRef.current;\n if (container?.contains(target)) {\n return;\n }\n\n const toggleButton = document.querySelector(\n \"[data-slot='chat-toggle-button']\",\n );\n if (toggleButton && toggleButton.contains(target)) {\n return;\n }\n\n setModalOpen?.(false);\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDown);\n return () => document.removeEventListener(\"pointerdown\", handlePointerDown);\n }, [isPopupOpen, clickOutsideToClose, setModalOpen]);\n\n const headerElement = useMemo(\n () => renderSlot(header, CopilotModalHeader, {}),\n [header],\n );\n const toggleButtonElement = useMemo(\n () => renderSlot(toggleButton, CopilotChatToggleButton, {}),\n [toggleButton],\n );\n\n const resolvedWidth = dimensionToCss(width, DEFAULT_POPUP_WIDTH);\n const resolvedHeight = dimensionToCss(height, DEFAULT_POPUP_HEIGHT);\n\n const popupStyle = useMemo(\n () =>\n ({\n \"--copilot-popup-width\": resolvedWidth,\n \"--copilot-popup-height\": resolvedHeight,\n \"--copilot-popup-max-width\": \"calc(100vw - 3rem)\",\n \"--copilot-popup-max-height\": \"calc(100dvh - 7.5rem)\",\n paddingTop: \"env(safe-area-inset-top)\",\n paddingBottom: \"env(safe-area-inset-bottom)\",\n paddingLeft: \"env(safe-area-inset-left)\",\n paddingRight: \"env(safe-area-inset-right)\",\n }) as React.CSSProperties,\n [resolvedHeight, resolvedWidth],\n );\n\n const popupAnimationClass =\n isPopupOpen && !isAnimatingOut\n ? \"cpk:pointer-events-auto cpk:translate-y-0 cpk:opacity-100 cpk:md:scale-100\"\n : \"cpk:pointer-events-none cpk:translate-y-4 cpk:opacity-0 cpk:md:translate-y-5 cpk:md:scale-[0.95]\";\n\n const popupContent = isRendered ? (\n <div\n data-copilotkit\n className={cn(\n \"cpk:fixed cpk:inset-0 cpk:z-[1200] cpk:flex cpk:max-w-full cpk:flex-col cpk:items-stretch\",\n \"cpk:md:inset-auto cpk:md:bottom-24 cpk:md:right-6 cpk:md:items-end cpk:md:gap-4\",\n )}\n >\n <div\n ref={containerRef}\n tabIndex={-1}\n role=\"dialog\"\n aria-label={labels.modalHeaderTitle}\n data-testid=\"copilot-popup\"\n data-copilot-popup\n className={cn(\n \"cpk:relative cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden cpk:bg-background cpk:text-foreground\",\n \"cpk:origin-bottom cpk:focus:outline-none cpk:transform-gpu cpk:transition-transform cpk:transition-opacity cpk:duration-200 cpk:ease-out\",\n \"cpk:md:transition-transform cpk:md:transition-opacity\",\n \"cpk:rounded-none cpk:border cpk:border-border/0 cpk:shadow-none cpk:ring-0\",\n \"cpk:md:h-[var(--copilot-popup-height)] cpk:md:w-[var(--copilot-popup-width)]\",\n \"cpk:md:max-h-[var(--copilot-popup-max-height)] cpk:md:max-w-[var(--copilot-popup-max-width)]\",\n \"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\",\n popupAnimationClass,\n )}\n style={popupStyle}\n >\n {headerElement}\n <div className=\"cpk:flex-1 cpk:overflow-hidden\" data-popup-chat>\n <CopilotChatView\n {...restProps}\n className={cn(\"cpk:h-full cpk:min-h-0\", className)}\n />\n </div>\n </div>\n </div>\n ) : null;\n\n return (\n <>\n {toggleButtonElement}\n {popupContent}\n </>\n );\n}\n\nCopilotPopupView.displayName = \"CopilotPopupView\";\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotPopupView {\n /**\n * Popup-specific welcome screen layout:\n * - Welcome message centered vertically\n * - Suggestions just above input\n * - Input fixed at the bottom\n */\n export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({\n welcomeMessage,\n input,\n suggestionView,\n className,\n children,\n ...props\n }) => {\n // Render the welcomeMessage slot internally\n const BoundWelcomeMessage = renderSlot(\n welcomeMessage,\n CopilotChatView.WelcomeMessage,\n {},\n );\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n welcomeMessage: BoundWelcomeMessage,\n input,\n suggestionView,\n className,\n ...props,\n })}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\"cpk:h-full cpk:flex cpk:flex-col\", className)}\n {...props}\n >\n {/* Welcome message - centered vertically */}\n <div className=\"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\">\n {BoundWelcomeMessage}\n </div>\n\n {/* Suggestions and input at bottom */}\n <div>\n {/* Suggestions above input */}\n <div className=\"cpk:mb-4 cpk:flex cpk:justify-center cpk:px-4\">\n {suggestionView}\n </div>\n {input}\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotPopupView;\n"],"mappings":"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"}
@@ -73,6 +73,7 @@ function CopilotSidebarViewInternal({ header, toggleButton, width, ...props }) {
73
73
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [require_slots.renderSlot(toggleButton, require_CopilotChatToggleButton.default, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("aside", {
74
74
  ref: sidebarRef,
75
75
  "data-copilotkit": true,
76
+ "data-testid": "copilot-sidebar",
76
77
  "data-copilot-sidebar": true,
77
78
  className: require_utils.cn("cpk:fixed cpk:right-0 cpk:top-0 cpk:z-[1200] cpk:flex", "cpk:h-[100vh] cpk:h-[100dvh] cpk:max-h-screen", "cpk:w-full", "cpk:border-l cpk:border-border cpk:bg-background cpk:text-foreground cpk:shadow-xl", "cpk:transition-transform cpk:duration-300 cpk:ease-out", isSidebarOpen ? "cpk:translate-x-0" : "cpk:translate-x-full cpk:pointer-events-none"),
78
79
  style: {
@@ -1 +1 @@
1
- {"version":3,"file":"CopilotSidebarView.cjs","names":["CopilotChatConfigurationProvider","useCopilotChatConfiguration","renderSlot","CopilotModalHeader","CopilotChatToggleButton","cn","CopilotChatView"],"sources":["../../../src/components/chat/CopilotSidebarView.tsx"],"sourcesContent":["import React, { useEffect, useLayoutEffect, useRef, useState } from \"react\";\n\nimport CopilotChatView, {\n CopilotChatViewProps,\n WelcomeScreenProps,\n} from \"./CopilotChatView\";\nimport {\n CopilotChatConfigurationProvider,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport CopilotChatToggleButton from \"./CopilotChatToggleButton\";\nimport { cn } from \"@/lib/utils\";\nimport { CopilotModalHeader } from \"./CopilotModalHeader\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\n\nconst DEFAULT_SIDEBAR_WIDTH = 480;\nconst SIDEBAR_TRANSITION_MS = 260;\n\nexport type CopilotSidebarViewProps = CopilotChatViewProps & {\n header?: SlotValue<typeof CopilotModalHeader>;\n toggleButton?: SlotValue<typeof CopilotChatToggleButton>;\n width?: number | string;\n defaultOpen?: boolean;\n};\n\nexport function CopilotSidebarView({\n header,\n toggleButton,\n width,\n defaultOpen = true,\n ...props\n}: CopilotSidebarViewProps) {\n return (\n <CopilotChatConfigurationProvider isModalDefaultOpen={defaultOpen}>\n <CopilotSidebarViewInternal\n header={header}\n toggleButton={toggleButton}\n width={width}\n {...props}\n />\n </CopilotChatConfigurationProvider>\n );\n}\n\nfunction CopilotSidebarViewInternal({\n header,\n toggleButton,\n width,\n ...props\n}: Omit<CopilotSidebarViewProps, \"defaultOpen\">) {\n const configuration = useCopilotChatConfiguration();\n\n const isSidebarOpen = configuration?.isModalOpen ?? false;\n\n const sidebarRef = useRef<HTMLDivElement | null>(null);\n const [sidebarWidth, setSidebarWidth] = useState<number | string>(\n width ?? DEFAULT_SIDEBAR_WIDTH,\n );\n\n // Helper to convert width to CSS value\n const widthToCss = (w: number | string): string => {\n return typeof w === \"number\" ? `${w}px` : w;\n };\n\n // Helper to extract numeric value for body margin (only works with px values)\n const widthToMargin = (w: number | string): string => {\n if (typeof w === \"number\") {\n return `${w}px`;\n }\n // For string values, use as-is (assumes valid CSS unit)\n return w;\n };\n\n useEffect(() => {\n // If width is explicitly provided, don't measure\n if (width !== undefined) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const element = sidebarRef.current;\n if (!element) {\n return;\n }\n\n const updateWidth = () => {\n const rect = element.getBoundingClientRect();\n if (rect.width > 0) {\n setSidebarWidth(rect.width);\n }\n };\n\n updateWidth();\n\n if (typeof ResizeObserver !== \"undefined\") {\n const observer = new ResizeObserver(() => updateWidth());\n observer.observe(element);\n return () => observer.disconnect();\n }\n\n window.addEventListener(\"resize\", updateWidth);\n return () => window.removeEventListener(\"resize\", updateWidth);\n }, [width]);\n\n // Manage body margin for sidebar docking (desktop only).\n // useLayoutEffect runs before paint, so defaultOpen={true} never causes a\n // visible layout shift — the margin is already applied on the first frame.\n const hasMounted = useRef(false);\n\n useLayoutEffect(() => {\n if (\n typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\"\n )\n return;\n if (!window.matchMedia(\"(min-width: 768px)\").matches) return;\n\n if (isSidebarOpen) {\n if (hasMounted.current) {\n document.body.style.transition = `margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease`;\n }\n document.body.style.marginInlineEnd = widthToMargin(sidebarWidth);\n } else if (hasMounted.current) {\n document.body.style.transition = `margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease`;\n document.body.style.marginInlineEnd = \"\";\n }\n\n hasMounted.current = true;\n\n return () => {\n document.body.style.marginInlineEnd = \"\";\n document.body.style.transition = \"\";\n };\n }, [isSidebarOpen, sidebarWidth]);\n\n const headerElement = renderSlot(header, CopilotModalHeader, {});\n const toggleButtonElement = renderSlot(\n toggleButton,\n CopilotChatToggleButton,\n {},\n );\n\n return (\n <>\n {toggleButtonElement}\n <aside\n ref={sidebarRef}\n data-copilotkit\n data-copilot-sidebar\n className={cn(\n \"cpk:fixed cpk:right-0 cpk:top-0 cpk:z-[1200] cpk:flex\",\n // Height with dvh fallback and safe area support\n \"cpk:h-[100vh] cpk:h-[100dvh] cpk:max-h-screen\",\n // Responsive width: full on mobile, custom on desktop\n \"cpk:w-full\",\n \"cpk:border-l cpk:border-border cpk:bg-background cpk:text-foreground cpk:shadow-xl\",\n \"cpk:transition-transform cpk:duration-300 cpk:ease-out\",\n isSidebarOpen\n ? \"cpk:translate-x-0\"\n : \"cpk:translate-x-full cpk:pointer-events-none\",\n )}\n style={\n {\n // Use CSS custom property for responsive width\n [\"--sidebar-width\" as string]: widthToCss(sidebarWidth),\n // Safe area insets for iOS\n paddingTop: \"env(safe-area-inset-top)\",\n paddingBottom: \"env(safe-area-inset-bottom)\",\n } as React.CSSProperties\n }\n aria-hidden={!isSidebarOpen}\n aria-label=\"Copilot chat sidebar\"\n role=\"complementary\"\n >\n <div className=\"cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden\">\n {headerElement}\n <div className=\"cpk:flex-1 cpk:overflow-hidden\" data-sidebar-chat>\n <CopilotChatView {...props} />\n </div>\n </div>\n </aside>\n </>\n );\n}\n\nCopilotSidebarView.displayName = \"CopilotSidebarView\";\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotSidebarView {\n /**\n * Sidebar-specific welcome screen layout:\n * - Suggestions at the top\n * - Welcome message in the middle\n * - Input fixed at the bottom (like normal chat)\n */\n export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({\n welcomeMessage,\n input,\n suggestionView,\n className,\n children,\n ...props\n }) => {\n // Render the welcomeMessage slot internally\n const BoundWelcomeMessage = renderSlot(\n welcomeMessage,\n CopilotChatView.WelcomeMessage,\n {},\n );\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n welcomeMessage: BoundWelcomeMessage,\n input,\n suggestionView,\n className,\n ...props,\n })}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\"cpk:h-full cpk:flex cpk:flex-col\", className)}\n {...props}\n >\n {/* Welcome message - centered vertically */}\n <div className=\"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\">\n {BoundWelcomeMessage}\n </div>\n\n {/* Suggestions and input at bottom */}\n <div className=\"cpk:px-8 cpk:pb-4\">\n <div className=\"cpk:max-w-3xl cpk:mx-auto\">\n {/* Suggestions above input */}\n <div className=\"cpk:mb-4 cpk:flex cpk:justify-center\">\n {suggestionView}\n </div>\n {input}\n </div>\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotSidebarView;\n"],"mappings":"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"}
1
+ {"version":3,"file":"CopilotSidebarView.cjs","names":["CopilotChatConfigurationProvider","useCopilotChatConfiguration","renderSlot","CopilotModalHeader","CopilotChatToggleButton","cn","CopilotChatView"],"sources":["../../../src/components/chat/CopilotSidebarView.tsx"],"sourcesContent":["import React, { useEffect, useLayoutEffect, useRef, useState } from \"react\";\n\nimport CopilotChatView, {\n CopilotChatViewProps,\n WelcomeScreenProps,\n} from \"./CopilotChatView\";\nimport {\n CopilotChatConfigurationProvider,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport CopilotChatToggleButton from \"./CopilotChatToggleButton\";\nimport { cn } from \"@/lib/utils\";\nimport { CopilotModalHeader } from \"./CopilotModalHeader\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\n\nconst DEFAULT_SIDEBAR_WIDTH = 480;\nconst SIDEBAR_TRANSITION_MS = 260;\n\nexport type CopilotSidebarViewProps = CopilotChatViewProps & {\n header?: SlotValue<typeof CopilotModalHeader>;\n toggleButton?: SlotValue<typeof CopilotChatToggleButton>;\n width?: number | string;\n defaultOpen?: boolean;\n};\n\nexport function CopilotSidebarView({\n header,\n toggleButton,\n width,\n defaultOpen = true,\n ...props\n}: CopilotSidebarViewProps) {\n return (\n <CopilotChatConfigurationProvider isModalDefaultOpen={defaultOpen}>\n <CopilotSidebarViewInternal\n header={header}\n toggleButton={toggleButton}\n width={width}\n {...props}\n />\n </CopilotChatConfigurationProvider>\n );\n}\n\nfunction CopilotSidebarViewInternal({\n header,\n toggleButton,\n width,\n ...props\n}: Omit<CopilotSidebarViewProps, \"defaultOpen\">) {\n const configuration = useCopilotChatConfiguration();\n\n const isSidebarOpen = configuration?.isModalOpen ?? false;\n\n const sidebarRef = useRef<HTMLDivElement | null>(null);\n const [sidebarWidth, setSidebarWidth] = useState<number | string>(\n width ?? DEFAULT_SIDEBAR_WIDTH,\n );\n\n // Helper to convert width to CSS value\n const widthToCss = (w: number | string): string => {\n return typeof w === \"number\" ? `${w}px` : w;\n };\n\n // Helper to extract numeric value for body margin (only works with px values)\n const widthToMargin = (w: number | string): string => {\n if (typeof w === \"number\") {\n return `${w}px`;\n }\n // For string values, use as-is (assumes valid CSS unit)\n return w;\n };\n\n useEffect(() => {\n // If width is explicitly provided, don't measure\n if (width !== undefined) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const element = sidebarRef.current;\n if (!element) {\n return;\n }\n\n const updateWidth = () => {\n const rect = element.getBoundingClientRect();\n if (rect.width > 0) {\n setSidebarWidth(rect.width);\n }\n };\n\n updateWidth();\n\n if (typeof ResizeObserver !== \"undefined\") {\n const observer = new ResizeObserver(() => updateWidth());\n observer.observe(element);\n return () => observer.disconnect();\n }\n\n window.addEventListener(\"resize\", updateWidth);\n return () => window.removeEventListener(\"resize\", updateWidth);\n }, [width]);\n\n // Manage body margin for sidebar docking (desktop only).\n // useLayoutEffect runs before paint, so defaultOpen={true} never causes a\n // visible layout shift — the margin is already applied on the first frame.\n const hasMounted = useRef(false);\n\n useLayoutEffect(() => {\n if (\n typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\"\n )\n return;\n if (!window.matchMedia(\"(min-width: 768px)\").matches) return;\n\n if (isSidebarOpen) {\n if (hasMounted.current) {\n document.body.style.transition = `margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease`;\n }\n document.body.style.marginInlineEnd = widthToMargin(sidebarWidth);\n } else if (hasMounted.current) {\n document.body.style.transition = `margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease`;\n document.body.style.marginInlineEnd = \"\";\n }\n\n hasMounted.current = true;\n\n return () => {\n document.body.style.marginInlineEnd = \"\";\n document.body.style.transition = \"\";\n };\n }, [isSidebarOpen, sidebarWidth]);\n\n const headerElement = renderSlot(header, CopilotModalHeader, {});\n const toggleButtonElement = renderSlot(\n toggleButton,\n CopilotChatToggleButton,\n {},\n );\n\n return (\n <>\n {toggleButtonElement}\n <aside\n ref={sidebarRef}\n data-copilotkit\n data-testid=\"copilot-sidebar\"\n data-copilot-sidebar\n className={cn(\n \"cpk:fixed cpk:right-0 cpk:top-0 cpk:z-[1200] cpk:flex\",\n // Height with dvh fallback and safe area support\n \"cpk:h-[100vh] cpk:h-[100dvh] cpk:max-h-screen\",\n // Responsive width: full on mobile, custom on desktop\n \"cpk:w-full\",\n \"cpk:border-l cpk:border-border cpk:bg-background cpk:text-foreground cpk:shadow-xl\",\n \"cpk:transition-transform cpk:duration-300 cpk:ease-out\",\n isSidebarOpen\n ? \"cpk:translate-x-0\"\n : \"cpk:translate-x-full cpk:pointer-events-none\",\n )}\n style={\n {\n // Use CSS custom property for responsive width\n [\"--sidebar-width\" as string]: widthToCss(sidebarWidth),\n // Safe area insets for iOS\n paddingTop: \"env(safe-area-inset-top)\",\n paddingBottom: \"env(safe-area-inset-bottom)\",\n } as React.CSSProperties\n }\n aria-hidden={!isSidebarOpen}\n aria-label=\"Copilot chat sidebar\"\n role=\"complementary\"\n >\n <div className=\"cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden\">\n {headerElement}\n <div className=\"cpk:flex-1 cpk:overflow-hidden\" data-sidebar-chat>\n <CopilotChatView {...props} />\n </div>\n </div>\n </aside>\n </>\n );\n}\n\nCopilotSidebarView.displayName = \"CopilotSidebarView\";\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotSidebarView {\n /**\n * Sidebar-specific welcome screen layout:\n * - Suggestions at the top\n * - Welcome message in the middle\n * - Input fixed at the bottom (like normal chat)\n */\n export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({\n welcomeMessage,\n input,\n suggestionView,\n className,\n children,\n ...props\n }) => {\n // Render the welcomeMessage slot internally\n const BoundWelcomeMessage = renderSlot(\n welcomeMessage,\n CopilotChatView.WelcomeMessage,\n {},\n );\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n welcomeMessage: BoundWelcomeMessage,\n input,\n suggestionView,\n className,\n ...props,\n })}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\"cpk:h-full cpk:flex cpk:flex-col\", className)}\n {...props}\n >\n {/* Welcome message - centered vertically */}\n <div className=\"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\">\n {BoundWelcomeMessage}\n </div>\n\n {/* Suggestions and input at bottom */}\n <div className=\"cpk:px-8 cpk:pb-4\">\n <div className=\"cpk:max-w-3xl cpk:mx-auto\">\n {/* Suggestions above input */}\n <div className=\"cpk:mb-4 cpk:flex cpk:justify-center\">\n {suggestionView}\n </div>\n {input}\n </div>\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotSidebarView;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CopilotSidebarView.d.cts","names":[],"sources":["../../../src/components/chat/CopilotSidebarView.tsx"],"mappings":";;;;;;;;KAkBY,uBAAA,GAA0B,oBAAA;EACpC,MAAA,GAAS,SAAA,QAAiB,kBAAA;EAC1B,YAAA,GAAe,SAAA,QAAiB,uBAAA;EAChC,KAAA;EACA,WAAA;AAAA;AAAA,iBAGc,kBAAA,CAAA;EACd,MAAA;EACA,YAAA;EACA,KAAA;EACA,WAAA;EAAA,GACG;AAAA,GACF,uBAAA,GAAuB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBANV,kBAAA;EAAA,IAAkB,WAAA;AAAA;AAAA,kBAsKjB,kBAAA;EA3KS;;;;;;EAAA,MAkLX,aAAA,EAAe,KAAA,CAAM,EAAA,CAAG,kBAAA;AAAA"}
1
+ {"version":3,"file":"CopilotSidebarView.d.cts","names":[],"sources":["../../../src/components/chat/CopilotSidebarView.tsx"],"mappings":";;;;;;;;KAkBY,uBAAA,GAA0B,oBAAA;EACpC,MAAA,GAAS,SAAA,QAAiB,kBAAA;EAC1B,YAAA,GAAe,SAAA,QAAiB,uBAAA;EAChC,KAAA;EACA,WAAA;AAAA;AAAA,iBAGc,kBAAA,CAAA;EACd,MAAA;EACA,YAAA;EACA,KAAA;EACA,WAAA;EAAA,GACG;AAAA,GACF,uBAAA,GAAuB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBANV,kBAAA;EAAA,IAAkB,WAAA;AAAA;AAAA,kBAuKjB,kBAAA;EA5KS;;;;;;EAAA,MAmLX,aAAA,EAAe,KAAA,CAAM,EAAA,CAAG,kBAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"CopilotSidebarView.d.mts","names":[],"sources":["../../../src/components/chat/CopilotSidebarView.tsx"],"mappings":";;;;;;;;KAkBY,uBAAA,GAA0B,oBAAA;EACpC,MAAA,GAAS,SAAA,QAAiB,kBAAA;EAC1B,YAAA,GAAe,SAAA,QAAiB,uBAAA;EAChC,KAAA;EACA,WAAA;AAAA;AAAA,iBAGc,kBAAA,CAAA;EACd,MAAA;EACA,YAAA;EACA,KAAA;EACA,WAAA;EAAA,GACG;AAAA,GACF,uBAAA,GAAuB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBANV,kBAAA;EAAA,IAAkB,WAAA;AAAA;AAAA,kBAsKjB,kBAAA;EA3KS;;;;;;EAAA,MAkLX,aAAA,EAAe,KAAA,CAAM,EAAA,CAAG,kBAAA;AAAA"}
1
+ {"version":3,"file":"CopilotSidebarView.d.mts","names":[],"sources":["../../../src/components/chat/CopilotSidebarView.tsx"],"mappings":";;;;;;;;KAkBY,uBAAA,GAA0B,oBAAA;EACpC,MAAA,GAAS,SAAA,QAAiB,kBAAA;EAC1B,YAAA,GAAe,SAAA,QAAiB,uBAAA;EAChC,KAAA;EACA,WAAA;AAAA;AAAA,iBAGc,kBAAA,CAAA;EACd,MAAA;EACA,YAAA;EACA,KAAA;EACA,WAAA;EAAA,GACG;AAAA,GACF,uBAAA,GAAuB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBANV,kBAAA;EAAA,IAAkB,WAAA;AAAA;AAAA,kBAuKjB,kBAAA;EA5KS;;;;;;EAAA,MAmLX,aAAA,EAAe,KAAA,CAAM,EAAA,CAAG,kBAAA;AAAA"}
@@ -71,6 +71,7 @@ function CopilotSidebarViewInternal({ header, toggleButton, width, ...props }) {
71
71
  return /* @__PURE__ */ jsxs(Fragment, { children: [renderSlot(toggleButton, CopilotChatToggleButton, {}), /* @__PURE__ */ jsx("aside", {
72
72
  ref: sidebarRef,
73
73
  "data-copilotkit": true,
74
+ "data-testid": "copilot-sidebar",
74
75
  "data-copilot-sidebar": true,
75
76
  className: cn("cpk:fixed cpk:right-0 cpk:top-0 cpk:z-[1200] cpk:flex", "cpk:h-[100vh] cpk:h-[100dvh] cpk:max-h-screen", "cpk:w-full", "cpk:border-l cpk:border-border cpk:bg-background cpk:text-foreground cpk:shadow-xl", "cpk:transition-transform cpk:duration-300 cpk:ease-out", isSidebarOpen ? "cpk:translate-x-0" : "cpk:translate-x-full cpk:pointer-events-none"),
76
77
  style: {
@@ -1 +1 @@
1
- {"version":3,"file":"CopilotSidebarView.mjs","names":["CopilotChatView"],"sources":["../../../src/components/chat/CopilotSidebarView.tsx"],"sourcesContent":["import React, { useEffect, useLayoutEffect, useRef, useState } from \"react\";\n\nimport CopilotChatView, {\n CopilotChatViewProps,\n WelcomeScreenProps,\n} from \"./CopilotChatView\";\nimport {\n CopilotChatConfigurationProvider,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport CopilotChatToggleButton from \"./CopilotChatToggleButton\";\nimport { cn } from \"@/lib/utils\";\nimport { CopilotModalHeader } from \"./CopilotModalHeader\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\n\nconst DEFAULT_SIDEBAR_WIDTH = 480;\nconst SIDEBAR_TRANSITION_MS = 260;\n\nexport type CopilotSidebarViewProps = CopilotChatViewProps & {\n header?: SlotValue<typeof CopilotModalHeader>;\n toggleButton?: SlotValue<typeof CopilotChatToggleButton>;\n width?: number | string;\n defaultOpen?: boolean;\n};\n\nexport function CopilotSidebarView({\n header,\n toggleButton,\n width,\n defaultOpen = true,\n ...props\n}: CopilotSidebarViewProps) {\n return (\n <CopilotChatConfigurationProvider isModalDefaultOpen={defaultOpen}>\n <CopilotSidebarViewInternal\n header={header}\n toggleButton={toggleButton}\n width={width}\n {...props}\n />\n </CopilotChatConfigurationProvider>\n );\n}\n\nfunction CopilotSidebarViewInternal({\n header,\n toggleButton,\n width,\n ...props\n}: Omit<CopilotSidebarViewProps, \"defaultOpen\">) {\n const configuration = useCopilotChatConfiguration();\n\n const isSidebarOpen = configuration?.isModalOpen ?? false;\n\n const sidebarRef = useRef<HTMLDivElement | null>(null);\n const [sidebarWidth, setSidebarWidth] = useState<number | string>(\n width ?? DEFAULT_SIDEBAR_WIDTH,\n );\n\n // Helper to convert width to CSS value\n const widthToCss = (w: number | string): string => {\n return typeof w === \"number\" ? `${w}px` : w;\n };\n\n // Helper to extract numeric value for body margin (only works with px values)\n const widthToMargin = (w: number | string): string => {\n if (typeof w === \"number\") {\n return `${w}px`;\n }\n // For string values, use as-is (assumes valid CSS unit)\n return w;\n };\n\n useEffect(() => {\n // If width is explicitly provided, don't measure\n if (width !== undefined) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const element = sidebarRef.current;\n if (!element) {\n return;\n }\n\n const updateWidth = () => {\n const rect = element.getBoundingClientRect();\n if (rect.width > 0) {\n setSidebarWidth(rect.width);\n }\n };\n\n updateWidth();\n\n if (typeof ResizeObserver !== \"undefined\") {\n const observer = new ResizeObserver(() => updateWidth());\n observer.observe(element);\n return () => observer.disconnect();\n }\n\n window.addEventListener(\"resize\", updateWidth);\n return () => window.removeEventListener(\"resize\", updateWidth);\n }, [width]);\n\n // Manage body margin for sidebar docking (desktop only).\n // useLayoutEffect runs before paint, so defaultOpen={true} never causes a\n // visible layout shift — the margin is already applied on the first frame.\n const hasMounted = useRef(false);\n\n useLayoutEffect(() => {\n if (\n typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\"\n )\n return;\n if (!window.matchMedia(\"(min-width: 768px)\").matches) return;\n\n if (isSidebarOpen) {\n if (hasMounted.current) {\n document.body.style.transition = `margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease`;\n }\n document.body.style.marginInlineEnd = widthToMargin(sidebarWidth);\n } else if (hasMounted.current) {\n document.body.style.transition = `margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease`;\n document.body.style.marginInlineEnd = \"\";\n }\n\n hasMounted.current = true;\n\n return () => {\n document.body.style.marginInlineEnd = \"\";\n document.body.style.transition = \"\";\n };\n }, [isSidebarOpen, sidebarWidth]);\n\n const headerElement = renderSlot(header, CopilotModalHeader, {});\n const toggleButtonElement = renderSlot(\n toggleButton,\n CopilotChatToggleButton,\n {},\n );\n\n return (\n <>\n {toggleButtonElement}\n <aside\n ref={sidebarRef}\n data-copilotkit\n data-copilot-sidebar\n className={cn(\n \"cpk:fixed cpk:right-0 cpk:top-0 cpk:z-[1200] cpk:flex\",\n // Height with dvh fallback and safe area support\n \"cpk:h-[100vh] cpk:h-[100dvh] cpk:max-h-screen\",\n // Responsive width: full on mobile, custom on desktop\n \"cpk:w-full\",\n \"cpk:border-l cpk:border-border cpk:bg-background cpk:text-foreground cpk:shadow-xl\",\n \"cpk:transition-transform cpk:duration-300 cpk:ease-out\",\n isSidebarOpen\n ? \"cpk:translate-x-0\"\n : \"cpk:translate-x-full cpk:pointer-events-none\",\n )}\n style={\n {\n // Use CSS custom property for responsive width\n [\"--sidebar-width\" as string]: widthToCss(sidebarWidth),\n // Safe area insets for iOS\n paddingTop: \"env(safe-area-inset-top)\",\n paddingBottom: \"env(safe-area-inset-bottom)\",\n } as React.CSSProperties\n }\n aria-hidden={!isSidebarOpen}\n aria-label=\"Copilot chat sidebar\"\n role=\"complementary\"\n >\n <div className=\"cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden\">\n {headerElement}\n <div className=\"cpk:flex-1 cpk:overflow-hidden\" data-sidebar-chat>\n <CopilotChatView {...props} />\n </div>\n </div>\n </aside>\n </>\n );\n}\n\nCopilotSidebarView.displayName = \"CopilotSidebarView\";\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotSidebarView {\n /**\n * Sidebar-specific welcome screen layout:\n * - Suggestions at the top\n * - Welcome message in the middle\n * - Input fixed at the bottom (like normal chat)\n */\n export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({\n welcomeMessage,\n input,\n suggestionView,\n className,\n children,\n ...props\n }) => {\n // Render the welcomeMessage slot internally\n const BoundWelcomeMessage = renderSlot(\n welcomeMessage,\n CopilotChatView.WelcomeMessage,\n {},\n );\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n welcomeMessage: BoundWelcomeMessage,\n input,\n suggestionView,\n className,\n ...props,\n })}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\"cpk:h-full cpk:flex cpk:flex-col\", className)}\n {...props}\n >\n {/* Welcome message - centered vertically */}\n <div className=\"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\">\n {BoundWelcomeMessage}\n </div>\n\n {/* Suggestions and input at bottom */}\n <div className=\"cpk:px-8 cpk:pb-4\">\n <div className=\"cpk:max-w-3xl cpk:mx-auto\">\n {/* Suggestions above input */}\n <div className=\"cpk:mb-4 cpk:flex cpk:justify-center\">\n {suggestionView}\n </div>\n {input}\n </div>\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotSidebarView;\n"],"mappings":"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"}
1
+ {"version":3,"file":"CopilotSidebarView.mjs","names":["CopilotChatView"],"sources":["../../../src/components/chat/CopilotSidebarView.tsx"],"sourcesContent":["import React, { useEffect, useLayoutEffect, useRef, useState } from \"react\";\n\nimport CopilotChatView, {\n CopilotChatViewProps,\n WelcomeScreenProps,\n} from \"./CopilotChatView\";\nimport {\n CopilotChatConfigurationProvider,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport CopilotChatToggleButton from \"./CopilotChatToggleButton\";\nimport { cn } from \"@/lib/utils\";\nimport { CopilotModalHeader } from \"./CopilotModalHeader\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\n\nconst DEFAULT_SIDEBAR_WIDTH = 480;\nconst SIDEBAR_TRANSITION_MS = 260;\n\nexport type CopilotSidebarViewProps = CopilotChatViewProps & {\n header?: SlotValue<typeof CopilotModalHeader>;\n toggleButton?: SlotValue<typeof CopilotChatToggleButton>;\n width?: number | string;\n defaultOpen?: boolean;\n};\n\nexport function CopilotSidebarView({\n header,\n toggleButton,\n width,\n defaultOpen = true,\n ...props\n}: CopilotSidebarViewProps) {\n return (\n <CopilotChatConfigurationProvider isModalDefaultOpen={defaultOpen}>\n <CopilotSidebarViewInternal\n header={header}\n toggleButton={toggleButton}\n width={width}\n {...props}\n />\n </CopilotChatConfigurationProvider>\n );\n}\n\nfunction CopilotSidebarViewInternal({\n header,\n toggleButton,\n width,\n ...props\n}: Omit<CopilotSidebarViewProps, \"defaultOpen\">) {\n const configuration = useCopilotChatConfiguration();\n\n const isSidebarOpen = configuration?.isModalOpen ?? false;\n\n const sidebarRef = useRef<HTMLDivElement | null>(null);\n const [sidebarWidth, setSidebarWidth] = useState<number | string>(\n width ?? DEFAULT_SIDEBAR_WIDTH,\n );\n\n // Helper to convert width to CSS value\n const widthToCss = (w: number | string): string => {\n return typeof w === \"number\" ? `${w}px` : w;\n };\n\n // Helper to extract numeric value for body margin (only works with px values)\n const widthToMargin = (w: number | string): string => {\n if (typeof w === \"number\") {\n return `${w}px`;\n }\n // For string values, use as-is (assumes valid CSS unit)\n return w;\n };\n\n useEffect(() => {\n // If width is explicitly provided, don't measure\n if (width !== undefined) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const element = sidebarRef.current;\n if (!element) {\n return;\n }\n\n const updateWidth = () => {\n const rect = element.getBoundingClientRect();\n if (rect.width > 0) {\n setSidebarWidth(rect.width);\n }\n };\n\n updateWidth();\n\n if (typeof ResizeObserver !== \"undefined\") {\n const observer = new ResizeObserver(() => updateWidth());\n observer.observe(element);\n return () => observer.disconnect();\n }\n\n window.addEventListener(\"resize\", updateWidth);\n return () => window.removeEventListener(\"resize\", updateWidth);\n }, [width]);\n\n // Manage body margin for sidebar docking (desktop only).\n // useLayoutEffect runs before paint, so defaultOpen={true} never causes a\n // visible layout shift — the margin is already applied on the first frame.\n const hasMounted = useRef(false);\n\n useLayoutEffect(() => {\n if (\n typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\"\n )\n return;\n if (!window.matchMedia(\"(min-width: 768px)\").matches) return;\n\n if (isSidebarOpen) {\n if (hasMounted.current) {\n document.body.style.transition = `margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease`;\n }\n document.body.style.marginInlineEnd = widthToMargin(sidebarWidth);\n } else if (hasMounted.current) {\n document.body.style.transition = `margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease`;\n document.body.style.marginInlineEnd = \"\";\n }\n\n hasMounted.current = true;\n\n return () => {\n document.body.style.marginInlineEnd = \"\";\n document.body.style.transition = \"\";\n };\n }, [isSidebarOpen, sidebarWidth]);\n\n const headerElement = renderSlot(header, CopilotModalHeader, {});\n const toggleButtonElement = renderSlot(\n toggleButton,\n CopilotChatToggleButton,\n {},\n );\n\n return (\n <>\n {toggleButtonElement}\n <aside\n ref={sidebarRef}\n data-copilotkit\n data-testid=\"copilot-sidebar\"\n data-copilot-sidebar\n className={cn(\n \"cpk:fixed cpk:right-0 cpk:top-0 cpk:z-[1200] cpk:flex\",\n // Height with dvh fallback and safe area support\n \"cpk:h-[100vh] cpk:h-[100dvh] cpk:max-h-screen\",\n // Responsive width: full on mobile, custom on desktop\n \"cpk:w-full\",\n \"cpk:border-l cpk:border-border cpk:bg-background cpk:text-foreground cpk:shadow-xl\",\n \"cpk:transition-transform cpk:duration-300 cpk:ease-out\",\n isSidebarOpen\n ? \"cpk:translate-x-0\"\n : \"cpk:translate-x-full cpk:pointer-events-none\",\n )}\n style={\n {\n // Use CSS custom property for responsive width\n [\"--sidebar-width\" as string]: widthToCss(sidebarWidth),\n // Safe area insets for iOS\n paddingTop: \"env(safe-area-inset-top)\",\n paddingBottom: \"env(safe-area-inset-bottom)\",\n } as React.CSSProperties\n }\n aria-hidden={!isSidebarOpen}\n aria-label=\"Copilot chat sidebar\"\n role=\"complementary\"\n >\n <div className=\"cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden\">\n {headerElement}\n <div className=\"cpk:flex-1 cpk:overflow-hidden\" data-sidebar-chat>\n <CopilotChatView {...props} />\n </div>\n </div>\n </aside>\n </>\n );\n}\n\nCopilotSidebarView.displayName = \"CopilotSidebarView\";\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotSidebarView {\n /**\n * Sidebar-specific welcome screen layout:\n * - Suggestions at the top\n * - Welcome message in the middle\n * - Input fixed at the bottom (like normal chat)\n */\n export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({\n welcomeMessage,\n input,\n suggestionView,\n className,\n children,\n ...props\n }) => {\n // Render the welcomeMessage slot internally\n const BoundWelcomeMessage = renderSlot(\n welcomeMessage,\n CopilotChatView.WelcomeMessage,\n {},\n );\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n welcomeMessage: BoundWelcomeMessage,\n input,\n suggestionView,\n className,\n ...props,\n })}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\"cpk:h-full cpk:flex cpk:flex-col\", className)}\n {...props}\n >\n {/* Welcome message - centered vertically */}\n <div className=\"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\">\n {BoundWelcomeMessage}\n </div>\n\n {/* Suggestions and input at bottom */}\n <div className=\"cpk:px-8 cpk:pb-4\">\n <div className=\"cpk:max-w-3xl cpk:mx-auto\">\n {/* Suggestions above input */}\n <div className=\"cpk:mb-4 cpk:flex cpk:justify-center\">\n {suggestionView}\n </div>\n {input}\n </div>\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotSidebarView;\n"],"mappings":";;;;;;;;;;AAeA,MAAM,wBAAwB;AAC9B,MAAM,wBAAwB;AAS9B,SAAgB,mBAAmB,EACjC,QACA,cACA,OACA,cAAc,MACd,GAAG,SACuB;AAC1B,QACE,oBAAC;EAAiC,oBAAoB;YACpD,oBAAC;GACS;GACM;GACP;GACP,GAAI;IACJ;GAC+B;;AAIvC,SAAS,2BAA2B,EAClC,QACA,cACA,OACA,GAAG,SAC4C;CAG/C,MAAM,gBAFgB,6BAA6B,EAEd,eAAe;CAEpD,MAAM,aAAa,OAA8B,KAAK;CACtD,MAAM,CAAC,cAAc,mBAAmB,SACtC,SAAS,sBACV;CAGD,MAAM,cAAc,MAA+B;AACjD,SAAO,OAAO,MAAM,WAAW,GAAG,EAAE,MAAM;;CAI5C,MAAM,iBAAiB,MAA+B;AACpD,MAAI,OAAO,MAAM,SACf,QAAO,GAAG,EAAE;AAGd,SAAO;;AAGT,iBAAgB;AAEd,MAAI,UAAU,OACZ;AAGF,MAAI,OAAO,WAAW,YACpB;EAGF,MAAM,UAAU,WAAW;AAC3B,MAAI,CAAC,QACH;EAGF,MAAM,oBAAoB;GACxB,MAAM,OAAO,QAAQ,uBAAuB;AAC5C,OAAI,KAAK,QAAQ,EACf,iBAAgB,KAAK,MAAM;;AAI/B,eAAa;AAEb,MAAI,OAAO,mBAAmB,aAAa;GACzC,MAAM,WAAW,IAAI,qBAAqB,aAAa,CAAC;AACxD,YAAS,QAAQ,QAAQ;AACzB,gBAAa,SAAS,YAAY;;AAGpC,SAAO,iBAAiB,UAAU,YAAY;AAC9C,eAAa,OAAO,oBAAoB,UAAU,YAAY;IAC7D,CAAC,MAAM,CAAC;CAKX,MAAM,aAAa,OAAO,MAAM;AAEhC,uBAAsB;AACpB,MACE,OAAO,WAAW,eAClB,OAAO,OAAO,eAAe,WAE7B;AACF,MAAI,CAAC,OAAO,WAAW,qBAAqB,CAAC,QAAS;AAEtD,MAAI,eAAe;AACjB,OAAI,WAAW,QACb,UAAS,KAAK,MAAM,aAAa,qBAAqB,sBAAsB;AAE9E,YAAS,KAAK,MAAM,kBAAkB,cAAc,aAAa;aACxD,WAAW,SAAS;AAC7B,YAAS,KAAK,MAAM,aAAa,qBAAqB,sBAAsB;AAC5E,YAAS,KAAK,MAAM,kBAAkB;;AAGxC,aAAW,UAAU;AAErB,eAAa;AACX,YAAS,KAAK,MAAM,kBAAkB;AACtC,YAAS,KAAK,MAAM,aAAa;;IAElC,CAAC,eAAe,aAAa,CAAC;CAEjC,MAAM,gBAAgB,WAAW,QAAQ,oBAAoB,EAAE,CAAC;AAOhE,QACE,4CAP0B,WAC1B,cACA,yBACA,EAAE,CACH,EAKG,oBAAC;EACC,KAAK;EACL;EACA,eAAY;EACZ;EACA,WAAW,GACT,yDAEA,iDAEA,cACA,sFACA,0DACA,gBACI,sBACA,+CACL;EACD,OACE;IAEG,oBAA8B,WAAW,aAAa;GAEvD,YAAY;GACZ,eAAe;GAChB;EAEH,eAAa,CAAC;EACd,cAAW;EACX,MAAK;YAEL,qBAAC;GAAI,WAAU;cACZ,eACD,oBAAC;IAAI,WAAU;IAAiC;cAC9C,oBAACA,2BAAgB,GAAI,QAAS;KAC1B;IACF;GACA,IACP;;AAIP,mBAAmB,cAAc;;sCAU6B,EAC1D,gBACA,OACA,gBACA,WACA,UACA,GAAG,YACC;EAEJ,MAAM,sBAAsB,WAC1B,gBACAA,wBAAgB,gBAChB,EAAE,CACH;AAED,MAAI,SACF,QACE,oBAAC;GAAI;GAAgB,OAAO,EAAE,SAAS,YAAY;aAChD,SAAS;IACR,gBAAgB;IAChB;IACA;IACA;IACA,GAAG;IACJ,CAAC;IACE;AAIV,SACE,qBAAC;GACC,WAAW,GAAG,oCAAoC,UAAU;GAC5D,GAAI;cAGJ,oBAAC;IAAI,WAAU;cACZ;KACG,EAGN,oBAAC;IAAI,WAAU;cACb,qBAAC;KAAI,WAAU;gBAEb,oBAAC;MAAI,WAAU;gBACZ;OACG,EACL;MACG;KACF;IACF"}
package/dist/index.umd.js CHANGED
@@ -1018,6 +1018,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
1018
1018
  })
1019
1019
  }) : null;
1020
1020
  const inputPill = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1021
+ "data-testid": "copilot-chat-input",
1021
1022
  className: (0, tailwind_merge.twMerge)("cpk:flex cpk:w-full cpk:flex-col cpk:items-center cpk:justify-center", "cpk:cursor-text", "cpk:overflow-visible cpk:bg-clip-padding cpk:contain-inline-size", "cpk:bg-white cpk:dark:bg-[#303030]", "cpk:shadow-[0_4px_4px_0_#0000000a,0_0_1px_0_#0000009e] cpk:rounded-[28px]"),
1022
1023
  onClick: handleContainerClick,
1023
1024
  "data-layout": isExpanded ? "expanded" : "compact",
@@ -1066,6 +1067,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
1066
1067
  className: "cpk:mr-[10px]",
1067
1068
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
1068
1069
  type: "button",
1070
+ "data-testid": "copilot-send-button",
1069
1071
  variant: "chatInputToolbarPrimary",
1070
1072
  size: "chatInputToolbarIcon",
1071
1073
  className,
@@ -1093,18 +1095,21 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
1093
1095
  })] });
1094
1096
  };
1095
1097
  _CopilotChatInput.StartTranscribeButton = (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
1098
+ "data-testid": "copilot-start-transcribe-button",
1096
1099
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Mic, { className: "cpk:size-[18px]" }),
1097
1100
  labelKey: "chatInputToolbarStartTranscribeButtonLabel",
1098
1101
  defaultClassName: "cpk:mr-2",
1099
1102
  ...props
1100
1103
  });
1101
1104
  _CopilotChatInput.CancelTranscribeButton = (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
1105
+ "data-testid": "copilot-cancel-transcribe-button",
1102
1106
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, { className: "cpk:size-[18px]" }),
1103
1107
  labelKey: "chatInputToolbarCancelTranscribeButtonLabel",
1104
1108
  defaultClassName: "cpk:mr-2",
1105
1109
  ...props
1106
1110
  });
1107
1111
  _CopilotChatInput.FinishTranscribeButton = (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
1112
+ "data-testid": "copilot-finish-transcribe-button",
1108
1113
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, { className: "cpk:size-[18px]" }),
1109
1114
  labelKey: "chatInputToolbarFinishTranscribeButtonLabel",
1110
1115
  defaultClassName: "cpk:mr-[10px]",
@@ -1150,6 +1155,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
1150
1155
  asChild: true,
1151
1156
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
1152
1157
  type: "button",
1158
+ "data-testid": "copilot-add-menu-button",
1153
1159
  variant: "chatInputToolbarSecondary",
1154
1160
  size: "chatInputToolbarIcon",
1155
1161
  className: (0, tailwind_merge.twMerge)("cpk:ml-1", className),
@@ -1201,6 +1207,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
1201
1207
  }, [autoFocus]);
1202
1208
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
1203
1209
  ref: internalTextareaRef,
1210
+ "data-testid": "copilot-chat-textarea",
1204
1211
  placeholder: placeholder !== null && placeholder !== void 0 ? placeholder : labels.chatInputPlaceholder,
1205
1212
  className: (0, tailwind_merge.twMerge)("cpk:bg-transparent cpk:outline-none cpk:antialiased cpk:font-regular cpk:leading-relaxed cpk:text-[16px] cpk:placeholder:text-[#00000077] cpk:dark:placeholder:text-[#fffc]", className),
1206
1213
  style: {
@@ -3208,6 +3215,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3208
3215
  });
3209
3216
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3210
3217
  "data-copilotkit": true,
3218
+ "data-testid": "copilot-assistant-message",
3211
3219
  className: (0, tailwind_merge.twMerge)(className),
3212
3220
  ...props,
3213
3221
  "data-message-id": message.id,
@@ -3228,6 +3236,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3228
3236
  children: content !== null && content !== void 0 ? content : ""
3229
3237
  });
3230
3238
  _CopilotChatAssistantMessage.Toolbar = ({ className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3239
+ "data-testid": "copilot-assistant-toolbar",
3231
3240
  className: (0, tailwind_merge.twMerge)("cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:-ml-[5px] cpk:-mt-[0px]", className),
3232
3241
  ...props
3233
3242
  });
@@ -3257,6 +3266,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3257
3266
  if (onClick) onClick(event);
3258
3267
  };
3259
3268
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
3269
+ "data-testid": "copilot-copy-button",
3260
3270
  title: title || labels.assistantMessageToolbarCopyMessageLabel,
3261
3271
  onClick: handleClick,
3262
3272
  className,
@@ -3269,6 +3279,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3269
3279
  const config = useCopilotChatConfiguration();
3270
3280
  const labels = (_config$labels2 = config === null || config === void 0 ? void 0 : config.labels) !== null && _config$labels2 !== void 0 ? _config$labels2 : CopilotChatDefaultLabels;
3271
3281
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
3282
+ "data-testid": "copilot-thumbs-up-button",
3272
3283
  title: title || labels.assistantMessageToolbarThumbsUpLabel,
3273
3284
  ...props,
3274
3285
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ThumbsUp, { className: "cpk:size-[18px]" })
@@ -3279,6 +3290,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3279
3290
  const config = useCopilotChatConfiguration();
3280
3291
  const labels = (_config$labels3 = config === null || config === void 0 ? void 0 : config.labels) !== null && _config$labels3 !== void 0 ? _config$labels3 : CopilotChatDefaultLabels;
3281
3292
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
3293
+ "data-testid": "copilot-thumbs-down-button",
3282
3294
  title: title || labels.assistantMessageToolbarThumbsDownLabel,
3283
3295
  ...props,
3284
3296
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ThumbsDown, { className: "cpk:size-[18px]" })
@@ -3289,6 +3301,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3289
3301
  const config = useCopilotChatConfiguration();
3290
3302
  const labels = (_config$labels4 = config === null || config === void 0 ? void 0 : config.labels) !== null && _config$labels4 !== void 0 ? _config$labels4 : CopilotChatDefaultLabels;
3291
3303
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
3304
+ "data-testid": "copilot-read-aloud-button",
3292
3305
  title: title || labels.assistantMessageToolbarReadAloudLabel,
3293
3306
  ...props,
3294
3307
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Volume2, { className: "cpk:size-[20px]" })
@@ -3299,6 +3312,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3299
3312
  const config = useCopilotChatConfiguration();
3300
3313
  const labels = (_config$labels5 = config === null || config === void 0 ? void 0 : config.labels) !== null && _config$labels5 !== void 0 ? _config$labels5 : CopilotChatDefaultLabels;
3301
3314
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
3315
+ "data-testid": "copilot-regenerate-button",
3302
3316
  title: title || labels.assistantMessageToolbarRegenerateLabel,
3303
3317
  ...props,
3304
3318
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.RefreshCw, { className: "cpk:size-[18px]" })
@@ -3368,6 +3382,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3368
3382
  });
3369
3383
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3370
3384
  "data-copilotkit": true,
3385
+ "data-testid": "copilot-user-message",
3371
3386
  className: (0, tailwind_merge.twMerge)("cpk:flex cpk:flex-col cpk:items-end cpk:group cpk:pt-10", className),
3372
3387
  "data-message-id": message.id,
3373
3388
  ...props,
@@ -3385,6 +3400,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3385
3400
  children: content
3386
3401
  });
3387
3402
  _CopilotChatUserMessage.Toolbar = ({ className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3403
+ "data-testid": "copilot-user-toolbar",
3388
3404
  className: (0, tailwind_merge.twMerge)("cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:justify-end cpk:-mr-[5px] cpk:mt-[4px] cpk:invisible cpk:group-hover:visible", className),
3389
3405
  ...props
3390
3406
  });
@@ -3415,6 +3431,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3415
3431
  if (onClick) onClick(event);
3416
3432
  };
3417
3433
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
3434
+ "data-testid": "copilot-user-copy-button",
3418
3435
  title: title || labels.userMessageToolbarCopyMessageLabel,
3419
3436
  onClick: handleClick,
3420
3437
  className,
@@ -3427,6 +3444,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3427
3444
  const config = useCopilotChatConfiguration();
3428
3445
  const labels = (_config$labels2 = config === null || config === void 0 ? void 0 : config.labels) !== null && _config$labels2 !== void 0 ? _config$labels2 : CopilotChatDefaultLabels;
3429
3446
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
3447
+ "data-testid": "copilot-edit-button",
3430
3448
  title: title || labels.userMessageToolbarEditMessageLabel,
3431
3449
  className,
3432
3450
  ...props,
@@ -3438,6 +3456,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3438
3456
  const canGoPrev = currentBranch > 0;
3439
3457
  const canGoNext = currentBranch < numberOfBranches - 1;
3440
3458
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3459
+ "data-testid": "copilot-branch-navigation",
3441
3460
  className: (0, tailwind_merge.twMerge)("cpk:flex cpk:items-center cpk:gap-1", className),
3442
3461
  ...props,
3443
3462
  children: [
@@ -3621,6 +3640,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3621
3640
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3622
3641
  ref,
3623
3642
  "data-copilotkit": true,
3643
+ "data-testid": "copilot-suggestion",
3624
3644
  "data-slot": "suggestion-pill",
3625
3645
  className: cn(baseClasses, className),
3626
3646
  type: type !== null && type !== void 0 ? type : "button",
@@ -3650,6 +3670,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3650
3670
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3651
3671
  ref,
3652
3672
  "data-copilotkit": true,
3673
+ "data-testid": "copilot-suggestions",
3653
3674
  className: cn("cpk:flex cpk:flex-wrap cpk:items-center cpk:gap-1.5 cpk:sm:gap-2 cpk:pl-0 cpk:pr-4 cpk:sm:px-0 cpk:pointer-events-none", className),
3654
3675
  ...props
3655
3676
  });
@@ -3914,6 +3935,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3914
3935
  const showCursor = isRunning && (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) !== "reasoning";
3915
3936
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3916
3937
  "data-copilotkit": true,
3938
+ "data-testid": "copilot-message-list",
3917
3939
  className: (0, tailwind_merge.twMerge)("cpk:flex cpk:flex-col", className),
3918
3940
  ...props,
3919
3941
  children: [
@@ -3928,6 +3950,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3928
3950
  }
3929
3951
  CopilotChatMessageView.Cursor = function Cursor({ className, ...props }) {
3930
3952
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3953
+ "data-testid": "copilot-loading-cursor",
3931
3954
  className: (0, tailwind_merge.twMerge)("cpk:w-[11px] cpk:h-[11px] cpk:rounded-full cpk:bg-foreground cpk:animate-pulse-cursor cpk:ml-1", className),
3932
3955
  ...props
3933
3956
  });
@@ -4072,6 +4095,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4072
4095
  });
4073
4096
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4074
4097
  "data-copilotkit": true,
4098
+ "data-testid": "copilot-chat",
4099
+ "data-copilot-running": isRunning ? "true" : "false",
4075
4100
  className: (0, tailwind_merge.twMerge)("cpk:relative cpk:h-full cpk:flex cpk:flex-col", className),
4076
4101
  ...props,
4077
4102
  children: BoundWelcomeScreen
@@ -4089,6 +4114,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4089
4114
  });
4090
4115
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4091
4116
  "data-copilotkit": true,
4117
+ "data-testid": "copilot-chat",
4118
+ "data-copilot-running": isRunning ? "true" : "false",
4092
4119
  className: (0, tailwind_merge.twMerge)("cpk:relative cpk:h-full", className),
4093
4120
  ...props,
4094
4121
  children: [BoundScrollView, BoundInput]
@@ -4184,6 +4211,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4184
4211
  });
4185
4212
  };
4186
4213
  _CopilotChatView.ScrollToBottomButton = ({ className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
4214
+ "data-testid": "copilot-scroll-to-bottom",
4187
4215
  variant: "outline",
4188
4216
  size: "sm",
4189
4217
  className: (0, tailwind_merge.twMerge)("cpk:rounded-full cpk:w-10 cpk:h-10 cpk:p-0 cpk:pointer-events-auto", "cpk:bg-white cpk:dark:bg-gray-900", "cpk:shadow-lg cpk:border cpk:border-gray-200 cpk:dark:border-gray-700", "cpk:hover:bg-gray-50 cpk:dark:hover:bg-gray-800", "cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer", className),
@@ -4219,6 +4247,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4219
4247
  })
4220
4248
  });
4221
4249
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4250
+ "data-testid": "copilot-welcome-screen",
4222
4251
  className: cn("cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4", className),
4223
4252
  ...props,
4224
4253
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -4612,6 +4641,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4612
4641
  ref,
4613
4642
  type: type !== null && type !== void 0 ? type : "button",
4614
4643
  "data-copilotkit": true,
4644
+ "data-testid": "copilot-chat-toggle",
4615
4645
  "data-slot": "chat-toggle-button",
4616
4646
  "data-state": isOpen ? "open" : "closed",
4617
4647
  className: cn(BUTTON_BASE_CLASSES, className),
@@ -4645,6 +4675,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4645
4675
  ...rest
4646
4676
  });
4647
4677
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("header", {
4678
+ "data-testid": "copilot-modal-header",
4648
4679
  "data-slot": "copilot-modal-header",
4649
4680
  className: cn("cpk:flex cpk:items-center cpk:justify-between cpk:border-b cpk:border-border cpk:px-4 cpk:py-4", "cpk:bg-background/95 cpk:backdrop-blur cpk:supports-[backdrop-filter]:bg-background/80", className),
4650
4681
  ...rest,
@@ -4670,12 +4701,14 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4670
4701
  CopilotModalHeader.displayName = "CopilotModalHeader";
4671
4702
  (function(_CopilotModalHeader) {
4672
4703
  _CopilotModalHeader.Title = ({ children, className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4704
+ "data-testid": "copilot-header-title",
4673
4705
  className: cn("cpk:w-full cpk:text-base cpk:font-medium cpk:leading-none cpk:tracking-tight cpk:text-foreground", className),
4674
4706
  ...props,
4675
4707
  children
4676
4708
  });
4677
4709
  _CopilotModalHeader.CloseButton = ({ className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4678
4710
  type: "button",
4711
+ "data-testid": "copilot-close-button",
4679
4712
  className: cn("cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer", "cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring", className),
4680
4713
  "aria-label": "Close",
4681
4714
  ...props,
@@ -4755,6 +4788,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4755
4788
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [renderSlot(toggleButton, CopilotChatToggleButton, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("aside", {
4756
4789
  ref: sidebarRef,
4757
4790
  "data-copilotkit": true,
4791
+ "data-testid": "copilot-sidebar",
4758
4792
  "data-copilot-sidebar": true,
4759
4793
  className: cn("cpk:fixed cpk:right-0 cpk:top-0 cpk:z-[1200] cpk:flex", "cpk:h-[100vh] cpk:h-[100dvh] cpk:max-h-screen", "cpk:w-full", "cpk:border-l cpk:border-border cpk:bg-background cpk:text-foreground cpk:shadow-xl", "cpk:transition-transform cpk:duration-300 cpk:ease-out", isSidebarOpen ? "cpk:translate-x-0" : "cpk:translate-x-full cpk:pointer-events-none"),
4760
4794
  style: {
@@ -4918,6 +4952,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4918
4952
  tabIndex: -1,
4919
4953
  role: "dialog",
4920
4954
  "aria-label": labels.modalHeaderTitle,
4955
+ "data-testid": "copilot-popup",
4921
4956
  "data-copilot-popup": true,
4922
4957
  className: cn("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),
4923
4958
  style: popupStyle,