@assistant-ui/react 0.12.20 → 0.12.22

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 (245) hide show
  1. package/dist/client/ExternalThread.d.ts.map +1 -1
  2. package/dist/client/ExternalThread.js +8 -2
  3. package/dist/client/ExternalThread.js.map +1 -1
  4. package/dist/index.d.ts +5 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +3 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/legacy-runtime/runtime-cores/assistant-transport/types.d.ts +3 -1
  9. package/dist/legacy-runtime/runtime-cores/assistant-transport/types.d.ts.map +1 -1
  10. package/dist/legacy-runtime/runtime-cores/assistant-transport/types.js.map +1 -1
  11. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
  12. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js +4 -0
  13. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
  14. package/dist/primitives/actionBar/ActionBarCopy.d.ts +3 -1
  15. package/dist/primitives/actionBar/ActionBarCopy.d.ts.map +1 -1
  16. package/dist/primitives/actionBar/ActionBarCopy.js +1 -1
  17. package/dist/primitives/actionBar/ActionBarCopy.js.map +1 -1
  18. package/dist/primitives/actionBar/ActionBarEdit.d.ts +4 -2
  19. package/dist/primitives/actionBar/ActionBarEdit.d.ts.map +1 -1
  20. package/dist/primitives/actionBar/ActionBarExportMarkdown.d.ts +3 -1
  21. package/dist/primitives/actionBar/ActionBarExportMarkdown.d.ts.map +1 -1
  22. package/dist/primitives/actionBar/ActionBarExportMarkdown.js +1 -1
  23. package/dist/primitives/actionBar/ActionBarExportMarkdown.js.map +1 -1
  24. package/dist/primitives/actionBar/ActionBarFeedbackNegative.d.ts +4 -2
  25. package/dist/primitives/actionBar/ActionBarFeedbackNegative.d.ts.map +1 -1
  26. package/dist/primitives/actionBar/ActionBarFeedbackNegative.js +1 -1
  27. package/dist/primitives/actionBar/ActionBarFeedbackNegative.js.map +1 -1
  28. package/dist/primitives/actionBar/ActionBarFeedbackPositive.d.ts +4 -2
  29. package/dist/primitives/actionBar/ActionBarFeedbackPositive.d.ts.map +1 -1
  30. package/dist/primitives/actionBar/ActionBarFeedbackPositive.js +1 -1
  31. package/dist/primitives/actionBar/ActionBarFeedbackPositive.js.map +1 -1
  32. package/dist/primitives/actionBar/ActionBarReload.d.ts +4 -2
  33. package/dist/primitives/actionBar/ActionBarReload.d.ts.map +1 -1
  34. package/dist/primitives/actionBar/ActionBarRoot.d.ts +4 -2
  35. package/dist/primitives/actionBar/ActionBarRoot.d.ts.map +1 -1
  36. package/dist/primitives/actionBar/ActionBarRoot.js +1 -1
  37. package/dist/primitives/actionBar/ActionBarRoot.js.map +1 -1
  38. package/dist/primitives/actionBar/ActionBarSpeak.d.ts +4 -2
  39. package/dist/primitives/actionBar/ActionBarSpeak.d.ts.map +1 -1
  40. package/dist/primitives/actionBar/ActionBarStopSpeaking.d.ts +4 -2
  41. package/dist/primitives/actionBar/ActionBarStopSpeaking.d.ts.map +1 -1
  42. package/dist/primitives/actionBar/ActionBarStopSpeaking.js +1 -1
  43. package/dist/primitives/actionBar/ActionBarStopSpeaking.js.map +1 -1
  44. package/dist/primitives/attachment/AttachmentRemove.d.ts +4 -2
  45. package/dist/primitives/attachment/AttachmentRemove.d.ts.map +1 -1
  46. package/dist/primitives/attachment/AttachmentRoot.d.ts +5 -3
  47. package/dist/primitives/attachment/AttachmentRoot.d.ts.map +1 -1
  48. package/dist/primitives/attachment/AttachmentRoot.js +1 -1
  49. package/dist/primitives/attachment/AttachmentRoot.js.map +1 -1
  50. package/dist/primitives/attachment/AttachmentThumb.d.ts +5 -3
  51. package/dist/primitives/attachment/AttachmentThumb.d.ts.map +1 -1
  52. package/dist/primitives/attachment/AttachmentThumb.js +1 -1
  53. package/dist/primitives/attachment/AttachmentThumb.js.map +1 -1
  54. package/dist/primitives/branchPicker/BranchPickerNext.d.ts +4 -2
  55. package/dist/primitives/branchPicker/BranchPickerNext.d.ts.map +1 -1
  56. package/dist/primitives/branchPicker/BranchPickerPrevious.d.ts +4 -2
  57. package/dist/primitives/branchPicker/BranchPickerPrevious.d.ts.map +1 -1
  58. package/dist/primitives/branchPicker/BranchPickerRoot.d.ts +4 -2
  59. package/dist/primitives/branchPicker/BranchPickerRoot.d.ts.map +1 -1
  60. package/dist/primitives/branchPicker/BranchPickerRoot.js +1 -1
  61. package/dist/primitives/branchPicker/BranchPickerRoot.js.map +1 -1
  62. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.d.ts +4 -2
  63. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.d.ts.map +1 -1
  64. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.d.ts +5 -3
  65. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.d.ts.map +1 -1
  66. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js +1 -1
  67. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js.map +1 -1
  68. package/dist/primitives/composer/ComposerAddAttachment.d.ts +3 -1
  69. package/dist/primitives/composer/ComposerAddAttachment.d.ts.map +1 -1
  70. package/dist/primitives/composer/ComposerAttachmentDropzone.d.ts +3 -0
  71. package/dist/primitives/composer/ComposerAttachmentDropzone.d.ts.map +1 -1
  72. package/dist/primitives/composer/ComposerAttachmentDropzone.js +18 -8
  73. package/dist/primitives/composer/ComposerAttachmentDropzone.js.map +1 -1
  74. package/dist/primitives/composer/ComposerCancel.d.ts +4 -2
  75. package/dist/primitives/composer/ComposerCancel.d.ts.map +1 -1
  76. package/dist/primitives/composer/ComposerDictate.d.ts +4 -2
  77. package/dist/primitives/composer/ComposerDictate.d.ts.map +1 -1
  78. package/dist/primitives/composer/ComposerDictationTranscript.d.ts +5 -3
  79. package/dist/primitives/composer/ComposerDictationTranscript.d.ts.map +1 -1
  80. package/dist/primitives/composer/ComposerDictationTranscript.js +1 -1
  81. package/dist/primitives/composer/ComposerDictationTranscript.js.map +1 -1
  82. package/dist/primitives/composer/ComposerInput.d.ts +5 -0
  83. package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
  84. package/dist/primitives/composer/ComposerInput.js +23 -6
  85. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  86. package/dist/primitives/composer/ComposerQuote.d.ts +13 -7
  87. package/dist/primitives/composer/ComposerQuote.d.ts.map +1 -1
  88. package/dist/primitives/composer/ComposerQuote.js +1 -1
  89. package/dist/primitives/composer/ComposerQuote.js.map +1 -1
  90. package/dist/primitives/composer/ComposerRoot.d.ts +5 -3
  91. package/dist/primitives/composer/ComposerRoot.d.ts.map +1 -1
  92. package/dist/primitives/composer/ComposerRoot.js +1 -1
  93. package/dist/primitives/composer/ComposerRoot.js.map +1 -1
  94. package/dist/primitives/composer/ComposerSend.d.ts +4 -2
  95. package/dist/primitives/composer/ComposerSend.d.ts.map +1 -1
  96. package/dist/primitives/composer/ComposerStopDictation.d.ts +4 -2
  97. package/dist/primitives/composer/ComposerStopDictation.d.ts.map +1 -1
  98. package/dist/primitives/composer/mention/ComposerMentionBack.d.ts +5 -3
  99. package/dist/primitives/composer/mention/ComposerMentionBack.d.ts.map +1 -1
  100. package/dist/primitives/composer/mention/ComposerMentionBack.js +1 -1
  101. package/dist/primitives/composer/mention/ComposerMentionBack.js.map +1 -1
  102. package/dist/primitives/composer/mention/ComposerMentionCategories.d.ts +8 -4
  103. package/dist/primitives/composer/mention/ComposerMentionCategories.d.ts.map +1 -1
  104. package/dist/primitives/composer/mention/ComposerMentionCategories.js +1 -1
  105. package/dist/primitives/composer/mention/ComposerMentionCategories.js.map +1 -1
  106. package/dist/primitives/composer/mention/ComposerMentionItems.d.ts +8 -4
  107. package/dist/primitives/composer/mention/ComposerMentionItems.d.ts.map +1 -1
  108. package/dist/primitives/composer/mention/ComposerMentionItems.js +1 -1
  109. package/dist/primitives/composer/mention/ComposerMentionItems.js.map +1 -1
  110. package/dist/primitives/composer/mention/ComposerMentionPopover.d.ts +5 -3
  111. package/dist/primitives/composer/mention/ComposerMentionPopover.d.ts.map +1 -1
  112. package/dist/primitives/composer/mention/ComposerMentionPopover.js +1 -1
  113. package/dist/primitives/composer/mention/ComposerMentionPopover.js.map +1 -1
  114. package/dist/primitives/error/ErrorMessage.d.ts +5 -3
  115. package/dist/primitives/error/ErrorMessage.d.ts.map +1 -1
  116. package/dist/primitives/error/ErrorMessage.js +1 -1
  117. package/dist/primitives/error/ErrorMessage.js.map +1 -1
  118. package/dist/primitives/error/ErrorRoot.d.ts +5 -3
  119. package/dist/primitives/error/ErrorRoot.d.ts.map +1 -1
  120. package/dist/primitives/error/ErrorRoot.js +1 -1
  121. package/dist/primitives/error/ErrorRoot.js.map +1 -1
  122. package/dist/primitives/message/MessageRoot.d.ts +5 -3
  123. package/dist/primitives/message/MessageRoot.d.ts.map +1 -1
  124. package/dist/primitives/message/MessageRoot.js +1 -1
  125. package/dist/primitives/message/MessageRoot.js.map +1 -1
  126. package/dist/primitives/messagePart/MessagePartImage.d.ts +5 -3
  127. package/dist/primitives/messagePart/MessagePartImage.d.ts.map +1 -1
  128. package/dist/primitives/messagePart/MessagePartImage.js +1 -1
  129. package/dist/primitives/messagePart/MessagePartImage.js.map +1 -1
  130. package/dist/primitives/messagePart/MessagePartText.d.ts +5 -3
  131. package/dist/primitives/messagePart/MessagePartText.d.ts.map +1 -1
  132. package/dist/primitives/queueItem/QueueItemRemove.d.ts +4 -2
  133. package/dist/primitives/queueItem/QueueItemRemove.d.ts.map +1 -1
  134. package/dist/primitives/queueItem/QueueItemSteer.d.ts +4 -2
  135. package/dist/primitives/queueItem/QueueItemSteer.d.ts.map +1 -1
  136. package/dist/primitives/queueItem/QueueItemText.d.ts +5 -3
  137. package/dist/primitives/queueItem/QueueItemText.d.ts.map +1 -1
  138. package/dist/primitives/queueItem/QueueItemText.js +1 -1
  139. package/dist/primitives/queueItem/QueueItemText.js.map +1 -1
  140. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.d.ts +5 -3
  141. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.d.ts.map +1 -1
  142. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js +1 -1
  143. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js.map +1 -1
  144. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.d.ts +5 -3
  145. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.d.ts.map +1 -1
  146. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js +1 -1
  147. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js.map +1 -1
  148. package/dist/primitives/suggestion/SuggestionDescription.d.ts +5 -3
  149. package/dist/primitives/suggestion/SuggestionDescription.d.ts.map +1 -1
  150. package/dist/primitives/suggestion/SuggestionDescription.js +1 -1
  151. package/dist/primitives/suggestion/SuggestionDescription.js.map +1 -1
  152. package/dist/primitives/suggestion/SuggestionTitle.d.ts +5 -3
  153. package/dist/primitives/suggestion/SuggestionTitle.d.ts.map +1 -1
  154. package/dist/primitives/suggestion/SuggestionTitle.js +1 -1
  155. package/dist/primitives/suggestion/SuggestionTitle.js.map +1 -1
  156. package/dist/primitives/suggestion/SuggestionTrigger.d.ts +3 -1
  157. package/dist/primitives/suggestion/SuggestionTrigger.d.ts.map +1 -1
  158. package/dist/primitives/thread/ThreadRoot.d.ts +5 -3
  159. package/dist/primitives/thread/ThreadRoot.d.ts.map +1 -1
  160. package/dist/primitives/thread/ThreadRoot.js +1 -1
  161. package/dist/primitives/thread/ThreadRoot.js.map +1 -1
  162. package/dist/primitives/thread/ThreadScrollToBottom.d.ts +4 -2
  163. package/dist/primitives/thread/ThreadScrollToBottom.d.ts.map +1 -1
  164. package/dist/primitives/thread/ThreadSuggestion.d.ts +3 -1
  165. package/dist/primitives/thread/ThreadSuggestion.d.ts.map +1 -1
  166. package/dist/primitives/thread/ThreadViewport.d.ts +4 -2
  167. package/dist/primitives/thread/ThreadViewport.d.ts.map +1 -1
  168. package/dist/primitives/thread/ThreadViewport.js +1 -1
  169. package/dist/primitives/thread/ThreadViewport.js.map +1 -1
  170. package/dist/primitives/thread/ThreadViewportFooter.d.ts +5 -3
  171. package/dist/primitives/thread/ThreadViewportFooter.d.ts.map +1 -1
  172. package/dist/primitives/thread/ThreadViewportFooter.js +1 -1
  173. package/dist/primitives/thread/ThreadViewportFooter.js.map +1 -1
  174. package/dist/primitives/threadList/ThreadListNew.d.ts +4 -2
  175. package/dist/primitives/threadList/ThreadListNew.d.ts.map +1 -1
  176. package/dist/primitives/threadList/ThreadListNew.js +1 -1
  177. package/dist/primitives/threadList/ThreadListNew.js.map +1 -1
  178. package/dist/primitives/threadList/ThreadListRoot.d.ts +5 -3
  179. package/dist/primitives/threadList/ThreadListRoot.d.ts.map +1 -1
  180. package/dist/primitives/threadList/ThreadListRoot.js +1 -1
  181. package/dist/primitives/threadList/ThreadListRoot.js.map +1 -1
  182. package/dist/primitives/threadListItem/ThreadListItemArchive.d.ts +4 -2
  183. package/dist/primitives/threadListItem/ThreadListItemArchive.d.ts.map +1 -1
  184. package/dist/primitives/threadListItem/ThreadListItemDelete.d.ts +4 -2
  185. package/dist/primitives/threadListItem/ThreadListItemDelete.d.ts.map +1 -1
  186. package/dist/primitives/threadListItem/ThreadListItemRoot.d.ts +5 -3
  187. package/dist/primitives/threadListItem/ThreadListItemRoot.d.ts.map +1 -1
  188. package/dist/primitives/threadListItem/ThreadListItemRoot.js +1 -1
  189. package/dist/primitives/threadListItem/ThreadListItemRoot.js.map +1 -1
  190. package/dist/primitives/threadListItem/ThreadListItemTrigger.d.ts +4 -2
  191. package/dist/primitives/threadListItem/ThreadListItemTrigger.d.ts.map +1 -1
  192. package/dist/primitives/threadListItem/ThreadListItemUnarchive.d.ts +4 -2
  193. package/dist/primitives/threadListItem/ThreadListItemUnarchive.d.ts.map +1 -1
  194. package/dist/utils/Primitive.d.ts +106 -0
  195. package/dist/utils/Primitive.d.ts.map +1 -0
  196. package/dist/utils/Primitive.js +54 -0
  197. package/dist/utils/Primitive.js.map +1 -0
  198. package/dist/utils/createActionButton.d.ts +5 -3
  199. package/dist/utils/createActionButton.d.ts.map +1 -1
  200. package/dist/utils/createActionButton.js +1 -1
  201. package/dist/utils/createActionButton.js.map +1 -1
  202. package/package.json +7 -8
  203. package/src/client/ExternalThread.ts +8 -2
  204. package/src/index.ts +22 -0
  205. package/src/legacy-runtime/runtime-cores/assistant-transport/types.ts +7 -0
  206. package/src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.ts +4 -0
  207. package/src/primitives/actionBar/ActionBarCopy.tsx +1 -1
  208. package/src/primitives/actionBar/ActionBarExportMarkdown.tsx +1 -1
  209. package/src/primitives/actionBar/ActionBarFeedbackNegative.tsx +1 -1
  210. package/src/primitives/actionBar/ActionBarFeedbackPositive.tsx +1 -1
  211. package/src/primitives/actionBar/ActionBarRoot.tsx +1 -1
  212. package/src/primitives/actionBar/ActionBarStopSpeaking.tsx +1 -1
  213. package/src/primitives/attachment/AttachmentRoot.tsx +1 -1
  214. package/src/primitives/attachment/AttachmentThumb.tsx +1 -1
  215. package/src/primitives/branchPicker/BranchPickerRoot.tsx +1 -1
  216. package/src/primitives/chainOfThought/ChainOfThoughtRoot.tsx +1 -1
  217. package/src/primitives/composer/ComposerAttachmentDropzone.tsx +41 -18
  218. package/src/primitives/composer/ComposerDictationTranscript.tsx +1 -1
  219. package/src/primitives/composer/ComposerInput.tsx +43 -17
  220. package/src/primitives/composer/ComposerQuote.tsx +1 -1
  221. package/src/primitives/composer/ComposerRoot.tsx +1 -1
  222. package/src/primitives/composer/mention/ComposerMentionBack.tsx +1 -1
  223. package/src/primitives/composer/mention/ComposerMentionCategories.tsx +1 -1
  224. package/src/primitives/composer/mention/ComposerMentionItems.tsx +1 -1
  225. package/src/primitives/composer/mention/ComposerMentionPopover.tsx +1 -1
  226. package/src/primitives/error/ErrorMessage.tsx +1 -1
  227. package/src/primitives/error/ErrorRoot.tsx +1 -1
  228. package/src/primitives/message/MessageRoot.tsx +1 -1
  229. package/src/primitives/messagePart/MessagePartImage.tsx +1 -1
  230. package/src/primitives/messagePart/MessagePartText.tsx +1 -1
  231. package/src/primitives/queueItem/QueueItemText.tsx +1 -1
  232. package/src/primitives/selectionToolbar/SelectionToolbarQuote.tsx +1 -1
  233. package/src/primitives/selectionToolbar/SelectionToolbarRoot.tsx +1 -1
  234. package/src/primitives/suggestion/SuggestionDescription.tsx +1 -1
  235. package/src/primitives/suggestion/SuggestionTitle.tsx +1 -1
  236. package/src/primitives/thread/ThreadRoot.tsx +1 -1
  237. package/src/primitives/thread/ThreadViewport.tsx +1 -1
  238. package/src/primitives/thread/ThreadViewportFooter.tsx +1 -1
  239. package/src/primitives/threadList/ThreadListNew.tsx +1 -1
  240. package/src/primitives/threadList/ThreadListRoot.tsx +1 -1
  241. package/src/primitives/threadListItem/ThreadListItemRoot.tsx +1 -1
  242. package/src/tests/BaseComposerRuntimeCore.test.ts +3 -1
  243. package/src/utils/Primitive.test.tsx +99 -0
  244. package/src/utils/Primitive.tsx +100 -0
  245. package/src/utils/createActionButton.tsx +1 -1
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { ComponentPropsWithoutRef, forwardRef, type ComponentRef } from "react";
4
4
  import { useAuiState } from "@assistant-ui/store";
5
- import { Primitive } from "@radix-ui/react-primitive";
5
+ import { Primitive } from "../../utils/Primitive";
6
6
 
7
7
  type PrimitiveDivProps = ComponentPropsWithoutRef<typeof Primitive.div>;
8
8
 
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import { type ComponentRef, forwardRef, ComponentPropsWithoutRef } from "react";
5
5
  import { MessagePrimitiveIf as If } from "../message/MessageIf";
6
6
 
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import { type ComponentRef, forwardRef, ComponentPropsWithoutRef } from "react";
5
5
 
6
6
  type PrimitiveDivProps = ComponentPropsWithoutRef<typeof Primitive.div>;
@@ -1,7 +1,15 @@
1
1
  "use client";
2
2
 
3
- import { forwardRef, useCallback, useState } from "react";
3
+ import {
4
+ forwardRef,
5
+ useCallback,
6
+ useState,
7
+ type ReactElement,
8
+ cloneElement,
9
+ isValidElement,
10
+ } from "react";
4
11
 
12
+ import { composeEventHandlers } from "@radix-ui/primitive";
5
13
  import { Slot } from "radix-ui";
6
14
  import React from "react";
7
15
  import { useAui } from "@assistant-ui/store";
@@ -10,6 +18,7 @@ export namespace ComposerPrimitiveAttachmentDropzone {
10
18
  export type Element = HTMLDivElement;
11
19
  export type Props = React.HTMLAttributes<HTMLDivElement> & {
12
20
  asChild?: boolean | undefined;
21
+ render?: ReactElement | undefined;
13
22
  disabled?: boolean | undefined;
14
23
  };
15
24
  }
@@ -17,7 +26,7 @@ export namespace ComposerPrimitiveAttachmentDropzone {
17
26
  export const ComposerPrimitiveAttachmentDropzone = forwardRef<
18
27
  HTMLDivElement,
19
28
  ComposerPrimitiveAttachmentDropzone.Props
20
- >(({ disabled, asChild = false, children, ...rest }, ref) => {
29
+ >(({ disabled, asChild = false, render, children, ...rest }, ref) => {
21
30
  const [isDragging, setIsDragging] = useState(false);
22
31
  const aui = useAui();
23
32
 
@@ -68,25 +77,39 @@ export const ComposerPrimitiveAttachmentDropzone = forwardRef<
68
77
  [disabled, aui],
69
78
  );
70
79
 
71
- const dragProps = {
72
- onDragEnterCapture: handleDragEnterCapture,
73
- onDragOverCapture: handleDragOverCapture,
74
- onDragLeaveCapture: handleDragLeaveCapture,
75
- onDropCapture: handleDrop,
80
+ const mergedProps = {
81
+ ...(isDragging ? { "data-dragging": "true" } : null),
82
+ ...rest,
83
+ onDragEnterCapture: composeEventHandlers(
84
+ rest.onDragEnterCapture,
85
+ handleDragEnterCapture,
86
+ ),
87
+ onDragOverCapture: composeEventHandlers(
88
+ rest.onDragOverCapture,
89
+ handleDragOverCapture,
90
+ ),
91
+ onDragLeaveCapture: composeEventHandlers(
92
+ rest.onDragLeaveCapture,
93
+ handleDragLeaveCapture,
94
+ ),
95
+ onDropCapture: composeEventHandlers(rest.onDropCapture, handleDrop),
96
+ ref,
76
97
  };
77
98
 
78
- const Comp = asChild ? Slot.Root : "div";
99
+ if (render && isValidElement(render)) {
100
+ const renderChildren =
101
+ children !== undefined
102
+ ? children
103
+ : (render.props as Record<string, unknown>).children;
104
+ return (
105
+ <Slot.Root {...mergedProps}>
106
+ {cloneElement(render, undefined, renderChildren as React.ReactNode)}
107
+ </Slot.Root>
108
+ );
109
+ }
79
110
 
80
- return (
81
- <Comp
82
- {...(isDragging ? { "data-dragging": "true" } : null)}
83
- ref={ref}
84
- {...dragProps}
85
- {...rest}
86
- >
87
- {children}
88
- </Comp>
89
- );
111
+ const Comp = asChild ? Slot.Root : "div";
112
+ return <Comp {...mergedProps}>{children}</Comp>;
90
113
  });
91
114
 
92
115
  ComposerPrimitiveAttachmentDropzone.displayName =
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import { type ComponentRef, forwardRef, ComponentPropsWithoutRef } from "react";
5
5
  import { useAuiState } from "@assistant-ui/store";
6
6
 
@@ -6,10 +6,14 @@ import { Slot } from "radix-ui";
6
6
  import {
7
7
  ClipboardEvent,
8
8
  type KeyboardEvent,
9
+ type ReactElement,
10
+ type ReactNode,
9
11
  forwardRef,
10
12
  useCallback,
11
13
  useEffect,
12
14
  useRef,
15
+ cloneElement,
16
+ isValidElement,
13
17
  } from "react";
14
18
  import TextareaAutosize, {
15
19
  type TextareaAutosizeProps,
@@ -32,6 +36,10 @@ export namespace ComposerPrimitiveInput {
32
36
  * When true, the component will merge its props with its child.
33
37
  */
34
38
  asChild?: boolean | undefined;
39
+ /**
40
+ * A React element to use as the input container, with props merged in.
41
+ */
42
+ render?: ReactElement | undefined;
35
43
  /**
36
44
  * Whether to cancel message composition when Escape is pressed.
37
45
  * @default true
@@ -118,6 +126,7 @@ export const ComposerPrimitiveInput = forwardRef<
118
126
  {
119
127
  autoFocus = false,
120
128
  asChild,
129
+ render,
121
130
  disabled: disabledProp,
122
131
  onChange,
123
132
  onKeyDown,
@@ -146,8 +155,6 @@ export const ComposerPrimitiveInput = forwardRef<
146
155
  return s.composer.text;
147
156
  });
148
157
 
149
- const Component = asChild ? Slot.Root : TextareaAutosize;
150
-
151
158
  const isDisabled =
152
159
  useAuiState(
153
160
  (s) => s.thread.isDisabled || s.composer.dictation?.inputDisabled,
@@ -277,14 +284,15 @@ export const ComposerPrimitiveInput = forwardRef<
277
284
  return aui.on("threadListItem.switchedTo", focus);
278
285
  }, [unstable_focusOnThreadSwitched, focus, aui]);
279
286
 
280
- return (
281
- <Component
282
- name="input"
283
- value={value}
284
- {...rest}
285
- ref={ref as React.ForwardedRef<HTMLTextAreaElement>}
286
- disabled={isDisabled}
287
- onChange={composeEventHandlers(onChange, (e) => {
287
+ const inputProps = {
288
+ name: "input" as const,
289
+ value,
290
+ ...rest,
291
+ ref: ref as React.ForwardedRef<HTMLTextAreaElement>,
292
+ disabled: isDisabled,
293
+ onChange: composeEventHandlers(
294
+ onChange,
295
+ (e: React.ChangeEvent<HTMLTextAreaElement>) => {
288
296
  if (!aui.composer().getState().isEditing) return;
289
297
  flushResourcesSync(() => {
290
298
  aui.composer().setText(e.target.value);
@@ -292,17 +300,35 @@ export const ComposerPrimitiveInput = forwardRef<
292
300
  mentionInternalContext?.setCursorPosition(
293
301
  e.target.selectionStart ?? e.target.value.length,
294
302
  );
295
- })}
296
- onKeyDown={composeEventHandlers(onKeyDown, handleKeyPress)}
297
- onSelect={composeEventHandlers(onSelect, (e) => {
303
+ },
304
+ ),
305
+ onKeyDown: composeEventHandlers(onKeyDown, handleKeyPress),
306
+ onSelect: composeEventHandlers(
307
+ onSelect,
308
+ (e: React.SyntheticEvent<HTMLTextAreaElement>) => {
298
309
  const target = e.target as HTMLTextAreaElement;
299
310
  mentionInternalContext?.setCursorPosition(
300
311
  target.selectionStart ?? target.value.length,
301
312
  );
302
- })}
303
- onPaste={composeEventHandlers(onPaste, handlePaste)}
304
- />
305
- );
313
+ },
314
+ ),
315
+ onPaste: composeEventHandlers(onPaste, handlePaste),
316
+ };
317
+
318
+ if (render && isValidElement(render)) {
319
+ const renderChildren =
320
+ (rest as any).children !== undefined
321
+ ? ((rest as any).children as ReactNode)
322
+ : ((render.props as Record<string, unknown>).children as ReactNode);
323
+ return (
324
+ <Slot.Root {...inputProps}>
325
+ {cloneElement(render, undefined, renderChildren)}
326
+ </Slot.Root>
327
+ );
328
+ }
329
+
330
+ const Component = asChild ? Slot.Root : TextareaAutosize;
331
+ return <Component {...inputProps} />;
306
332
  },
307
333
  );
308
334
 
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import {
5
5
  type ComponentRef,
6
6
  type ComponentPropsWithoutRef,
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import { composeEventHandlers } from "@radix-ui/primitive";
4
- import { Primitive } from "@radix-ui/react-primitive";
4
+ import { Primitive } from "../../utils/Primitive";
5
5
  import {
6
6
  type ComponentRef,
7
7
  type FormEvent,
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../../utils/Primitive";
4
4
  import {
5
5
  type ComponentRef,
6
6
  type ComponentPropsWithoutRef,
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../../utils/Primitive";
4
4
  import {
5
5
  type ComponentRef,
6
6
  type ComponentPropsWithoutRef,
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../../utils/Primitive";
4
4
  import {
5
5
  type ComponentRef,
6
6
  type ComponentPropsWithoutRef,
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../../utils/Primitive";
4
4
  import {
5
5
  type ComponentRef,
6
6
  type ComponentPropsWithoutRef,
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import { type ComponentRef, forwardRef, ComponentPropsWithoutRef } from "react";
5
5
  import { useMessageError } from "@assistant-ui/core/react";
6
6
 
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import { type ComponentRef, forwardRef, ComponentPropsWithoutRef } from "react";
5
5
 
6
6
  export namespace ErrorPrimitiveRoot {
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import {
5
5
  type ComponentRef,
6
6
  forwardRef,
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import { type ComponentRef, forwardRef, ComponentPropsWithoutRef } from "react";
5
5
  import { useMessagePartImage } from "./useMessagePartImage";
6
6
 
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import {
5
5
  type ComponentRef,
6
6
  forwardRef,
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import {
5
5
  type ComponentRef,
6
6
  type ComponentPropsWithoutRef,
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import { composeEventHandlers } from "@radix-ui/primitive";
5
5
  import {
6
6
  type ComponentPropsWithoutRef,
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import {
5
5
  type ComponentPropsWithoutRef,
6
6
  type ComponentRef,
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import { type ElementRef, forwardRef, ComponentPropsWithoutRef } from "react";
5
5
  import { useAuiState } from "@assistant-ui/store";
6
6
 
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import { type ElementRef, forwardRef, ComponentPropsWithoutRef } from "react";
5
5
  import { useAuiState } from "@assistant-ui/store";
6
6
 
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import { type ComponentRef, forwardRef, ComponentPropsWithoutRef } from "react";
5
5
 
6
6
  export namespace ThreadPrimitiveRoot {
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import { useComposedRefs } from "@radix-ui/react-compose-refs";
4
- import { Primitive } from "@radix-ui/react-primitive";
4
+ import { Primitive } from "../../utils/Primitive";
5
5
  import {
6
6
  type ComponentRef,
7
7
  forwardRef,
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import { useComposedRefs } from "@radix-ui/react-compose-refs";
4
- import { Primitive } from "@radix-ui/react-primitive";
4
+ import { Primitive } from "../../utils/Primitive";
5
5
  import {
6
6
  type ComponentRef,
7
7
  forwardRef,
@@ -5,7 +5,7 @@ import {
5
5
  ActionButtonProps,
6
6
  } from "../../utils/createActionButton";
7
7
  import { forwardRef } from "react";
8
- import { Primitive } from "@radix-ui/react-primitive";
8
+ import { Primitive } from "../../utils/Primitive";
9
9
  import { composeEventHandlers } from "@radix-ui/primitive";
10
10
  import { useAuiState } from "@assistant-ui/store";
11
11
  import { useThreadListNew as useThreadListNewBehavior } from "@assistant-ui/core/react";
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import { ComponentPropsWithoutRef, ComponentRef, forwardRef } from "react";
5
5
 
6
6
  type PrimitiveDivProps = ComponentPropsWithoutRef<typeof Primitive.div>;
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { Primitive } from "@radix-ui/react-primitive";
3
+ import { Primitive } from "../../utils/Primitive";
4
4
  import { type ComponentRef, forwardRef, ComponentPropsWithoutRef } from "react";
5
5
  import { useAuiState } from "@assistant-ui/store";
6
6
 
@@ -204,7 +204,9 @@ describe("BaseComposerRuntimeCore", () => {
204
204
  };
205
205
  composer.setAttachmentAdapter(adapter);
206
206
 
207
- await composer.addAttachment(new File(["data"], "test.txt"));
207
+ await composer.addAttachment(
208
+ new File(["data"], "test.txt", { type: "text/plain" }),
209
+ );
208
210
 
209
211
  expect(composer.attachments).toHaveLength(1);
210
212
  expect(composer.attachments[0]!.id).toBe("att-1");
@@ -0,0 +1,99 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { renderToStaticMarkup } from "react-dom/server";
3
+ import { Primitive } from "./Primitive";
4
+
5
+ const ALL_NODES = [
6
+ "a",
7
+ "button",
8
+ "div",
9
+ "form",
10
+ "h2",
11
+ "h3",
12
+ "img",
13
+ "input",
14
+ "label",
15
+ "li",
16
+ "nav",
17
+ "ol",
18
+ "p",
19
+ "select",
20
+ "span",
21
+ "svg",
22
+ "ul",
23
+ ] as const;
24
+
25
+ // Void elements cannot have children
26
+ const VOID_ELEMENTS = new Set(["img", "input"]);
27
+
28
+ describe("Primitive", () => {
29
+ describe.each(ALL_NODES)("Primitive.%s", (node) => {
30
+ const Comp = Primitive[node];
31
+
32
+ it("renders the correct HTML tag", () => {
33
+ const html = VOID_ELEMENTS.has(node)
34
+ ? renderToStaticMarkup(<Comp />)
35
+ : renderToStaticMarkup(<Comp>content</Comp>);
36
+
37
+ expect(html).toMatch(new RegExp(`^<${node}[\\s/>]`));
38
+ });
39
+
40
+ it("renders the render element instead of the default tag", () => {
41
+ // Use <i> as render target — it won't collide with any Primitive node name
42
+ const html = VOID_ELEMENTS.has(node)
43
+ ? renderToStaticMarkup(<Comp render={<i data-test="yes" />} />)
44
+ : renderToStaticMarkup(
45
+ <Comp render={<i data-test="yes" />}>content</Comp>,
46
+ );
47
+
48
+ expect(html).toContain("<i");
49
+ expect(html).toContain('data-test="yes"');
50
+ expect(html).not.toMatch(new RegExp(`<${node}[\\s>]`));
51
+ });
52
+
53
+ if (!VOID_ELEMENTS.has(node)) {
54
+ it("render produces same markup as asChild", () => {
55
+ const renderHtml = renderToStaticMarkup(
56
+ <Comp render={<i className="child" />} className="parent">
57
+ text
58
+ </Comp>,
59
+ );
60
+
61
+ const asChildHtml = renderToStaticMarkup(
62
+ <Comp asChild className="parent">
63
+ <i className="child">text</i>
64
+ </Comp>,
65
+ );
66
+
67
+ expect(renderHtml).toBe(asChildHtml);
68
+ });
69
+ }
70
+ });
71
+
72
+ describe("render prop edge cases", () => {
73
+ it("uses render element's own children as fallback", () => {
74
+ const html = renderToStaticMarkup(
75
+ <Primitive.span render={<em>Fallback</em>} />,
76
+ );
77
+ expect(html).toBe("<em>Fallback</em>");
78
+ });
79
+
80
+ it("outer children override render element's children", () => {
81
+ const html = renderToStaticMarkup(
82
+ <Primitive.span render={<em>Original</em>}>Override</Primitive.span>,
83
+ );
84
+ expect(html).toBe("<em>Override</em>");
85
+ });
86
+
87
+ it("passes multiple children into the render element", () => {
88
+ const html = renderToStaticMarkup(
89
+ <Primitive.div render={<section />}>
90
+ <p>A</p>
91
+ <p>B</p>
92
+ </Primitive.div>,
93
+ );
94
+ expect(html).toContain("<section");
95
+ expect(html).toContain("<p>A</p>");
96
+ expect(html).toContain("<p>B</p>");
97
+ });
98
+ });
99
+ });
@@ -0,0 +1,100 @@
1
+ import {
2
+ type ComponentPropsWithoutRef,
3
+ type ComponentRef,
4
+ type ForwardRefExoticComponent,
5
+ type ReactElement,
6
+ type ReactNode,
7
+ type RefAttributes,
8
+ cloneElement,
9
+ forwardRef,
10
+ isValidElement,
11
+ } from "react";
12
+ import { Primitive as RadixPrimitive } from "@radix-ui/react-primitive";
13
+
14
+ /**
15
+ * Thin wrapper around `@radix-ui/react-primitive` that adds `render` prop support.
16
+ *
17
+ * When `render` is provided, it is converted to the equivalent `asChild` pattern:
18
+ * render={<Comp props />} + children → asChild + <Comp props>{children}</Comp>
19
+ *
20
+ * All prop merging, ref composition, and event handler chaining remain handled
21
+ * by Radix's battle-tested Slot implementation — we add zero custom logic for that.
22
+ */
23
+
24
+ // Match @radix-ui/react-primitive's full element set
25
+ const NODES = [
26
+ "a",
27
+ "button",
28
+ "div",
29
+ "form",
30
+ "h2",
31
+ "h3",
32
+ "img",
33
+ "input",
34
+ "label",
35
+ "li",
36
+ "nav",
37
+ "ol",
38
+ "p",
39
+ "select",
40
+ "span",
41
+ "svg",
42
+ "ul",
43
+ ] as const;
44
+ type PrimitiveNode = (typeof NODES)[number];
45
+
46
+ type PrimitiveProps<E extends PrimitiveNode> = ComponentPropsWithoutRef<
47
+ (typeof RadixPrimitive)[E]
48
+ > & {
49
+ render?: ReactElement | undefined;
50
+ };
51
+
52
+ type PrimitiveRef<E extends PrimitiveNode> = ComponentRef<
53
+ (typeof RadixPrimitive)[E]
54
+ >;
55
+
56
+ function createPrimitive<E extends PrimitiveNode>(node: E) {
57
+ const RadixComp = RadixPrimitive[node];
58
+
59
+ const Component = forwardRef<PrimitiveRef<E>, PrimitiveProps<E>>(
60
+ ({ render, asChild, children, ...props }, ref) => {
61
+ if (render && isValidElement(render)) {
62
+ // render={<Comp p />} + children
63
+ // → asChild + <Comp p>{children}</Comp>
64
+ const renderChildren =
65
+ children !== undefined
66
+ ? children
67
+ : ((render.props as Record<string, unknown>).children as ReactNode);
68
+ return (
69
+ <RadixComp asChild {...(props as any)} ref={ref}>
70
+ {cloneElement(render, undefined, renderChildren)}
71
+ </RadixComp>
72
+ );
73
+ }
74
+
75
+ return (
76
+ <RadixComp asChild={asChild} {...(props as any)} ref={ref}>
77
+ {children}
78
+ </RadixComp>
79
+ );
80
+ },
81
+ );
82
+
83
+ Component.displayName = `Primitive.${node}`;
84
+ return Component as ForwardRefExoticComponent<
85
+ PrimitiveProps<E> & RefAttributes<PrimitiveRef<E>>
86
+ >;
87
+ }
88
+
89
+ const Primitive = NODES.reduce(
90
+ (acc, node) => {
91
+ acc[node] = createPrimitive(node);
92
+ return acc;
93
+ },
94
+ {} as {
95
+ [K in PrimitiveNode]: ReturnType<typeof createPrimitive<K>>;
96
+ },
97
+ );
98
+
99
+ export { Primitive };
100
+ export type { PrimitiveProps };
@@ -4,7 +4,7 @@ import {
4
4
  ComponentPropsWithoutRef,
5
5
  MouseEventHandler,
6
6
  } from "react";
7
- import { Primitive } from "@radix-ui/react-primitive";
7
+ import { Primitive } from "./Primitive";
8
8
  import { composeEventHandlers } from "@radix-ui/primitive";
9
9
 
10
10
  type ActionButtonCallback<TProps> = (