@copilotkit/vue 2.0.0-rc.1 → 2.0.0-rc.2

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 (239) hide show
  1. package/PARITY.md +13 -12
  2. package/README.md +1 -2
  3. package/dist/components/copilot-provider/CopilotKit.vue.d.ts +3 -1
  4. package/dist/components/copilot-provider/CopilotKit.vue.d.ts.map +1 -1
  5. package/dist/index.cjs +43 -46
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.mjs +10170 -7506
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/v2/components/A2UIMessageRenderer.d.ts +7 -0
  10. package/dist/v2/components/A2UIMessageRenderer.d.ts.map +1 -1
  11. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts.map +1 -1
  12. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts +11 -2
  13. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts.map +1 -1
  14. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts +136 -0
  15. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts.map +1 -0
  16. package/dist/v2/components/chat/BasicMarkdown.vue.d.ts.map +1 -1
  17. package/dist/v2/components/chat/CopilotChat.vue.d.ts +1 -0
  18. package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -1
  19. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts +3 -1
  20. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts.map +1 -1
  21. package/dist/v2/components/chat/CopilotChatAssistantToolbarButton.vue.d.ts +16 -0
  22. package/dist/v2/components/chat/CopilotChatAssistantToolbarButton.vue.d.ts.map +1 -0
  23. package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts.map +1 -1
  24. package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts.map +1 -1
  25. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts.map +1 -1
  26. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts +22 -0
  27. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts.map +1 -0
  28. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +69 -16
  29. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts.map +1 -1
  30. package/dist/v2/components/chat/CopilotChatInspectorButton.vue.d.ts +12 -0
  31. package/dist/v2/components/chat/CopilotChatInspectorButton.vue.d.ts.map +1 -0
  32. package/dist/v2/components/chat/CopilotChatLightbox.vue.d.ts +22 -0
  33. package/dist/v2/components/chat/CopilotChatLightbox.vue.d.ts.map +1 -0
  34. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts +20 -0
  35. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts.map +1 -1
  36. package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts.map +1 -1
  37. package/dist/v2/components/chat/CopilotChatSuggestionPill.vue.d.ts.map +1 -1
  38. package/dist/v2/components/chat/CopilotChatSuggestionView.vue.d.ts.map +1 -1
  39. package/dist/v2/components/chat/CopilotChatToggleButton.vue.d.ts.map +1 -1
  40. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts +32 -0
  41. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts.map +1 -0
  42. package/dist/v2/components/chat/CopilotChatToolCallItem.vue.d.ts.map +1 -1
  43. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts +11 -1
  44. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts.map +1 -1
  45. package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts.map +1 -1
  46. package/dist/v2/components/chat/CopilotChatView.vue.d.ts +1 -0
  47. package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -1
  48. package/dist/v2/components/chat/CopilotChatWorkSummary.vue.d.ts +5 -0
  49. package/dist/v2/components/chat/CopilotChatWorkSummary.vue.d.ts.map +1 -0
  50. package/dist/v2/components/chat/CopilotModalHeader.vue.d.ts.map +1 -1
  51. package/dist/v2/components/chat/CopilotModalHeaderCloseButton.d.ts.map +1 -1
  52. package/dist/v2/components/chat/CopilotModalHeaderTitle.d.ts.map +1 -1
  53. package/dist/v2/components/chat/CopilotPopup.vue.d.ts +1 -0
  54. package/dist/v2/components/chat/CopilotPopup.vue.d.ts.map +1 -1
  55. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts +1 -0
  56. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts.map +1 -1
  57. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts +1 -0
  58. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts.map +1 -1
  59. package/dist/v2/components/chat/CopilotPopupWelcomeScreen.vue.d.ts.map +1 -1
  60. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts +2 -0
  61. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts.map +1 -1
  62. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts +2 -0
  63. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts.map +1 -1
  64. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts +2 -0
  65. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts.map +1 -1
  66. package/dist/v2/components/chat/CopilotSidebarWelcomeScreen.vue.d.ts.map +1 -1
  67. package/dist/v2/components/chat/StreamingMarkdownDefault.vue.d.ts.map +1 -1
  68. package/dist/v2/components/chat/index.d.ts +17 -0
  69. package/dist/v2/components/chat/index.d.ts.map +1 -1
  70. package/dist/v2/components/chat/inspector-shortcuts.d.ts +12 -0
  71. package/dist/v2/components/chat/inspector-shortcuts.d.ts.map +1 -0
  72. package/dist/v2/components/chat/message-feedback.d.ts +89 -0
  73. package/dist/v2/components/chat/message-feedback.d.ts.map +1 -0
  74. package/dist/v2/components/chat/tool-call-capture.d.ts +39 -0
  75. package/dist/v2/components/chat/tool-call-capture.d.ts.map +1 -0
  76. package/dist/v2/components/chat/tool-call-display-context.d.ts +39 -0
  77. package/dist/v2/components/chat/tool-call-display-context.d.ts.map +1 -0
  78. package/dist/v2/components/chat/tool-call-group-parts.d.ts +144 -0
  79. package/dist/v2/components/chat/tool-call-group-parts.d.ts.map +1 -0
  80. package/dist/v2/components/chat/tool-call-layout.d.ts +115 -0
  81. package/dist/v2/components/chat/tool-call-layout.d.ts.map +1 -0
  82. package/dist/v2/components/chat/turn-work.d.ts +35 -0
  83. package/dist/v2/components/chat/turn-work.d.ts.map +1 -0
  84. package/dist/v2/components/chat/types.d.ts +104 -4
  85. package/dist/v2/components/chat/types.d.ts.map +1 -1
  86. package/dist/v2/components/chat/use-lightbox.d.ts +18 -0
  87. package/dist/v2/components/chat/use-lightbox.d.ts.map +1 -0
  88. package/dist/v2/components/icons/index.d.ts +1 -1
  89. package/dist/v2/components/icons/index.d.ts.map +1 -1
  90. package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts +55 -0
  91. package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts.map +1 -0
  92. package/dist/v2/components/ui/CopilotPopover.vue.d.ts +40 -0
  93. package/dist/v2/components/ui/CopilotPopover.vue.d.ts.map +1 -0
  94. package/dist/v2/components/ui/CopilotTooltip.vue.d.ts +37 -0
  95. package/dist/v2/components/ui/CopilotTooltip.vue.d.ts.map +1 -0
  96. package/dist/v2/components/ui/dropdown-menu.d.ts +14 -0
  97. package/dist/v2/components/ui/dropdown-menu.d.ts.map +1 -0
  98. package/dist/v2/components/ui/floating.d.ts +84 -0
  99. package/dist/v2/components/ui/floating.d.ts.map +1 -0
  100. package/dist/v2/components/ui/presence.d.ts +9 -0
  101. package/dist/v2/components/ui/presence.d.ts.map +1 -0
  102. package/dist/v2/components/ui/use-id.d.ts +9 -0
  103. package/dist/v2/components/ui/use-id.d.ts.map +1 -0
  104. package/dist/v2/hooks/use-default-render-tool.d.ts +6 -0
  105. package/dist/v2/hooks/use-default-render-tool.d.ts.map +1 -1
  106. package/dist/v2/hooks/use-render-tool.d.ts +4 -0
  107. package/dist/v2/hooks/use-render-tool.d.ts.map +1 -1
  108. package/dist/v2/index.cjs +1 -1
  109. package/dist/v2/index.d.cts +3 -0
  110. package/dist/v2/index.d.mts +3 -0
  111. package/dist/v2/index.d.ts +3 -0
  112. package/dist/v2/index.d.ts.map +1 -1
  113. package/dist/v2/index.mjs +165 -162
  114. package/dist/v2/lib/message-feedback.d.ts +33 -0
  115. package/dist/v2/lib/message-feedback.d.ts.map +1 -0
  116. package/dist/v2/providers/CopilotChatConfigurationProvider.vue.d.ts.map +1 -1
  117. package/dist/v2/providers/CopilotKitProvider.types.d.ts +56 -1
  118. package/dist/v2/providers/CopilotKitProvider.types.d.ts.map +1 -1
  119. package/dist/v2/providers/CopilotKitProvider.vue.d.ts +5 -1
  120. package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -1
  121. package/dist/v2/providers/index.d.ts +1 -1
  122. package/dist/v2/providers/index.d.ts.map +1 -1
  123. package/dist/v2/providers/keys.d.ts +8 -0
  124. package/dist/v2/providers/keys.d.ts.map +1 -1
  125. package/dist/v2/providers/types.d.ts +9 -0
  126. package/dist/v2/providers/types.d.ts.map +1 -1
  127. package/dist/v2/styles/CopilotKitStyles.d.ts +18 -0
  128. package/dist/v2/styles/CopilotKitStyles.d.ts.map +1 -0
  129. package/dist/v2/types/defineToolCallRenderer.d.ts +2 -0
  130. package/dist/v2/types/defineToolCallRenderer.d.ts.map +1 -1
  131. package/dist/v2/types/vue-tool-call-renderer.d.ts +7 -0
  132. package/dist/v2/types/vue-tool-call-renderer.d.ts.map +1 -1
  133. package/package.json +11 -23
  134. package/src/components/copilot-provider/CopilotKit.vue +4 -1
  135. package/src/v2/__tests__/exports.test.ts +4 -2
  136. package/src/v2/components/A2UIMessageRenderer.ts +55 -67
  137. package/src/v2/components/A2UISurfaceActivityRenderer.vue +11 -23
  138. package/src/v2/components/__tests__/A2UIBasicCatalogColors.test.ts +8 -9
  139. package/src/v2/components/__tests__/A2UIMessageRenderer.test.ts +63 -36
  140. package/src/v2/components/a2ui/A2UIBuiltInToolCallRenderer.ts +14 -257
  141. package/src/v2/components/a2ui/A2UIRecoveryStates.ts +444 -0
  142. package/src/v2/components/a2ui/__tests__/A2UIRecoveryStates.test.ts +175 -0
  143. package/src/v2/components/chat/BasicMarkdown.vue +8 -6
  144. package/src/v2/components/chat/CopilotChat.vue +7 -0
  145. package/src/v2/components/chat/CopilotChatAssistantMessage.vue +267 -67
  146. package/src/v2/components/chat/CopilotChatAssistantToolbarButton.vue +46 -0
  147. package/src/v2/components/chat/CopilotChatAttachmentQueue.vue +141 -168
  148. package/src/v2/components/chat/CopilotChatAttachmentRenderer.vue +67 -18
  149. package/src/v2/components/chat/CopilotChatAudioRecorder.vue +2 -2
  150. package/src/v2/components/chat/CopilotChatFeedbackCommentPopover.vue +240 -0
  151. package/src/v2/components/chat/CopilotChatInput.vue +210 -161
  152. package/src/v2/components/chat/CopilotChatInspectorButton.vue +331 -0
  153. package/src/v2/components/chat/CopilotChatLightbox.vue +105 -0
  154. package/src/v2/components/chat/CopilotChatMessageView.vue +261 -18
  155. package/src/v2/components/chat/CopilotChatReasoningMessage.vue +21 -22
  156. package/src/v2/components/chat/CopilotChatSuggestionPill.vue +5 -14
  157. package/src/v2/components/chat/CopilotChatSuggestionView.vue +1 -4
  158. package/src/v2/components/chat/CopilotChatToggleButton.vue +3 -9
  159. package/src/v2/components/chat/CopilotChatToggleButtonCloseIcon.ts +1 -1
  160. package/src/v2/components/chat/CopilotChatToggleButtonOpenIcon.ts +1 -1
  161. package/src/v2/components/chat/CopilotChatToolCallGroup.vue +330 -0
  162. package/src/v2/components/chat/CopilotChatToolCallItem.vue +21 -11
  163. package/src/v2/components/chat/CopilotChatToolCallsView.vue +192 -21
  164. package/src/v2/components/chat/CopilotChatUserMessage.vue +105 -42
  165. package/src/v2/components/chat/CopilotChatView.vue +33 -38
  166. package/src/v2/components/chat/CopilotChatWorkSummary.vue +85 -0
  167. package/src/v2/components/chat/CopilotModalHeader.vue +10 -8
  168. package/src/v2/components/chat/CopilotModalHeaderCloseButton.ts +7 -6
  169. package/src/v2/components/chat/CopilotModalHeaderTitle.ts +1 -4
  170. package/src/v2/components/chat/CopilotPopup.vue +3 -0
  171. package/src/v2/components/chat/CopilotPopupView.vue +1 -0
  172. package/src/v2/components/chat/CopilotPopupViewInternal.vue +9 -19
  173. package/src/v2/components/chat/CopilotPopupWelcomeScreen.vue +5 -8
  174. package/src/v2/components/chat/CopilotSidebar.vue +5 -0
  175. package/src/v2/components/chat/CopilotSidebarView.vue +2 -0
  176. package/src/v2/components/chat/CopilotSidebarViewInternal.vue +24 -17
  177. package/src/v2/components/chat/CopilotSidebarWelcomeScreen.vue +7 -10
  178. package/src/v2/components/chat/StreamingMarkdownDefault.vue +3 -5
  179. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.inspector.test.ts +269 -0
  180. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.learningFeedback.test.ts +760 -0
  181. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.slots.e2e.test.ts +3 -5
  182. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.test.ts +2 -2
  183. package/src/v2/components/chat/__tests__/CopilotChatInput.addMenu.test.ts +328 -0
  184. package/src/v2/components/chat/__tests__/CopilotChatInput.slots.e2e.test.ts +6 -3
  185. package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +22 -13
  186. package/src/v2/components/chat/__tests__/CopilotChatLightbox.test.ts +160 -0
  187. package/src/v2/components/chat/__tests__/CopilotChatMessageView.toolCallDisplay.test.ts +735 -0
  188. package/src/v2/components/chat/__tests__/CopilotChatSuggestionPill.test.ts +1 -1
  189. package/src/v2/components/chat/__tests__/CopilotChatSuggestionView.slots.e2e.test.ts +3 -1
  190. package/src/v2/components/chat/__tests__/CopilotChatToolCallsView.learning.test.ts +75 -0
  191. package/src/v2/components/chat/__tests__/CopilotChatUserMessage.attachments.test.ts +143 -0
  192. package/src/v2/components/chat/__tests__/CopilotChatView.inputOverlay.test.ts +5 -4
  193. package/src/v2/components/chat/__tests__/CopilotChatView.rootWidth.test.ts +7 -33
  194. package/src/v2/components/chat/__tests__/CopilotModalHeader.slots.e2e.test.ts +1 -1
  195. package/src/v2/components/chat/__tests__/CopilotPopupView.slots.e2e.test.ts +3 -3
  196. package/src/v2/components/chat/__tests__/CopilotSidebarView.position.test.ts +126 -0
  197. package/src/v2/components/chat/__tests__/messageFeedbackDefaults.test.ts +33 -0
  198. package/src/v2/components/chat/__tests__/modalChatDisplayProps.test.ts +44 -0
  199. package/src/v2/components/chat/index.ts +2 -0
  200. package/src/v2/components/chat/inspector-shortcuts.ts +34 -0
  201. package/src/v2/components/chat/message-feedback.ts +291 -0
  202. package/src/v2/components/chat/tool-call-capture.ts +55 -0
  203. package/src/v2/components/chat/tool-call-display-context.ts +49 -0
  204. package/src/v2/components/chat/tool-call-group-parts.ts +292 -0
  205. package/src/v2/components/chat/tool-call-layout.ts +304 -0
  206. package/src/v2/components/chat/turn-work.ts +61 -0
  207. package/src/v2/components/chat/types.ts +113 -3
  208. package/src/v2/components/chat/use-lightbox.ts +64 -0
  209. package/src/v2/components/icons/index.ts +4 -0
  210. package/src/v2/components/ui/CopilotDropdownMenuContent.vue +465 -0
  211. package/src/v2/components/ui/CopilotPopover.vue +138 -0
  212. package/src/v2/components/ui/CopilotTooltip.vue +237 -0
  213. package/src/v2/components/ui/__tests__/CopilotTooltip.test.ts +168 -0
  214. package/src/v2/components/ui/dropdown-menu.ts +15 -0
  215. package/src/v2/components/ui/floating.ts +321 -0
  216. package/src/v2/components/ui/presence.ts +54 -0
  217. package/src/v2/components/ui/use-id.ts +16 -0
  218. package/src/v2/hooks/use-default-render-tool.ts +123 -62
  219. package/src/v2/hooks/use-render-tool.ts +8 -0
  220. package/src/v2/index.ts +3 -0
  221. package/src/v2/lib/__tests__/message-feedback.test.ts +152 -0
  222. package/src/v2/lib/message-feedback.ts +120 -0
  223. package/src/v2/providers/CopilotChatConfigurationProvider.vue +29 -2
  224. package/src/v2/providers/CopilotKitProvider.types.ts +57 -0
  225. package/src/v2/providers/CopilotKitProvider.vue +125 -3
  226. package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.openThread.test.ts +69 -0
  227. package/src/v2/providers/__tests__/CopilotKitProvider.learning.test.ts +534 -0
  228. package/src/v2/providers/index.ts +4 -1
  229. package/src/v2/providers/keys.ts +12 -0
  230. package/src/v2/providers/types.ts +11 -0
  231. package/src/v2/styles/CopilotKitStyles.ts +95 -0
  232. package/src/v2/styles/__tests__/CopilotKitStyles.client.test.ts +149 -0
  233. package/src/v2/styles/__tests__/CopilotKitStyles.ssr.test.ts +71 -0
  234. package/src/v2/types/defineToolCallRenderer.ts +4 -0
  235. package/src/v2/types/vue-tool-call-renderer.ts +7 -0
  236. package/vite.config.ts +2 -1
  237. package/dist/styles.css +0 -2
  238. package/scripts/scope-preflight.mjs +0 -100
  239. package/src/styles/globals.css +0 -233
@@ -0,0 +1,331 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * React's `CopilotChatInspectorButton`: the Inspector shortcut in the
4
+ * assistant message toolbar. A click (or Enter or Space) opens the message in
5
+ * the Inspector. Hovering the button, or ArrowDown, shows a menu that
6
+ * explains it and can hide the shortcut until the page reloads.
7
+ *
8
+ * @internal
9
+ */
10
+ import { computed, onBeforeUnmount, ref, shallowRef } from "vue";
11
+ import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
12
+ import { CopilotChatDefaultLabels } from "../../providers/types";
13
+ import { IconEyeOff, IconWrench } from "../icons";
14
+ import CopilotDropdownMenuContent from "../ui/CopilotDropdownMenuContent.vue";
15
+ import type {
16
+ CopilotDropdownMenuDismissReason,
17
+ CopilotDropdownMenuEntry,
18
+ CopilotDropdownMenuItem,
19
+ } from "../ui/dropdown-menu";
20
+ import CopilotTooltip from "../ui/CopilotTooltip.vue";
21
+ import { useCopilotId } from "../ui/use-id";
22
+ import { hideInspectorShortcuts } from "./inspector-shortcuts";
23
+
24
+ defineOptions({ inheritAttrs: false });
25
+
26
+ const props = defineProps<{
27
+ /** Name of the menu item that inspects; defaults to the label. */
28
+ title?: string;
29
+ disabled?: boolean;
30
+ }>();
31
+
32
+ const emit = defineEmits<{ click: [] }>();
33
+
34
+ const config = useCopilotChatConfiguration();
35
+ const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
36
+ const menuId = useCopilotId("cpk-inspector-menu");
37
+ const triggerId = useCopilotId("cpk-inspector-button");
38
+ const kiteId = useCopilotId("cpk-inspector-kite");
39
+ const trigger = shallowRef<HTMLButtonElement | null>(null);
40
+ const open = ref(false);
41
+ const dark = ref(false);
42
+ const initialFocus = ref<"first" | "none">("none");
43
+ let closeTimer: ReturnType<typeof setTimeout> | null = null;
44
+ // Hover opens it without moving focus, and leaving closes it again.
45
+ let openedByHover = false;
46
+
47
+ const cancelClose = () => {
48
+ if (closeTimer !== null) clearTimeout(closeTimer);
49
+ closeTimer = null;
50
+ };
51
+ onBeforeUnmount(cancelClose);
52
+
53
+ const changeOpen = (next: boolean) => {
54
+ cancelClose();
55
+ if (next) dark.value = !!trigger.value?.closest(".dark");
56
+ open.value = next;
57
+ };
58
+
59
+ const scheduleClose = () => {
60
+ cancelClose();
61
+ closeTimer = setTimeout(() => {
62
+ // Keep the panel available while the keyboard is interacting with it.
63
+ if (openedByHover) open.value = false;
64
+ }, 180);
65
+ };
66
+
67
+ const items = computed<CopilotDropdownMenuEntry[]>(() => [
68
+ {
69
+ label: props.title || labels.value.assistantMessageToolbarInspectorLabel,
70
+ action: () => emit("click"),
71
+ class: "cpk-inspector-button-menu-item cpk-inspector-button-inspect-item",
72
+ },
73
+ {
74
+ label: labels.value.assistantMessageToolbarInspectorHideLabel,
75
+ action: hideInspectorShortcuts,
76
+ class: "cpk-inspector-button-menu-item cpk-inspector-button-hide-item",
77
+ },
78
+ ]);
79
+
80
+ const isInspectItem = (item: CopilotDropdownMenuItem) =>
81
+ item === items.value[0];
82
+
83
+ function onPointerEnter(event: PointerEvent) {
84
+ if (props.disabled || event.pointerType === "touch") return;
85
+ openedByHover = true;
86
+ initialFocus.value = "none";
87
+ changeOpen(true);
88
+ }
89
+
90
+ function onClick() {
91
+ changeOpen(false);
92
+ emit("click");
93
+ }
94
+
95
+ function onKeyDown(event: KeyboardEvent) {
96
+ openedByHover = false;
97
+ if (event.key === "Enter" || event.key === " ") {
98
+ // Enter and Space inspect, as a click does, instead of opening the menu.
99
+ event.preventDefault();
100
+ onClick();
101
+ } else if (event.key === "ArrowDown") {
102
+ event.preventDefault();
103
+ initialFocus.value = "first";
104
+ if (open.value) {
105
+ // Open already from hover: move into it.
106
+ open.value = false;
107
+ queueMicrotask(() => changeOpen(true));
108
+ } else {
109
+ changeOpen(true);
110
+ }
111
+ }
112
+ }
113
+
114
+ function onSelect(item: CopilotDropdownMenuItem) {
115
+ const returnFocus = !openedByHover;
116
+ changeOpen(false);
117
+ item.action?.();
118
+ if (returnFocus && !isInspectItem(item)) trigger.value?.focus();
119
+ }
120
+
121
+ function onDismiss(reason: CopilotDropdownMenuDismissReason) {
122
+ const returnFocus = !openedByHover && reason !== "outside";
123
+ changeOpen(false);
124
+ if (returnFocus) trigger.value?.focus();
125
+ }
126
+
127
+ const ariaLabel = computed(
128
+ () =>
129
+ `${labels.value.assistantMessageToolbarInspectorTitle} (${labels.value.assistantMessageToolbarInspectorLocalOnlyLabel.toLowerCase()})`,
130
+ );
131
+
132
+ const descriptionFor = (item: CopilotDropdownMenuItem) =>
133
+ isInspectItem(item)
134
+ ? labels.value.assistantMessageToolbarInspectorDescription
135
+ : labels.value.assistantMessageToolbarInspectorHideDescription;
136
+ </script>
137
+
138
+ <template>
139
+ <button
140
+ :id="triggerId"
141
+ ref="trigger"
142
+ v-bind="$attrs"
143
+ type="button"
144
+ :disabled="disabled"
145
+ data-testid="copilot-inspector-button"
146
+ class="cpk-button cpk-button-assistant-message-toolbar cpk-button-size-icon cpk-inspector-button"
147
+ :aria-label="ariaLabel"
148
+ aria-haspopup="menu"
149
+ :aria-expanded="open"
150
+ :aria-controls="open ? menuId : undefined"
151
+ :data-state="open ? 'open' : 'closed'"
152
+ @pointerenter="onPointerEnter"
153
+ @pointerleave="scheduleClose"
154
+ @pointerdown.prevent
155
+ @click="onClick"
156
+ @keydown="onKeyDown"
157
+ >
158
+ <IconWrench
159
+ aria-hidden="true"
160
+ class="cpk-inspector-button-icon"
161
+ data-testid="copilot-inspector-icon"
162
+ />
163
+ </button>
164
+ <CopilotDropdownMenuContent
165
+ :id="menuId"
166
+ :open="open"
167
+ :anchor="trigger"
168
+ :items="items"
169
+ :menu-id="menuId"
170
+ :labelled-by="triggerId"
171
+ side="top"
172
+ align="start"
173
+ :side-offset="6"
174
+ :initial-focus="initialFocus"
175
+ class="cpk-inspector-button-menu"
176
+ :class="{ dark }"
177
+ @select="onSelect"
178
+ @dismiss="onDismiss"
179
+ @pointer-enter="cancelClose"
180
+ @pointer-leave="scheduleClose"
181
+ @keydown="openedByHover = false"
182
+ >
183
+ <template #header>
184
+ <div
185
+ data-slot="dropdown-menu-label"
186
+ class="cpk-dropdown-menu-label cpk-inspector-button-menu-header"
187
+ >
188
+ <span class="cpk-inspector-button-menu-title">
189
+ {{ labels.assistantMessageToolbarInspectorTitle }}
190
+ </span>
191
+ <CopilotTooltip
192
+ :content="labels.assistantMessageToolbarInspectorLocalOnlyDescription"
193
+ side="top"
194
+ :side-offset="6"
195
+ :delay-duration="1000"
196
+ :content-class="
197
+ dark
198
+ ? 'cpk-inspector-button-local-tooltip dark'
199
+ : 'cpk-inspector-button-local-tooltip'
200
+ "
201
+ >
202
+ <template #default="{ triggerProps }">
203
+ <span
204
+ tabindex="0"
205
+ class="cpk-inspector-button-local-badge"
206
+ v-bind="triggerProps"
207
+ >
208
+ {{ labels.assistantMessageToolbarInspectorLocalOnlyLabel }}
209
+ </span>
210
+ </template>
211
+ <template #content>
212
+ {{ labels.assistantMessageToolbarInspectorLocalOnlyDescription }}
213
+ </template>
214
+ </CopilotTooltip>
215
+ </div>
216
+ <div
217
+ role="separator"
218
+ aria-orientation="horizontal"
219
+ data-slot="dropdown-menu-separator"
220
+ class="cpk-dropdown-menu-separator"
221
+ />
222
+ </template>
223
+ <template #item="{ item }">
224
+ <!-- Matches the Inspector launcher artwork in web-inspector/src/assets/inspector-logo-kite.svg. -->
225
+ <svg
226
+ v-if="isInspectItem(item)"
227
+ aria-hidden="true"
228
+ class="cpk-inspector-button-kite-icon cpk-inspector-button-menu-item-icon"
229
+ viewBox="4.57 3.36 17.8 17.8"
230
+ fill="none"
231
+ >
232
+ <path
233
+ d="M6.36084 10.9855C8.34277 8.393 9.98843 5.82939 10.6204 3.75914C10.6382 3.70281 10.7043 3.67888 10.7534 3.7114C12.9536 5.16894 16.9635 6.12833 20.5086 6.15085C20.5703 6.15124 20.6124 6.2114 20.5895 6.26829C19.4109 9.25938 17.9705 14.6189 17.9148 20.7392C17.9148 20.8301 17.7873 20.8627 17.7419 20.7837C15.7236 17.2522 9.26021 12.2898 6.39414 11.1186C6.34112 11.0968 6.32556 11.0313 6.36084 10.9855Z"
234
+ :fill="`url(#${kiteId}-paint0_linear)`"
235
+ />
236
+ <path
237
+ d="M13.0475 9.39974C9.95016 10.3806 7.11935 10.9259 6.44331 11.0498C6.40027 11.0577 6.39115 11.1172 6.43152 11.134C9.3203 12.3347 15.7516 17.2826 17.7511 20.7998C17.7551 20.8075 17.7647 20.8103 17.7728 20.8068C17.7809 20.803 17.7853 20.793 17.7819 20.7844L13.0475 9.39974Z"
238
+ :fill="`url(#${kiteId}-paint1_linear)`"
239
+ />
240
+ <path
241
+ d="M10.762 3.705C13.4137 5.15161 16.4787 5.80132 20.545 6.14367C20.5703 6.14585 20.5787 6.18008 20.5557 6.19197C20.0359 6.45923 17.0574 7.97512 14.8455 8.78701C14.2524 9.00453 13.6564 9.20632 13.0692 9.39249C13.0562 9.39656 13.0419 9.39015 13.0369 9.37774L10.7005 3.75979C10.6849 3.72196 10.7257 3.68538 10.762 3.705Z"
242
+ :fill="`url(#${kiteId}-paint2_linear)`"
243
+ />
244
+ <path
245
+ d="M10.7145 3.79041L17.8305 20.7659"
246
+ stroke="#513C9F"
247
+ stroke-width="0.17284"
248
+ stroke-linecap="round"
249
+ />
250
+ <path
251
+ d="M6.44531 11.0476C6.44531 11.0476 10.375 10.3422 14.0686 9.06804C17.7623 7.7939 20.5122 6.23373 20.5122 6.23373"
252
+ stroke="#513C9F"
253
+ stroke-width="0.17284"
254
+ stroke-linecap="round"
255
+ />
256
+ <path
257
+ d="M11.6914 5.93518L9.05534 14.7068M9.05534 14.7068H15.3203M9.05534 14.7068L0.15625 26.3646"
258
+ stroke="#ABABAB"
259
+ stroke-width="0.302474"
260
+ stroke-linecap="round"
261
+ />
262
+ <path
263
+ d="M6.02539 23.9646L4.85806 24.1287C5.46272 25.7287 6.70381 26.4276 8.18528 26.4276C11.8147 26.4276 10.707 22.3227 12.8103 22.3227C14.3358 22.3227 13.7155 25.6498 16.9992 25.6498C19.0029 25.6498 19.2028 23.631 18.8607 22.7625C18.8589 22.7572 18.8568 22.7524 18.8538 22.7476L18.3166 21.9253C18.2817 21.8706 18.1968 21.8912 18.1907 21.9562L18.0908 22.9529C18.0838 23.0222 18.0857 23.0913 18.0936 23.1605C18.1764 23.8491 18.2291 25.5202 16.9992 25.5202C15.7015 25.5202 15.3895 22.2362 12.8103 22.2362C9.78393 22.2362 10.1726 26.298 8.31487 26.298C7.08938 26.298 6.15447 24.9153 6.02539 23.9646Z"
264
+ :fill="`url(#${kiteId}-paint3_linear)`"
265
+ />
266
+ <defs>
267
+ <linearGradient
268
+ :id="`${kiteId}-paint0_linear`"
269
+ x1="15.5372"
270
+ y1="5.0278"
271
+ x2="12.0802"
272
+ y2="14.534"
273
+ gradientUnits="userSpaceOnUse"
274
+ >
275
+ <stop stop-color="#6430AB" />
276
+ <stop offset="1" stop-color="#AA89D8" />
277
+ </linearGradient>
278
+ <linearGradient
279
+ :id="`${kiteId}-paint1_linear`"
280
+ x1="12.8583"
281
+ y1="10.3858"
282
+ x2="8.40764"
283
+ y2="18.9846"
284
+ gradientUnits="userSpaceOnUse"
285
+ >
286
+ <stop stop-color="#005DBB" />
287
+ <stop offset="1" stop-color="#3D92E8" />
288
+ </linearGradient>
289
+ <linearGradient
290
+ :id="`${kiteId}-paint2_linear`"
291
+ x1="14.8452"
292
+ y1="5.02774"
293
+ x2="13.5047"
294
+ y2="9.21911"
295
+ gradientUnits="userSpaceOnUse"
296
+ >
297
+ <stop stop-color="#1B70C4" />
298
+ <stop offset="1" stop-color="#54A4F2" />
299
+ </linearGradient>
300
+ <linearGradient
301
+ :id="`${kiteId}-paint3_linear`"
302
+ x1="4.85806"
303
+ y1="24.2455"
304
+ x2="18.9963"
305
+ y2="24.2455"
306
+ gradientUnits="userSpaceOnUse"
307
+ >
308
+ <stop stop-color="#4497EA" />
309
+ <stop offset="0.254755" stop-color="#1463B2" />
310
+ <stop offset="0.498725" stop-color="#0A437D" />
311
+ <stop offset="0.666667" stop-color="#2476C8" />
312
+ <stop offset="0.972542" stop-color="#0C549A" />
313
+ </linearGradient>
314
+ </defs>
315
+ </svg>
316
+ <IconEyeOff
317
+ v-else
318
+ aria-hidden="true"
319
+ class="cpk-inspector-button-menu-item-icon"
320
+ />
321
+ <span>
322
+ <span class="cpk-inspector-button-menu-item-label">{{
323
+ item.label
324
+ }}</span>
325
+ <span class="cpk-inspector-button-menu-item-description">{{
326
+ descriptionFor(item)
327
+ }}</span>
328
+ </span>
329
+ </template>
330
+ </CopilotDropdownMenuContent>
331
+ </template>
@@ -0,0 +1,105 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * A full-screen preview, teleported to `document.body`, as React's
4
+ * `<Lightbox>`. It closes on Escape, a click on the backdrop, or its close
5
+ * button, which is named by `labels.attachmentPreviewCloseButtonLabel`.
6
+ *
7
+ * Beyond React, it is a modal dialog for assistive technology: focus moves to
8
+ * the close button when it opens, Tab stays inside it, and focus returns to
9
+ * the element that opened it (or `returnFocusTo`) when it closes.
10
+ */
11
+ import { computed, nextTick, onBeforeUnmount, onMounted, ref } from "vue";
12
+ import { IconX } from "../icons";
13
+ import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
14
+ import { CopilotChatDefaultLabels } from "../../providers/types";
15
+
16
+ const props = defineProps<{
17
+ /** Accessible name of the dialog, for example the file name. */
18
+ label?: string;
19
+ /** Where focus goes on close. Defaults to the element focused on open. */
20
+ returnFocusTo?: HTMLElement | null;
21
+ }>();
22
+
23
+ const emit = defineEmits<{ close: [] }>();
24
+
25
+ defineSlots<{ default(): unknown }>();
26
+
27
+ const config = useCopilotChatConfiguration();
28
+ const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
29
+
30
+ const root = ref<HTMLElement | null>(null);
31
+ const closeButton = ref<HTMLButtonElement | null>(null);
32
+ let previouslyFocused: HTMLElement | null = null;
33
+
34
+ const FOCUSABLE =
35
+ 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), audio[controls], video[controls], iframe, [tabindex]:not([tabindex="-1"])';
36
+
37
+ function handleKeydown(event: KeyboardEvent) {
38
+ if (event.key === "Escape") emit("close");
39
+ }
40
+
41
+ /** Keeps Tab inside the lightbox while it is open. */
42
+ function handleTab(event: KeyboardEvent) {
43
+ if (event.key !== "Tab" || !root.value) return;
44
+ const focusables = Array.from(
45
+ root.value.querySelectorAll<HTMLElement>(FOCUSABLE),
46
+ );
47
+ const first = focusables[0];
48
+ const last = focusables[focusables.length - 1];
49
+ if (!first || !last) return;
50
+ const active = document.activeElement;
51
+ if (event.shiftKey && (active === first || !root.value.contains(active))) {
52
+ event.preventDefault();
53
+ last.focus();
54
+ } else if (!event.shiftKey && active === last) {
55
+ event.preventDefault();
56
+ first.focus();
57
+ }
58
+ }
59
+
60
+ onMounted(() => {
61
+ if (typeof document === "undefined") return;
62
+ previouslyFocused =
63
+ document.activeElement instanceof HTMLElement
64
+ ? document.activeElement
65
+ : null;
66
+ document.addEventListener("keydown", handleKeydown);
67
+ void nextTick(() => closeButton.value?.focus());
68
+ });
69
+
70
+ onBeforeUnmount(() => {
71
+ if (typeof document === "undefined") return;
72
+ document.removeEventListener("keydown", handleKeydown);
73
+ const target = props.returnFocusTo ?? previouslyFocused;
74
+ if (target?.isConnected) target.focus();
75
+ });
76
+ </script>
77
+
78
+ <template>
79
+ <Teleport to="body">
80
+ <div
81
+ ref="root"
82
+ class="cpk-attachment-lightbox"
83
+ role="dialog"
84
+ aria-modal="true"
85
+ :aria-label="label"
86
+ data-testid="copilot-chat-attachment-lightbox"
87
+ @click="emit('close')"
88
+ @keydown="handleTab"
89
+ >
90
+ <button
91
+ ref="closeButton"
92
+ type="button"
93
+ class="cpk-attachment-lightbox-close-button"
94
+ :aria-label="labels.attachmentPreviewCloseButtonLabel"
95
+ @click.stop="emit('close')"
96
+ >
97
+ <IconX class="cpk-attachment-lightbox-close-icon" aria-hidden="true" />
98
+ </button>
99
+
100
+ <div data-testid="copilot-chat-attachment-lightbox-content" @click.stop>
101
+ <slot />
102
+ </div>
103
+ </div>
104
+ </Teleport>
105
+ </template>