@copilotkit/vue 1.57.1

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 (437) hide show
  1. package/AGENTS.md +50 -0
  2. package/CHANGELOG.md +13 -0
  3. package/PARITY.md +434 -0
  4. package/README.md +396 -0
  5. package/dist/components/copilot-provider/CopilotKit.vue.d.ts +20 -0
  6. package/dist/components/copilot-provider/CopilotKit.vue.d.ts.map +1 -0
  7. package/dist/components/copilot-provider/index.d.ts +3 -0
  8. package/dist/components/copilot-provider/index.d.ts.map +1 -0
  9. package/dist/components/copilot-provider/types.d.ts +22 -0
  10. package/dist/components/copilot-provider/types.d.ts.map +1 -0
  11. package/dist/hooks/index.d.ts +7 -0
  12. package/dist/hooks/index.d.ts.map +1 -0
  13. package/dist/hooks/use-copilot-action.d.ts +27 -0
  14. package/dist/hooks/use-copilot-action.d.ts.map +1 -0
  15. package/dist/hooks/use-copilot-readable.d.ts +20 -0
  16. package/dist/hooks/use-copilot-readable.d.ts.map +1 -0
  17. package/dist/hooks/use-frontend-tool.d.ts +21 -0
  18. package/dist/hooks/use-frontend-tool.d.ts.map +1 -0
  19. package/dist/index.cjs +2 -0
  20. package/dist/index.cjs.map +1 -0
  21. package/dist/index.d.cts +10 -0
  22. package/dist/index.d.mts +10 -0
  23. package/dist/index.d.ts +10 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.mjs +252 -0
  26. package/dist/index.mjs.map +1 -0
  27. package/dist/styles.css +2 -0
  28. package/dist/use-render-activity-message-BRL1Rpl-.cjs +85 -0
  29. package/dist/use-render-activity-message-BRL1Rpl-.cjs.map +1 -0
  30. package/dist/use-render-activity-message-CqtxiFSs.js +8927 -0
  31. package/dist/use-render-activity-message-CqtxiFSs.js.map +1 -0
  32. package/dist/v2/components/A2UIMessageRenderer.d.ts +9 -0
  33. package/dist/v2/components/A2UIMessageRenderer.d.ts.map +1 -0
  34. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts +16 -0
  35. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts.map +1 -0
  36. package/dist/v2/components/CopilotKitInspector.vue.d.ts +7 -0
  37. package/dist/v2/components/CopilotKitInspector.vue.d.ts.map +1 -0
  38. package/dist/v2/components/InlineFeatureWarning.vue.d.ts +6 -0
  39. package/dist/v2/components/InlineFeatureWarning.vue.d.ts.map +1 -0
  40. package/dist/v2/components/LicenseWarningBanner.vue.d.ts +18 -0
  41. package/dist/v2/components/LicenseWarningBanner.vue.d.ts.map +1 -0
  42. package/dist/v2/components/MCPAppsActivityRenderer.d.ts +88 -0
  43. package/dist/v2/components/MCPAppsActivityRenderer.d.ts.map +1 -0
  44. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts +154 -0
  45. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts.map +1 -0
  46. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts +19 -0
  47. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts.map +1 -0
  48. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts +16 -0
  49. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts.map +1 -0
  50. package/dist/v2/components/a2ui/VueSurface.d.ts +62 -0
  51. package/dist/v2/components/a2ui/VueSurface.d.ts.map +1 -0
  52. package/dist/v2/components/a2ui/adapter.d.ts +38 -0
  53. package/dist/v2/components/a2ui/adapter.d.ts.map +1 -0
  54. package/dist/v2/components/a2ui/catalog.d.ts +29 -0
  55. package/dist/v2/components/a2ui/catalog.d.ts.map +1 -0
  56. package/dist/v2/components/a2ui/index.d.ts +5 -0
  57. package/dist/v2/components/a2ui/index.d.ts.map +1 -0
  58. package/dist/v2/components/a2ui/utils.d.ts +18 -0
  59. package/dist/v2/components/a2ui/utils.d.ts.map +1 -0
  60. package/dist/v2/components/a2ui.d.ts +12 -0
  61. package/dist/v2/components/a2ui.d.ts.map +1 -0
  62. package/dist/v2/components/chat/CopilotChat.vue.d.ts +50 -0
  63. package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -0
  64. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts +164 -0
  65. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts.map +1 -0
  66. package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts +12 -0
  67. package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts.map +1 -0
  68. package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts +7 -0
  69. package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts.map +1 -0
  70. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts +12 -0
  71. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts.map +1 -0
  72. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +290 -0
  73. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts.map +1 -0
  74. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts +72 -0
  75. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts.map +1 -0
  76. package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts +65 -0
  77. package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts.map +1 -0
  78. package/dist/v2/components/chat/CopilotChatSuggestionPill.vue.d.ts +27 -0
  79. package/dist/v2/components/chat/CopilotChatSuggestionPill.vue.d.ts.map +1 -0
  80. package/dist/v2/components/chat/CopilotChatSuggestionView.vue.d.ts +26 -0
  81. package/dist/v2/components/chat/CopilotChatSuggestionView.vue.d.ts.map +1 -0
  82. package/dist/v2/components/chat/CopilotChatToggleButton.vue.d.ts +17 -0
  83. package/dist/v2/components/chat/CopilotChatToggleButton.vue.d.ts.map +1 -0
  84. package/dist/v2/components/chat/CopilotChatToggleButtonCloseIcon.d.ts +5 -0
  85. package/dist/v2/components/chat/CopilotChatToggleButtonCloseIcon.d.ts.map +1 -0
  86. package/dist/v2/components/chat/CopilotChatToggleButtonOpenIcon.d.ts +5 -0
  87. package/dist/v2/components/chat/CopilotChatToggleButtonOpenIcon.d.ts.map +1 -0
  88. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts +21 -0
  89. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts.map +1 -0
  90. package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts +34 -0
  91. package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts.map +1 -0
  92. package/dist/v2/components/chat/CopilotChatView.vue.d.ts +106 -0
  93. package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -0
  94. package/dist/v2/components/chat/CopilotModalHeader.vue.d.ts +15 -0
  95. package/dist/v2/components/chat/CopilotModalHeader.vue.d.ts.map +1 -0
  96. package/dist/v2/components/chat/CopilotModalHeaderCloseButton.d.ts +5 -0
  97. package/dist/v2/components/chat/CopilotModalHeaderCloseButton.d.ts.map +1 -0
  98. package/dist/v2/components/chat/CopilotModalHeaderTitle.d.ts +5 -0
  99. package/dist/v2/components/chat/CopilotModalHeaderTitle.d.ts.map +1 -0
  100. package/dist/v2/components/chat/CopilotPopup.vue.d.ts +50 -0
  101. package/dist/v2/components/chat/CopilotPopup.vue.d.ts.map +1 -0
  102. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts +55 -0
  103. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts.map +1 -0
  104. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts +55 -0
  105. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts.map +1 -0
  106. package/dist/v2/components/chat/CopilotPopupWelcomeScreen.vue.d.ts +28 -0
  107. package/dist/v2/components/chat/CopilotPopupWelcomeScreen.vue.d.ts.map +1 -0
  108. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts +48 -0
  109. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts.map +1 -0
  110. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts +62 -0
  111. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts.map +1 -0
  112. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts +53 -0
  113. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts.map +1 -0
  114. package/dist/v2/components/chat/CopilotSidebarWelcomeScreen.vue.d.ts +28 -0
  115. package/dist/v2/components/chat/CopilotSidebarWelcomeScreen.vue.d.ts.map +1 -0
  116. package/dist/v2/components/chat/audioRecorder.d.ts +11 -0
  117. package/dist/v2/components/chat/audioRecorder.d.ts.map +1 -0
  118. package/dist/v2/components/chat/index.d.ts +682 -0
  119. package/dist/v2/components/chat/index.d.ts.map +1 -0
  120. package/dist/v2/components/chat/last-user-message-context.d.ts +29 -0
  121. package/dist/v2/components/chat/last-user-message-context.d.ts.map +1 -0
  122. package/dist/v2/components/chat/normalize-auto-scroll.d.ts +3 -0
  123. package/dist/v2/components/chat/normalize-auto-scroll.d.ts.map +1 -0
  124. package/dist/v2/components/chat/types.d.ts +380 -0
  125. package/dist/v2/components/chat/types.d.ts.map +1 -0
  126. package/dist/v2/components/icons/index.d.ts +2 -0
  127. package/dist/v2/components/icons/index.d.ts.map +1 -0
  128. package/dist/v2/components/index.d.ts +8 -0
  129. package/dist/v2/components/index.d.ts.map +1 -0
  130. package/dist/v2/hooks/index.d.ts +24 -0
  131. package/dist/v2/hooks/index.d.ts.map +1 -0
  132. package/dist/v2/hooks/use-agent-context.d.ts +24 -0
  133. package/dist/v2/hooks/use-agent-context.d.ts.map +1 -0
  134. package/dist/v2/hooks/use-agent.d.ts +53 -0
  135. package/dist/v2/hooks/use-agent.d.ts.map +1 -0
  136. package/dist/v2/hooks/use-attachments.d.ts +21 -0
  137. package/dist/v2/hooks/use-attachments.d.ts.map +1 -0
  138. package/dist/v2/hooks/use-capabilities.d.ts +16 -0
  139. package/dist/v2/hooks/use-capabilities.d.ts.map +1 -0
  140. package/dist/v2/hooks/use-component.d.ts +13 -0
  141. package/dist/v2/hooks/use-component.d.ts.map +1 -0
  142. package/dist/v2/hooks/use-configure-suggestions.d.ts +24 -0
  143. package/dist/v2/hooks/use-configure-suggestions.d.ts.map +1 -0
  144. package/dist/v2/hooks/use-default-render-tool.d.ts +14 -0
  145. package/dist/v2/hooks/use-default-render-tool.d.ts.map +1 -0
  146. package/dist/v2/hooks/use-frontend-tool.d.ts +19 -0
  147. package/dist/v2/hooks/use-frontend-tool.d.ts.map +1 -0
  148. package/dist/v2/hooks/use-human-in-the-loop.d.ts +19 -0
  149. package/dist/v2/hooks/use-human-in-the-loop.d.ts.map +1 -0
  150. package/dist/v2/hooks/use-interrupt.d.ts +36 -0
  151. package/dist/v2/hooks/use-interrupt.d.ts.map +1 -0
  152. package/dist/v2/hooks/use-katex-styles.d.ts +22 -0
  153. package/dist/v2/hooks/use-katex-styles.d.ts.map +1 -0
  154. package/dist/v2/hooks/use-keyboard-height.d.ts +33 -0
  155. package/dist/v2/hooks/use-keyboard-height.d.ts.map +1 -0
  156. package/dist/v2/hooks/use-pin-to-send.d.ts +28 -0
  157. package/dist/v2/hooks/use-pin-to-send.d.ts.map +1 -0
  158. package/dist/v2/hooks/use-render-activity-message.d.ts +21 -0
  159. package/dist/v2/hooks/use-render-activity-message.d.ts.map +1 -0
  160. package/dist/v2/hooks/use-render-custom-messages.d.ts +27 -0
  161. package/dist/v2/hooks/use-render-custom-messages.d.ts.map +1 -0
  162. package/dist/v2/hooks/use-render-tool.d.ts +36 -0
  163. package/dist/v2/hooks/use-render-tool.d.ts.map +1 -0
  164. package/dist/v2/hooks/use-suggestions.d.ts +26 -0
  165. package/dist/v2/hooks/use-suggestions.d.ts.map +1 -0
  166. package/dist/v2/hooks/use-threads.d.ts +42 -0
  167. package/dist/v2/hooks/use-threads.d.ts.map +1 -0
  168. package/dist/v2/index.cjs +2 -0
  169. package/dist/v2/index.cjs.map +1 -0
  170. package/dist/v2/index.d.cts +9 -0
  171. package/dist/v2/index.d.mts +9 -0
  172. package/dist/v2/index.d.ts +9 -0
  173. package/dist/v2/index.d.ts.map +1 -0
  174. package/dist/v2/index.mjs +75 -0
  175. package/dist/v2/index.mjs.map +1 -0
  176. package/dist/v2/lib/processPartialHtml.d.ts +3 -0
  177. package/dist/v2/lib/processPartialHtml.d.ts.map +1 -0
  178. package/dist/v2/lib/shallow-stable.d.ts +7 -0
  179. package/dist/v2/lib/shallow-stable.d.ts.map +1 -0
  180. package/dist/v2/lib/transcription-client.d.ts +19 -0
  181. package/dist/v2/lib/transcription-client.d.ts.map +1 -0
  182. package/dist/v2/lib/vue-core.d.ts +47 -0
  183. package/dist/v2/lib/vue-core.d.ts.map +1 -0
  184. package/dist/v2/providers/CopilotChatConfigurationProvider.types.d.ts +15 -0
  185. package/dist/v2/providers/CopilotChatConfigurationProvider.types.d.ts.map +1 -0
  186. package/dist/v2/providers/CopilotChatConfigurationProvider.vue.d.ts +17 -0
  187. package/dist/v2/providers/CopilotChatConfigurationProvider.vue.d.ts.map +1 -0
  188. package/dist/v2/providers/CopilotKitProvider.types.d.ts +61 -0
  189. package/dist/v2/providers/CopilotKitProvider.types.d.ts.map +1 -0
  190. package/dist/v2/providers/CopilotKitProvider.vue.d.ts +37 -0
  191. package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -0
  192. package/dist/v2/providers/SandboxFunctionsContext.d.ts +4 -0
  193. package/dist/v2/providers/SandboxFunctionsContext.d.ts.map +1 -0
  194. package/dist/v2/providers/index.d.ts +13 -0
  195. package/dist/v2/providers/index.d.ts.map +1 -0
  196. package/dist/v2/providers/keys.d.ts +17 -0
  197. package/dist/v2/providers/keys.d.ts.map +1 -0
  198. package/dist/v2/providers/license-context.d.ts +7 -0
  199. package/dist/v2/providers/license-context.d.ts.map +1 -0
  200. package/dist/v2/providers/types.d.ts +38 -0
  201. package/dist/v2/providers/types.d.ts.map +1 -0
  202. package/dist/v2/providers/useCopilotChatConfiguration.d.ts +4 -0
  203. package/dist/v2/providers/useCopilotChatConfiguration.d.ts.map +1 -0
  204. package/dist/v2/providers/useCopilotKit.d.ts +2 -0
  205. package/dist/v2/providers/useCopilotKit.d.ts.map +1 -0
  206. package/dist/v2/providers/useLicenseContext.d.ts +14 -0
  207. package/dist/v2/providers/useLicenseContext.d.ts.map +1 -0
  208. package/dist/v2/types/a2ui.d.ts +5 -0
  209. package/dist/v2/types/a2ui.d.ts.map +1 -0
  210. package/dist/v2/types/defineToolCallRenderer.d.ts +15 -0
  211. package/dist/v2/types/defineToolCallRenderer.d.ts.map +1 -0
  212. package/dist/v2/types/frontend-tool.d.ts +6 -0
  213. package/dist/v2/types/frontend-tool.d.ts.map +1 -0
  214. package/dist/v2/types/human-in-the-loop.d.ts +29 -0
  215. package/dist/v2/types/human-in-the-loop.d.ts.map +1 -0
  216. package/dist/v2/types/index.d.ts +10 -0
  217. package/dist/v2/types/index.d.ts.map +1 -0
  218. package/dist/v2/types/interrupt.d.ts +14 -0
  219. package/dist/v2/types/interrupt.d.ts.map +1 -0
  220. package/dist/v2/types/sandbox-function.d.ts +8 -0
  221. package/dist/v2/types/sandbox-function.d.ts.map +1 -0
  222. package/dist/v2/types/vue-activity-message-renderer.d.ts +18 -0
  223. package/dist/v2/types/vue-activity-message-renderer.d.ts.map +1 -0
  224. package/dist/v2/types/vue-custom-message-renderer.d.ts +19 -0
  225. package/dist/v2/types/vue-custom-message-renderer.d.ts.map +1 -0
  226. package/dist/v2/types/vue-tool-call-renderer.d.ts +37 -0
  227. package/dist/v2/types/vue-tool-call-renderer.d.ts.map +1 -0
  228. package/env.d.ts +7 -0
  229. package/eslint.config.mjs +42 -0
  230. package/package.json +130 -0
  231. package/scripts/scope-preflight.mjs +100 -0
  232. package/src/components/copilot-provider/CopilotKit.vue +18 -0
  233. package/src/components/copilot-provider/index.ts +2 -0
  234. package/src/components/copilot-provider/types.ts +24 -0
  235. package/src/hooks/index.ts +9 -0
  236. package/src/hooks/use-copilot-action.ts +168 -0
  237. package/src/hooks/use-copilot-readable.ts +75 -0
  238. package/src/hooks/use-frontend-tool.ts +76 -0
  239. package/src/index.ts +12 -0
  240. package/src/styles/globals.css +314 -0
  241. package/src/v2/__tests__/exports.test.ts +35 -0
  242. package/src/v2/__tests__/mocks/web-inspector.ts +5 -0
  243. package/src/v2/__tests__/setup.ts +141 -0
  244. package/src/v2/__tests__/utils/agents.ts +391 -0
  245. package/src/v2/__tests__/utils/mount.ts +83 -0
  246. package/src/v2/__tests__/utils/test-helpers.ts +712 -0
  247. package/src/v2/components/A2UIMessageRenderer.ts +125 -0
  248. package/src/v2/components/A2UISurfaceActivityRenderer.vue +186 -0
  249. package/src/v2/components/CopilotKitInspector.vue +42 -0
  250. package/src/v2/components/InlineFeatureWarning.vue +35 -0
  251. package/src/v2/components/LicenseWarningBanner.vue +196 -0
  252. package/src/v2/components/MCPAppsActivityRenderer.ts +778 -0
  253. package/src/v2/components/OpenGenerativeUIRenderer.ts +550 -0
  254. package/src/v2/components/__tests__/A2UIMessageRenderer.test.ts +271 -0
  255. package/src/v2/components/__tests__/CopilotKitInspector.test.ts +57 -0
  256. package/src/v2/components/__tests__/MCPAppsActivityRenderer.e2e.test.ts +851 -0
  257. package/src/v2/components/__tests__/MCPAppsActivityRenderer.test.ts +237 -0
  258. package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.ts +516 -0
  259. package/src/v2/components/a2ui/A2UIBuiltInToolCallRenderer.ts +295 -0
  260. package/src/v2/components/a2ui/A2UICatalogContext.ts +190 -0
  261. package/src/v2/components/a2ui/VueSurface.ts +144 -0
  262. package/src/v2/components/a2ui/adapter.ts +156 -0
  263. package/src/v2/components/a2ui/catalog.ts +858 -0
  264. package/src/v2/components/a2ui/index.ts +7 -0
  265. package/src/v2/components/a2ui/utils.ts +67 -0
  266. package/src/v2/components/a2ui.ts +30 -0
  267. package/src/v2/components/chat/CopilotChat.vue +777 -0
  268. package/src/v2/components/chat/CopilotChatAssistantMessage.vue +891 -0
  269. package/src/v2/components/chat/CopilotChatAttachmentQueue.vue +411 -0
  270. package/src/v2/components/chat/CopilotChatAttachmentRenderer.vue +87 -0
  271. package/src/v2/components/chat/CopilotChatAudioRecorder.vue +269 -0
  272. package/src/v2/components/chat/CopilotChatInput.vue +1271 -0
  273. package/src/v2/components/chat/CopilotChatMessageView.vue +476 -0
  274. package/src/v2/components/chat/CopilotChatReasoningMessage.vue +247 -0
  275. package/src/v2/components/chat/CopilotChatSuggestionPill.vue +56 -0
  276. package/src/v2/components/chat/CopilotChatSuggestionView.vue +93 -0
  277. package/src/v2/components/chat/CopilotChatToggleButton.vue +145 -0
  278. package/src/v2/components/chat/CopilotChatToggleButtonCloseIcon.ts +17 -0
  279. package/src/v2/components/chat/CopilotChatToggleButtonOpenIcon.ts +18 -0
  280. package/src/v2/components/chat/CopilotChatToolCallsView.vue +161 -0
  281. package/src/v2/components/chat/CopilotChatUserMessage.vue +322 -0
  282. package/src/v2/components/chat/CopilotChatView.vue +740 -0
  283. package/src/v2/components/chat/CopilotModalHeader.vue +73 -0
  284. package/src/v2/components/chat/CopilotModalHeaderCloseButton.ts +38 -0
  285. package/src/v2/components/chat/CopilotModalHeaderTitle.ts +22 -0
  286. package/src/v2/components/chat/CopilotPopup.vue +182 -0
  287. package/src/v2/components/chat/CopilotPopupView.vue +168 -0
  288. package/src/v2/components/chat/CopilotPopupViewInternal.vue +453 -0
  289. package/src/v2/components/chat/CopilotPopupWelcomeScreen.vue +140 -0
  290. package/src/v2/components/chat/CopilotSidebar.vue +178 -0
  291. package/src/v2/components/chat/CopilotSidebarView.vue +172 -0
  292. package/src/v2/components/chat/CopilotSidebarViewInternal.vue +366 -0
  293. package/src/v2/components/chat/CopilotSidebarWelcomeScreen.vue +142 -0
  294. package/src/v2/components/chat/__tests__/CopilotChat.attachments.test.ts +237 -0
  295. package/src/v2/components/chat/__tests__/CopilotChat.e2e.test.ts +1240 -0
  296. package/src/v2/components/chat/__tests__/CopilotChat.licenseWarning.test.ts +138 -0
  297. package/src/v2/components/chat/__tests__/CopilotChat.onError.test.ts +85 -0
  298. package/src/v2/components/chat/__tests__/CopilotChat.slots.e2e.test.ts +141 -0
  299. package/src/v2/components/chat/__tests__/CopilotChat.test.ts +652 -0
  300. package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.ts +683 -0
  301. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.slots.e2e.test.ts +768 -0
  302. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.test.ts +1108 -0
  303. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.thumbs.test.ts +87 -0
  304. package/src/v2/components/chat/__tests__/CopilotChatAttachmentQueue.test.ts +277 -0
  305. package/src/v2/components/chat/__tests__/CopilotChatAttachmentRenderer.test.ts +124 -0
  306. package/src/v2/components/chat/__tests__/CopilotChatCopyButton.clipboard.test.ts +230 -0
  307. package/src/v2/components/chat/__tests__/CopilotChatInput.bottomAnchored.test.ts +83 -0
  308. package/src/v2/components/chat/__tests__/CopilotChatInput.slots.e2e.test.ts +1139 -0
  309. package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +1051 -0
  310. package/src/v2/components/chat/__tests__/CopilotChatMessageView.slots.e2e.test.ts +141 -0
  311. package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.ts +494 -0
  312. package/src/v2/components/chat/__tests__/CopilotChatPropsRerender.e2e.test.ts +181 -0
  313. package/src/v2/components/chat/__tests__/CopilotChatReasoningMessage.test.ts +73 -0
  314. package/src/v2/components/chat/__tests__/CopilotChatSuggestionPill.test.ts +73 -0
  315. package/src/v2/components/chat/__tests__/CopilotChatSuggestionView.slots.e2e.test.ts +674 -0
  316. package/src/v2/components/chat/__tests__/CopilotChatSuggestionView.test.ts +91 -0
  317. package/src/v2/components/chat/__tests__/CopilotChatToggleButton.test.ts +93 -0
  318. package/src/v2/components/chat/__tests__/CopilotChatToolCallsView.test.ts +382 -0
  319. package/src/v2/components/chat/__tests__/CopilotChatToolRendering.e2e.test.ts +1019 -0
  320. package/src/v2/components/chat/__tests__/CopilotChatToolRerenders.e2e.test.ts +516 -0
  321. package/src/v2/components/chat/__tests__/CopilotChatUserMessage.slots.e2e.test.ts +701 -0
  322. package/src/v2/components/chat/__tests__/CopilotChatUserMessage.test.ts +337 -0
  323. package/src/v2/components/chat/__tests__/CopilotChatView.connectingGate.test.ts +135 -0
  324. package/src/v2/components/chat/__tests__/CopilotChatView.inputOverlay.test.ts +278 -0
  325. package/src/v2/components/chat/__tests__/CopilotChatView.onClick.e2e.test.ts +1082 -0
  326. package/src/v2/components/chat/__tests__/CopilotChatView.pinToSend.test.ts +166 -0
  327. package/src/v2/components/chat/__tests__/CopilotChatView.slots.e2e.test.ts +1145 -0
  328. package/src/v2/components/chat/__tests__/CopilotChatView.test.ts +374 -0
  329. package/src/v2/components/chat/__tests__/CopilotModalHeader.slots.e2e.test.ts +636 -0
  330. package/src/v2/components/chat/__tests__/CopilotModalHeader.test.ts +112 -0
  331. package/src/v2/components/chat/__tests__/CopilotPopup.test.ts +58 -0
  332. package/src/v2/components/chat/__tests__/CopilotPopupView.slots.e2e.test.ts +725 -0
  333. package/src/v2/components/chat/__tests__/CopilotPopupView.test.ts +112 -0
  334. package/src/v2/components/chat/__tests__/CopilotSidebar.test.ts +58 -0
  335. package/src/v2/components/chat/__tests__/CopilotSidebarView.slots.e2e.test.ts +603 -0
  336. package/src/v2/components/chat/__tests__/CopilotSidebarView.test.ts +214 -0
  337. package/src/v2/components/chat/__tests__/MCPAppsUiMessage.e2e.test.ts +394 -0
  338. package/src/v2/components/chat/__tests__/copilot-chat-throttle.test.ts +82 -0
  339. package/src/v2/components/chat/__tests__/normalize-auto-scroll.test.ts +39 -0
  340. package/src/v2/components/chat/audioRecorder.ts +15 -0
  341. package/src/v2/components/chat/index.ts +52 -0
  342. package/src/v2/components/chat/last-user-message-context.ts +39 -0
  343. package/src/v2/components/chat/normalize-auto-scroll.ts +17 -0
  344. package/src/v2/components/chat/types.ts +481 -0
  345. package/src/v2/components/icons/__tests__/icons.test.ts +86 -0
  346. package/src/v2/components/icons/index.ts +22 -0
  347. package/src/v2/components/index.ts +7 -0
  348. package/src/v2/hooks/__tests__/standard-schema-types.test.ts +149 -0
  349. package/src/v2/hooks/__tests__/standard-schema.test.ts +315 -0
  350. package/src/v2/hooks/__tests__/use-agent-context-timing.e2e.test.ts +144 -0
  351. package/src/v2/hooks/__tests__/use-agent-context.test.ts +271 -0
  352. package/src/v2/hooks/__tests__/use-agent-error-state.test.ts +64 -0
  353. package/src/v2/hooks/__tests__/use-agent-stability.test.ts +268 -0
  354. package/src/v2/hooks/__tests__/use-agent-thread-isolation.test.ts +433 -0
  355. package/src/v2/hooks/__tests__/use-agent-throttle.test.ts +747 -0
  356. package/src/v2/hooks/__tests__/use-agent.e2e.test.ts +187 -0
  357. package/src/v2/hooks/__tests__/use-agent.test.ts +126 -0
  358. package/src/v2/hooks/__tests__/use-attachments.test.ts +181 -0
  359. package/src/v2/hooks/__tests__/use-component.test.ts +145 -0
  360. package/src/v2/hooks/__tests__/use-configure-suggestions.e2e.test.ts +527 -0
  361. package/src/v2/hooks/__tests__/use-configure-suggestions.test.ts +399 -0
  362. package/src/v2/hooks/__tests__/use-default-render-tool.test.ts +214 -0
  363. package/src/v2/hooks/__tests__/use-frontend-tool-available.test.ts +220 -0
  364. package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.ts +2320 -0
  365. package/src/v2/hooks/__tests__/use-frontend-tool.test.ts +648 -0
  366. package/src/v2/hooks/__tests__/use-human-in-the-loop.e2e.test.ts +1379 -0
  367. package/src/v2/hooks/__tests__/use-human-in-the-loop.test.ts +282 -0
  368. package/src/v2/hooks/__tests__/use-interrupt.test.ts +345 -0
  369. package/src/v2/hooks/__tests__/use-katex-styles.test.ts +69 -0
  370. package/src/v2/hooks/__tests__/use-keyboard-height.test.ts +199 -0
  371. package/src/v2/hooks/__tests__/use-pin-to-send.test.ts +363 -0
  372. package/src/v2/hooks/__tests__/use-render-tool.test.ts +329 -0
  373. package/src/v2/hooks/__tests__/use-suggestions.e2e.test.ts +397 -0
  374. package/src/v2/hooks/__tests__/use-suggestions.test.ts +198 -0
  375. package/src/v2/hooks/__tests__/use-threads.test.ts +1041 -0
  376. package/src/v2/hooks/__tests__/zod-regression.test.ts +339 -0
  377. package/src/v2/hooks/index.ts +29 -0
  378. package/src/v2/hooks/use-agent-context.ts +55 -0
  379. package/src/v2/hooks/use-agent.ts +345 -0
  380. package/src/v2/hooks/use-attachments.ts +261 -0
  381. package/src/v2/hooks/use-capabilities.ts +30 -0
  382. package/src/v2/hooks/use-component.ts +46 -0
  383. package/src/v2/hooks/use-configure-suggestions.ts +252 -0
  384. package/src/v2/hooks/use-default-render-tool.ts +130 -0
  385. package/src/v2/hooks/use-frontend-tool.ts +68 -0
  386. package/src/v2/hooks/use-human-in-the-loop.ts +90 -0
  387. package/src/v2/hooks/use-interrupt.ts +257 -0
  388. package/src/v2/hooks/use-katex-styles.ts +44 -0
  389. package/src/v2/hooks/use-keyboard-height.ts +87 -0
  390. package/src/v2/hooks/use-pin-to-send.ts +160 -0
  391. package/src/v2/hooks/use-render-activity-message.ts +92 -0
  392. package/src/v2/hooks/use-render-custom-messages.ts +129 -0
  393. package/src/v2/hooks/use-render-tool.ts +128 -0
  394. package/src/v2/hooks/use-suggestions.ts +98 -0
  395. package/src/v2/hooks/use-threads.ts +208 -0
  396. package/src/v2/index.ts +11 -0
  397. package/src/v2/lib/__tests__/processPartialHtml.test.ts +84 -0
  398. package/src/v2/lib/__tests__/transcription-client.test.ts +65 -0
  399. package/src/v2/lib/processPartialHtml.ts +21 -0
  400. package/src/v2/lib/shallow-stable.ts +54 -0
  401. package/src/v2/lib/transcription-client.ts +151 -0
  402. package/src/v2/lib/vue-core.ts +161 -0
  403. package/src/v2/providers/CopilotChatConfigurationProvider.types.ts +15 -0
  404. package/src/v2/providers/CopilotChatConfigurationProvider.vue +95 -0
  405. package/src/v2/providers/CopilotKitProvider.types.ts +66 -0
  406. package/src/v2/providers/CopilotKitProvider.vue +653 -0
  407. package/src/v2/providers/SandboxFunctionsContext.ts +11 -0
  408. package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.test.ts +309 -0
  409. package/src/v2/providers/__tests__/CopilotKitProvider.debug.test.ts +295 -0
  410. package/src/v2/providers/__tests__/CopilotKitProvider.license.test.ts +110 -0
  411. package/src/v2/providers/__tests__/CopilotKitProvider.onError.test.ts +67 -0
  412. package/src/v2/providers/__tests__/CopilotKitProvider.renderCustomMessages.e2e.test.ts +901 -0
  413. package/src/v2/providers/__tests__/CopilotKitProvider.sandboxFunctions.test.ts +141 -0
  414. package/src/v2/providers/__tests__/CopilotKitProvider.stability.test.ts +871 -0
  415. package/src/v2/providers/__tests__/CopilotKitProvider.test.ts +603 -0
  416. package/src/v2/providers/__tests__/CopilotKitProvider.wildcard.test.ts +104 -0
  417. package/src/v2/providers/index.ts +21 -0
  418. package/src/v2/providers/keys.ts +25 -0
  419. package/src/v2/providers/license-context.ts +16 -0
  420. package/src/v2/providers/types.ts +40 -0
  421. package/src/v2/providers/useCopilotChatConfiguration.ts +11 -0
  422. package/src/v2/providers/useCopilotKit.ts +11 -0
  423. package/src/v2/providers/useLicenseContext.ts +21 -0
  424. package/src/v2/types/__tests__/defineToolCallRenderer.test.ts +157 -0
  425. package/src/v2/types/a2ui.ts +5 -0
  426. package/src/v2/types/defineToolCallRenderer.ts +32 -0
  427. package/src/v2/types/frontend-tool.ts +8 -0
  428. package/src/v2/types/human-in-the-loop.ts +38 -0
  429. package/src/v2/types/index.ts +9 -0
  430. package/src/v2/types/interrupt.ts +15 -0
  431. package/src/v2/types/sandbox-function.ts +8 -0
  432. package/src/v2/types/vue-activity-message-renderer.ts +22 -0
  433. package/src/v2/types/vue-custom-message-renderer.ts +24 -0
  434. package/src/v2/types/vue-tool-call-renderer.ts +44 -0
  435. package/tsconfig.json +27 -0
  436. package/vite.config.ts +49 -0
  437. package/vitest.config.ts +23 -0
@@ -0,0 +1,1139 @@
1
+ import { render, screen, fireEvent } from "@testing-library/vue";
2
+ import { defineComponent, ref } from "vue";
3
+ import { describe, it, expect, vi } from "vitest";
4
+ import CopilotKitProvider from "../../../providers/CopilotKitProvider.vue";
5
+ import CopilotChatConfigurationProvider from "../../../providers/CopilotChatConfigurationProvider.vue";
6
+ import type { ToolsMenuItem } from "../types";
7
+ import CopilotChatInput from "../CopilotChatInput.vue";
8
+
9
+ const TestWrapper = defineComponent({
10
+ components: {
11
+ CopilotKitProvider,
12
+ CopilotChatConfigurationProvider,
13
+ },
14
+ template: `
15
+ <CopilotKitProvider>
16
+ <CopilotChatConfigurationProvider thread-id="test-thread">
17
+ <div style="height: 200px;">
18
+ <slot />
19
+ </div>
20
+ </CopilotChatConfigurationProvider>
21
+ </CopilotKitProvider>
22
+ `,
23
+ });
24
+
25
+ function renderInWrapper(component: ReturnType<typeof defineComponent>) {
26
+ const Wrapped = defineComponent({
27
+ components: { TestWrapper, UnderTest: component },
28
+ template: `
29
+ <TestWrapper>
30
+ <UnderTest />
31
+ </TestWrapper>
32
+ `,
33
+ });
34
+
35
+ return render(Wrapped);
36
+ }
37
+
38
+ describe("CopilotChatInput Slot System E2E Tests", () => {
39
+ describe("1. Tailwind Class Slot Override", () => {
40
+ describe("textArea slot", () => {
41
+ it("should apply tailwind class string to textArea", () => {
42
+ const Host = defineComponent({
43
+ components: { CopilotChatInput },
44
+ template: `
45
+ <CopilotChatInput>
46
+ <template #text-area="{ value, onInput, onKeydown }">
47
+ <textarea
48
+ data-testid="custom-text-area"
49
+ class="border-2 border-blue-500 rounded-lg p-4"
50
+ :value="value"
51
+ @input="onInput"
52
+ @keydown="onKeydown"
53
+ />
54
+ </template>
55
+ </CopilotChatInput>
56
+ `,
57
+ });
58
+
59
+ renderInWrapper(Host);
60
+ expect(
61
+ screen
62
+ .getByTestId("custom-text-area")
63
+ .classList.contains("border-blue-500"),
64
+ ).toBe(true);
65
+ });
66
+
67
+ it("should override default textArea className", () => {
68
+ const Host = defineComponent({
69
+ components: { CopilotChatInput },
70
+ template: `
71
+ <CopilotChatInput>
72
+ <template #text-area="{ value, onInput, onKeydown }">
73
+ <textarea
74
+ data-testid="override-text-area"
75
+ class="custom-textarea-class"
76
+ :value="value"
77
+ @input="onInput"
78
+ @keydown="onKeydown"
79
+ />
80
+ </template>
81
+ </CopilotChatInput>
82
+ `,
83
+ });
84
+
85
+ renderInWrapper(Host);
86
+ expect(document.querySelector(".custom-textarea-class")).toBeDefined();
87
+ });
88
+ });
89
+
90
+ describe("sendButton slot", () => {
91
+ it("should apply tailwind class string to sendButton", () => {
92
+ const Host = defineComponent({
93
+ components: { CopilotChatInput },
94
+ template: `
95
+ <CopilotChatInput model-value="hello" @submit-message="() => {}">
96
+ <template #send-button="{ onClick }">
97
+ <button data-testid="custom-send-btn" class="bg-green-500 hover:bg-green-600 rounded-full" @click="onClick">
98
+ Send
99
+ </button>
100
+ </template>
101
+ </CopilotChatInput>
102
+ `,
103
+ });
104
+
105
+ renderInWrapper(Host);
106
+ expect(
107
+ screen
108
+ .getByTestId("custom-send-btn")
109
+ .classList.contains("bg-green-500"),
110
+ ).toBe(true);
111
+ });
112
+ });
113
+
114
+ describe("startTranscribeButton slot", () => {
115
+ it("should apply tailwind class string to startTranscribeButton", () => {
116
+ const Host = defineComponent({
117
+ components: { CopilotChatInput },
118
+ template: `
119
+ <CopilotChatInput @start-transcribe="() => {}">
120
+ <template #start-transcribe-button="{ onClick }">
121
+ <button data-testid="custom-start-transcribe" class="bg-red-500 rounded" @click="onClick">
122
+ Start
123
+ </button>
124
+ </template>
125
+ </CopilotChatInput>
126
+ `,
127
+ });
128
+
129
+ renderInWrapper(Host);
130
+ expect(
131
+ screen
132
+ .getByTestId("custom-start-transcribe")
133
+ .classList.contains("bg-red-500"),
134
+ ).toBe(true);
135
+ });
136
+ });
137
+
138
+ describe("cancelTranscribeButton slot", () => {
139
+ it("should apply tailwind class string to cancelTranscribeButton", () => {
140
+ const Host = defineComponent({
141
+ components: { CopilotChatInput },
142
+ template: `
143
+ <CopilotChatInput mode="transcribe" @cancel-transcribe="() => {}">
144
+ <template #cancel-transcribe-button="{ onClick }">
145
+ <button data-testid="custom-cancel-transcribe" class="bg-gray-500" @click="onClick">
146
+ Cancel
147
+ </button>
148
+ </template>
149
+ </CopilotChatInput>
150
+ `,
151
+ });
152
+
153
+ renderInWrapper(Host);
154
+ expect(
155
+ screen
156
+ .getByTestId("custom-cancel-transcribe")
157
+ .classList.contains("bg-gray-500"),
158
+ ).toBe(true);
159
+ });
160
+ });
161
+
162
+ describe("finishTranscribeButton slot", () => {
163
+ it("should apply tailwind class string to finishTranscribeButton", () => {
164
+ const Host = defineComponent({
165
+ components: { CopilotChatInput },
166
+ template: `
167
+ <CopilotChatInput mode="transcribe" @finish-transcribe="() => {}">
168
+ <template #finish-transcribe-button="{ onClick }">
169
+ <button data-testid="custom-finish-transcribe" class="bg-purple-500" @click="onClick">
170
+ Finish
171
+ </button>
172
+ </template>
173
+ </CopilotChatInput>
174
+ `,
175
+ });
176
+
177
+ renderInWrapper(Host);
178
+ expect(
179
+ screen
180
+ .getByTestId("custom-finish-transcribe")
181
+ .classList.contains("bg-purple-500"),
182
+ ).toBe(true);
183
+ });
184
+ });
185
+
186
+ describe("addMenuButton slot", () => {
187
+ it("should apply tailwind class string to addMenuButton", () => {
188
+ const toolsMenu: (ToolsMenuItem | "-")[] = [
189
+ { label: "Test", action: vi.fn() },
190
+ ];
191
+ const Host = defineComponent({
192
+ components: { CopilotChatInput },
193
+ setup() {
194
+ return { toolsMenu };
195
+ },
196
+ template: `
197
+ <CopilotChatInput :tools-menu="toolsMenu">
198
+ <template #add-menu-button="{ toggleMenu }">
199
+ <button data-testid="custom-add-button" class="bg-yellow-500" @click="toggleMenu">
200
+ Add
201
+ </button>
202
+ </template>
203
+ </CopilotChatInput>
204
+ `,
205
+ });
206
+
207
+ renderInWrapper(Host);
208
+ expect(
209
+ screen
210
+ .getByTestId("custom-add-button")
211
+ .classList.contains("bg-yellow-500"),
212
+ ).toBe(true);
213
+ });
214
+ });
215
+
216
+ describe("audioRecorder slot", () => {
217
+ it("should apply tailwind class string to audioRecorder", () => {
218
+ const Host = defineComponent({
219
+ components: { CopilotChatInput },
220
+ template: `
221
+ <CopilotChatInput mode="transcribe">
222
+ <template #audio-recorder>
223
+ <div data-testid="custom-audio-recorder" class="border-dashed border-2">
224
+ Recorder
225
+ </div>
226
+ </template>
227
+ </CopilotChatInput>
228
+ `,
229
+ });
230
+
231
+ renderInWrapper(Host);
232
+ expect(
233
+ screen
234
+ .getByTestId("custom-audio-recorder")
235
+ .classList.contains("border-dashed"),
236
+ ).toBe(true);
237
+ });
238
+ });
239
+ });
240
+
241
+ describe("2. Properties Slot Override", () => {
242
+ describe("textArea props", () => {
243
+ it("should pass placeholder prop to textArea", () => {
244
+ const Host = defineComponent({
245
+ components: { CopilotChatInput },
246
+ template: `
247
+ <CopilotChatInput>
248
+ <template #text-area="{ value, onInput, onKeydown }">
249
+ <textarea
250
+ data-testid="props-text-area"
251
+ placeholder="Custom placeholder..."
252
+ :value="value"
253
+ @input="onInput"
254
+ @keydown="onKeydown"
255
+ />
256
+ </template>
257
+ </CopilotChatInput>
258
+ `,
259
+ });
260
+
261
+ renderInWrapper(Host);
262
+ expect(
263
+ screen.getByPlaceholderText("Custom placeholder..."),
264
+ ).toBeDefined();
265
+ });
266
+
267
+ it("should pass disabled prop to textArea", () => {
268
+ const Host = defineComponent({
269
+ components: { CopilotChatInput },
270
+ template: `
271
+ <CopilotChatInput>
272
+ <template #text-area="{ value, onInput, onKeydown }">
273
+ <textarea
274
+ data-testid="disabled-textarea"
275
+ :value="value"
276
+ disabled
277
+ @input="onInput"
278
+ @keydown="onKeydown"
279
+ />
280
+ </template>
281
+ </CopilotChatInput>
282
+ `,
283
+ });
284
+
285
+ renderInWrapper(Host);
286
+ expect(
287
+ screen.getByTestId("disabled-textarea").hasAttribute("disabled"),
288
+ ).toBe(true);
289
+ });
290
+
291
+ it("should pass onKeyDown prop to textArea", async () => {
292
+ const onKeyDown = vi.fn();
293
+ const Host = defineComponent({
294
+ components: { CopilotChatInput },
295
+ setup() {
296
+ return { onKeyDown };
297
+ },
298
+ template: `
299
+ <CopilotChatInput>
300
+ <template #text-area="{ value, onInput, onKeydown }">
301
+ <textarea
302
+ data-testid="keydown-textarea"
303
+ :value="value"
304
+ @input="onInput"
305
+ @keydown="
306
+ onKeyDown();
307
+ onKeydown($event);
308
+ "
309
+ />
310
+ </template>
311
+ </CopilotChatInput>
312
+ `,
313
+ });
314
+
315
+ renderInWrapper(Host);
316
+ await fireEvent.keyDown(screen.getByTestId("keydown-textarea"), {
317
+ key: "a",
318
+ });
319
+ expect(onKeyDown).toHaveBeenCalled();
320
+ });
321
+
322
+ it("should pass autoFocus prop to textArea", () => {
323
+ const Host = defineComponent({
324
+ components: { CopilotChatInput },
325
+ template: `
326
+ <CopilotChatInput>
327
+ <template #text-area="{ value, onInput, onKeydown }">
328
+ <textarea
329
+ data-testid="autofocus-textarea"
330
+ :value="value"
331
+ autofocus
332
+ @input="onInput"
333
+ @keydown="onKeydown"
334
+ />
335
+ </template>
336
+ </CopilotChatInput>
337
+ `,
338
+ });
339
+
340
+ renderInWrapper(Host);
341
+ expect(
342
+ screen.getByTestId("autofocus-textarea").hasAttribute("autofocus"),
343
+ ).toBe(true);
344
+ });
345
+ });
346
+
347
+ describe("sendButton props", () => {
348
+ it("should pass onClick handler to sendButton", async () => {
349
+ const handleClick = vi.fn();
350
+ const Host = defineComponent({
351
+ components: { CopilotChatInput },
352
+ setup() {
353
+ return { handleClick };
354
+ },
355
+ template: `
356
+ <CopilotChatInput model-value="message" @submit-message="() => {}">
357
+ <template #send-button="{ onClick }">
358
+ <button
359
+ data-testid="send-btn"
360
+ @click="
361
+ handleClick();
362
+ onClick();
363
+ "
364
+ >
365
+ Send
366
+ </button>
367
+ </template>
368
+ </CopilotChatInput>
369
+ `,
370
+ });
371
+
372
+ renderInWrapper(Host);
373
+ await fireEvent.click(screen.getByTestId("send-btn"));
374
+ expect(handleClick).toHaveBeenCalled();
375
+ });
376
+
377
+ it("should pass disabled prop to sendButton", () => {
378
+ const Host = defineComponent({
379
+ components: { CopilotChatInput },
380
+ template: `
381
+ <CopilotChatInput model-value="message" @submit-message="() => {}">
382
+ <template #send-button="{ onClick }">
383
+ <button data-testid="disabled-send" disabled @click="onClick">Send</button>
384
+ </template>
385
+ </CopilotChatInput>
386
+ `,
387
+ });
388
+
389
+ renderInWrapper(Host);
390
+ expect(
391
+ screen.getByTestId("disabled-send").hasAttribute("disabled"),
392
+ ).toBe(true);
393
+ });
394
+
395
+ it("should pass aria-label prop to sendButton", () => {
396
+ const Host = defineComponent({
397
+ components: { CopilotChatInput },
398
+ template: `
399
+ <CopilotChatInput model-value="message" @submit-message="() => {}">
400
+ <template #send-button="{ onClick }">
401
+ <button data-testid="aria-send" aria-label="Submit message" @click="onClick">Send</button>
402
+ </template>
403
+ </CopilotChatInput>
404
+ `,
405
+ });
406
+
407
+ renderInWrapper(Host);
408
+ expect(
409
+ document.querySelector("[aria-label='Submit message']"),
410
+ ).toBeDefined();
411
+ });
412
+ });
413
+
414
+ describe("addMenuButton props", () => {
415
+ it("should pass onClick handler to addMenuButton", async () => {
416
+ const handleClick = vi.fn();
417
+ const toolsMenu: (ToolsMenuItem | "-")[] = [
418
+ { label: "Item", action: () => {} },
419
+ ];
420
+ const Host = defineComponent({
421
+ components: { CopilotChatInput },
422
+ setup() {
423
+ return { handleClick, toolsMenu };
424
+ },
425
+ template: `
426
+ <CopilotChatInput :tools-menu="toolsMenu">
427
+ <template #add-menu-button="{ toggleMenu }">
428
+ <button
429
+ data-testid="add-menu"
430
+ @click="
431
+ handleClick();
432
+ toggleMenu();
433
+ "
434
+ >
435
+ Add
436
+ </button>
437
+ </template>
438
+ </CopilotChatInput>
439
+ `,
440
+ });
441
+
442
+ renderInWrapper(Host);
443
+ await fireEvent.click(screen.getByTestId("add-menu"));
444
+ expect(handleClick).toHaveBeenCalled();
445
+ });
446
+ });
447
+
448
+ describe("user props override pre-set props", () => {
449
+ it("user disabled should override default disabled state", () => {
450
+ const Host = defineComponent({
451
+ components: { CopilotChatInput },
452
+ template: `
453
+ <CopilotChatInput disabled model-value="message" @submit-message="() => {}">
454
+ <template #send-button="{ onClick }">
455
+ <button data-testid="override-send" @click="onClick">Send</button>
456
+ </template>
457
+ </CopilotChatInput>
458
+ `,
459
+ });
460
+
461
+ renderInWrapper(Host);
462
+ expect(
463
+ screen.getByTestId("override-send").hasAttribute("disabled"),
464
+ ).toBe(false);
465
+ });
466
+ });
467
+ });
468
+
469
+ describe("3. Custom Component Slot Override", () => {
470
+ describe("textArea custom component", () => {
471
+ it("should render custom textArea component", () => {
472
+ const Host = defineComponent({
473
+ components: { CopilotChatInput },
474
+ template: `
475
+ <CopilotChatInput>
476
+ <template #text-area="{ value, onInput, onKeydown }">
477
+ <textarea
478
+ data-testid="custom-textarea"
479
+ class="custom-input"
480
+ :value="value"
481
+ @input="onInput"
482
+ @keydown="onKeydown"
483
+ />
484
+ </template>
485
+ </CopilotChatInput>
486
+ `,
487
+ });
488
+
489
+ renderInWrapper(Host);
490
+ expect(screen.getByTestId("custom-textarea")).toBeDefined();
491
+ });
492
+
493
+ it("custom textArea should receive value and onChange props", async () => {
494
+ const onUpdateValue = vi.fn();
495
+
496
+ const Host = defineComponent({
497
+ components: { CopilotChatInput },
498
+ setup() {
499
+ return {
500
+ onUpdateValue,
501
+ };
502
+ },
503
+ template: `
504
+ <CopilotChatInput model-value="test value" @update:model-value="onUpdateValue">
505
+ <template #text-area="{ value, onInput, onKeydown }">
506
+ <textarea
507
+ data-testid="value-check-textarea"
508
+ :value="value"
509
+ @input="onInput($event)"
510
+ @keydown="onKeydown"
511
+ />
512
+ </template>
513
+ </CopilotChatInput>
514
+ `,
515
+ });
516
+
517
+ renderInWrapper(Host);
518
+ const textArea = screen.getByTestId(
519
+ "value-check-textarea",
520
+ ) as HTMLTextAreaElement;
521
+ expect(textArea.value).toBe("test value");
522
+ await fireEvent.update(textArea, "next value");
523
+ expect(onUpdateValue).toHaveBeenCalled();
524
+ });
525
+ });
526
+
527
+ describe("sendButton custom component", () => {
528
+ it("should render custom sendButton component", () => {
529
+ const Host = defineComponent({
530
+ components: { CopilotChatInput },
531
+ template: `
532
+ <CopilotChatInput model-value="hello" @submit-message="() => {}">
533
+ <template #send-button="{ onClick, disabled }">
534
+ <button data-testid="custom-send" :disabled="disabled" @click="onClick">🚀 Send Message</button>
535
+ </template>
536
+ </CopilotChatInput>
537
+ `,
538
+ });
539
+
540
+ renderInWrapper(Host);
541
+ expect(screen.getByTestId("custom-send")).toBeDefined();
542
+ expect(screen.getByText("🚀 Send Message")).toBeDefined();
543
+ });
544
+
545
+ it("custom sendButton should receive onClick callback", async () => {
546
+ const submitHandler = vi.fn();
547
+ const Host = defineComponent({
548
+ components: { CopilotChatInput },
549
+ setup() {
550
+ return { submitHandler };
551
+ },
552
+ template: `
553
+ <CopilotChatInput model-value="hello" @submit-message="submitHandler">
554
+ <template #send-button="{ onClick }">
555
+ <button data-testid="onclick-send" @click="onClick">Send</button>
556
+ </template>
557
+ </CopilotChatInput>
558
+ `,
559
+ });
560
+
561
+ renderInWrapper(Host);
562
+ await fireEvent.click(screen.getByTestId("onclick-send"));
563
+ expect(submitHandler).toHaveBeenCalled();
564
+ });
565
+ });
566
+
567
+ describe("startTranscribeButton custom component", () => {
568
+ it("should render custom startTranscribeButton component", () => {
569
+ const Host = defineComponent({
570
+ components: { CopilotChatInput },
571
+ template: `
572
+ <CopilotChatInput @start-transcribe="() => {}">
573
+ <template #start-transcribe-button="{ onClick }">
574
+ <button data-testid="custom-start-transcribe" @click="onClick">🎤 Start Recording</button>
575
+ </template>
576
+ </CopilotChatInput>
577
+ `,
578
+ });
579
+
580
+ renderInWrapper(Host);
581
+ expect(
582
+ screen.getByTestId("custom-start-transcribe").textContent,
583
+ ).toContain("Start Recording");
584
+ });
585
+ });
586
+
587
+ describe("cancelTranscribeButton custom component", () => {
588
+ it("should render custom cancelTranscribeButton component", () => {
589
+ const Host = defineComponent({
590
+ components: { CopilotChatInput },
591
+ template: `
592
+ <CopilotChatInput mode="transcribe" @cancel-transcribe="() => {}">
593
+ <template #cancel-transcribe-button="{ onClick }">
594
+ <button data-testid="custom-cancel-transcribe" @click="onClick">❌ Cancel</button>
595
+ </template>
596
+ </CopilotChatInput>
597
+ `,
598
+ });
599
+
600
+ renderInWrapper(Host);
601
+ expect(
602
+ screen.getByTestId("custom-cancel-transcribe").textContent,
603
+ ).toContain("Cancel");
604
+ });
605
+ });
606
+
607
+ describe("finishTranscribeButton custom component", () => {
608
+ it("should render custom finishTranscribeButton component", () => {
609
+ const Host = defineComponent({
610
+ components: { CopilotChatInput },
611
+ template: `
612
+ <CopilotChatInput mode="transcribe" @finish-transcribe="() => {}">
613
+ <template #finish-transcribe-button="{ onClick }">
614
+ <button data-testid="custom-finish-transcribe" @click="onClick">✓ Done</button>
615
+ </template>
616
+ </CopilotChatInput>
617
+ `,
618
+ });
619
+
620
+ renderInWrapper(Host);
621
+ expect(
622
+ screen.getByTestId("custom-finish-transcribe").textContent,
623
+ ).toContain("Done");
624
+ });
625
+ });
626
+
627
+ describe("addMenuButton custom component", () => {
628
+ it("should render custom addMenuButton component", () => {
629
+ const toolsMenu: (ToolsMenuItem | "-")[] = [
630
+ { label: "Tool", action: () => {} },
631
+ ];
632
+ const Host = defineComponent({
633
+ components: { CopilotChatInput },
634
+ setup() {
635
+ return { toolsMenu };
636
+ },
637
+ template: `
638
+ <CopilotChatInput :tools-menu="toolsMenu">
639
+ <template #add-menu-button="{ toggleMenu }">
640
+ <button data-testid="custom-add-menu" @click="toggleMenu">➕ Add</button>
641
+ </template>
642
+ </CopilotChatInput>
643
+ `,
644
+ });
645
+
646
+ renderInWrapper(Host);
647
+ expect(screen.getByTestId("custom-add-menu").textContent).toContain(
648
+ "Add",
649
+ );
650
+ });
651
+ });
652
+
653
+ describe("audioRecorder custom component", () => {
654
+ it("should render custom audioRecorder component", () => {
655
+ const Host = defineComponent({
656
+ components: { CopilotChatInput },
657
+ template: `
658
+ <CopilotChatInput mode="transcribe">
659
+ <template #audio-recorder>
660
+ <div data-testid="custom-recorder">
661
+ <button>Custom Recorder</button>
662
+ </div>
663
+ </template>
664
+ </CopilotChatInput>
665
+ `,
666
+ });
667
+
668
+ renderInWrapper(Host);
669
+ expect(screen.getByTestId("custom-recorder").textContent).toContain(
670
+ "Custom Recorder",
671
+ );
672
+ });
673
+ });
674
+
675
+ describe("multiple custom components", () => {
676
+ it("should render multiple custom components together", () => {
677
+ const Host = defineComponent({
678
+ components: { CopilotChatInput },
679
+ template: `
680
+ <CopilotChatInput model-value="hello" @submit-message="() => {}">
681
+ <template #text-area="{ value, onInput, onKeydown }">
682
+ <textarea data-testid="multi-textarea" :value="value" @input="onInput" @keydown="onKeydown" />
683
+ </template>
684
+ <template #send-button="{ onClick }">
685
+ <button data-testid="multi-send" @click="onClick">Send</button>
686
+ </template>
687
+ </CopilotChatInput>
688
+ `,
689
+ });
690
+
691
+ renderInWrapper(Host);
692
+ expect(screen.getByTestId("multi-textarea")).toBeDefined();
693
+ expect(screen.getByTestId("multi-send")).toBeDefined();
694
+ });
695
+ });
696
+ });
697
+
698
+ describe("4. Nested Props and Complex Configurations", () => {
699
+ describe("complex textArea configuration", () => {
700
+ it("should support complex props configuration", () => {
701
+ const Host = defineComponent({
702
+ components: { CopilotChatInput },
703
+ template: `
704
+ <CopilotChatInput>
705
+ <template #text-area="{ value, onInput, onKeydown }">
706
+ <textarea
707
+ data-testid="complex-ta"
708
+ class="complex-textarea"
709
+ placeholder="Complex placeholder"
710
+ rows="4"
711
+ :value="value"
712
+ @input="onInput"
713
+ @keydown="onKeydown"
714
+ />
715
+ </template>
716
+ </CopilotChatInput>
717
+ `,
718
+ });
719
+
720
+ renderInWrapper(Host);
721
+ const textarea = screen.getByTestId("complex-ta");
722
+ expect(textarea.getAttribute("placeholder")).toBe(
723
+ "Complex placeholder",
724
+ );
725
+ });
726
+ });
727
+
728
+ describe("complex sendButton configuration", () => {
729
+ it("should support complex props on sendButton", () => {
730
+ const Host = defineComponent({
731
+ components: { CopilotChatInput },
732
+ template: `
733
+ <CopilotChatInput model-value="message" @submit-message="() => {}">
734
+ <template #send-button="{ onClick }">
735
+ <button
736
+ data-testid="complex-send-btn"
737
+ class="complex-send"
738
+ aria-label="Send your message"
739
+ title="Click to send"
740
+ @click="onClick"
741
+ >
742
+ Send
743
+ </button>
744
+ </template>
745
+ </CopilotChatInput>
746
+ `,
747
+ });
748
+
749
+ renderInWrapper(Host);
750
+ const send = screen.getByTestId("complex-send-btn");
751
+ expect(send.getAttribute("aria-label")).toBe("Send your message");
752
+ expect(send.getAttribute("title")).toBe("Click to send");
753
+ });
754
+ });
755
+ });
756
+
757
+ describe("5. className Override with Tailwind", () => {
758
+ describe("className prop in object slots", () => {
759
+ it("should allow className prop in textArea object slot", () => {
760
+ const Host = defineComponent({
761
+ components: { CopilotChatInput },
762
+ template: `
763
+ <CopilotChatInput>
764
+ <template #text-area="{ value, onInput, onKeydown }">
765
+ <textarea
766
+ data-testid="class-slot-textarea"
767
+ class="textarea-class-override"
768
+ :value="value"
769
+ @input="onInput"
770
+ @keydown="onKeydown"
771
+ />
772
+ </template>
773
+ </CopilotChatInput>
774
+ `,
775
+ });
776
+
777
+ const { container } = renderInWrapper(Host);
778
+ expect(
779
+ container.querySelector(".textarea-class-override"),
780
+ ).toBeDefined();
781
+ });
782
+
783
+ it("should allow className prop in sendButton object slot", () => {
784
+ const Host = defineComponent({
785
+ components: { CopilotChatInput },
786
+ template: `
787
+ <CopilotChatInput model-value="hello" @submit-message="() => {}">
788
+ <template #send-button="{ onClick }">
789
+ <button data-testid="class-slot-send" class="send-class-override" @click="onClick">
790
+ Send
791
+ </button>
792
+ </template>
793
+ </CopilotChatInput>
794
+ `,
795
+ });
796
+
797
+ const { container } = renderInWrapper(Host);
798
+ expect(container.querySelector(".send-class-override")).toBeDefined();
799
+ });
800
+ });
801
+
802
+ describe("string slot vs className prop equivalence", () => {
803
+ it("string slot should set className on textArea", () => {
804
+ const Host = defineComponent({
805
+ components: { CopilotChatInput },
806
+ template: `
807
+ <CopilotChatInput>
808
+ <template #text-area="{ value, onInput, onKeydown }">
809
+ <textarea data-testid="string-textarea" class="string-class-textarea" :value="value" @input="onInput" @keydown="onKeydown" />
810
+ </template>
811
+ </CopilotChatInput>
812
+ `,
813
+ });
814
+
815
+ const { container } = renderInWrapper(Host);
816
+ expect(container.querySelector(".string-class-textarea")).toBeDefined();
817
+ });
818
+
819
+ it("string slot should set className on sendButton", () => {
820
+ const Host = defineComponent({
821
+ components: { CopilotChatInput },
822
+ template: `
823
+ <CopilotChatInput model-value="hello" @submit-message="() => {}">
824
+ <template #send-button="{ onClick }">
825
+ <button data-testid="string-send" class="string-class-send" @click="onClick">Send</button>
826
+ </template>
827
+ </CopilotChatInput>
828
+ `,
829
+ });
830
+
831
+ const { container } = renderInWrapper(Host);
832
+ expect(container.querySelector(".string-class-send")).toBeDefined();
833
+ });
834
+ });
835
+
836
+ describe("tailwind utility classes", () => {
837
+ it("should apply tailwind focus utilities to textArea", () => {
838
+ const Host = defineComponent({
839
+ components: { CopilotChatInput },
840
+ template: `
841
+ <CopilotChatInput>
842
+ <template #text-area="{ value, onInput, onKeydown }">
843
+ <textarea
844
+ data-testid="focus-textarea"
845
+ class="focus:ring-2 focus:ring-blue-500 focus:outline-none"
846
+ :value="value"
847
+ @input="onInput"
848
+ @keydown="onKeydown"
849
+ />
850
+ </template>
851
+ </CopilotChatInput>
852
+ `,
853
+ });
854
+
855
+ const { container } = renderInWrapper(Host);
856
+ expect(container.querySelector(".focus\\:ring-2")).toBeDefined();
857
+ });
858
+
859
+ it("should apply tailwind hover utilities to sendButton", () => {
860
+ const Host = defineComponent({
861
+ components: { CopilotChatInput },
862
+ template: `
863
+ <CopilotChatInput model-value="hello" @submit-message="() => {}">
864
+ <template #send-button="{ onClick }">
865
+ <button data-testid="hover-send" class="hover:bg-blue-600 active:bg-blue-700" @click="onClick">
866
+ Send
867
+ </button>
868
+ </template>
869
+ </CopilotChatInput>
870
+ `,
871
+ });
872
+
873
+ const { container } = renderInWrapper(Host);
874
+ expect(container.querySelector(".hover\\:bg-blue-600")).toBeDefined();
875
+ });
876
+ });
877
+ });
878
+
879
+ describe("6. Children Render Function", () => {
880
+ it("should support children render function for custom layout", () => {
881
+ const Host = defineComponent({
882
+ components: { CopilotChatInput },
883
+ methods: {
884
+ readValue(event: Event) {
885
+ return (event.target as HTMLTextAreaElement).value;
886
+ },
887
+ },
888
+ template: `
889
+ <CopilotChatInput>
890
+ <template #layout="{ value, onUpdateValue, onSendClick }">
891
+ <div data-testid="custom-input-layout">
892
+ <div class="input-row">
893
+ <textarea data-testid="layout-textarea" :value="value" @input="onUpdateValue(readValue($event))" />
894
+ <button data-testid="layout-send" @click="onSendClick">Send</button>
895
+ </div>
896
+ </div>
897
+ </template>
898
+ </CopilotChatInput>
899
+ `,
900
+ });
901
+
902
+ renderInWrapper(Host);
903
+ expect(screen.getByTestId("custom-input-layout")).toBeDefined();
904
+ });
905
+
906
+ it("children render function should receive all slot elements", () => {
907
+ const receivedFunctions = ref<string[]>([]);
908
+ const Host = defineComponent({
909
+ components: { CopilotChatInput },
910
+ setup() {
911
+ return { receivedFunctions };
912
+ },
913
+ template: `
914
+ <CopilotChatInput>
915
+ <template #layout="{ onUpdateValue, onSubmit, onKeydown, onSendClick, onToggleMenu }">
916
+ <div data-testid="slots-check">
917
+ {{
918
+ receivedFunctions = [
919
+ typeof onUpdateValue,
920
+ typeof onSubmit,
921
+ typeof onKeydown,
922
+ typeof onSendClick,
923
+ typeof onToggleMenu,
924
+ ]
925
+ }}
926
+ Rendered
927
+ </div>
928
+ </template>
929
+ </CopilotChatInput>
930
+ `,
931
+ });
932
+
933
+ renderInWrapper(Host);
934
+ expect(screen.getByTestId("slots-check")).toBeDefined();
935
+ expect(
936
+ receivedFunctions.value.every((value) => value === "function"),
937
+ ).toBe(true);
938
+ });
939
+
940
+ it("children render function allows complete layout control", () => {
941
+ const toolsMenu: (ToolsMenuItem | "-")[] = [
942
+ { label: "Tool", action: () => {} },
943
+ ];
944
+ const Host = defineComponent({
945
+ components: { CopilotChatInput },
946
+ setup() {
947
+ return { toolsMenu };
948
+ },
949
+ methods: {
950
+ readValue(event: Event) {
951
+ return (event.target as HTMLTextAreaElement).value;
952
+ },
953
+ },
954
+ template: `
955
+ <CopilotChatInput :tools-menu="toolsMenu" model-value="hello" @submit-message="() => {}">
956
+ <template #layout="{ value, onUpdateValue, onSendClick, onToggleMenu }">
957
+ <div data-testid="full-control-layout">
958
+ <div class="toolbar">
959
+ <button data-testid="layout-add" @click="onToggleMenu">Add</button>
960
+ </div>
961
+ <div class="main">
962
+ <textarea :value="value" @input="onUpdateValue(readValue($event))" />
963
+ </div>
964
+ <div class="actions">
965
+ <button data-testid="layout-send-custom" @click="onSendClick">Send</button>
966
+ </div>
967
+ </div>
968
+ </template>
969
+ </CopilotChatInput>
970
+ `,
971
+ });
972
+
973
+ renderInWrapper(Host);
974
+ expect(screen.getByTestId("full-control-layout")).toBeDefined();
975
+ expect(document.querySelector(".toolbar")).toBeDefined();
976
+ expect(document.querySelector(".main")).toBeDefined();
977
+ expect(document.querySelector(".actions")).toBeDefined();
978
+ });
979
+ });
980
+
981
+ describe("7. Positioning Prop", () => {
982
+ it("should render static positioning by default", () => {
983
+ const Host = defineComponent({
984
+ components: { CopilotChatInput },
985
+ template: `
986
+ <CopilotChatInput data-testid="input-container" />
987
+ `,
988
+ });
989
+ const { container } = renderInWrapper(Host);
990
+
991
+ const inputContainer = container.querySelector(
992
+ "[data-testid='input-container']",
993
+ ) as HTMLElement;
994
+ expect(inputContainer).not.toBeNull();
995
+ expect(inputContainer.classList.contains("cpk:absolute")).toBe(false);
996
+ });
997
+
998
+ it("should render absolute positioning when positioning='absolute'", () => {
999
+ const Host = defineComponent({
1000
+ components: { CopilotChatInput },
1001
+ template: `
1002
+ <CopilotChatInput positioning="absolute" data-testid="absolute-input" />
1003
+ `,
1004
+ });
1005
+ const { container } = renderInWrapper(Host);
1006
+
1007
+ const inputContainer = container.querySelector(
1008
+ "[data-testid='absolute-input']",
1009
+ ) as HTMLElement;
1010
+ expect(inputContainer).not.toBeNull();
1011
+ expect(inputContainer.classList.contains("cpk:absolute")).toBe(true);
1012
+ expect(inputContainer.classList.contains("cpk:bottom-0")).toBe(true);
1013
+ });
1014
+
1015
+ it("should apply keyboard height transform", () => {
1016
+ const Host = defineComponent({
1017
+ components: { CopilotChatInput },
1018
+ template: `
1019
+ <CopilotChatInput positioning="absolute" :keyboard-height="300" data-testid="keyboard-input" />
1020
+ `,
1021
+ });
1022
+ const { container } = renderInWrapper(Host);
1023
+
1024
+ const inputContainer = container.querySelector(
1025
+ "[data-testid='keyboard-input']",
1026
+ ) as HTMLElement;
1027
+ expect(inputContainer).not.toBeNull();
1028
+ expect(inputContainer.style.transform).toBe("translateY(-300px)");
1029
+ });
1030
+
1031
+ it("should forward containerRef", () => {
1032
+ const Host = defineComponent({
1033
+ components: { CopilotChatInput },
1034
+ template: `
1035
+ <CopilotChatInput data-testid="forwarded-input" data-extra="x" />
1036
+ `,
1037
+ });
1038
+
1039
+ renderInWrapper(Host);
1040
+ const input = screen.getByTestId("forwarded-input");
1041
+ expect(input.getAttribute("data-extra")).toBe("x");
1042
+ });
1043
+ });
1044
+
1045
+ describe("8. Disclaimer Slot", () => {
1046
+ it("should render disclaimer when showDisclaimer=true", () => {
1047
+ const Host = defineComponent({
1048
+ components: { CopilotChatInput },
1049
+ template: `
1050
+ <CopilotChatInput :show-disclaimer="true" />
1051
+ `,
1052
+ });
1053
+
1054
+ renderInWrapper(Host);
1055
+ expect(screen.getByTestId("copilot-chat-input-disclaimer")).toBeDefined();
1056
+ });
1057
+
1058
+ it("should hide disclaimer when showDisclaimer=false", () => {
1059
+ const Host = defineComponent({
1060
+ components: { CopilotChatInput },
1061
+ template: `
1062
+ <CopilotChatInput :show-disclaimer="false" />
1063
+ `,
1064
+ });
1065
+ const { container } = renderInWrapper(Host);
1066
+
1067
+ const disclaimer = container.querySelector(
1068
+ "[data-testid='copilot-chat-input-disclaimer']",
1069
+ );
1070
+ expect(disclaimer).toBeNull();
1071
+ });
1072
+
1073
+ it("should show disclaimer by default with absolute positioning", () => {
1074
+ const Host = defineComponent({
1075
+ components: { CopilotChatInput },
1076
+ template: `
1077
+ <CopilotChatInput positioning="absolute" />
1078
+ `,
1079
+ });
1080
+ const { container } = renderInWrapper(Host);
1081
+
1082
+ const disclaimer = container.querySelector(
1083
+ "[data-testid='copilot-chat-input-disclaimer']",
1084
+ );
1085
+ expect(disclaimer).not.toBeNull();
1086
+ });
1087
+
1088
+ it("should hide disclaimer by default with static positioning", () => {
1089
+ const Host = defineComponent({
1090
+ components: { CopilotChatInput },
1091
+ template: `
1092
+ <CopilotChatInput positioning="static" />
1093
+ `,
1094
+ });
1095
+ const { container } = renderInWrapper(Host);
1096
+
1097
+ const disclaimer = container.querySelector(
1098
+ "[data-testid='copilot-chat-input-disclaimer']",
1099
+ );
1100
+ expect(disclaimer).toBeNull();
1101
+ });
1102
+
1103
+ it("should apply tailwind class to disclaimer", () => {
1104
+ const Host = defineComponent({
1105
+ components: { CopilotChatInput },
1106
+ template: `
1107
+ <CopilotChatInput :show-disclaimer="true">
1108
+ <template #disclaimer>
1109
+ <p data-testid="custom-disclaimer-class" class="text-red-500 italic">Disclaimer</p>
1110
+ </template>
1111
+ </CopilotChatInput>
1112
+ `,
1113
+ });
1114
+
1115
+ renderInWrapper(Host);
1116
+ const disclaimer = screen.getByTestId("custom-disclaimer-class");
1117
+ expect(disclaimer.classList.contains("text-red-500")).toBe(true);
1118
+ expect(disclaimer.classList.contains("italic")).toBe(true);
1119
+ });
1120
+
1121
+ it("should render custom disclaimer component", () => {
1122
+ const Host = defineComponent({
1123
+ components: { CopilotChatInput },
1124
+ template: `
1125
+ <CopilotChatInput :show-disclaimer="true">
1126
+ <template #disclaimer>
1127
+ <div data-testid="custom-disclaimer">Custom Disclaimer Content</div>
1128
+ </template>
1129
+ </CopilotChatInput>
1130
+ `,
1131
+ });
1132
+
1133
+ renderInWrapper(Host);
1134
+ expect(screen.getByTestId("custom-disclaimer").textContent).toContain(
1135
+ "Custom Disclaimer",
1136
+ );
1137
+ });
1138
+ });
1139
+ });