@assistant-ui/react 0.14.18 → 0.14.19

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 (335) hide show
  1. package/dist/client/ExternalThread.d.ts +3 -2
  2. package/dist/client/ExternalThread.d.ts.map +1 -1
  3. package/dist/client/ExternalThread.js +721 -256
  4. package/dist/client/ExternalThread.js.map +1 -1
  5. package/dist/client/InMemoryThreadList.d.ts.map +1 -1
  6. package/dist/client/InMemoryThreadList.js +292 -108
  7. package/dist/client/InMemoryThreadList.js.map +1 -1
  8. package/dist/client/SingleThreadList.js +139 -53
  9. package/dist/client/SingleThreadList.js.map +1 -1
  10. package/dist/context/ReadonlyStore.js.map +1 -1
  11. package/dist/context/providers/MessageProvider.js +38 -5
  12. package/dist/context/providers/MessageProvider.js.map +1 -1
  13. package/dist/context/providers/ThreadViewportProvider.js +76 -20
  14. package/dist/context/providers/ThreadViewportProvider.js.map +1 -1
  15. package/dist/context/react/ThreadViewportContext.js.map +1 -1
  16. package/dist/context/react/utils/createContextHook.js.map +1 -1
  17. package/dist/context/react/utils/createContextStoreHook.js +17 -2
  18. package/dist/context/react/utils/createContextStoreHook.js.map +1 -1
  19. package/dist/context/react/utils/createStateHookForRuntime.js.map +1 -1
  20. package/dist/context/react/utils/ensureBinding.js.map +1 -1
  21. package/dist/context/react/utils/useRuntimeState.js +18 -2
  22. package/dist/context/react/utils/useRuntimeState.js.map +1 -1
  23. package/dist/context/stores/ThreadViewport.js.map +1 -1
  24. package/dist/devtools/DevToolsHooks.js.map +1 -1
  25. package/dist/hooks/useMessageQuote.js.map +1 -1
  26. package/dist/hooks/useMessageTiming.js +4 -1
  27. package/dist/hooks/useMessageTiming.js.map +1 -1
  28. package/dist/hooks/useToolCallElapsed.d.ts +23 -0
  29. package/dist/hooks/useToolCallElapsed.d.ts.map +1 -0
  30. package/dist/hooks/useToolCallElapsed.js +72 -0
  31. package/dist/hooks/useToolCallElapsed.js.map +1 -0
  32. package/dist/index.d.ts +4 -2
  33. package/dist/index.js +3 -1
  34. package/dist/internal.js.map +1 -1
  35. package/dist/legacy-runtime/AssistantRuntimeProvider.js +46 -10
  36. package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
  37. package/dist/legacy-runtime/cloud/auiV0.js.map +1 -1
  38. package/dist/legacy-runtime/cloud/useCloudThreadListRuntime.js +27 -6
  39. package/dist/legacy-runtime/cloud/useCloudThreadListRuntime.js.map +1 -1
  40. package/dist/legacy-runtime/hooks/AssistantContext.js +13 -2
  41. package/dist/legacy-runtime/hooks/AssistantContext.js.map +1 -1
  42. package/dist/legacy-runtime/hooks/AttachmentContext.js +9 -1
  43. package/dist/legacy-runtime/hooks/AttachmentContext.js.map +1 -1
  44. package/dist/legacy-runtime/hooks/ComposerContext.js +9 -1
  45. package/dist/legacy-runtime/hooks/ComposerContext.js.map +1 -1
  46. package/dist/legacy-runtime/hooks/MessageContext.js +12 -2
  47. package/dist/legacy-runtime/hooks/MessageContext.js.map +1 -1
  48. package/dist/legacy-runtime/hooks/MessagePartContext.js +9 -1
  49. package/dist/legacy-runtime/hooks/MessagePartContext.js.map +1 -1
  50. package/dist/legacy-runtime/hooks/ThreadContext.js +33 -5
  51. package/dist/legacy-runtime/hooks/ThreadContext.js.map +1 -1
  52. package/dist/legacy-runtime/hooks/ThreadListItemContext.js +9 -1
  53. package/dist/legacy-runtime/hooks/ThreadListItemContext.js.map +1 -1
  54. package/dist/legacy-runtime/runtime-cores/assistant-transport/commandQueue.js +3 -3
  55. package/dist/legacy-runtime/runtime-cores/assistant-transport/commandQueue.js.map +1 -1
  56. package/dist/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.js +71 -31
  57. package/dist/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.js.map +1 -1
  58. package/dist/legacy-runtime/runtime-cores/assistant-transport/runManager.js.map +1 -1
  59. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js +24 -16
  60. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
  61. package/dist/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.js +17 -12
  62. package/dist/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.js.map +1 -1
  63. package/dist/legacy-runtime/runtime-cores/assistant-transport/useLatestRef.js +17 -3
  64. package/dist/legacy-runtime/runtime-cores/assistant-transport/useLatestRef.js.map +1 -1
  65. package/dist/mcp-apps/McpAppRenderer.js +6 -6
  66. package/dist/mcp-apps/McpAppRenderer.js.map +1 -1
  67. package/dist/mcp-apps/McpAppsRemoteHost.js +3 -3
  68. package/dist/mcp-apps/McpAppsRemoteHost.js.map +1 -1
  69. package/dist/mcp-apps/app-frame.js +33 -14
  70. package/dist/mcp-apps/app-frame.js.map +1 -1
  71. package/dist/mcp-apps/bridge.js.map +1 -1
  72. package/dist/mcp-apps/types.js.map +1 -1
  73. package/dist/mcp-apps/utils.js.map +1 -1
  74. package/dist/model-context/frame/useAssistantFrameHost.js +32 -14
  75. package/dist/model-context/frame/useAssistantFrameHost.js.map +1 -1
  76. package/dist/model-context/makeAssistantVisible.js +64 -26
  77. package/dist/model-context/makeAssistantVisible.js.map +1 -1
  78. package/dist/primitives/actionBar/ActionBarCopy.js +94 -20
  79. package/dist/primitives/actionBar/ActionBarCopy.js.map +1 -1
  80. package/dist/primitives/actionBar/ActionBarEdit.js.map +1 -1
  81. package/dist/primitives/actionBar/ActionBarExportMarkdown.js +105 -37
  82. package/dist/primitives/actionBar/ActionBarExportMarkdown.js.map +1 -1
  83. package/dist/primitives/actionBar/ActionBarFeedbackNegative.js +60 -11
  84. package/dist/primitives/actionBar/ActionBarFeedbackNegative.js.map +1 -1
  85. package/dist/primitives/actionBar/ActionBarFeedbackPositive.js +60 -11
  86. package/dist/primitives/actionBar/ActionBarFeedbackPositive.js.map +1 -1
  87. package/dist/primitives/actionBar/ActionBarInteractionContext.js +3 -1
  88. package/dist/primitives/actionBar/ActionBarInteractionContext.js.map +1 -1
  89. package/dist/primitives/actionBar/ActionBarReload.js.map +1 -1
  90. package/dist/primitives/actionBar/ActionBarRoot.js +84 -25
  91. package/dist/primitives/actionBar/ActionBarRoot.js.map +1 -1
  92. package/dist/primitives/actionBar/ActionBarSpeak.js.map +1 -1
  93. package/dist/primitives/actionBar/ActionBarStopSpeaking.js +45 -14
  94. package/dist/primitives/actionBar/ActionBarStopSpeaking.js.map +1 -1
  95. package/dist/primitives/actionBar/useActionBarFloatStatus.js +22 -10
  96. package/dist/primitives/actionBar/useActionBarFloatStatus.js.map +1 -1
  97. package/dist/primitives/actionBar.js.map +1 -1
  98. package/dist/primitives/actionBarMore/ActionBarMoreContent.js +44 -7
  99. package/dist/primitives/actionBarMore/ActionBarMoreContent.js.map +1 -1
  100. package/dist/primitives/actionBarMore/ActionBarMoreItem.js +28 -6
  101. package/dist/primitives/actionBarMore/ActionBarMoreItem.js.map +1 -1
  102. package/dist/primitives/actionBarMore/ActionBarMoreRoot.js +103 -36
  103. package/dist/primitives/actionBarMore/ActionBarMoreRoot.js.map +1 -1
  104. package/dist/primitives/actionBarMore/ActionBarMoreSeparator.js +28 -6
  105. package/dist/primitives/actionBarMore/ActionBarMoreSeparator.js.map +1 -1
  106. package/dist/primitives/actionBarMore/ActionBarMoreTrigger.js +28 -6
  107. package/dist/primitives/actionBarMore/ActionBarMoreTrigger.js.map +1 -1
  108. package/dist/primitives/actionBarMore/scope.js.map +1 -1
  109. package/dist/primitives/actionBarMore.js.map +1 -1
  110. package/dist/primitives/assistantModal/AssistantModalAnchor.js +27 -6
  111. package/dist/primitives/assistantModal/AssistantModalAnchor.js.map +1 -1
  112. package/dist/primitives/assistantModal/AssistantModalContent.js +71 -10
  113. package/dist/primitives/assistantModal/AssistantModalContent.js.map +1 -1
  114. package/dist/primitives/assistantModal/AssistantModalRoot.js +93 -26
  115. package/dist/primitives/assistantModal/AssistantModalRoot.js.map +1 -1
  116. package/dist/primitives/assistantModal/AssistantModalTrigger.js +27 -6
  117. package/dist/primitives/assistantModal/AssistantModalTrigger.js.map +1 -1
  118. package/dist/primitives/assistantModal/scope.js.map +1 -1
  119. package/dist/primitives/assistantModal.js.map +1 -1
  120. package/dist/primitives/attachment/AttachmentName.js +13 -1
  121. package/dist/primitives/attachment/AttachmentName.js.map +1 -1
  122. package/dist/primitives/attachment/AttachmentRemove.js +11 -4
  123. package/dist/primitives/attachment/AttachmentRemove.js.map +1 -1
  124. package/dist/primitives/attachment/AttachmentRoot.js +13 -4
  125. package/dist/primitives/attachment/AttachmentRoot.js.map +1 -1
  126. package/dist/primitives/attachment/AttachmentThumb.js +20 -9
  127. package/dist/primitives/attachment/AttachmentThumb.js.map +1 -1
  128. package/dist/primitives/attachment.js.map +1 -1
  129. package/dist/primitives/branchPicker/BranchPickerCount.js +14 -2
  130. package/dist/primitives/branchPicker/BranchPickerCount.js.map +1 -1
  131. package/dist/primitives/branchPicker/BranchPickerNext.js.map +1 -1
  132. package/dist/primitives/branchPicker/BranchPickerNumber.js +14 -2
  133. package/dist/primitives/branchPicker/BranchPickerNumber.js.map +1 -1
  134. package/dist/primitives/branchPicker/BranchPickerPrevious.js.map +1 -1
  135. package/dist/primitives/branchPicker/BranchPickerRoot.js +34 -6
  136. package/dist/primitives/branchPicker/BranchPickerRoot.js.map +1 -1
  137. package/dist/primitives/branchPicker.js.map +1 -1
  138. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js +16 -5
  139. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js.map +1 -1
  140. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js +13 -4
  141. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js.map +1 -1
  142. package/dist/primitives/chainOfThought.js.map +1 -1
  143. package/dist/primitives/composer/ComposerAddAttachment.js +37 -24
  144. package/dist/primitives/composer/ComposerAddAttachment.js.map +1 -1
  145. package/dist/primitives/composer/ComposerAttachmentDropzone.js +124 -49
  146. package/dist/primitives/composer/ComposerAttachmentDropzone.js.map +1 -1
  147. package/dist/primitives/composer/ComposerCancel.js.map +1 -1
  148. package/dist/primitives/composer/ComposerDictate.js.map +1 -1
  149. package/dist/primitives/composer/ComposerDictationTranscript.js +32 -7
  150. package/dist/primitives/composer/ComposerDictationTranscript.js.map +1 -1
  151. package/dist/primitives/composer/ComposerInput.js +26 -26
  152. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  153. package/dist/primitives/composer/ComposerInputPluginContext.js +71 -25
  154. package/dist/primitives/composer/ComposerInputPluginContext.js.map +1 -1
  155. package/dist/primitives/composer/ComposerQuote.js +92 -23
  156. package/dist/primitives/composer/ComposerQuote.js.map +1 -1
  157. package/dist/primitives/composer/ComposerRoot.js +45 -11
  158. package/dist/primitives/composer/ComposerRoot.js.map +1 -1
  159. package/dist/primitives/composer/ComposerSend.js +9 -2
  160. package/dist/primitives/composer/ComposerSend.js.map +1 -1
  161. package/dist/primitives/composer/ComposerStopDictation.js +15 -5
  162. package/dist/primitives/composer/ComposerStopDictation.js.map +1 -1
  163. package/dist/primitives/composer/trigger/TriggerPopover.d.ts.map +1 -1
  164. package/dist/primitives/composer/trigger/TriggerPopover.js +215 -75
  165. package/dist/primitives/composer/trigger/TriggerPopover.js.map +1 -1
  166. package/dist/primitives/composer/trigger/TriggerPopoverAction.js.map +1 -1
  167. package/dist/primitives/composer/trigger/TriggerPopoverBack.js +35 -7
  168. package/dist/primitives/composer/trigger/TriggerPopoverBack.js.map +1 -1
  169. package/dist/primitives/composer/trigger/TriggerPopoverCategories.js +134 -28
  170. package/dist/primitives/composer/trigger/TriggerPopoverCategories.js.map +1 -1
  171. package/dist/primitives/composer/trigger/TriggerPopoverDirective.js.map +1 -1
  172. package/dist/primitives/composer/trigger/TriggerPopoverItems.js +132 -28
  173. package/dist/primitives/composer/trigger/TriggerPopoverItems.js.map +1 -1
  174. package/dist/primitives/composer/trigger/TriggerPopoverResource.js +124 -52
  175. package/dist/primitives/composer/trigger/TriggerPopoverResource.js.map +1 -1
  176. package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js +181 -78
  177. package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js.map +1 -1
  178. package/dist/primitives/composer/trigger/detectTrigger.js.map +1 -1
  179. package/dist/primitives/composer/trigger/index.js.map +1 -1
  180. package/dist/primitives/composer/trigger/triggerDetectionResource.js +28 -14
  181. package/dist/primitives/composer/trigger/triggerDetectionResource.js.map +1 -1
  182. package/dist/primitives/composer/trigger/triggerKeyboardResource.js +115 -58
  183. package/dist/primitives/composer/trigger/triggerKeyboardResource.js.map +1 -1
  184. package/dist/primitives/composer/trigger/triggerNavigationResource.js +202 -70
  185. package/dist/primitives/composer/trigger/triggerNavigationResource.js.map +1 -1
  186. package/dist/primitives/composer/trigger/triggerSelectionResource.js +49 -13
  187. package/dist/primitives/composer/trigger/triggerSelectionResource.js.map +1 -1
  188. package/dist/primitives/composer.js.map +1 -1
  189. package/dist/primitives/dropdownMenuRenderPrimitives.js.map +1 -1
  190. package/dist/primitives/error/ErrorMessage.js +28 -6
  191. package/dist/primitives/error/ErrorMessage.js.map +1 -1
  192. package/dist/primitives/error/ErrorRoot.js +14 -5
  193. package/dist/primitives/error/ErrorRoot.js.map +1 -1
  194. package/dist/primitives/error.js.map +1 -1
  195. package/dist/primitives/message/MessageError.js +2 -1
  196. package/dist/primitives/message/MessageError.js.map +1 -1
  197. package/dist/primitives/message/MessageIf.js +50 -20
  198. package/dist/primitives/message/MessageIf.js.map +1 -1
  199. package/dist/primitives/message/MessageParts.js +41 -7
  200. package/dist/primitives/message/MessageParts.js.map +1 -1
  201. package/dist/primitives/message/MessagePartsGrouped.js +399 -94
  202. package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
  203. package/dist/primitives/message/MessageRoot.js +197 -65
  204. package/dist/primitives/message/MessageRoot.js.map +1 -1
  205. package/dist/primitives/message.js.map +1 -1
  206. package/dist/primitives/messagePart/MessagePartImage.js +15 -5
  207. package/dist/primitives/messagePart/MessagePartImage.js.map +1 -1
  208. package/dist/primitives/messagePart/MessagePartText.js +35 -7
  209. package/dist/primitives/messagePart/MessagePartText.js.map +1 -1
  210. package/dist/primitives/messagePart/useMessagePartData.js +5 -4
  211. package/dist/primitives/messagePart/useMessagePartData.js.map +1 -1
  212. package/dist/primitives/messagePart/useMessagePartFile.js +5 -4
  213. package/dist/primitives/messagePart/useMessagePartFile.js.map +1 -1
  214. package/dist/primitives/messagePart/useMessagePartImage.js +5 -4
  215. package/dist/primitives/messagePart/useMessagePartImage.js.map +1 -1
  216. package/dist/primitives/messagePart/useMessagePartReasoning.js +5 -4
  217. package/dist/primitives/messagePart/useMessagePartReasoning.js.map +1 -1
  218. package/dist/primitives/messagePart/useMessagePartSource.js +5 -4
  219. package/dist/primitives/messagePart/useMessagePartSource.js.map +1 -1
  220. package/dist/primitives/messagePart/useMessagePartText.js +5 -4
  221. package/dist/primitives/messagePart/useMessagePartText.js.map +1 -1
  222. package/dist/primitives/messagePart.js.map +1 -1
  223. package/dist/primitives/queueItem/QueueItemRemove.js +11 -4
  224. package/dist/primitives/queueItem/QueueItemRemove.js.map +1 -1
  225. package/dist/primitives/queueItem/QueueItemSteer.js +11 -4
  226. package/dist/primitives/queueItem/QueueItemSteer.js.map +1 -1
  227. package/dist/primitives/queueItem/QueueItemText.js +20 -6
  228. package/dist/primitives/queueItem/QueueItemText.js.map +1 -1
  229. package/dist/primitives/queueItem.js.map +1 -1
  230. package/dist/primitives/reasoning/useScrollLock.js +61 -43
  231. package/dist/primitives/reasoning/useScrollLock.js.map +1 -1
  232. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js +56 -16
  233. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js.map +1 -1
  234. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js +120 -59
  235. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js.map +1 -1
  236. package/dist/primitives/selectionToolbar.js.map +1 -1
  237. package/dist/primitives/suggestion/SuggestionDescription.js +20 -6
  238. package/dist/primitives/suggestion/SuggestionDescription.js.map +1 -1
  239. package/dist/primitives/suggestion/SuggestionTitle.js +20 -6
  240. package/dist/primitives/suggestion/SuggestionTitle.js.map +1 -1
  241. package/dist/primitives/suggestion/SuggestionTrigger.js +39 -26
  242. package/dist/primitives/suggestion/SuggestionTrigger.js.map +1 -1
  243. package/dist/primitives/suggestion.js.map +1 -1
  244. package/dist/primitives/thread/ThreadEmpty.js +6 -2
  245. package/dist/primitives/thread/ThreadEmpty.js.map +1 -1
  246. package/dist/primitives/thread/ThreadIf.js +32 -10
  247. package/dist/primitives/thread/ThreadIf.js.map +1 -1
  248. package/dist/primitives/thread/ThreadRoot.js +13 -4
  249. package/dist/primitives/thread/ThreadRoot.js.map +1 -1
  250. package/dist/primitives/thread/ThreadScrollToBottom.js +24 -6
  251. package/dist/primitives/thread/ThreadScrollToBottom.js.map +1 -1
  252. package/dist/primitives/thread/ThreadSuggestion.js +18 -6
  253. package/dist/primitives/thread/ThreadSuggestion.js.map +1 -1
  254. package/dist/primitives/thread/ThreadViewport.js +185 -47
  255. package/dist/primitives/thread/ThreadViewport.js.map +1 -1
  256. package/dist/primitives/thread/ThreadViewportFooter.js +22 -9
  257. package/dist/primitives/thread/ThreadViewportFooter.js.map +1 -1
  258. package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.js.map +1 -1
  259. package/dist/primitives/thread/topAnchor/createReserveObservers.js.map +1 -1
  260. package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.js.map +1 -1
  261. package/dist/primitives/thread/topAnchor/topAnchorTurn.js.map +1 -1
  262. package/dist/primitives/thread/topAnchor/topAnchorUtils.js.map +1 -1
  263. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js +19 -4
  264. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js.map +1 -1
  265. package/dist/primitives/thread/useThreadViewportAutoScroll.js +16 -16
  266. package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
  267. package/dist/primitives/thread.js.map +1 -1
  268. package/dist/primitives/threadList/ThreadListLoadMore.js.map +1 -1
  269. package/dist/primitives/threadList/ThreadListNew.js +53 -11
  270. package/dist/primitives/threadList/ThreadListNew.js.map +1 -1
  271. package/dist/primitives/threadList/ThreadListRoot.js +13 -4
  272. package/dist/primitives/threadList/ThreadListRoot.js.map +1 -1
  273. package/dist/primitives/threadList.js.map +1 -1
  274. package/dist/primitives/threadListItem/ThreadListItemArchive.js.map +1 -1
  275. package/dist/primitives/threadListItem/ThreadListItemDelete.js.map +1 -1
  276. package/dist/primitives/threadListItem/ThreadListItemRoot.js +26 -7
  277. package/dist/primitives/threadListItem/ThreadListItemRoot.js.map +1 -1
  278. package/dist/primitives/threadListItem/ThreadListItemTrigger.js.map +1 -1
  279. package/dist/primitives/threadListItem/ThreadListItemUnarchive.js.map +1 -1
  280. package/dist/primitives/threadListItem.js.map +1 -1
  281. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js +44 -7
  282. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js.map +1 -1
  283. package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.js +28 -6
  284. package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.js.map +1 -1
  285. package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.js +25 -5
  286. package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.js.map +1 -1
  287. package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.js +28 -6
  288. package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.js.map +1 -1
  289. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js +28 -6
  290. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js.map +1 -1
  291. package/dist/primitives/threadListItemMore/scope.js.map +1 -1
  292. package/dist/primitives/threadListItemMore.js.map +1 -1
  293. package/dist/sandbox-host/SandboxHost.js.map +1 -1
  294. package/dist/tests/remote-thread-list-test-helpers.js.map +1 -1
  295. package/dist/tests/setup.js.map +1 -1
  296. package/dist/unstable/useComposerInputHistory.js.map +1 -1
  297. package/dist/unstable/useMentionAdapter.js.map +1 -1
  298. package/dist/unstable/useMessageStallDetection.d.ts +29 -0
  299. package/dist/unstable/useMessageStallDetection.d.ts.map +1 -0
  300. package/dist/unstable/useMessageStallDetection.js +69 -0
  301. package/dist/unstable/useMessageStallDetection.js.map +1 -0
  302. package/dist/unstable/useSlashCommandAdapter.js.map +1 -1
  303. package/dist/utils/Primitive.js +57 -12
  304. package/dist/utils/Primitive.js.map +1 -1
  305. package/dist/utils/createActionButton.js +23 -7
  306. package/dist/utils/createActionButton.js.map +1 -1
  307. package/dist/utils/getSelectionMessageId.js.map +1 -1
  308. package/dist/utils/hooks/useManagedRef.js +16 -8
  309. package/dist/utils/hooks/useManagedRef.js.map +1 -1
  310. package/dist/utils/hooks/useMediaQuery.js +25 -10
  311. package/dist/utils/hooks/useMediaQuery.js.map +1 -1
  312. package/dist/utils/hooks/useOnResizeContent.js +29 -19
  313. package/dist/utils/hooks/useOnResizeContent.js.map +1 -1
  314. package/dist/utils/hooks/useOnScrollToBottom.js +20 -4
  315. package/dist/utils/hooks/useOnScrollToBottom.js.map +1 -1
  316. package/dist/utils/hooks/useSizeHandle.js +23 -15
  317. package/dist/utils/hooks/useSizeHandle.js.map +1 -1
  318. package/dist/utils/json/is-json-equal.js.map +1 -1
  319. package/dist/utils/json/is-json.js.map +1 -1
  320. package/dist/utils/smooth/SmoothContext.js +41 -11
  321. package/dist/utils/smooth/SmoothContext.js.map +1 -1
  322. package/dist/utils/smooth/useSmooth.js +5 -5
  323. package/dist/utils/smooth/useSmooth.js.map +1 -1
  324. package/dist/utils/useToolArgsFieldStatus.d.ts +2 -2
  325. package/dist/utils/useToolArgsFieldStatus.d.ts.map +1 -1
  326. package/dist/utils/useToolArgsFieldStatus.js +13 -5
  327. package/dist/utils/useToolArgsFieldStatus.js.map +1 -1
  328. package/package.json +6 -6
  329. package/src/client/ExternalThread.ts +81 -52
  330. package/src/client/InMemoryThreadList.ts +12 -14
  331. package/src/hooks/useToolCallElapsed.ts +52 -0
  332. package/src/index.ts +11 -0
  333. package/src/primitives/composer/trigger/TriggerPopover.tsx +4 -5
  334. package/src/tests/toolCallTiming.test.tsx +221 -0
  335. package/src/unstable/useMessageStallDetection.ts +91 -0
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { Primitive } from "../../utils/Primitive.js";
3
3
  import { useAuiState } from "@assistant-ui/store";
4
+ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
4
5
  import { forwardRef } from "@assistant-ui/tap/react-shim";
5
6
  import { jsx } from "react/jsx-runtime";
6
7
  //#region src/primitives/composer/ComposerDictationTranscript.tsx
@@ -19,16 +20,40 @@ import { jsx } from "react/jsx-runtime";
19
20
  * </ComposerPrimitive.If>
20
21
  * ```
21
22
  */
22
- const ComposerPrimitiveDictationTranscript = forwardRef(({ children, ...props }, forwardRef) => {
23
- const transcript = useAuiState((s) => s.composer.dictation?.transcript);
23
+ const ComposerPrimitiveDictationTranscript = forwardRef((t0, forwardRef) => {
24
+ const $ = c(7);
25
+ let children;
26
+ let props;
27
+ if ($[0] !== t0) {
28
+ ({children, ...props} = t0);
29
+ $[0] = t0;
30
+ $[1] = children;
31
+ $[2] = props;
32
+ } else {
33
+ children = $[1];
34
+ props = $[2];
35
+ }
36
+ const transcript = useAuiState(_temp);
24
37
  if (!transcript) return null;
25
- return /* @__PURE__ */ jsx(Primitive.span, {
26
- ...props,
27
- ref: forwardRef,
28
- children: children ?? transcript
29
- });
38
+ const t1 = children ?? transcript;
39
+ let t2;
40
+ if ($[3] !== forwardRef || $[4] !== props || $[5] !== t1) {
41
+ t2 = /* @__PURE__ */ jsx(Primitive.span, {
42
+ ...props,
43
+ ref: forwardRef,
44
+ children: t1
45
+ });
46
+ $[3] = forwardRef;
47
+ $[4] = props;
48
+ $[5] = t1;
49
+ $[6] = t2;
50
+ } else t2 = $[6];
51
+ return t2;
30
52
  });
31
53
  ComposerPrimitiveDictationTranscript.displayName = "ComposerPrimitive.DictationTranscript";
54
+ function _temp(s) {
55
+ return s.composer.dictation?.transcript;
56
+ }
32
57
  //#endregion
33
58
  export { ComposerPrimitiveDictationTranscript };
34
59
 
@@ -1 +1 @@
1
- {"version":3,"file":"ComposerDictationTranscript.js","names":[],"sources":["../../../src/primitives/composer/ComposerDictationTranscript.tsx"],"sourcesContent":["\"use client\";\n\nimport { Primitive } from \"../../utils/Primitive\";\nimport {\n type ComponentRef,\n forwardRef,\n type ComponentPropsWithoutRef,\n} from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\n\nexport namespace ComposerPrimitiveDictationTranscript {\n export type Element = ComponentRef<typeof Primitive.span>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.span>;\n}\n\n/**\n * Renders the current interim (partial) transcript while dictation is active.\n *\n * This component displays real-time feedback of what the user is saying before\n * the transcription is finalized and committed to the composer input.\n *\n * @example\n * ```tsx\n * <ComposerPrimitive.If dictation>\n * <div className=\"dictation-preview\">\n * <ComposerPrimitive.DictationTranscript />\n * </div>\n * </ComposerPrimitive.If>\n * ```\n */\nexport const ComposerPrimitiveDictationTranscript = forwardRef<\n ComposerPrimitiveDictationTranscript.Element,\n ComposerPrimitiveDictationTranscript.Props\n>(({ children, ...props }, forwardRef) => {\n const transcript = useAuiState((s) => s.composer.dictation?.transcript);\n\n if (!transcript) return null;\n\n return (\n <Primitive.span {...props} ref={forwardRef}>\n {children ?? transcript}\n </Primitive.span>\n );\n});\n\nComposerPrimitiveDictationTranscript.displayName =\n \"ComposerPrimitive.DictationTranscript\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA8BA,MAAa,uCAAuC,YAGjD,EAAE,UAAU,GAAG,SAAS,eAAe;CACxC,MAAM,aAAa,aAAa,MAAM,EAAE,SAAS,WAAW,UAAU;CAEtE,IAAI,CAAC,YAAY,OAAO;CAExB,OACE,oBAAC,UAAU,MAAX;EAAgB,GAAI;EAAO,KAAK;YAC7B,YAAY;CACC,CAAA;AAEpB,CAAC;AAED,qCAAqC,cACnC"}
1
+ {"version":3,"file":"ComposerDictationTranscript.js","names":["c","_c","Primitive","ComponentRef","forwardRef","ComponentPropsWithoutRef","useAuiState","ComposerPrimitiveDictationTranscript","Element","span","Props","t0","$","children","props","transcript","_temp","t1","t2","displayName","s","composer","dictation"],"sources":["../../../src/primitives/composer/ComposerDictationTranscript.tsx"],"sourcesContent":["\"use client\";\n\nimport { Primitive } from \"../../utils/Primitive\";\nimport {\n type ComponentRef,\n forwardRef,\n type ComponentPropsWithoutRef,\n} from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\n\nexport namespace ComposerPrimitiveDictationTranscript {\n export type Element = ComponentRef<typeof Primitive.span>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.span>;\n}\n\n/**\n * Renders the current interim (partial) transcript while dictation is active.\n *\n * This component displays real-time feedback of what the user is saying before\n * the transcription is finalized and committed to the composer input.\n *\n * @example\n * ```tsx\n * <ComposerPrimitive.If dictation>\n * <div className=\"dictation-preview\">\n * <ComposerPrimitive.DictationTranscript />\n * </div>\n * </ComposerPrimitive.If>\n * ```\n */\nexport const ComposerPrimitiveDictationTranscript = forwardRef<\n ComposerPrimitiveDictationTranscript.Element,\n ComposerPrimitiveDictationTranscript.Props\n>(({ children, ...props }, forwardRef) => {\n const transcript = useAuiState((s) => s.composer.dictation?.transcript);\n\n if (!transcript) return null;\n\n return (\n <Primitive.span {...props} ref={forwardRef}>\n {children ?? transcript}\n </Primitive.span>\n );\n});\n\nComposerPrimitiveDictationTranscript.displayName =\n \"ComposerPrimitive.DictationTranscript\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAaO,uCAAuCH,YAGlDO,IAAAP,eAAA;CAAA,MAAAQ,IAAAX,EAAA,CAAA;CAAA,IAAAY;CAAA,IAAAC;CAAA,IAAAF,EAAA,OAAAD,IAAA;EAAC,CAAA,CAAAE,aAAAC,SAAAH;EAAsBC,EAAA,KAAAD;EAAAC,EAAA,KAAAC;EAAAD,EAAA,KAAAE;CAAA,OAAA;EAAAD,WAAAD,EAAA;EAAAE,QAAAF,EAAA;CAAA;CACvB,MAAAG,aAAmBT,YAAYU,KAAuC;CAEtE,IAAI,CAACD,YAAU,OAAS;CAInB,MAAAE,KAAAJ,YAAAE;CAAsB,IAAAG;CAAA,IAAAN,EAAA,OAAAR,cAAAQ,EAAA,OAAAE,SAAAF,EAAA,OAAAK,IAAA;EADzBC,KAAA,oBAAA,UAAA,MAAA;GAAA,GAAoBJ;GAAYV,KAAAA;aAC7Ba;EACH,CAAA;EAAiBL,EAAA,KAAAR;EAAAQ,EAAA,KAAAE;EAAAF,EAAA,KAAAK;EAAAL,EAAA,KAAAM;CAAA,OAAAA,KAAAN,EAAA;CAAA,OAFjBM;AAEiB,CAEpB;AAEDX,qCAAqCY,cACnC;AAbA,SAAAH,MAAAI,GAAA;CAAA,OACsCA,EAACC,SAASC,WAAsBP;AAAA"}
@@ -59,7 +59,7 @@ const ComposerPrimitiveInput = forwardRef(({ autoFocus = false, asChild, render,
59
59
  if (!s.composer.isEditing) return "";
60
60
  return s.composer.text;
61
61
  });
62
- const isDisabled = useAuiState((s) => s.thread.isDisabled || s.composer.dictation?.inputDisabled) || disabledProp;
62
+ const isDisabled = useAuiState((s_0) => s_0.thread.isDisabled || s_0.composer.dictation?.inputDisabled) || disabledProp;
63
63
  const textareaRef = useRef(null);
64
64
  const ref = useComposedRefs(forwardedRef, textareaRef);
65
65
  const compositionRef = useRef(false);
@@ -75,37 +75,37 @@ const ComposerPrimitiveInput = forwardRef(({ autoFocus = false, asChild, render,
75
75
  e.preventDefault();
76
76
  }
77
77
  });
78
- const handleKeyPress = (e) => {
78
+ const handleKeyPress = (e_0) => {
79
79
  if (isDisabled) return;
80
- if (e.nativeEvent.isComposing) return;
80
+ if (e_0.nativeEvent.isComposing) return;
81
81
  if (pluginRegistry) {
82
- for (const plugin of pluginRegistry.getPlugins()) if (plugin.handleKeyDown(e)) return;
82
+ for (const plugin_0 of pluginRegistry.getPlugins()) if (plugin_0.handleKeyDown(e_0)) return;
83
83
  }
84
- if (e.key === "Enter") {
84
+ if (e_0.key === "Enter") {
85
85
  const threadState = aui.thread().getState();
86
86
  const hasQueue = threadState.capabilities.queue;
87
- if (e.shiftKey && (e.ctrlKey || e.metaKey) && hasQueue && declaredSubmitMode !== "none" && aui.composer().getState().canSend) {
88
- e.preventDefault();
87
+ if (e_0.shiftKey && (e_0.ctrlKey || e_0.metaKey) && hasQueue && declaredSubmitMode !== "none" && aui.composer().getState().canSend) {
88
+ e_0.preventDefault();
89
89
  aui.composer().send({ steer: true });
90
90
  return;
91
91
  }
92
- if (e.shiftKey) return;
92
+ if (e_0.shiftKey) return;
93
93
  if (threadState.isRunning && !hasQueue) return;
94
94
  let shouldSubmit = false;
95
- if (effectiveSubmitMode === "ctrlEnter") shouldSubmit = e.ctrlKey || e.metaKey;
95
+ if (effectiveSubmitMode === "ctrlEnter") shouldSubmit = e_0.ctrlKey || e_0.metaKey;
96
96
  else if (effectiveSubmitMode === "enter") shouldSubmit = true;
97
97
  if (shouldSubmit) {
98
- e.preventDefault();
98
+ e_0.preventDefault();
99
99
  textareaRef.current?.closest("form")?.requestSubmit();
100
100
  }
101
101
  }
102
102
  };
103
- const handlePaste = async (e) => {
103
+ const handlePaste = async (e_1) => {
104
104
  if (!addAttachmentOnPaste) return;
105
105
  const threadCapabilities = aui.thread().getState().capabilities;
106
- const files = Array.from(e.clipboardData?.files || []);
106
+ const files = Array.from(e_1.clipboardData?.files || []);
107
107
  if (threadCapabilities.attachments && files.length > 0) try {
108
- e.preventDefault();
108
+ e_1.preventDefault();
109
109
  await Promise.all(files.map((file) => aui.composer().addAttachment(file)));
110
110
  } catch (error) {
111
111
  console.error("Error adding attachment:", error);
@@ -151,37 +151,37 @@ const ComposerPrimitiveInput = forwardRef(({ autoFocus = false, asChild, render,
151
151
  ...ariaComboboxProps,
152
152
  ref,
153
153
  disabled: isDisabled,
154
- onChange: composeEventHandlers(onChange, (e) => {
154
+ onChange: composeEventHandlers(onChange, (e_2) => {
155
155
  if (!aui.composer().getState().isEditing) return;
156
- const nativeIsComposing = e.nativeEvent.isComposing === true;
156
+ const nativeIsComposing = e_2.nativeEvent.isComposing === true;
157
157
  if (compositionRef.current && !nativeIsComposing) compositionRef.current = false;
158
158
  const isComposing = nativeIsComposing || compositionRef.current;
159
159
  flushTapSync(() => {
160
- aui.composer().setText(e.target.value);
160
+ aui.composer().setText(e_2.target.value);
161
161
  });
162
162
  if (isComposing) return;
163
- const pos = e.target.selectionStart ?? e.target.value.length;
164
- if (pluginRegistry) for (const plugin of pluginRegistry.getPlugins()) plugin.setCursorPosition(pos);
163
+ const pos = e_2.target.selectionStart ?? e_2.target.value.length;
164
+ if (pluginRegistry) for (const plugin_1 of pluginRegistry.getPlugins()) plugin_1.setCursorPosition(pos);
165
165
  }),
166
166
  onKeyDown: composeEventHandlers(onKeyDown, handleKeyPress),
167
167
  onCompositionStart: composeEventHandlers(rest.onCompositionStart, () => {
168
168
  compositionRef.current = true;
169
169
  }),
170
- onCompositionEnd: composeEventHandlers(rest.onCompositionEnd, (e) => {
170
+ onCompositionEnd: composeEventHandlers(rest.onCompositionEnd, (e_3) => {
171
171
  compositionRef.current = false;
172
172
  if (!aui.composer().getState().isEditing) return;
173
- const target = e.target;
173
+ const target = e_3.target;
174
174
  flushTapSync(() => {
175
175
  aui.composer().setText(target.value);
176
176
  });
177
- const pos = target.selectionStart ?? target.value.length;
178
- if (pluginRegistry) for (const plugin of pluginRegistry.getPlugins()) plugin.setCursorPosition(pos);
177
+ const pos_0 = target.selectionStart ?? target.value.length;
178
+ if (pluginRegistry) for (const plugin_2 of pluginRegistry.getPlugins()) plugin_2.setCursorPosition(pos_0);
179
179
  }),
180
- onSelect: composeEventHandlers(onSelect, (e) => {
180
+ onSelect: composeEventHandlers(onSelect, (e_4) => {
181
181
  if (compositionRef.current) return;
182
- const target = e.target;
183
- const pos = target.selectionStart ?? target.value.length;
184
- if (pluginRegistry) for (const plugin of pluginRegistry.getPlugins()) plugin.setCursorPosition(pos);
182
+ const target_0 = e_4.target;
183
+ const pos_1 = target_0.selectionStart ?? target_0.value.length;
184
+ if (pluginRegistry) for (const plugin_3 of pluginRegistry.getPlugins()) plugin_3.setCursorPosition(pos_1);
185
185
  }),
186
186
  onPaste: composeEventHandlers(onPaste, handlePaste)
187
187
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ComposerInput.js","names":[],"sources":["../../../src/primitives/composer/ComposerInput.tsx"],"sourcesContent":["\"use client\";\n\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { Slot } from \"radix-ui\";\nimport {\n type ClipboardEvent,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n cloneElement,\n isValidElement,\n} from \"react\";\nimport TextareaAutosize, {\n type TextareaAutosizeProps,\n} from \"react-textarea-autosize\";\nimport { useEscapeKeydown } from \"@radix-ui/react-use-escape-keydown\";\nimport { useOnScrollToBottom } from \"../../utils/hooks/useOnScrollToBottom\";\nimport { useMediaQuery } from \"../../utils/hooks/useMediaQuery\";\nimport { useAuiState, useAui } from \"@assistant-ui/store\";\nimport { flushTapSync } from \"@assistant-ui/tap\";\nimport { useComposerInputPluginRegistryOptional } from \"./ComposerInputPluginContext\";\nimport { useTriggerPopoverActiveAriaOptional } from \"./trigger/TriggerPopoverRootContext\";\n\nconst TOUCH_PRIMARY_QUERY = \"(pointer: coarse) and (not (any-pointer: fine))\";\n\nexport namespace ComposerPrimitiveInput {\n export type Element = HTMLTextAreaElement;\n\n type BaseProps = {\n /**\n * Whether to render as a child component using Slot.\n * When true, the component will merge its props with its child.\n */\n asChild?: boolean | undefined;\n /**\n * A React element to use as the input container, with props merged in.\n */\n render?: ReactElement | undefined;\n /**\n * Whether to cancel message composition when Escape is pressed.\n * @default true\n */\n cancelOnEscape?: boolean | undefined;\n /**\n * Whether to automatically focus the input when a new run starts.\n * @default true\n */\n unstable_focusOnRunStart?: boolean | undefined;\n /**\n * Whether to automatically focus the input when scrolling to bottom.\n * @default true\n */\n unstable_focusOnScrollToBottom?: boolean | undefined;\n /**\n * Whether to automatically focus the input when switching threads.\n * @default true\n */\n unstable_focusOnThreadSwitched?: boolean | undefined;\n /**\n * Whether plain Enter on a touch-primary device should insert a newline\n * instead of submitting, detected via\n * `(pointer: coarse) and (not (any-pointer: fine))`. Only takes effect\n * when `submitMode` resolves to `\"enter\"`.\n * @default false\n */\n unstable_insertNewlineOnTouchEnter?: boolean | undefined;\n /**\n * Whether to automatically add pasted files as attachments.\n * @default true\n */\n addAttachmentOnPaste?: boolean | undefined;\n };\n\n type SubmitModeProps =\n | {\n /**\n * Controls how the Enter key submits messages.\n * - \"enter\": Plain Enter submits (Shift+Enter for newline)\n * - \"ctrlEnter\": Ctrl/Cmd+Enter submits (plain Enter for newline)\n * - \"none\": Keyboard submission disabled\n * @default \"enter\"\n */\n submitMode?: \"enter\" | \"ctrlEnter\" | \"none\" | undefined;\n /**\n * @deprecated Use `submitMode` instead\n * @ignore\n */\n submitOnEnter?: never;\n }\n | {\n submitMode?: never;\n /**\n * Whether to submit the message when Enter is pressed (without Shift).\n * @default true\n * @deprecated Use `submitMode` instead. Will be removed in a future version.\n */\n submitOnEnter?: boolean | undefined;\n };\n\n export type Props = TextareaAutosizeProps & BaseProps & SubmitModeProps;\n}\n\n/**\n * A text input component for composing messages.\n *\n * This component provides a rich text input experience with automatic resizing,\n * keyboard shortcuts, file paste support, and intelligent focus management.\n * It integrates with the composer context to manage message state and submission.\n *\n * When rendered inside `Unstable_TriggerPopoverRoot` and a popover is open, the\n * underlying `<textarea>` automatically receives `aria-controls`,\n * `aria-expanded`, `aria-haspopup`, and `aria-activedescendant` for the\n * combobox relationship. These computed attributes override user-provided\n * values for those four ARIA props while the popover is open.\n *\n * @example\n * ```tsx\n * // Ctrl/Cmd+Enter to submit (plain Enter inserts newline)\n * <ComposerPrimitive.Input\n * placeholder=\"Type your message...\"\n * submitMode=\"ctrlEnter\"\n * />\n *\n * // Insert a newline on Enter on touch-primary devices.\n * <ComposerPrimitive.Input\n * placeholder=\"Type your message...\"\n * unstable_insertNewlineOnTouchEnter\n * />\n *\n * // Old API (deprecated, still supported)\n * <ComposerPrimitive.Input\n * placeholder=\"Type your message...\"\n * submitOnEnter={true}\n * />\n * ```\n */\nexport const ComposerPrimitiveInput = forwardRef<\n ComposerPrimitiveInput.Element,\n ComposerPrimitiveInput.Props\n>(\n (\n {\n autoFocus = false,\n asChild,\n render,\n disabled: disabledProp,\n onChange,\n onKeyDown,\n onPaste,\n onSelect,\n submitOnEnter,\n submitMode,\n cancelOnEscape = true,\n unstable_focusOnRunStart = true,\n unstable_focusOnScrollToBottom = true,\n unstable_focusOnThreadSwitched = true,\n unstable_insertNewlineOnTouchEnter = false,\n addAttachmentOnPaste = true,\n ...rest\n },\n forwardedRef,\n ) => {\n const aui = useAui();\n const pluginRegistry = useComposerInputPluginRegistryOptional();\n const activeAria = useTriggerPopoverActiveAriaOptional();\n\n const declaredSubmitMode =\n submitMode ?? (submitOnEnter === false ? \"none\" : \"enter\");\n const isTouchPrimary = useMediaQuery(\n unstable_insertNewlineOnTouchEnter ? TOUCH_PRIMARY_QUERY : null,\n );\n const effectiveSubmitMode =\n unstable_insertNewlineOnTouchEnter &&\n isTouchPrimary &&\n declaredSubmitMode === \"enter\"\n ? \"none\"\n : declaredSubmitMode;\n\n const value = useAuiState((s) => {\n if (!s.composer.isEditing) return \"\";\n return s.composer.text;\n });\n\n const isDisabled =\n useAuiState(\n (s) => s.thread.isDisabled || s.composer.dictation?.inputDisabled,\n ) || disabledProp;\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const ref = useComposedRefs(forwardedRef, textareaRef);\n // suppress text/cursor broadcasts during IME composition\n const compositionRef = useRef(false);\n\n useEscapeKeydown((e) => {\n // Only handle ESC if it originated from within this input\n if (!textareaRef.current?.contains(e.target as Node)) return;\n\n // Let registered plugins (mention, slash command, etc.) handle Escape first\n if (pluginRegistry) {\n for (const plugin of pluginRegistry.getPlugins()) {\n if (plugin.handleKeyDown(e)) return;\n }\n }\n\n if (!cancelOnEscape) return;\n\n const composer = aui.composer();\n if (composer.getState().canCancel) {\n composer.cancel();\n e.preventDefault();\n }\n });\n\n const handleKeyPress = (e: KeyboardEvent) => {\n if (isDisabled) return;\n\n // ignore IME composition events\n if (e.nativeEvent.isComposing) return;\n\n // Let registered plugins (mention, slash command, etc.) handle keyboard events first\n if (pluginRegistry) {\n for (const plugin of pluginRegistry.getPlugins()) {\n if (plugin.handleKeyDown(e)) return;\n }\n }\n\n if (e.key === \"Enter\") {\n const threadState = aui.thread().getState();\n const hasQueue = threadState.capabilities.queue;\n\n // Steer hotkey: Cmd/Ctrl+Shift+Enter (respects submitMode=\"none\" and canSend)\n if (\n e.shiftKey &&\n (e.ctrlKey || e.metaKey) &&\n hasQueue &&\n declaredSubmitMode !== \"none\" &&\n aui.composer().getState().canSend\n ) {\n e.preventDefault();\n aui.composer().send({ steer: true });\n return;\n }\n\n // Regular newline: Shift+Enter\n if (e.shiftKey) return;\n\n // Block submission when running unless queue is supported\n if (threadState.isRunning && !hasQueue) return;\n\n let shouldSubmit = false;\n if (effectiveSubmitMode === \"ctrlEnter\") {\n shouldSubmit = e.ctrlKey || e.metaKey;\n } else if (effectiveSubmitMode === \"enter\") {\n shouldSubmit = true;\n }\n\n if (shouldSubmit) {\n e.preventDefault();\n textareaRef.current?.closest(\"form\")?.requestSubmit();\n }\n }\n };\n\n const handlePaste = async (e: ClipboardEvent<HTMLTextAreaElement>) => {\n if (!addAttachmentOnPaste) return;\n const threadCapabilities = aui.thread().getState().capabilities;\n const files = Array.from(e.clipboardData?.files || []);\n\n if (threadCapabilities.attachments && files.length > 0) {\n try {\n e.preventDefault();\n await Promise.all(\n files.map((file) => aui.composer().addAttachment(file)),\n );\n } catch (error) {\n console.error(\"Error adding attachment:\", error);\n }\n }\n };\n\n const autoFocusEnabled = autoFocus && !isDisabled;\n const focus = useCallback(() => {\n const textarea = textareaRef.current;\n if (!textarea || !autoFocusEnabled) return;\n\n textarea.focus({ preventScroll: true });\n textarea.setSelectionRange(textarea.value.length, textarea.value.length);\n }, [autoFocusEnabled]);\n\n useEffect(() => focus(), [focus]);\n\n useOnScrollToBottom(() => {\n if (\n aui.composer().getState().type === \"thread\" &&\n unstable_focusOnScrollToBottom\n ) {\n focus();\n }\n });\n\n useEffect(() => {\n if (\n aui.composer().getState().type !== \"thread\" ||\n !unstable_focusOnRunStart\n )\n return undefined;\n\n return aui.on(\"thread.runStart\", focus);\n }, [unstable_focusOnRunStart, focus, aui]);\n\n useEffect(() => {\n if (\n aui.composer().getState().type !== \"thread\" ||\n !unstable_focusOnThreadSwitched\n )\n return undefined;\n\n return aui.on(\"threadListItem.switchedTo\", focus);\n }, [unstable_focusOnThreadSwitched, focus, aui]);\n\n const ariaComboboxProps = activeAria\n ? {\n \"aria-controls\": activeAria.popoverId,\n \"aria-expanded\": true as const,\n \"aria-haspopup\": \"listbox\" as const,\n \"aria-activedescendant\": activeAria.highlightedItemId,\n }\n : {};\n\n const inputProps = {\n name: \"input\" as const,\n value,\n ...rest,\n ...ariaComboboxProps,\n ref: ref as React.ForwardedRef<HTMLTextAreaElement>,\n disabled: isDisabled,\n onChange: composeEventHandlers(\n onChange,\n (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (!aui.composer().getState().isEditing) return;\n const nativeIsComposing =\n (e.nativeEvent as { isComposing?: boolean }).isComposing === true;\n // recover stuck compositionRef when the browser drops compositionend\n if (compositionRef.current && !nativeIsComposing) {\n compositionRef.current = false;\n }\n const isComposing = nativeIsComposing || compositionRef.current;\n // keep controlled value in sync mid-IME so react does not reset the textarea to a stale value\n flushTapSync(() => {\n aui.composer().setText(e.target.value);\n });\n if (isComposing) return;\n const pos = e.target.selectionStart ?? e.target.value.length;\n if (pluginRegistry) {\n for (const plugin of pluginRegistry.getPlugins()) {\n plugin.setCursorPosition(pos);\n }\n }\n },\n ),\n onKeyDown: composeEventHandlers(onKeyDown, handleKeyPress),\n onCompositionStart: composeEventHandlers(\n (rest as { onCompositionStart?: React.CompositionEventHandler })\n .onCompositionStart,\n () => {\n compositionRef.current = true;\n },\n ),\n onCompositionEnd: composeEventHandlers(\n (rest as { onCompositionEnd?: React.CompositionEventHandler })\n .onCompositionEnd,\n (e: React.CompositionEvent<HTMLTextAreaElement>) => {\n compositionRef.current = false;\n if (!aui.composer().getState().isEditing) return;\n const target = e.target as HTMLTextAreaElement;\n flushTapSync(() => {\n aui.composer().setText(target.value);\n });\n const pos = target.selectionStart ?? target.value.length;\n if (pluginRegistry) {\n for (const plugin of pluginRegistry.getPlugins()) {\n plugin.setCursorPosition(pos);\n }\n }\n },\n ),\n onSelect: composeEventHandlers(\n onSelect,\n (e: React.SyntheticEvent<HTMLTextAreaElement>) => {\n if (compositionRef.current) return;\n const target = e.target as HTMLTextAreaElement;\n const pos = target.selectionStart ?? target.value.length;\n if (pluginRegistry) {\n for (const plugin of pluginRegistry.getPlugins()) {\n plugin.setCursorPosition(pos);\n }\n }\n },\n ),\n onPaste: composeEventHandlers(onPaste, handlePaste),\n };\n\n if (render && isValidElement(render)) {\n const renderChildren =\n (rest as any).children !== undefined\n ? ((rest as any).children as ReactNode)\n : ((render.props as Record<string, unknown>).children as ReactNode);\n return (\n <Slot.Root {...inputProps}>\n {cloneElement(render, undefined, renderChildren)}\n </Slot.Root>\n );\n }\n\n const Component = asChild ? Slot.Root : TextareaAutosize;\n return <Component {...inputProps} />;\n },\n);\n\nComposerPrimitiveInput.displayName = \"ComposerPrimitive.Input\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"ComposerInput.js","names":["composeEventHandlers","useComposedRefs","Slot","ClipboardEvent","KeyboardEvent","ReactElement","ReactNode","forwardRef","useCallback","useEffect","useRef","cloneElement","isValidElement","TextareaAutosize","TextareaAutosizeProps","useEscapeKeydown","useOnScrollToBottom","useMediaQuery","useAuiState","useAui","flushTapSync","useComposerInputPluginRegistryOptional","useTriggerPopoverActiveAriaOptional","TOUCH_PRIMARY_QUERY","ComposerPrimitiveInput","Element","HTMLTextAreaElement","BaseProps","asChild","render","cancelOnEscape","unstable_focusOnRunStart","unstable_focusOnScrollToBottom","unstable_focusOnThreadSwitched","unstable_insertNewlineOnTouchEnter","addAttachmentOnPaste","SubmitModeProps","submitMode","submitOnEnter","Props","autoFocus","disabled","disabledProp","onChange","onKeyDown","onPaste","onSelect","rest","forwardedRef","aui","pluginRegistry","activeAria","declaredSubmitMode","isTouchPrimary","effectiveSubmitMode","value","s","composer","isEditing","text","isDisabled","thread","dictation","inputDisabled","textareaRef","ref","compositionRef","e","current","contains","target","Node","plugin","getPlugins","handleKeyDown","getState","canCancel","cancel","preventDefault","handleKeyPress","nativeEvent","isComposing","key","threadState","hasQueue","capabilities","queue","shiftKey","ctrlKey","metaKey","canSend","send","steer","isRunning","shouldSubmit","closest","requestSubmit","handlePaste","threadCapabilities","files","Array","from","clipboardData","attachments","length","Promise","all","map","file","addAttachment","error","console","autoFocusEnabled","focus","textarea","preventScroll","setSelectionRange","type","undefined","on","ariaComboboxProps","popoverId","const","highlightedItemId","inputProps","name","React","ForwardedRef","ChangeEvent","nativeIsComposing","setText","pos","selectionStart","setCursorPosition","onCompositionStart","CompositionEventHandler","onCompositionEnd","CompositionEvent","SyntheticEvent","renderChildren","children","props","Record","Component","Root","displayName"],"sources":["../../../src/primitives/composer/ComposerInput.tsx"],"sourcesContent":["\"use client\";\n\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { Slot } from \"radix-ui\";\nimport {\n type ClipboardEvent,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n cloneElement,\n isValidElement,\n} from \"react\";\nimport TextareaAutosize, {\n type TextareaAutosizeProps,\n} from \"react-textarea-autosize\";\nimport { useEscapeKeydown } from \"@radix-ui/react-use-escape-keydown\";\nimport { useOnScrollToBottom } from \"../../utils/hooks/useOnScrollToBottom\";\nimport { useMediaQuery } from \"../../utils/hooks/useMediaQuery\";\nimport { useAuiState, useAui } from \"@assistant-ui/store\";\nimport { flushTapSync } from \"@assistant-ui/tap\";\nimport { useComposerInputPluginRegistryOptional } from \"./ComposerInputPluginContext\";\nimport { useTriggerPopoverActiveAriaOptional } from \"./trigger/TriggerPopoverRootContext\";\n\nconst TOUCH_PRIMARY_QUERY = \"(pointer: coarse) and (not (any-pointer: fine))\";\n\nexport namespace ComposerPrimitiveInput {\n export type Element = HTMLTextAreaElement;\n\n type BaseProps = {\n /**\n * Whether to render as a child component using Slot.\n * When true, the component will merge its props with its child.\n */\n asChild?: boolean | undefined;\n /**\n * A React element to use as the input container, with props merged in.\n */\n render?: ReactElement | undefined;\n /**\n * Whether to cancel message composition when Escape is pressed.\n * @default true\n */\n cancelOnEscape?: boolean | undefined;\n /**\n * Whether to automatically focus the input when a new run starts.\n * @default true\n */\n unstable_focusOnRunStart?: boolean | undefined;\n /**\n * Whether to automatically focus the input when scrolling to bottom.\n * @default true\n */\n unstable_focusOnScrollToBottom?: boolean | undefined;\n /**\n * Whether to automatically focus the input when switching threads.\n * @default true\n */\n unstable_focusOnThreadSwitched?: boolean | undefined;\n /**\n * Whether plain Enter on a touch-primary device should insert a newline\n * instead of submitting, detected via\n * `(pointer: coarse) and (not (any-pointer: fine))`. Only takes effect\n * when `submitMode` resolves to `\"enter\"`.\n * @default false\n */\n unstable_insertNewlineOnTouchEnter?: boolean | undefined;\n /**\n * Whether to automatically add pasted files as attachments.\n * @default true\n */\n addAttachmentOnPaste?: boolean | undefined;\n };\n\n type SubmitModeProps =\n | {\n /**\n * Controls how the Enter key submits messages.\n * - \"enter\": Plain Enter submits (Shift+Enter for newline)\n * - \"ctrlEnter\": Ctrl/Cmd+Enter submits (plain Enter for newline)\n * - \"none\": Keyboard submission disabled\n * @default \"enter\"\n */\n submitMode?: \"enter\" | \"ctrlEnter\" | \"none\" | undefined;\n /**\n * @deprecated Use `submitMode` instead\n * @ignore\n */\n submitOnEnter?: never;\n }\n | {\n submitMode?: never;\n /**\n * Whether to submit the message when Enter is pressed (without Shift).\n * @default true\n * @deprecated Use `submitMode` instead. Will be removed in a future version.\n */\n submitOnEnter?: boolean | undefined;\n };\n\n export type Props = TextareaAutosizeProps & BaseProps & SubmitModeProps;\n}\n\n/**\n * A text input component for composing messages.\n *\n * This component provides a rich text input experience with automatic resizing,\n * keyboard shortcuts, file paste support, and intelligent focus management.\n * It integrates with the composer context to manage message state and submission.\n *\n * When rendered inside `Unstable_TriggerPopoverRoot` and a popover is open, the\n * underlying `<textarea>` automatically receives `aria-controls`,\n * `aria-expanded`, `aria-haspopup`, and `aria-activedescendant` for the\n * combobox relationship. These computed attributes override user-provided\n * values for those four ARIA props while the popover is open.\n *\n * @example\n * ```tsx\n * // Ctrl/Cmd+Enter to submit (plain Enter inserts newline)\n * <ComposerPrimitive.Input\n * placeholder=\"Type your message...\"\n * submitMode=\"ctrlEnter\"\n * />\n *\n * // Insert a newline on Enter on touch-primary devices.\n * <ComposerPrimitive.Input\n * placeholder=\"Type your message...\"\n * unstable_insertNewlineOnTouchEnter\n * />\n *\n * // Old API (deprecated, still supported)\n * <ComposerPrimitive.Input\n * placeholder=\"Type your message...\"\n * submitOnEnter={true}\n * />\n * ```\n */\nexport const ComposerPrimitiveInput = forwardRef<\n ComposerPrimitiveInput.Element,\n ComposerPrimitiveInput.Props\n>(\n (\n {\n autoFocus = false,\n asChild,\n render,\n disabled: disabledProp,\n onChange,\n onKeyDown,\n onPaste,\n onSelect,\n submitOnEnter,\n submitMode,\n cancelOnEscape = true,\n unstable_focusOnRunStart = true,\n unstable_focusOnScrollToBottom = true,\n unstable_focusOnThreadSwitched = true,\n unstable_insertNewlineOnTouchEnter = false,\n addAttachmentOnPaste = true,\n ...rest\n },\n forwardedRef,\n ) => {\n const aui = useAui();\n const pluginRegistry = useComposerInputPluginRegistryOptional();\n const activeAria = useTriggerPopoverActiveAriaOptional();\n\n const declaredSubmitMode =\n submitMode ?? (submitOnEnter === false ? \"none\" : \"enter\");\n const isTouchPrimary = useMediaQuery(\n unstable_insertNewlineOnTouchEnter ? TOUCH_PRIMARY_QUERY : null,\n );\n const effectiveSubmitMode =\n unstable_insertNewlineOnTouchEnter &&\n isTouchPrimary &&\n declaredSubmitMode === \"enter\"\n ? \"none\"\n : declaredSubmitMode;\n\n const value = useAuiState((s) => {\n if (!s.composer.isEditing) return \"\";\n return s.composer.text;\n });\n\n const isDisabled =\n useAuiState(\n (s) => s.thread.isDisabled || s.composer.dictation?.inputDisabled,\n ) || disabledProp;\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const ref = useComposedRefs(forwardedRef, textareaRef);\n // suppress text/cursor broadcasts during IME composition\n const compositionRef = useRef(false);\n\n useEscapeKeydown((e) => {\n // Only handle ESC if it originated from within this input\n if (!textareaRef.current?.contains(e.target as Node)) return;\n\n // Let registered plugins (mention, slash command, etc.) handle Escape first\n if (pluginRegistry) {\n for (const plugin of pluginRegistry.getPlugins()) {\n if (plugin.handleKeyDown(e)) return;\n }\n }\n\n if (!cancelOnEscape) return;\n\n const composer = aui.composer();\n if (composer.getState().canCancel) {\n composer.cancel();\n e.preventDefault();\n }\n });\n\n const handleKeyPress = (e: KeyboardEvent) => {\n if (isDisabled) return;\n\n // ignore IME composition events\n if (e.nativeEvent.isComposing) return;\n\n // Let registered plugins (mention, slash command, etc.) handle keyboard events first\n if (pluginRegistry) {\n for (const plugin of pluginRegistry.getPlugins()) {\n if (plugin.handleKeyDown(e)) return;\n }\n }\n\n if (e.key === \"Enter\") {\n const threadState = aui.thread().getState();\n const hasQueue = threadState.capabilities.queue;\n\n // Steer hotkey: Cmd/Ctrl+Shift+Enter (respects submitMode=\"none\" and canSend)\n if (\n e.shiftKey &&\n (e.ctrlKey || e.metaKey) &&\n hasQueue &&\n declaredSubmitMode !== \"none\" &&\n aui.composer().getState().canSend\n ) {\n e.preventDefault();\n aui.composer().send({ steer: true });\n return;\n }\n\n // Regular newline: Shift+Enter\n if (e.shiftKey) return;\n\n // Block submission when running unless queue is supported\n if (threadState.isRunning && !hasQueue) return;\n\n let shouldSubmit = false;\n if (effectiveSubmitMode === \"ctrlEnter\") {\n shouldSubmit = e.ctrlKey || e.metaKey;\n } else if (effectiveSubmitMode === \"enter\") {\n shouldSubmit = true;\n }\n\n if (shouldSubmit) {\n e.preventDefault();\n textareaRef.current?.closest(\"form\")?.requestSubmit();\n }\n }\n };\n\n const handlePaste = async (e: ClipboardEvent<HTMLTextAreaElement>) => {\n if (!addAttachmentOnPaste) return;\n const threadCapabilities = aui.thread().getState().capabilities;\n const files = Array.from(e.clipboardData?.files || []);\n\n if (threadCapabilities.attachments && files.length > 0) {\n try {\n e.preventDefault();\n await Promise.all(\n files.map((file) => aui.composer().addAttachment(file)),\n );\n } catch (error) {\n console.error(\"Error adding attachment:\", error);\n }\n }\n };\n\n const autoFocusEnabled = autoFocus && !isDisabled;\n const focus = useCallback(() => {\n const textarea = textareaRef.current;\n if (!textarea || !autoFocusEnabled) return;\n\n textarea.focus({ preventScroll: true });\n textarea.setSelectionRange(textarea.value.length, textarea.value.length);\n }, [autoFocusEnabled]);\n\n useEffect(() => focus(), [focus]);\n\n useOnScrollToBottom(() => {\n if (\n aui.composer().getState().type === \"thread\" &&\n unstable_focusOnScrollToBottom\n ) {\n focus();\n }\n });\n\n useEffect(() => {\n if (\n aui.composer().getState().type !== \"thread\" ||\n !unstable_focusOnRunStart\n )\n return undefined;\n\n return aui.on(\"thread.runStart\", focus);\n }, [unstable_focusOnRunStart, focus, aui]);\n\n useEffect(() => {\n if (\n aui.composer().getState().type !== \"thread\" ||\n !unstable_focusOnThreadSwitched\n )\n return undefined;\n\n return aui.on(\"threadListItem.switchedTo\", focus);\n }, [unstable_focusOnThreadSwitched, focus, aui]);\n\n const ariaComboboxProps = activeAria\n ? {\n \"aria-controls\": activeAria.popoverId,\n \"aria-expanded\": true as const,\n \"aria-haspopup\": \"listbox\" as const,\n \"aria-activedescendant\": activeAria.highlightedItemId,\n }\n : {};\n\n const inputProps = {\n name: \"input\" as const,\n value,\n ...rest,\n ...ariaComboboxProps,\n ref: ref as React.ForwardedRef<HTMLTextAreaElement>,\n disabled: isDisabled,\n onChange: composeEventHandlers(\n onChange,\n (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (!aui.composer().getState().isEditing) return;\n const nativeIsComposing =\n (e.nativeEvent as { isComposing?: boolean }).isComposing === true;\n // recover stuck compositionRef when the browser drops compositionend\n if (compositionRef.current && !nativeIsComposing) {\n compositionRef.current = false;\n }\n const isComposing = nativeIsComposing || compositionRef.current;\n // keep controlled value in sync mid-IME so react does not reset the textarea to a stale value\n flushTapSync(() => {\n aui.composer().setText(e.target.value);\n });\n if (isComposing) return;\n const pos = e.target.selectionStart ?? e.target.value.length;\n if (pluginRegistry) {\n for (const plugin of pluginRegistry.getPlugins()) {\n plugin.setCursorPosition(pos);\n }\n }\n },\n ),\n onKeyDown: composeEventHandlers(onKeyDown, handleKeyPress),\n onCompositionStart: composeEventHandlers(\n (rest as { onCompositionStart?: React.CompositionEventHandler })\n .onCompositionStart,\n () => {\n compositionRef.current = true;\n },\n ),\n onCompositionEnd: composeEventHandlers(\n (rest as { onCompositionEnd?: React.CompositionEventHandler })\n .onCompositionEnd,\n (e: React.CompositionEvent<HTMLTextAreaElement>) => {\n compositionRef.current = false;\n if (!aui.composer().getState().isEditing) return;\n const target = e.target as HTMLTextAreaElement;\n flushTapSync(() => {\n aui.composer().setText(target.value);\n });\n const pos = target.selectionStart ?? target.value.length;\n if (pluginRegistry) {\n for (const plugin of pluginRegistry.getPlugins()) {\n plugin.setCursorPosition(pos);\n }\n }\n },\n ),\n onSelect: composeEventHandlers(\n onSelect,\n (e: React.SyntheticEvent<HTMLTextAreaElement>) => {\n if (compositionRef.current) return;\n const target = e.target as HTMLTextAreaElement;\n const pos = target.selectionStart ?? target.value.length;\n if (pluginRegistry) {\n for (const plugin of pluginRegistry.getPlugins()) {\n plugin.setCursorPosition(pos);\n }\n }\n },\n ),\n onPaste: composeEventHandlers(onPaste, handlePaste),\n };\n\n if (render && isValidElement(render)) {\n const renderChildren =\n (rest as any).children !== undefined\n ? ((rest as any).children as ReactNode)\n : ((render.props as Record<string, unknown>).children as ReactNode);\n return (\n <Slot.Root {...inputProps}>\n {cloneElement(render, undefined, renderChildren)}\n </Slot.Root>\n );\n }\n\n const Component = asChild ? Slot.Root : TextareaAutosize;\n return <Component {...inputProps} />;\n },\n);\n\nComposerPrimitiveInput.displayName = \"ComposerPrimitive.Input\";\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  "use client";
2
- import { createContext, useCallback, useContext, useMemo, useRef } from "@assistant-ui/tap/react-shim";
2
+ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
3
+ import { createContext, useContext, useRef } from "@assistant-ui/tap/react-shim";
3
4
  import { jsx } from "react/jsx-runtime";
4
5
  //#region src/primitives/composer/ComposerInputPluginContext.tsx
5
6
  const ComposerInputPluginRegistryContext = createContext(null);
@@ -11,33 +12,78 @@ const useComposerInputPluginRegistry = () => {
11
12
  const useComposerInputPluginRegistryOptional = () => {
12
13
  return useContext(ComposerInputPluginRegistryContext);
13
14
  };
14
- const ComposerInputPluginProvider = ({ children }) => {
15
- const pluginsRef = useRef(/* @__PURE__ */ new Map());
16
- const snapshotRef = useRef([]);
17
- const refreshSnapshot = useCallback(() => {
18
- const entries = Array.from(pluginsRef.current.entries());
19
- entries.sort((a, b) => b[1] - a[1]);
20
- snapshotRef.current = entries.map(([plugin]) => plugin);
21
- }, []);
22
- const register = useCallback((plugin, opts) => {
23
- const priority = opts?.priority ?? 0;
24
- pluginsRef.current.set(plugin, priority);
25
- refreshSnapshot();
26
- return () => {
27
- pluginsRef.current.delete(plugin);
15
+ const ComposerInputPluginProvider = (t0) => {
16
+ const $ = c(8);
17
+ const { children } = t0;
18
+ let t1;
19
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
20
+ t1 = /* @__PURE__ */ new Map();
21
+ $[0] = t1;
22
+ } else t1 = $[0];
23
+ const pluginsRef = useRef(t1);
24
+ let t2;
25
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
26
+ t2 = [];
27
+ $[1] = t2;
28
+ } else t2 = $[1];
29
+ const snapshotRef = useRef(t2);
30
+ let t3;
31
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
32
+ t3 = () => {
33
+ const entries = Array.from(pluginsRef.current.entries());
34
+ entries.sort(_temp);
35
+ snapshotRef.current = entries.map(_temp2);
36
+ };
37
+ $[2] = t3;
38
+ } else t3 = $[2];
39
+ const refreshSnapshot = t3;
40
+ let t4;
41
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
42
+ t4 = (plugin_0, opts) => {
43
+ const priority = opts?.priority ?? 0;
44
+ pluginsRef.current.set(plugin_0, priority);
28
45
  refreshSnapshot();
46
+ return () => {
47
+ pluginsRef.current.delete(plugin_0);
48
+ refreshSnapshot();
49
+ };
50
+ };
51
+ $[3] = t4;
52
+ } else t4 = $[3];
53
+ const register = t4;
54
+ let t5;
55
+ if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
56
+ t5 = () => snapshotRef.current;
57
+ $[4] = t5;
58
+ } else t5 = $[4];
59
+ const getPlugins = t5;
60
+ let t6;
61
+ if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
62
+ t6 = {
63
+ register,
64
+ getPlugins
29
65
  };
30
- }, [refreshSnapshot]);
31
- const getPlugins = useCallback(() => snapshotRef.current, []);
32
- const registry = useMemo(() => ({
33
- register,
34
- getPlugins
35
- }), [register, getPlugins]);
36
- return /* @__PURE__ */ jsx(ComposerInputPluginRegistryContext.Provider, {
37
- value: registry,
38
- children
39
- });
66
+ $[5] = t6;
67
+ } else t6 = $[5];
68
+ const registry = t6;
69
+ let t7;
70
+ if ($[6] !== children) {
71
+ t7 = /* @__PURE__ */ jsx(ComposerInputPluginRegistryContext.Provider, {
72
+ value: registry,
73
+ children
74
+ });
75
+ $[6] = children;
76
+ $[7] = t7;
77
+ } else t7 = $[7];
78
+ return t7;
40
79
  };
80
+ function _temp(a, b) {
81
+ return b[1] - a[1];
82
+ }
83
+ function _temp2(t0) {
84
+ const [plugin] = t0;
85
+ return plugin;
86
+ }
41
87
  //#endregion
42
88
  export { ComposerInputPluginProvider, useComposerInputPluginRegistry, useComposerInputPluginRegistryOptional };
43
89
 
@@ -1 +1 @@
1
- {"version":3,"file":"ComposerInputPluginContext.js","names":[],"sources":["../../../src/primitives/composer/ComposerInputPluginContext.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n useContext,\n useRef,\n useCallback,\n useMemo,\n type ReactNode,\n type FC,\n} from \"react\";\n\n/**\n * A plugin that intercepts keyboard events and cursor changes in the composer\n * input. Used by trigger popover declarations to handle popover navigation\n * without ComposerInput knowing about specific triggers.\n */\nexport type ComposerInputPlugin = {\n /** Handle a key event. Return true if consumed (stops propagation to other plugins and default behavior). */\n handleKeyDown(e: {\n readonly key: string;\n readonly shiftKey: boolean;\n readonly ctrlKey?: boolean;\n readonly metaKey?: boolean;\n readonly nativeEvent?: { isComposing?: boolean };\n preventDefault(): void;\n }): boolean;\n\n /** Called on every cursor position change (selection change / text change). */\n setCursorPosition(pos: number): void;\n};\n\n/** Options for registering a plugin. */\nexport type ComposerInputPluginRegisterOptions = {\n /**\n * Relative priority. Plugins with higher priority receive events first.\n * @default 0\n */\n priority?: number;\n};\n\n// Ref-based registry: plugins are read imperatively at event time, so register/unregister does not trigger re-renders.\nexport type ComposerInputPluginRegistry = {\n register(\n plugin: ComposerInputPlugin,\n opts?: ComposerInputPluginRegisterOptions,\n ): () => void;\n getPlugins(): readonly ComposerInputPlugin[];\n};\n\nconst ComposerInputPluginRegistryContext =\n createContext<ComposerInputPluginRegistry | null>(null);\n\nexport const useComposerInputPluginRegistry =\n (): ComposerInputPluginRegistry => {\n const ctx = useContext(ComposerInputPluginRegistryContext);\n if (!ctx)\n throw new Error(\n \"useComposerInputPluginRegistry must be used within a ComposerInputPluginProvider\",\n );\n return ctx;\n };\n\nexport const useComposerInputPluginRegistryOptional =\n (): ComposerInputPluginRegistry | null => {\n return useContext(ComposerInputPluginRegistryContext);\n };\n\nexport const ComposerInputPluginProvider: FC<{ children: ReactNode }> = ({\n children,\n}) => {\n const pluginsRef = useRef<Map<ComposerInputPlugin, number>>(new Map());\n const snapshotRef = useRef<readonly ComposerInputPlugin[]>([]);\n\n const refreshSnapshot = useCallback(() => {\n const entries = Array.from(pluginsRef.current.entries());\n // Sort by priority descending; stable insertion order for equal priorities.\n entries.sort((a, b) => b[1] - a[1]);\n snapshotRef.current = entries.map(([plugin]) => plugin);\n }, []);\n\n const register = useCallback(\n (\n plugin: ComposerInputPlugin,\n opts?: ComposerInputPluginRegisterOptions,\n ) => {\n const priority = opts?.priority ?? 0;\n pluginsRef.current.set(plugin, priority);\n refreshSnapshot();\n return () => {\n pluginsRef.current.delete(plugin);\n refreshSnapshot();\n };\n },\n [refreshSnapshot],\n );\n\n const getPlugins = useCallback(\n (): readonly ComposerInputPlugin[] => snapshotRef.current,\n [],\n );\n\n const registry = useMemo<ComposerInputPluginRegistry>(\n () => ({ register, getPlugins }),\n [register, getPlugins],\n );\n\n return (\n <ComposerInputPluginRegistryContext.Provider value={registry}>\n {children}\n </ComposerInputPluginRegistryContext.Provider>\n );\n};\n"],"mappings":";;;;AAkDA,MAAM,qCACJ,cAAkD,IAAI;AAExD,MAAa,uCACwB;CACjC,MAAM,MAAM,WAAW,kCAAkC;CACzD,IAAI,CAAC,KACH,MAAM,IAAI,MACR,kFACF;CACF,OAAO;AACT;AAEF,MAAa,+CAC+B;CACxC,OAAO,WAAW,kCAAkC;AACtD;AAEF,MAAa,+BAA4D,EACvE,eACI;CACJ,MAAM,aAAa,uBAAyC,IAAI,IAAI,CAAC;CACrE,MAAM,cAAc,OAAuC,CAAC,CAAC;CAE7D,MAAM,kBAAkB,kBAAkB;EACxC,MAAM,UAAU,MAAM,KAAK,WAAW,QAAQ,QAAQ,CAAC;EAEvD,QAAQ,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE;EAClC,YAAY,UAAU,QAAQ,KAAK,CAAC,YAAY,MAAM;CACxD,GAAG,CAAC,CAAC;CAEL,MAAM,WAAW,aAEb,QACA,SACG;EACH,MAAM,WAAW,MAAM,YAAY;EACnC,WAAW,QAAQ,IAAI,QAAQ,QAAQ;EACvC,gBAAgB;EAChB,aAAa;GACX,WAAW,QAAQ,OAAO,MAAM;GAChC,gBAAgB;EAClB;CACF,GACA,CAAC,eAAe,CAClB;CAEA,MAAM,aAAa,kBACqB,YAAY,SAClD,CAAC,CACH;CAEA,MAAM,WAAW,eACR;EAAE;EAAU;CAAW,IAC9B,CAAC,UAAU,UAAU,CACvB;CAEA,OACE,oBAAC,mCAAmC,UAApC;EAA6C,OAAO;EACjD;CAC0C,CAAA;AAEjD"}
1
+ {"version":3,"file":"ComposerInputPluginContext.js","names":["c","_c","createContext","useContext","useRef","useCallback","useMemo","ReactNode","FC","ComposerInputPlugin","handleKeyDown","e","key","shiftKey","ctrlKey","metaKey","nativeEvent","isComposing","preventDefault","setCursorPosition","pos","ComposerInputPluginRegisterOptions","priority","ComposerInputPluginRegistry","register","plugin","opts","getPlugins","ComposerInputPluginRegistryContext","useComposerInputPluginRegistry","ctx","Error","useComposerInputPluginRegistryOptional","ComposerInputPluginProvider","children","t0","$","t1","Symbol","for","Map","pluginsRef","t2","snapshotRef","t3","entries","Array","from","current","sort","_temp","map","_temp2","refreshSnapshot","t4","plugin_0","set","delete","t5","t6","registry","t7","a","b"],"sources":["../../../src/primitives/composer/ComposerInputPluginContext.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n useContext,\n useRef,\n useCallback,\n useMemo,\n type ReactNode,\n type FC,\n} from \"react\";\n\n/**\n * A plugin that intercepts keyboard events and cursor changes in the composer\n * input. Used by trigger popover declarations to handle popover navigation\n * without ComposerInput knowing about specific triggers.\n */\nexport type ComposerInputPlugin = {\n /** Handle a key event. Return true if consumed (stops propagation to other plugins and default behavior). */\n handleKeyDown(e: {\n readonly key: string;\n readonly shiftKey: boolean;\n readonly ctrlKey?: boolean;\n readonly metaKey?: boolean;\n readonly nativeEvent?: { isComposing?: boolean };\n preventDefault(): void;\n }): boolean;\n\n /** Called on every cursor position change (selection change / text change). */\n setCursorPosition(pos: number): void;\n};\n\n/** Options for registering a plugin. */\nexport type ComposerInputPluginRegisterOptions = {\n /**\n * Relative priority. Plugins with higher priority receive events first.\n * @default 0\n */\n priority?: number;\n};\n\n// Ref-based registry: plugins are read imperatively at event time, so register/unregister does not trigger re-renders.\nexport type ComposerInputPluginRegistry = {\n register(\n plugin: ComposerInputPlugin,\n opts?: ComposerInputPluginRegisterOptions,\n ): () => void;\n getPlugins(): readonly ComposerInputPlugin[];\n};\n\nconst ComposerInputPluginRegistryContext =\n createContext<ComposerInputPluginRegistry | null>(null);\n\nexport const useComposerInputPluginRegistry =\n (): ComposerInputPluginRegistry => {\n const ctx = useContext(ComposerInputPluginRegistryContext);\n if (!ctx)\n throw new Error(\n \"useComposerInputPluginRegistry must be used within a ComposerInputPluginProvider\",\n );\n return ctx;\n };\n\nexport const useComposerInputPluginRegistryOptional =\n (): ComposerInputPluginRegistry | null => {\n return useContext(ComposerInputPluginRegistryContext);\n };\n\nexport const ComposerInputPluginProvider: FC<{ children: ReactNode }> = ({\n children,\n}) => {\n const pluginsRef = useRef<Map<ComposerInputPlugin, number>>(new Map());\n const snapshotRef = useRef<readonly ComposerInputPlugin[]>([]);\n\n const refreshSnapshot = useCallback(() => {\n const entries = Array.from(pluginsRef.current.entries());\n // Sort by priority descending; stable insertion order for equal priorities.\n entries.sort((a, b) => b[1] - a[1]);\n snapshotRef.current = entries.map(([plugin]) => plugin);\n }, []);\n\n const register = useCallback(\n (\n plugin: ComposerInputPlugin,\n opts?: ComposerInputPluginRegisterOptions,\n ) => {\n const priority = opts?.priority ?? 0;\n pluginsRef.current.set(plugin, priority);\n refreshSnapshot();\n return () => {\n pluginsRef.current.delete(plugin);\n refreshSnapshot();\n };\n },\n [refreshSnapshot],\n );\n\n const getPlugins = useCallback(\n (): readonly ComposerInputPlugin[] => snapshotRef.current,\n [],\n );\n\n const registry = useMemo<ComposerInputPluginRegistry>(\n () => ({ register, getPlugins }),\n [register, getPlugins],\n );\n\n return (\n <ComposerInputPluginRegistryContext.Provider value={registry}>\n {children}\n </ComposerInputPluginRegistryContext.Provider>\n );\n};\n"],"mappings":";;;;;AAkDA,MAAM4B,qCACJ1B,cAAkD,IAAI;AAExD,MAAa2B,uCACX;CACE,MAAAC,MAAY3B,WAAWyB,kCAAkC;CACzD,IAAI,CAACE,KACH,MAAM,IAAIC,MACR,kFACF;CAAE,OACGD;AAAG;AAGd,MAAaE,+CACX;CAAA,OACS7B,WAAWyB,kCAAkC;AAAC;AAGzD,MAAaK,+BAA2DE,OAAA;CAAA,MAAAC,IAAAnC,EAAA,CAAA;CAAC,MAAA,EAAAiC,aAAAC;CAExE,IAAAE;CAAA,IAAAD,EAAA,OAAAE,OAAAC,IAAA,2BAAA,GAAA;EAC6DF,qBAAA,IAAIG,IAAI;EAACJ,EAAA,KAAAC;CAAA,OAAAA,KAAAD,EAAA;CAArE,MAAAK,aAAmBrC,OAAyCiC,EAAS;CAAE,IAAAK;CAAA,IAAAN,EAAA,OAAAE,OAAAC,IAAA,2BAAA,GAAA;EACZG,KAAA,CAAA;EAAEN,EAAA,KAAAM;CAAA,OAAAA,KAAAN,EAAA;CAA7D,MAAAO,cAAoBvC,OAAuCsC,EAAE;CAAE,IAAAE;CAAA,IAAAR,EAAA,OAAAE,OAAAC,IAAA,2BAAA,GAAA;EAE3BK,WAAA;GAClC,MAAAC,UAAgBC,MAAKC,KAAMN,WAAUO,QAAQH,QAAS,CAAC;GAEvDA,QAAOI,KAAMC,KAAqB;GAClCP,YAAWK,UAAWH,QAAOM,IAAKC,MAAoB;EAAnC;EACpBhB,EAAA,KAAAQ;CAAA,OAAAA,KAAAR,EAAA;CALD,MAAAiB,kBAAwBT;CAKjB,IAAAU;CAAA,IAAAlB,EAAA,OAAAE,OAAAC,IAAA,2BAAA,GAAA;EAGLe,MAAAC,UAAA7B,SAAA;GAIE,MAAAJ,WAAiBI,MAAIJ,YAAJ;GACjBmB,WAAUO,QAAQQ,IAAK/B,UAAQH,QAAQ;GACvC+B,gBAAgB;GAAC,aACV;IACLZ,WAAUO,QAAQS,OAAQhC,QAAM;IAChC4B,gBAAgB;GAAC;EAClB;EACFjB,EAAA,KAAAkB;CAAA,OAAAA,KAAAlB,EAAA;CAZH,MAAAZ,WAAiB8B;CAcf,IAAAI;CAAA,IAAAtB,EAAA,OAAAE,OAAAC,IAAA,2BAAA,GAAA;EAGAmB,WAAsCf,YAAWK;EAAQZ,EAAA,KAAAsB;CAAA,OAAAA,KAAAtB,EAAA;CAD3D,MAAAT,aAAmB+B;CAGjB,IAAAC;CAAA,IAAAvB,EAAA,OAAAE,OAAAC,IAAA,2BAAA,GAAA;EAGOoB,KAAA;GAAAnC;GAAAG;EAAuB;EAACS,EAAA,KAAAuB;CAAA,OAAAA,KAAAvB,EAAA;CADjC,MAAAwB,WACSD;CAEP,IAAAE;CAAA,IAAAzB,EAAA,OAAAF,UAAA;EAGA2B,KAAA,oBAAA,mCAAA,UAAA;GAAoDD,OAAAA;GACjD1B;EACH,CAAA;EAA8CE,EAAA,KAAAF;EAAAE,EAAA,KAAAyB;CAAA,OAAAA,KAAAzB,EAAA;CAAA,OAF9CyB;AAE8C;AA1CsB,SAAAX,MAAAY,GAAAC,GAAA;CAAA,OAS7CA,EAAC,KAAMD,EAAC;AAAG;AATkC,SAAAV,OAAAjB,IAAA;CAUjC,MAAA,CAAAV,UAAAU;CAAQ,OAAKV;AAAM"}
@@ -1,7 +1,8 @@
1
1
  "use client";
2
2
  import { Primitive } from "../../utils/Primitive.js";
3
3
  import { useAui, useAuiState } from "@assistant-ui/store";
4
- import { forwardRef, useCallback } from "@assistant-ui/tap/react-shim";
4
+ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
5
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
5
6
  import { jsx } from "react/jsx-runtime";
6
7
  import { composeEventHandlers } from "@radix-ui/primitive";
7
8
  //#region src/primitives/composer/ComposerQuote.tsx
@@ -18,11 +19,19 @@ import { composeEventHandlers } from "@radix-ui/primitive";
18
19
  * ```
19
20
  */
20
21
  const ComposerPrimitiveQuote = forwardRef((props, forwardedRef) => {
21
- if (!useAuiState((s) => s.composer.quote)) return null;
22
- return /* @__PURE__ */ jsx(Primitive.div, {
23
- ...props,
24
- ref: forwardedRef
25
- });
22
+ const $ = c(3);
23
+ if (!useAuiState(_temp)) return null;
24
+ let t0;
25
+ if ($[0] !== forwardedRef || $[1] !== props) {
26
+ t0 = /* @__PURE__ */ jsx(Primitive.div, {
27
+ ...props,
28
+ ref: forwardedRef
29
+ });
30
+ $[0] = forwardedRef;
31
+ $[1] = props;
32
+ $[2] = t0;
33
+ } else t0 = $[2];
34
+ return t0;
26
35
  });
27
36
  ComposerPrimitiveQuote.displayName = "ComposerPrimitive.Quote";
28
37
  /**
@@ -33,14 +42,35 @@ ComposerPrimitiveQuote.displayName = "ComposerPrimitive.Quote";
33
42
  * <ComposerPrimitive.QuoteText />
34
43
  * ```
35
44
  */
36
- const ComposerPrimitiveQuoteText = forwardRef(({ children, ...props }, forwardedRef) => {
37
- const text = useAuiState((s) => s.composer.quote?.text);
45
+ const ComposerPrimitiveQuoteText = forwardRef((t0, forwardedRef) => {
46
+ const $ = c(7);
47
+ let children;
48
+ let props;
49
+ if ($[0] !== t0) {
50
+ ({children, ...props} = t0);
51
+ $[0] = t0;
52
+ $[1] = children;
53
+ $[2] = props;
54
+ } else {
55
+ children = $[1];
56
+ props = $[2];
57
+ }
58
+ const text = useAuiState(_temp2);
38
59
  if (!text) return null;
39
- return /* @__PURE__ */ jsx(Primitive.span, {
40
- ...props,
41
- ref: forwardedRef,
42
- children: children ?? text
43
- });
60
+ const t1 = children ?? text;
61
+ let t2;
62
+ if ($[3] !== forwardedRef || $[4] !== props || $[5] !== t1) {
63
+ t2 = /* @__PURE__ */ jsx(Primitive.span, {
64
+ ...props,
65
+ ref: forwardedRef,
66
+ children: t1
67
+ });
68
+ $[3] = forwardedRef;
69
+ $[4] = props;
70
+ $[5] = t1;
71
+ $[6] = t2;
72
+ } else t2 = $[6];
73
+ return t2;
44
74
  });
45
75
  ComposerPrimitiveQuoteText.displayName = "ComposerPrimitive.QuoteText";
46
76
  /**
@@ -51,19 +81,58 @@ ComposerPrimitiveQuoteText.displayName = "ComposerPrimitive.QuoteText";
51
81
  * <ComposerPrimitive.QuoteDismiss>×</ComposerPrimitive.QuoteDismiss>
52
82
  * ```
53
83
  */
54
- const ComposerPrimitiveQuoteDismiss = forwardRef(({ onClick, ...props }, forwardedRef) => {
84
+ const ComposerPrimitiveQuoteDismiss = forwardRef((t0, forwardedRef) => {
85
+ const $ = c(12);
86
+ let onClick;
87
+ let props;
88
+ if ($[0] !== t0) {
89
+ ({onClick, ...props} = t0);
90
+ $[0] = t0;
91
+ $[1] = onClick;
92
+ $[2] = props;
93
+ } else {
94
+ onClick = $[1];
95
+ props = $[2];
96
+ }
55
97
  const aui = useAui();
56
- const handleDismiss = useCallback(() => {
57
- aui.composer().setQuote(void 0);
58
- }, [aui]);
59
- return /* @__PURE__ */ jsx(Primitive.button, {
60
- type: "button",
61
- ...props,
62
- ref: forwardedRef,
63
- onClick: composeEventHandlers(onClick, handleDismiss)
64
- });
98
+ let t1;
99
+ if ($[3] !== aui) {
100
+ t1 = () => {
101
+ aui.composer().setQuote(void 0);
102
+ };
103
+ $[3] = aui;
104
+ $[4] = t1;
105
+ } else t1 = $[4];
106
+ const handleDismiss = t1;
107
+ let t2;
108
+ if ($[5] !== handleDismiss || $[6] !== onClick) {
109
+ t2 = composeEventHandlers(onClick, handleDismiss);
110
+ $[5] = handleDismiss;
111
+ $[6] = onClick;
112
+ $[7] = t2;
113
+ } else t2 = $[7];
114
+ let t3;
115
+ if ($[8] !== forwardedRef || $[9] !== props || $[10] !== t2) {
116
+ t3 = /* @__PURE__ */ jsx(Primitive.button, {
117
+ type: "button",
118
+ ...props,
119
+ ref: forwardedRef,
120
+ onClick: t2
121
+ });
122
+ $[8] = forwardedRef;
123
+ $[9] = props;
124
+ $[10] = t2;
125
+ $[11] = t3;
126
+ } else t3 = $[11];
127
+ return t3;
65
128
  });
66
129
  ComposerPrimitiveQuoteDismiss.displayName = "ComposerPrimitive.QuoteDismiss";
130
+ function _temp(s) {
131
+ return s.composer.quote;
132
+ }
133
+ function _temp2(s) {
134
+ return s.composer.quote?.text;
135
+ }
67
136
  //#endregion
68
137
  export { ComposerPrimitiveQuote, ComposerPrimitiveQuoteDismiss, ComposerPrimitiveQuoteText };
69
138
 
@@ -1 +1 @@
1
- {"version":3,"file":"ComposerQuote.js","names":[],"sources":["../../../src/primitives/composer/ComposerQuote.tsx"],"sourcesContent":["\"use client\";\n\nimport { Primitive } from \"../../utils/Primitive\";\nimport {\n type ComponentRef,\n type ComponentPropsWithoutRef,\n forwardRef,\n useCallback,\n} from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\n\n// ---- Root ----\n\nexport namespace ComposerPrimitiveQuote {\n export type Element = ComponentRef<typeof Primitive.div>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.div>;\n}\n\n/**\n * Renders a container for the quoted text preview in the composer.\n * Only renders when a quote is set.\n *\n * @example\n * ```tsx\n * <ComposerPrimitive.Quote>\n * <ComposerPrimitive.QuoteText />\n * <ComposerPrimitive.QuoteDismiss>×</ComposerPrimitive.QuoteDismiss>\n * </ComposerPrimitive.Quote>\n * ```\n */\nexport const ComposerPrimitiveQuote = forwardRef<\n ComposerPrimitiveQuote.Element,\n ComposerPrimitiveQuote.Props\n>((props, forwardedRef) => {\n const quote = useAuiState((s) => s.composer.quote);\n if (!quote) return null;\n\n return <Primitive.div {...props} ref={forwardedRef} />;\n});\n\nComposerPrimitiveQuote.displayName = \"ComposerPrimitive.Quote\";\n\n// ---- QuoteText ----\n\nexport namespace ComposerPrimitiveQuoteText {\n export type Element = ComponentRef<typeof Primitive.span>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.span>;\n}\n\n/**\n * Renders the quoted text content.\n *\n * @example\n * ```tsx\n * <ComposerPrimitive.QuoteText />\n * ```\n */\nexport const ComposerPrimitiveQuoteText = forwardRef<\n ComposerPrimitiveQuoteText.Element,\n ComposerPrimitiveQuoteText.Props\n>(({ children, ...props }, forwardedRef) => {\n const text = useAuiState((s) => s.composer.quote?.text);\n if (!text) return null;\n\n return (\n <Primitive.span {...props} ref={forwardedRef}>\n {children ?? text}\n </Primitive.span>\n );\n});\n\nComposerPrimitiveQuoteText.displayName = \"ComposerPrimitive.QuoteText\";\n\n// ---- QuoteDismiss ----\n\nexport namespace ComposerPrimitiveQuoteDismiss {\n export type Element = ComponentRef<typeof Primitive.button>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.button>;\n}\n\n/**\n * A button that clears the current quote from the composer.\n *\n * @example\n * ```tsx\n * <ComposerPrimitive.QuoteDismiss>×</ComposerPrimitive.QuoteDismiss>\n * ```\n */\nexport const ComposerPrimitiveQuoteDismiss = forwardRef<\n ComposerPrimitiveQuoteDismiss.Element,\n ComposerPrimitiveQuoteDismiss.Props\n>(({ onClick, ...props }, forwardedRef) => {\n const aui = useAui();\n const handleDismiss = useCallback(() => {\n aui.composer().setQuote(undefined);\n }, [aui]);\n\n return (\n <Primitive.button\n type=\"button\"\n {...props}\n ref={forwardedRef}\n onClick={composeEventHandlers(onClick, handleDismiss)}\n />\n );\n});\n\nComposerPrimitiveQuoteDismiss.displayName = \"ComposerPrimitive.QuoteDismiss\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA+BA,MAAa,yBAAyB,YAGnC,OAAO,iBAAiB;CAEzB,IAAI,CADU,aAAa,MAAM,EAAE,SAAS,KACnC,GAAG,OAAO;CAEnB,OAAO,oBAAC,UAAU,KAAX;EAAe,GAAI;EAAO,KAAK;CAAe,CAAA;AACvD,CAAC;AAED,uBAAuB,cAAc;;;;;;;;;AAiBrC,MAAa,6BAA6B,YAGvC,EAAE,UAAU,GAAG,SAAS,iBAAiB;CAC1C,MAAM,OAAO,aAAa,MAAM,EAAE,SAAS,OAAO,IAAI;CACtD,IAAI,CAAC,MAAM,OAAO;CAElB,OACE,oBAAC,UAAU,MAAX;EAAgB,GAAI;EAAO,KAAK;YAC7B,YAAY;CACC,CAAA;AAEpB,CAAC;AAED,2BAA2B,cAAc;;;;;;;;;AAiBzC,MAAa,gCAAgC,YAG1C,EAAE,SAAS,GAAG,SAAS,iBAAiB;CACzC,MAAM,MAAM,OAAO;CACnB,MAAM,gBAAgB,kBAAkB;EACtC,IAAI,SAAS,CAAC,CAAC,SAAS,KAAA,CAAS;CACnC,GAAG,CAAC,GAAG,CAAC;CAER,OACE,oBAAC,UAAU,QAAX;EACE,MAAK;EACL,GAAI;EACJ,KAAK;EACL,SAAS,qBAAqB,SAAS,aAAa;CACrD,CAAA;AAEL,CAAC;AAED,8BAA8B,cAAc"}
1
+ {"version":3,"file":"ComposerQuote.js","names":["c","_c","Primitive","ComponentRef","ComponentPropsWithoutRef","forwardRef","useCallback","useAui","useAuiState","composeEventHandlers","ComposerPrimitiveQuote","Element","div","Props","props","forwardedRef","$","quote","_temp","t0","displayName","ComposerPrimitiveQuoteText","span","children","text","_temp2","t1","t2","ComposerPrimitiveQuoteDismiss","button","onClick","aui","composer","setQuote","undefined","handleDismiss","t3","s"],"sources":["../../../src/primitives/composer/ComposerQuote.tsx"],"sourcesContent":["\"use client\";\n\nimport { Primitive } from \"../../utils/Primitive\";\nimport {\n type ComponentRef,\n type ComponentPropsWithoutRef,\n forwardRef,\n useCallback,\n} from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\n\n// ---- Root ----\n\nexport namespace ComposerPrimitiveQuote {\n export type Element = ComponentRef<typeof Primitive.div>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.div>;\n}\n\n/**\n * Renders a container for the quoted text preview in the composer.\n * Only renders when a quote is set.\n *\n * @example\n * ```tsx\n * <ComposerPrimitive.Quote>\n * <ComposerPrimitive.QuoteText />\n * <ComposerPrimitive.QuoteDismiss>×</ComposerPrimitive.QuoteDismiss>\n * </ComposerPrimitive.Quote>\n * ```\n */\nexport const ComposerPrimitiveQuote = forwardRef<\n ComposerPrimitiveQuote.Element,\n ComposerPrimitiveQuote.Props\n>((props, forwardedRef) => {\n const quote = useAuiState((s) => s.composer.quote);\n if (!quote) return null;\n\n return <Primitive.div {...props} ref={forwardedRef} />;\n});\n\nComposerPrimitiveQuote.displayName = \"ComposerPrimitive.Quote\";\n\n// ---- QuoteText ----\n\nexport namespace ComposerPrimitiveQuoteText {\n export type Element = ComponentRef<typeof Primitive.span>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.span>;\n}\n\n/**\n * Renders the quoted text content.\n *\n * @example\n * ```tsx\n * <ComposerPrimitive.QuoteText />\n * ```\n */\nexport const ComposerPrimitiveQuoteText = forwardRef<\n ComposerPrimitiveQuoteText.Element,\n ComposerPrimitiveQuoteText.Props\n>(({ children, ...props }, forwardedRef) => {\n const text = useAuiState((s) => s.composer.quote?.text);\n if (!text) return null;\n\n return (\n <Primitive.span {...props} ref={forwardedRef}>\n {children ?? text}\n </Primitive.span>\n );\n});\n\nComposerPrimitiveQuoteText.displayName = \"ComposerPrimitive.QuoteText\";\n\n// ---- QuoteDismiss ----\n\nexport namespace ComposerPrimitiveQuoteDismiss {\n export type Element = ComponentRef<typeof Primitive.button>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.button>;\n}\n\n/**\n * A button that clears the current quote from the composer.\n *\n * @example\n * ```tsx\n * <ComposerPrimitive.QuoteDismiss>×</ComposerPrimitive.QuoteDismiss>\n * ```\n */\nexport const ComposerPrimitiveQuoteDismiss = forwardRef<\n ComposerPrimitiveQuoteDismiss.Element,\n ComposerPrimitiveQuoteDismiss.Props\n>(({ onClick, ...props }, forwardedRef) => {\n const aui = useAui();\n const handleDismiss = useCallback(() => {\n aui.composer().setQuote(undefined);\n }, [aui]);\n\n return (\n <Primitive.button\n type=\"button\"\n {...props}\n ref={forwardedRef}\n onClick={composeEventHandlers(onClick, handleDismiss)}\n />\n );\n});\n\nComposerPrimitiveQuoteDismiss.displayName = \"ComposerPrimitive.QuoteDismiss\";\n"],"mappings":"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"}