@assistant-ui/react 0.15.25 → 0.15.27

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 (159) hide show
  1. package/dist/hooks/useToolCallElapsed.d.ts.map +1 -1
  2. package/dist/hooks/useToolCallElapsed.js +3 -2
  3. package/dist/hooks/useToolCallElapsed.js.map +1 -1
  4. package/dist/index.d.ts +31 -5
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/mcp-apps/McpAppRenderer.d.ts.map +1 -1
  7. package/dist/mcp-apps/McpAppRenderer.js +3 -2
  8. package/dist/mcp-apps/McpAppRenderer.js.map +1 -1
  9. package/dist/mcp-apps/app-frame.d.ts.map +1 -1
  10. package/dist/mcp-apps/app-frame.js +58 -48
  11. package/dist/mcp-apps/app-frame.js.map +1 -1
  12. package/dist/mcp-apps/bridge.d.ts.map +1 -1
  13. package/dist/mcp-apps/bridge.js +28 -3
  14. package/dist/mcp-apps/bridge.js.map +1 -1
  15. package/dist/mcp-apps/csp.d.ts +4 -0
  16. package/dist/mcp-apps/csp.d.ts.map +1 -0
  17. package/dist/mcp-apps/csp.js +93 -0
  18. package/dist/mcp-apps/csp.js.map +1 -0
  19. package/dist/mcp-apps/index.d.ts +1 -1
  20. package/dist/mcp-apps/index.d.ts.map +1 -1
  21. package/dist/mcp-apps/types.d.ts +19 -1
  22. package/dist/mcp-apps/types.d.ts.map +1 -1
  23. package/dist/mcp-apps/types.js.map +1 -1
  24. package/dist/primitives/assistantModal/AssistantModalRoot.d.ts +1 -0
  25. package/dist/primitives/assistantModal/AssistantModalRoot.d.ts.map +1 -1
  26. package/dist/primitives/assistantModal/AssistantModalRoot.js.map +1 -1
  27. package/dist/primitives/attachment.d.ts +3 -1
  28. package/dist/primitives/attachment.d.ts.map +1 -1
  29. package/dist/primitives/attachment.js.map +1 -1
  30. package/dist/primitives/composer/ComposerAttachmentDropzone.d.ts.map +1 -1
  31. package/dist/primitives/composer/ComposerAttachmentDropzone.js +14 -12
  32. package/dist/primitives/composer/ComposerAttachmentDropzone.js.map +1 -1
  33. package/dist/primitives/composer/ComposerCancel.d.ts +5 -1
  34. package/dist/primitives/composer/ComposerCancel.d.ts.map +1 -1
  35. package/dist/primitives/composer/ComposerCancel.js +14 -1
  36. package/dist/primitives/composer/ComposerCancel.js.map +1 -1
  37. package/dist/primitives/composer/ComposerInput.d.ts +14 -0
  38. package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
  39. package/dist/primitives/composer/ComposerInput.js +4 -3
  40. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  41. package/dist/primitives/composer/ComposerRoot.d.ts.map +1 -1
  42. package/dist/primitives/composer/ComposerRoot.js +24 -19
  43. package/dist/primitives/composer/ComposerRoot.js.map +1 -1
  44. package/dist/primitives/composer/composerInputSelector.d.ts +3 -0
  45. package/dist/primitives/composer/composerInputSelector.d.ts.map +1 -0
  46. package/dist/primitives/composer/composerInputSelector.js +7 -0
  47. package/dist/primitives/composer/composerInputSelector.js.map +1 -0
  48. package/dist/primitives/composer/useComposerCancelWithFocus.d.ts +2 -0
  49. package/dist/primitives/composer/useComposerCancelWithFocus.d.ts.map +1 -0
  50. package/dist/primitives/composer/useComposerCancelWithFocus.js +42 -0
  51. package/dist/primitives/composer/useComposerCancelWithFocus.js.map +1 -0
  52. package/dist/primitives/composer.d.ts +35 -14
  53. package/dist/primitives/composer.d.ts.map +1 -1
  54. package/dist/primitives/composer.js.map +1 -1
  55. package/dist/primitives/message/MessagePartsGrouped.d.ts +8 -1
  56. package/dist/primitives/message/MessagePartsGrouped.d.ts.map +1 -1
  57. package/dist/primitives/message/MessagePartsGrouped.js +58 -278
  58. package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
  59. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.d.ts.map +1 -1
  60. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js +5 -2
  61. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js.map +1 -1
  62. package/dist/primitives/thread/ThreadViewport.d.ts.map +1 -1
  63. package/dist/primitives/thread/ThreadViewport.js +4 -3
  64. package/dist/primitives/thread/ThreadViewport.js.map +1 -1
  65. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js +2 -2
  66. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js.map +1 -1
  67. package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts.map +1 -1
  68. package/dist/primitives/thread/useThreadViewportAutoScroll.js +90 -21
  69. package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
  70. package/dist/sandbox-host/SandboxHost.d.ts.map +1 -1
  71. package/dist/sandbox-host/SandboxHost.js +3 -2
  72. package/dist/sandbox-host/SandboxHost.js.map +1 -1
  73. package/dist/unstable/useComposerInput.d.ts +9 -4
  74. package/dist/unstable/useComposerInput.d.ts.map +1 -1
  75. package/dist/unstable/useComposerInput.js +6 -4
  76. package/dist/unstable/useComposerInput.js.map +1 -1
  77. package/dist/unstable/useComposerInputHistory.d.ts +3 -2
  78. package/dist/unstable/useComposerInputHistory.d.ts.map +1 -1
  79. package/dist/unstable/useComposerInputHistory.js +2 -2
  80. package/dist/unstable/useComposerInputHistory.js.map +1 -1
  81. package/dist/unstable/useLiveCompletionAdapter.d.ts +3 -2
  82. package/dist/unstable/useLiveCompletionAdapter.d.ts.map +1 -1
  83. package/dist/unstable/useLiveCompletionAdapter.js +8 -7
  84. package/dist/unstable/useLiveCompletionAdapter.js.map +1 -1
  85. package/dist/unstable/useMentionAdapter.d.ts +12 -3
  86. package/dist/unstable/useMentionAdapter.d.ts.map +1 -1
  87. package/dist/unstable/useMentionAdapter.js +2 -2
  88. package/dist/unstable/useMentionAdapter.js.map +1 -1
  89. package/dist/unstable/useMessageStallDetection.d.ts +4 -2
  90. package/dist/unstable/useMessageStallDetection.d.ts.map +1 -1
  91. package/dist/unstable/useMessageStallDetection.js +2 -2
  92. package/dist/unstable/useMessageStallDetection.js.map +1 -1
  93. package/dist/unstable/useSlashCommandAdapter.d.ts +5 -2
  94. package/dist/unstable/useSlashCommandAdapter.d.ts.map +1 -1
  95. package/dist/unstable/useSlashCommandAdapter.js +5 -4
  96. package/dist/unstable/useSlashCommandAdapter.js.map +1 -1
  97. package/dist/unstable/webmcp/useWebMcpProvider.d.ts +4 -0
  98. package/dist/unstable/webmcp/useWebMcpProvider.d.ts.map +1 -1
  99. package/dist/unstable/webmcp/useWebMcpProvider.js +2 -0
  100. package/dist/unstable/webmcp/useWebMcpProvider.js.map +1 -1
  101. package/dist/utils/getSelectionMessageId.d.ts.map +1 -1
  102. package/dist/utils/getSelectionMessageId.js +31 -8
  103. package/dist/utils/getSelectionMessageId.js.map +1 -1
  104. package/dist/utils/hooks/useOnResizeContent.d.ts.map +1 -1
  105. package/dist/utils/hooks/useOnResizeContent.js +2 -22
  106. package/dist/utils/hooks/useOnResizeContent.js.map +1 -1
  107. package/dist/utils/useIsomorphicLayoutEffect.d.ts +3 -0
  108. package/dist/utils/useIsomorphicLayoutEffect.d.ts.map +1 -0
  109. package/dist/utils/useIsomorphicLayoutEffect.js +6 -0
  110. package/dist/utils/useIsomorphicLayoutEffect.js.map +1 -0
  111. package/package.json +10 -10
  112. package/src/hooks/useToolCallElapsed.test.tsx +4 -2
  113. package/src/hooks/useToolCallElapsed.ts +3 -2
  114. package/src/index.ts +20 -2
  115. package/src/mcp-apps/McpAppRenderer.test.tsx +7 -2
  116. package/src/mcp-apps/McpAppRenderer.tsx +3 -9
  117. package/src/mcp-apps/app-frame.test.tsx +102 -6
  118. package/src/mcp-apps/app-frame.tsx +7 -10
  119. package/src/mcp-apps/bridge.test.ts +154 -0
  120. package/src/mcp-apps/bridge.ts +51 -9
  121. package/src/mcp-apps/csp.test.ts +112 -0
  122. package/src/mcp-apps/csp.ts +124 -0
  123. package/src/mcp-apps/index.ts +1 -0
  124. package/src/mcp-apps/types.ts +16 -1
  125. package/src/model-context/frame/AssistantFrame.test.ts +45 -0
  126. package/src/model-context/frame/SPEC_AssistantFrame.md +1 -0
  127. package/src/primitives/assistantModal/AssistantModalRoot.tsx +1 -0
  128. package/src/primitives/attachment.ts +4 -1
  129. package/src/primitives/composer/ComposerAttachmentDropzone.test.tsx +32 -1
  130. package/src/primitives/composer/ComposerAttachmentDropzone.tsx +14 -12
  131. package/src/primitives/composer/ComposerCancel.focus.test.tsx +307 -0
  132. package/src/primitives/composer/ComposerCancel.ts +8 -1
  133. package/src/primitives/composer/ComposerDisabledThread.test.tsx +121 -0
  134. package/src/primitives/composer/ComposerInput.tsx +19 -1
  135. package/src/primitives/composer/ComposerRoot.tsx +6 -5
  136. package/src/primitives/composer/composerInputSelector.ts +4 -0
  137. package/src/primitives/composer/useComposerCancelWithFocus.ts +57 -0
  138. package/src/primitives/composer.ts +56 -21
  139. package/src/primitives/message/MessagePartsGrouped.test.tsx +106 -2
  140. package/src/primitives/message/MessagePartsGrouped.tsx +36 -134
  141. package/src/primitives/selectionToolbar/SelectionToolbarRoot.test.tsx +20 -12
  142. package/src/primitives/selectionToolbar/SelectionToolbarRoot.tsx +6 -2
  143. package/src/primitives/thread/ThreadViewport.tsx +3 -3
  144. package/src/primitives/thread/topAnchor/useTopAnchorReserve.ts +2 -2
  145. package/src/primitives/thread/useThreadViewportAutoScroll.test.tsx +666 -63
  146. package/src/primitives/thread/useThreadViewportAutoScroll.ts +201 -73
  147. package/src/sandbox-host/SandboxHost.tsx +3 -8
  148. package/src/unstable/useComposerInput.ts +9 -4
  149. package/src/unstable/useComposerInputHistory.ts +3 -2
  150. package/src/unstable/useLiveCompletionAdapter.ts +9 -14
  151. package/src/unstable/useMentionAdapter.ts +12 -3
  152. package/src/unstable/useMessageStallDetection.ts +4 -2
  153. package/src/unstable/useSlashCommandAdapter.ts +8 -4
  154. package/src/unstable/webmcp/useWebMcpProvider.ts +4 -0
  155. package/src/utils/getSelectionMessageId.test.ts +231 -0
  156. package/src/utils/getSelectionMessageId.ts +45 -7
  157. package/src/utils/hooks/useOnResizeContent.ts +2 -29
  158. package/src/utils/useIsomorphicLayoutEffect.test.tsx +21 -0
  159. package/src/utils/useIsomorphicLayoutEffect.ts +9 -0
@@ -1 +1 @@
1
- {"version":3,"file":"MessagePartsGrouped.js","names":["c","_c","ComponentType","FC","memo","PropsWithChildren","useMemo","useAuiState","useAui","PartByIndexProvider","TextMessagePartProvider","MessagePartPrimitiveText","MessagePartPrimitiveImage","Unstable_AudioMessagePartComponent","DataMessagePartComponent","DataMessagePartProps","EmptyMessagePartComponent","TextMessagePartComponent","ImageMessagePartComponent","SourceMessagePartComponent","ToolCallMessagePartComponent","ToolCallMessagePartProps","FileMessagePartComponent","ReasoningMessagePartComponent","MessagePartPrimitiveInProgress","MessagePartStatus","getMessagePartKeys","MessagePartGroup","groupKey","indices","GroupingFunction","parts","groupMessagePartsByParentId","groupMap","Map","i","length","part","parentId","groupId","get","push","set","groups","undefined","useMessagePartsGrouped","groupingFunction","$","_temp","t0","bb0","t1","Symbol","for","t2","partKeys","MessagePrimitiveUnstable_PartsGrouped","Props","components","Empty","Text","Reasoning","Source","Image","File","Unstable_Audio","data","by_name","Record","Fallback","tools","Override","Group","ToolUIDisplay","props","toolName","s","toolUIs","render","Render","DataUIDisplay","name","named","dataRenderers","renderers","fallbacks","defaultComponents","whiteSpace","fontFamily","children","MessagePartComponentProps","MessagePartComponent","t3","t4","t5","t6","t7","t8","t9","Audio","t10","aui","_temp2","type","addResult","addToolResult","resume","resumeToolCall","respondToApproval","respondToToolApproval","unstable_recordInteraction","t11","t12","Object","hasOwn","Tool","t13","status","Error","Data","console","warn","MessagePartProps","partIndex","MessagePartImpl","MessagePart","prev","next","EmptyPartFallback","component","Component","COMPLETE_STATUS","freeze","EmptyPartsImpl","_temp3","EmptyParts","contentLength","_temp4","messageGroups","group","groupIndex","GroupComponent","identity","JSON","stringify","includes","map","partsElements","displayName","MessagePrimitiveUnstable_PartsGroupedByParentId","Omit","message","_c"],"sources":["../../../src/primitives/message/MessagePartsGrouped.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ComponentType,\n type FC,\n memo,\n type PropsWithChildren,\n useMemo,\n} from \"react\";\nimport { useAuiState, useAui } from \"@assistant-ui/store\";\nimport { PartByIndexProvider } from \"../../context/providers/PartByIndexProvider\";\nimport { TextMessagePartProvider } from \"../../context/providers/TextMessagePartProvider\";\nimport { MessagePartPrimitiveText } from \"../messagePart/MessagePartText\";\nimport { MessagePartPrimitiveImage } from \"../messagePart/MessagePartImage\";\nimport type {\n Unstable_AudioMessagePartComponent,\n DataMessagePartComponent,\n DataMessagePartProps,\n EmptyMessagePartComponent,\n TextMessagePartComponent,\n ImageMessagePartComponent,\n SourceMessagePartComponent,\n ToolCallMessagePartComponent,\n ToolCallMessagePartProps,\n FileMessagePartComponent,\n ReasoningMessagePartComponent,\n} from \"@assistant-ui/core/react\";\nimport { MessagePartPrimitiveInProgress } from \"../messagePart/MessagePartInProgress\";\nimport type { MessagePartStatus } from \"@assistant-ui/core\";\nimport { getMessagePartKeys } from \"@assistant-ui/core/internal\";\n\ntype MessagePartGroup = {\n groupKey: string | undefined;\n indices: number[];\n};\n\nexport type GroupingFunction = (parts: readonly any[]) => MessagePartGroup[];\n\n/**\n * Groups message parts by their parent ID.\n * Parts without a parent ID appear in their chronological position as individual groups.\n * Parts with the same parent ID are grouped together at the position of their first occurrence.\n */\nconst groupMessagePartsByParentId: GroupingFunction = (\n parts: readonly any[],\n): MessagePartGroup[] => {\n // Map maintains insertion order, so groups appear in order of first occurrence\n const groupMap = new Map<string | number, number[]>();\n\n // Process each part in order\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const parentId = part?.parentId as string | undefined;\n\n // For parts without parentId, assign a unique group ID to maintain their position\n const groupId = parentId ?? i;\n\n // Get or create the indices array for this group\n const indices = groupMap.get(groupId) ?? [];\n indices.push(i);\n groupMap.set(groupId, indices);\n }\n\n // Convert map to array of groups\n const groups: MessagePartGroup[] = [];\n for (const [groupId, indices] of groupMap) {\n // Extract parentId (undefined for ungrouped parts)\n const groupKey = typeof groupId === \"string\" ? groupId : undefined;\n groups.push({ groupKey, indices });\n }\n\n return groups;\n};\n\nconst useMessagePartsGrouped = (\n groupingFunction: GroupingFunction,\n): { groups: MessagePartGroup[]; partKeys: string[] } => {\n const parts = useAuiState((s) => s.message.parts);\n\n const groups = useMemo(() => {\n if (parts.length === 0) {\n return [];\n }\n return groupingFunction(parts);\n }, [parts, groupingFunction]);\n return { groups, partKeys: getMessagePartKeys(parts) };\n};\n\nexport namespace MessagePrimitiveUnstable_PartsGrouped {\n export type Props = {\n /**\n * Function that takes an array of message parts and returns an array of groups.\n * Each group contains a key (for identification) and an array of indices.\n *\n * @example\n * ```tsx\n * // Group by parent ID (default behavior)\n * groupingFunction={(parts) => {\n * const groups = new Map<string | number, number[]>();\n * parts.forEach((part, i) => {\n * const key = part.parentId ?? i;\n * const indices = groups.get(key) ?? [];\n * indices.push(i);\n * groups.set(key, indices);\n * });\n * return Array.from(groups.entries()).map(([key, indices]) => ({\n * groupKey: typeof key === \"string\" ? key : undefined,\n * indices\n * }));\n * }}\n * ```\n *\n * @example\n * ```tsx\n * // Group by tool name\n * import { groupMessagePartsByToolName } from \"@assistant-ui/react\";\n *\n * <MessagePrimitive.Unstable_PartsGrouped\n * groupingFunction={groupMessagePartsByToolName}\n * components={{\n * Group: ({ key, indices, children }) => {\n * if (!key) return <>{children}</>;\n * return (\n * <div className=\"tool-group\">\n * <h4>Tool: {key}</h4>\n * {children}\n * </div>\n * );\n * }\n * }}\n * />\n * ```\n */\n groupingFunction: GroupingFunction;\n\n /**\n * Component configuration for rendering different types of message content.\n *\n * You can provide custom components for each content type (text, image, file, etc.)\n * and configure tool rendering behavior. If not provided, default components will be used.\n */\n components:\n | {\n /** Component for rendering empty messages */\n Empty?: EmptyMessagePartComponent | undefined;\n /** Component for rendering text content */\n Text?: TextMessagePartComponent | undefined;\n /** Component for rendering reasoning content (typically hidden) */\n Reasoning?: ReasoningMessagePartComponent | undefined;\n /** Component for rendering source content */\n Source?: SourceMessagePartComponent | undefined;\n /** Component for rendering image content */\n Image?: ImageMessagePartComponent | undefined;\n /** Component for rendering file content */\n File?: FileMessagePartComponent | undefined;\n /**\n * Component for rendering audio content.\n *\n * @deprecated Render audio through the `File` slot instead, branching\n * on an `audio/*` mime type.\n */\n Unstable_Audio?: Unstable_AudioMessagePartComponent | undefined;\n /** Configuration for data part rendering */\n data?:\n | {\n /** Map data event names to specific components */\n by_name?:\n | Record<string, DataMessagePartComponent | undefined>\n | undefined;\n /** Fallback component for unmatched data events */\n Fallback?: DataMessagePartComponent | undefined;\n }\n | undefined;\n /** Configuration for tool call rendering */\n tools?:\n | {\n /** Map of tool names to their specific components */\n by_name?:\n | Record<string, ToolCallMessagePartComponent | undefined>\n | undefined;\n /** Fallback component for unregistered tools */\n Fallback?: ComponentType<ToolCallMessagePartProps> | undefined;\n }\n | {\n /** Override component that handles all tool calls */\n Override: ComponentType<ToolCallMessagePartProps>;\n }\n | undefined;\n\n /**\n * Component for rendering grouped message parts.\n *\n * When provided, this component will automatically wrap message parts that share\n * the same group key as determined by the groupingFunction.\n *\n * The component receives:\n * - `groupKey`: The group key (or undefined for ungrouped parts)\n * - `indices`: Array of indices for the parts in this group\n * - `children`: The rendered message part components\n *\n * @example\n * ```tsx\n * // Collapsible group\n * Group: ({ groupKey, indices, children }) => {\n * if (!groupKey) return <>{children}</>;\n * return (\n * <details className=\"message-group\">\n * <summary>\n * Group {groupKey} ({indices.length} parts)\n * </summary>\n * <div className=\"group-content\">\n * {children}\n * </div>\n * </details>\n * );\n * }\n * ```\n *\n * @param groupKey - The group key (undefined for ungrouped parts)\n * @param indices - Array of indices for the parts in this group\n * @param children - Rendered message part components to display within the group\n */\n Group?: ComponentType<\n PropsWithChildren<{\n groupKey: string | undefined;\n indices: number[];\n }>\n >;\n }\n | undefined;\n };\n}\n\nconst ToolUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: ToolCallMessagePartComponent | undefined;\n} & ToolCallMessagePartProps) => {\n const Render = useAuiState(\n (s) => s.tools.toolUIs[props.toolName]?.[0]?.render ?? Fallback,\n );\n if (!Render) return null;\n return <Render {...props} />;\n};\n\nconst DataUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: DataMessagePartComponent | undefined;\n} & DataMessagePartProps) => {\n const Render = useAuiState((s) => {\n const named = s.dataRenderers.renderers[props.name]?.[0];\n if (named) return named;\n return s.dataRenderers.fallbacks[0] ?? Fallback;\n });\n if (!Render) return null;\n return <Render {...props} />;\n};\n\nconst defaultComponents = {\n Text: () => (\n <p style={{ whiteSpace: \"pre-line\" }}>\n <MessagePartPrimitiveText />\n <MessagePartPrimitiveInProgress>\n <span style={{ fontFamily: \"revert\" }}>{\" \\u25CF\"}</span>\n </MessagePartPrimitiveInProgress>\n </p>\n ),\n Reasoning: () => null,\n Source: () => null,\n Image: () => <MessagePartPrimitiveImage />,\n File: () => null,\n Unstable_Audio: () => null,\n Group: ({ children }) => children,\n} satisfies MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n\ntype MessagePartComponentProps = {\n components: MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n};\n\nconst MessagePartComponent: FC<MessagePartComponentProps> = ({\n components: {\n Text = defaultComponents.Text,\n Reasoning = defaultComponents.Reasoning,\n Image = defaultComponents.Image,\n Source = defaultComponents.Source,\n File = defaultComponents.File,\n Unstable_Audio: Audio = defaultComponents.Unstable_Audio,\n tools = {},\n data,\n } = {},\n}) => {\n const aui = useAui();\n const part = useAuiState((s) => s.part);\n\n const type = part.type;\n if (type === \"tool-call\") {\n const addResult = aui.part.addToolResult;\n const resume = aui.part.resumeToolCall;\n const respondToApproval = aui.part.respondToToolApproval;\n const unstable_recordInteraction = aui.part.unstable_recordInteraction;\n if (\"Override\" in tools)\n return (\n <tools.Override\n {...part}\n addResult={addResult}\n resume={resume}\n respondToApproval={respondToApproval}\n {...(unstable_recordInteraction && { unstable_recordInteraction })}\n />\n );\n const Tool =\n (tools.by_name && Object.hasOwn(tools.by_name, part.toolName)\n ? tools.by_name[part.toolName]\n : undefined) ?? tools.Fallback;\n return (\n <ToolUIDisplay\n {...part}\n Fallback={Tool}\n addResult={addResult}\n resume={resume}\n respondToApproval={respondToApproval}\n {...(unstable_recordInteraction && { unstable_recordInteraction })}\n />\n );\n }\n\n if (part.status?.type === \"requires-action\")\n throw new Error(\"Encountered unexpected requires-action status\");\n\n switch (type) {\n case \"text\":\n return <Text {...part} />;\n\n case \"reasoning\":\n return <Reasoning {...part} />;\n\n case \"source\":\n return <Source {...part} />;\n\n case \"image\":\n return <Image {...part} />;\n\n case \"file\":\n return <File {...part} />;\n\n case \"audio\":\n return <Audio {...part} />;\n\n case \"data\": {\n const Data =\n (data?.by_name && Object.hasOwn(data.by_name, part.name)\n ? data.by_name[part.name]\n : undefined) ?? data?.Fallback;\n return <DataUIDisplay {...part} Fallback={Data} />;\n }\n\n default:\n console.warn(`Unknown message part type: ${type}`);\n return null;\n }\n};\n\ntype MessagePartProps = {\n partIndex: number;\n components: MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n};\n\nconst MessagePartImpl: FC<MessagePartProps> = ({ partIndex, components }) => {\n return (\n <PartByIndexProvider index={partIndex}>\n <MessagePartComponent components={components} />\n </PartByIndexProvider>\n );\n};\n\nconst MessagePart = memo(\n MessagePartImpl,\n (prev, next) =>\n prev.partIndex === next.partIndex &&\n prev.components?.Text === next.components?.Text &&\n prev.components?.Reasoning === next.components?.Reasoning &&\n prev.components?.Source === next.components?.Source &&\n prev.components?.Image === next.components?.Image &&\n prev.components?.File === next.components?.File &&\n prev.components?.Unstable_Audio === next.components?.Unstable_Audio &&\n prev.components?.tools === next.components?.tools &&\n prev.components?.data === next.components?.data &&\n prev.components?.Group === next.components?.Group,\n);\n\nconst EmptyPartFallback: FC<{\n status: MessagePartStatus;\n component: TextMessagePartComponent;\n}> = ({ status, component: Component }) => {\n return (\n <TextMessagePartProvider text=\"\" isRunning={status.type === \"running\"}>\n <Component type=\"text\" text=\"\" status={status} />\n </TextMessagePartProvider>\n );\n};\n\nconst COMPLETE_STATUS: MessagePartStatus = Object.freeze({\n type: \"complete\",\n});\n\nconst EmptyPartsImpl: FC<MessagePartComponentProps> = ({ components }) => {\n const status = useAuiState(\n (s) => (s.message.status ?? COMPLETE_STATUS) as MessagePartStatus,\n );\n\n if (components?.Empty) return <components.Empty status={status} />;\n\n return (\n <EmptyPartFallback\n status={status}\n component={components?.Text ?? defaultComponents.Text}\n />\n );\n};\n\nconst EmptyParts = memo(\n EmptyPartsImpl,\n (prev, next) =>\n prev.components?.Empty === next.components?.Empty &&\n prev.components?.Text === next.components?.Text,\n);\n\n/**\n * Renders the parts of a message grouped by a custom grouping function.\n *\n * This component allows you to group message parts based on any criteria you define.\n * The grouping function receives all message parts and returns an array of groups,\n * where each group has a key and an array of part indices.\n *\n * @deprecated Prefer `<MessagePrimitive.GroupedParts>` for adjacent\n * grouping — it dispatches all rendering through one `switch (part.type)`\n * and supports nested group paths. Keep this primitive only for\n * non-adjacent clustering (e.g., gathering parts with the same parent-id\n * across the message).\n *\n * @example\n * ```tsx\n * // Group by parent ID (default behavior)\n * <MessagePrimitive.Unstable_PartsGrouped\n * components={{\n * Text: ({ text }) => <p className=\"message-text\">{text}</p>,\n * Image: ({ image }) => <img src={image} alt=\"Message image\" />,\n * Group: ({ groupKey, indices, children }) => {\n * if (!groupKey) return <>{children}</>;\n * return (\n * <div className=\"parent-group border rounded p-4\">\n * <h4>Parent ID: {groupKey}</h4>\n * {children}\n * </div>\n * );\n * }\n * }}\n * />\n * ```\n */\nexport const MessagePrimitiveUnstable_PartsGrouped: FC<\n MessagePrimitiveUnstable_PartsGrouped.Props\n> = ({ groupingFunction, components }) => {\n const contentLength = useAuiState((s) => s.message.parts.length);\n const { groups: messageGroups, partKeys } =\n useMessagePartsGrouped(groupingFunction);\n\n const partsElements = useMemo(() => {\n if (contentLength === 0) {\n return <EmptyParts components={components} />;\n }\n\n return messageGroups.map((group, groupIndex) => {\n const GroupComponent = components?.Group ?? defaultComponents.Group;\n const identity = partKeys[group.indices[0]!];\n\n return (\n <GroupComponent\n key={JSON.stringify([\n \"group\",\n group.groupKey ?? null,\n identity?.includes(\":\") ? `id:${identity}` : groupIndex,\n ])}\n groupKey={group.groupKey}\n indices={group.indices}\n >\n {group.indices.map((partIndex) => (\n <MessagePart\n key={partKeys[partIndex]}\n partIndex={partIndex}\n components={components}\n />\n ))}\n </GroupComponent>\n );\n });\n }, [messageGroups, components, contentLength, partKeys]);\n\n return <>{partsElements}</>;\n};\n\nMessagePrimitiveUnstable_PartsGrouped.displayName =\n \"MessagePrimitive.Unstable_PartsGrouped\";\n\n/**\n * Renders the parts of a message grouped by their parent ID.\n * This is a convenience wrapper around Unstable_PartsGrouped with parent ID grouping.\n *\n * @deprecated Use MessagePrimitive.Unstable_PartsGrouped instead for more flexibility\n */\nexport const MessagePrimitiveUnstable_PartsGroupedByParentId: FC<\n Omit<MessagePrimitiveUnstable_PartsGrouped.Props, \"groupingFunction\">\n> = ({ components, ...props }) => {\n return (\n <MessagePrimitiveUnstable_PartsGrouped\n {...props}\n components={components}\n groupingFunction={groupMessagePartsByParentId}\n />\n );\n};\n\nMessagePrimitiveUnstable_PartsGroupedByParentId.displayName =\n \"MessagePrimitive.Unstable_PartsGroupedByParentId\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"MessagePartsGrouped.js","names":["c","_c","ComponentType","FC","memo","PropsWithChildren","useMemo","useAuiState","PartByIndexProvider","TextMessagePartProvider","MessagePartPrimitiveText","MessagePartPrimitiveImage","MessagePartComponent","Unstable_AudioMessagePartComponent","DataMessagePartComponent","EmptyMessagePartComponent","TextMessagePartComponent","ImageMessagePartComponent","SourceMessagePartComponent","ToolCallMessagePartComponent","ToolCallMessagePartProps","FileMessagePartComponent","ReasoningMessagePartComponent","MessagePartPrimitiveInProgress","MessagePartStatus","getMessagePartKeys","MessagePartGroup","groupKey","indices","GroupingFunction","parts","groupMessagePartsByParentId","groupMap","Map","i","length","part","parentId","groupId","get","push","set","groups","undefined","useMessagePartsGrouped","groupingFunction","$","_temp","t0","bb0","t1","Symbol","for","t2","partKeys","MessagePrimitiveUnstable_PartsGrouped","Props","components","Empty","Text","Reasoning","Source","Image","File","Unstable_Audio","data","by_name","Record","Fallback","tools","Override","Group","defaultComponents","whiteSpace","fontFamily","children","MessagePartComponentProps","MessagePartProps","partIndex","MessagePart","prev","next","EmptyPartFallback","status","component","Component","type","t3","COMPLETE_STATUS","Object","freeze","EmptyPartsImpl","_temp2","EmptyParts","contentLength","_temp3","messageGroups","t4","t5","t6","t7","t8","leafComponents","t9","t10","group","groupIndex","GroupComponent","identity","JSON","stringify","includes","map","partsElements","displayName","MessagePrimitiveUnstable_PartsGroupedByParentId","Omit","props","s","message","_c"],"sources":["../../../src/primitives/message/MessagePartsGrouped.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ComponentType,\n type FC,\n memo,\n type PropsWithChildren,\n useMemo,\n} from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\nimport { PartByIndexProvider } from \"../../context/providers/PartByIndexProvider\";\nimport { TextMessagePartProvider } from \"../../context/providers/TextMessagePartProvider\";\nimport { MessagePartPrimitiveText } from \"../messagePart/MessagePartText\";\nimport { MessagePartPrimitiveImage } from \"../messagePart/MessagePartImage\";\nimport {\n MessagePartComponent,\n type Unstable_AudioMessagePartComponent,\n type DataMessagePartComponent,\n type EmptyMessagePartComponent,\n type TextMessagePartComponent,\n type ImageMessagePartComponent,\n type SourceMessagePartComponent,\n type ToolCallMessagePartComponent,\n type ToolCallMessagePartProps,\n type FileMessagePartComponent,\n type ReasoningMessagePartComponent,\n} from \"@assistant-ui/core/react\";\nimport { MessagePartPrimitiveInProgress } from \"../messagePart/MessagePartInProgress\";\nimport type { MessagePartStatus } from \"@assistant-ui/core\";\nimport { getMessagePartKeys } from \"@assistant-ui/core/internal\";\n\ntype MessagePartGroup = {\n groupKey: string | undefined;\n indices: number[];\n};\n\nexport type GroupingFunction = (parts: readonly any[]) => MessagePartGroup[];\n\n/**\n * Groups message parts by their parent ID.\n * Parts without a parent ID appear in their chronological position as individual groups.\n * Parts with the same parent ID are grouped together at the position of their first occurrence.\n */\nconst groupMessagePartsByParentId: GroupingFunction = (\n parts: readonly any[],\n): MessagePartGroup[] => {\n // Map maintains insertion order, so groups appear in order of first occurrence\n const groupMap = new Map<string | number, number[]>();\n\n // Process each part in order\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const parentId = part?.parentId as string | undefined;\n\n // For parts without parentId, assign a unique group ID to maintain their position\n const groupId = parentId ?? i;\n\n // Get or create the indices array for this group\n const indices = groupMap.get(groupId) ?? [];\n indices.push(i);\n groupMap.set(groupId, indices);\n }\n\n // Convert map to array of groups\n const groups: MessagePartGroup[] = [];\n for (const [groupId, indices] of groupMap) {\n // Extract parentId (undefined for ungrouped parts)\n const groupKey = typeof groupId === \"string\" ? groupId : undefined;\n groups.push({ groupKey, indices });\n }\n\n return groups;\n};\n\nconst useMessagePartsGrouped = (\n groupingFunction: GroupingFunction,\n): { groups: MessagePartGroup[]; partKeys: string[] } => {\n const parts = useAuiState((s) => s.message.parts);\n\n const groups = useMemo(() => {\n if (parts.length === 0) {\n return [];\n }\n return groupingFunction(parts);\n }, [parts, groupingFunction]);\n return { groups, partKeys: getMessagePartKeys(parts) };\n};\n\n/**\n * @deprecated Prefer `<MessagePrimitive.GroupedParts>` for adjacent\n * grouping — it dispatches all rendering through one `switch (part.type)`\n * and supports nested group paths. Keep this primitive only for\n * non-adjacent clustering (e.g., gathering parts with the same parent-id\n * across the message).\n */\nexport namespace MessagePrimitiveUnstable_PartsGrouped {\n export type Props = {\n /**\n * Function that takes an array of message parts and returns an array of groups.\n * Each group contains a key (for identification) and an array of indices.\n *\n * @example\n * ```tsx\n * // Group by parent ID (default behavior)\n * groupingFunction={(parts) => {\n * const groups = new Map<string | number, number[]>();\n * parts.forEach((part, i) => {\n * const key = part.parentId ?? i;\n * const indices = groups.get(key) ?? [];\n * indices.push(i);\n * groups.set(key, indices);\n * });\n * return Array.from(groups.entries()).map(([key, indices]) => ({\n * groupKey: typeof key === \"string\" ? key : undefined,\n * indices\n * }));\n * }}\n * ```\n *\n * @example\n * ```tsx\n * // Group by tool name\n * import { groupMessagePartsByToolName } from \"@assistant-ui/react\";\n *\n * <MessagePrimitive.Unstable_PartsGrouped\n * groupingFunction={groupMessagePartsByToolName}\n * components={{\n * Group: ({ key, indices, children }) => {\n * if (!key) return <>{children}</>;\n * return (\n * <div className=\"tool-group\">\n * <h4>Tool: {key}</h4>\n * {children}\n * </div>\n * );\n * }\n * }}\n * />\n * ```\n */\n groupingFunction: GroupingFunction;\n\n /**\n * Component configuration for rendering different types of message content.\n *\n * You can provide custom components for each content type (text, image, file, etc.)\n * and configure tool rendering behavior. If not provided, default components will be used.\n */\n components:\n | {\n /** Component for rendering empty messages */\n Empty?: EmptyMessagePartComponent | undefined;\n /** Component for rendering text content */\n Text?: TextMessagePartComponent | undefined;\n /** Component for rendering reasoning content (typically hidden) */\n Reasoning?: ReasoningMessagePartComponent | undefined;\n /** Component for rendering source content */\n Source?: SourceMessagePartComponent | undefined;\n /** Component for rendering image content */\n Image?: ImageMessagePartComponent | undefined;\n /** Component for rendering file content */\n File?: FileMessagePartComponent | undefined;\n /**\n * Component for rendering audio content.\n *\n * @deprecated Render audio through the `File` slot instead, branching\n * on an `audio/*` mime type.\n */\n Unstable_Audio?: Unstable_AudioMessagePartComponent | undefined;\n /** Configuration for data part rendering */\n data?:\n | {\n /** Map data event names to specific components */\n by_name?:\n | Record<string, DataMessagePartComponent | undefined>\n | undefined;\n /** Fallback component for unmatched data events */\n Fallback?: DataMessagePartComponent | undefined;\n }\n | undefined;\n /** Configuration for tool call rendering */\n tools?:\n | {\n /** Map of tool names to their specific components */\n by_name?:\n | Record<string, ToolCallMessagePartComponent | undefined>\n | undefined;\n /** Fallback component for unregistered tools */\n Fallback?: ComponentType<ToolCallMessagePartProps> | undefined;\n }\n | {\n /** Override component that handles all tool calls */\n Override: ComponentType<ToolCallMessagePartProps>;\n }\n | undefined;\n\n /**\n * Component for rendering grouped message parts.\n *\n * When provided, this component will automatically wrap message parts that share\n * the same group key as determined by the groupingFunction.\n *\n * The component receives:\n * - `groupKey`: The group key (or undefined for ungrouped parts)\n * - `indices`: Array of indices for the parts in this group\n * - `children`: The rendered message part components\n *\n * @example\n * ```tsx\n * // Collapsible group\n * Group: ({ groupKey, indices, children }) => {\n * if (!groupKey) return <>{children}</>;\n * return (\n * <details className=\"message-group\">\n * <summary>\n * Group {groupKey} ({indices.length} parts)\n * </summary>\n * <div className=\"group-content\">\n * {children}\n * </div>\n * </details>\n * );\n * }\n * ```\n *\n * @param groupKey - The group key (undefined for ungrouped parts)\n * @param indices - Array of indices for the parts in this group\n * @param children - Rendered message part components to display within the group\n */\n Group?: ComponentType<\n PropsWithChildren<{\n groupKey: string | undefined;\n indices: number[];\n }>\n >;\n }\n | undefined;\n };\n}\n\nconst defaultComponents = {\n Text: () => (\n <p style={{ whiteSpace: \"pre-line\" }}>\n <MessagePartPrimitiveText />\n <MessagePartPrimitiveInProgress>\n <span style={{ fontFamily: \"revert\" }}>{\" \\u25CF\"}</span>\n </MessagePartPrimitiveInProgress>\n </p>\n ),\n Reasoning: () => null,\n Source: () => null,\n Image: () => <MessagePartPrimitiveImage />,\n File: () => null,\n Unstable_Audio: () => null,\n Group: ({ children }) => children,\n} satisfies MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n\ntype MessagePartComponentProps = {\n components: MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n};\n\ntype MessagePartProps = {\n partIndex: number;\n components: MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n};\n\nconst MessagePart = memo(\n ({ partIndex, components }: MessagePartProps) => (\n <PartByIndexProvider index={partIndex}>\n <MessagePartComponent components={components} />\n </PartByIndexProvider>\n ),\n (prev, next) =>\n prev.partIndex === next.partIndex &&\n prev.components?.Text === next.components?.Text &&\n prev.components?.Reasoning === next.components?.Reasoning &&\n prev.components?.Source === next.components?.Source &&\n prev.components?.Image === next.components?.Image &&\n prev.components?.File === next.components?.File &&\n prev.components?.Unstable_Audio === next.components?.Unstable_Audio &&\n prev.components?.tools === next.components?.tools &&\n prev.components?.data === next.components?.data,\n);\n\nconst EmptyPartFallback: FC<{\n status: MessagePartStatus;\n component: TextMessagePartComponent;\n}> = ({ status, component: Component }) => {\n return (\n <TextMessagePartProvider text=\"\" isRunning={status.type === \"running\"}>\n <Component type=\"text\" text=\"\" status={status} />\n </TextMessagePartProvider>\n );\n};\n\nconst COMPLETE_STATUS: MessagePartStatus = Object.freeze({\n type: \"complete\",\n});\n\nconst EmptyPartsImpl: FC<MessagePartComponentProps> = ({ components }) => {\n const status = useAuiState(\n (s) => (s.message.status ?? COMPLETE_STATUS) as MessagePartStatus,\n );\n\n if (components?.Empty) return <components.Empty status={status} />;\n\n return (\n <EmptyPartFallback\n status={status}\n component={components?.Text ?? defaultComponents.Text}\n />\n );\n};\n\nconst EmptyParts = memo(\n EmptyPartsImpl,\n (prev, next) =>\n prev.components?.Empty === next.components?.Empty &&\n prev.components?.Text === next.components?.Text,\n);\n\n/**\n * Renders the parts of a message grouped by a custom grouping function.\n *\n * This component allows you to group message parts based on any criteria you define.\n * The grouping function receives all message parts and returns an array of groups,\n * where each group has a key and an array of part indices.\n *\n * @deprecated Prefer `<MessagePrimitive.GroupedParts>` for adjacent\n * grouping — it dispatches all rendering through one `switch (part.type)`\n * and supports nested group paths. Keep this primitive only for\n * non-adjacent clustering (e.g., gathering parts with the same parent-id\n * across the message).\n *\n * @example\n * ```tsx\n * // Group by parent ID (default behavior)\n * <MessagePrimitive.Unstable_PartsGrouped\n * components={{\n * Text: ({ text }) => <p className=\"message-text\">{text}</p>,\n * Image: ({ image }) => <img src={image} alt=\"Message image\" />,\n * Group: ({ groupKey, indices, children }) => {\n * if (!groupKey) return <>{children}</>;\n * return (\n * <div className=\"parent-group border rounded p-4\">\n * <h4>Parent ID: {groupKey}</h4>\n * {children}\n * </div>\n * );\n * }\n * }}\n * />\n * ```\n */\nexport const MessagePrimitiveUnstable_PartsGrouped: FC<\n MessagePrimitiveUnstable_PartsGrouped.Props\n> = ({ groupingFunction, components }) => {\n const contentLength = useAuiState((s) => s.message.parts.length);\n const { groups: messageGroups, partKeys } =\n useMessagePartsGrouped(groupingFunction);\n\n const partsElements = useMemo(() => {\n if (contentLength === 0) {\n return <EmptyParts components={components} />;\n }\n\n const leafComponents = {\n ...components,\n Text: components?.Text ?? defaultComponents.Text,\n Reasoning: components?.Reasoning ?? defaultComponents.Reasoning,\n Image: components?.Image ?? defaultComponents.Image,\n Source: components?.Source ?? defaultComponents.Source,\n File: components?.File ?? defaultComponents.File,\n Unstable_Audio:\n components?.Unstable_Audio ?? defaultComponents.Unstable_Audio,\n };\n\n return messageGroups.map((group, groupIndex) => {\n const GroupComponent = components?.Group ?? defaultComponents.Group;\n const identity = partKeys[group.indices[0]!];\n\n return (\n <GroupComponent\n key={JSON.stringify([\n \"group\",\n group.groupKey ?? null,\n identity?.includes(\":\") ? `id:${identity}` : groupIndex,\n ])}\n groupKey={group.groupKey}\n indices={group.indices}\n >\n {group.indices.map((partIndex) => (\n <MessagePart\n key={partKeys[partIndex]}\n partIndex={partIndex}\n components={leafComponents}\n />\n ))}\n </GroupComponent>\n );\n });\n }, [messageGroups, components, contentLength, partKeys]);\n\n return <>{partsElements}</>;\n};\n\nMessagePrimitiveUnstable_PartsGrouped.displayName =\n \"MessagePrimitive.Unstable_PartsGrouped\";\n\n/**\n * Renders the parts of a message grouped by their parent ID.\n * This is a convenience wrapper around Unstable_PartsGrouped with parent ID grouping.\n *\n * @deprecated Use MessagePrimitive.Unstable_PartsGrouped instead for more flexibility\n */\nexport const MessagePrimitiveUnstable_PartsGroupedByParentId: FC<\n Omit<MessagePrimitiveUnstable_PartsGrouped.Props, \"groupingFunction\">\n> = ({ components, ...props }) => {\n return (\n <MessagePrimitiveUnstable_PartsGrouped\n {...props}\n components={components}\n groupingFunction={groupMessagePartsByParentId}\n />\n );\n};\n\nMessagePrimitiveUnstable_PartsGroupedByParentId.displayName =\n \"MessagePrimitive.Unstable_PartsGroupedByParentId\";\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SelectionToolbarRoot.d.ts","sourceRoot":"","sources":["../../../src/primitives/selectionToolbar/SelectionToolbarRoot.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,iCAA8B;AAElD,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,YAAY,EAOlB,MAAM,OAAO,CAAC;AAKf,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAIF,eAAO,MAAM,uBAAuB,4BACC,CAAC;AAEtC,yBAAiB,6BAA6B,CAAC;IAC7C,KAAY,OAAO,GAAG,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;IACzD,KAAY,KAAK,GAAG,wBAAwB,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;CACpE;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,6BAA6B;;;;0GAsIxC,CAAC"}
1
+ {"version":3,"file":"SelectionToolbarRoot.d.ts","sourceRoot":"","sources":["../../../src/primitives/selectionToolbar/SelectionToolbarRoot.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,iCAA8B;AAElD,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,YAAY,EAOlB,MAAM,OAAO,CAAC;AAKf,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAIF,eAAO,MAAM,uBAAuB,4BACC,CAAC;AAEtC,yBAAiB,6BAA6B,CAAC;IAC7C,KAAY,OAAO,GAAG,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;IACzD,KAAY,KAAK,GAAG,wBAAwB,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;CACpE;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,6BAA6B;;;;0GA0IxC,CAAC"}
@@ -113,11 +113,14 @@ const SelectionToolbarPrimitiveRoot = forwardRef((t0, forwardedRef) => {
113
113
  const handleMouseCancel = () => {
114
114
  isMouseDragging = false;
115
115
  };
116
+ const handleWindowBlur = () => {
117
+ if (isMouseDragging) handleMouseUp();
118
+ };
116
119
  document.addEventListener("mousedown", handleMouseDown, true);
117
120
  document.addEventListener("mouseup", handleMouseUp, true);
118
121
  document.addEventListener("dragend", handleMouseUp, true);
119
122
  document.addEventListener("contextmenu", handleMouseCancel, true);
120
- window.addEventListener("blur", handleMouseCancel);
123
+ window.addEventListener("blur", handleWindowBlur);
121
124
  document.addEventListener("selectionchange", handleSelectionChange);
122
125
  document.addEventListener("scroll", handleScroll, true);
123
126
  return () => {
@@ -126,7 +129,7 @@ const SelectionToolbarPrimitiveRoot = forwardRef((t0, forwardedRef) => {
126
129
  document.removeEventListener("mouseup", handleMouseUp, true);
127
130
  document.removeEventListener("dragend", handleMouseUp, true);
128
131
  document.removeEventListener("contextmenu", handleMouseCancel, true);
129
- window.removeEventListener("blur", handleMouseCancel);
132
+ window.removeEventListener("blur", handleWindowBlur);
130
133
  document.removeEventListener("selectionchange", handleSelectionChange);
131
134
  document.removeEventListener("scroll", handleScroll, true);
132
135
  };
@@ -1 +1 @@
1
- {"version":3,"file":"SelectionToolbarRoot.js","names":["c","_c","Primitive","composeEventHandlers","ComponentPropsWithoutRef","ComponentRef","createContext","forwardRef","useContext","useEffect","useRef","useState","createPortal","getSelectionMessageId","useThreadRootElementRef","SelectionInfo","text","messageId","rect","DOMRect","SelectionToolbarContext","useSelectionToolbarInfo","SelectionToolbarPrimitiveRoot","Element","div","Props","t0","forwardedRef","$","onMouseDown","props","style","info","setInfo","threadRootRef","warnedAboutMissingThreadRootRef","t1","t2","pendingFrame","isMouseDragging","checkSelection","cancelAnimationFrame","requestAnimationFrame","sel","window","getSelection","isCollapsed","toString","trim","current","process","env","NODE_ENV","console","warn","range","getRangeAt","getBoundingClientRect","handleSelectionChange","sel_0","handleScroll","handleMouseDown","handleMouseUp","handleMouseCancel","document","addEventListener","removeEventListener","t3","top","t4","left","width","t5","position","transform","zIndex","positionStyle","t6","_temp","t7","t8","body","displayName","e","preventDefault","_c","Primitive"],"sources":["../../../src/primitives/selectionToolbar/SelectionToolbarRoot.tsx"],"sourcesContent":["\"use client\";\n\nimport { Primitive } from \"../../utils/Primitive\";\nimport { composeEventHandlers } from \"radix-ui/internal\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { getSelectionMessageId } from \"../../utils/getSelectionMessageId\";\nimport { useThreadRootElementRef } from \"../thread/ThreadRootElementContext\";\n\ntype SelectionInfo = {\n text: string;\n messageId: string;\n rect: DOMRect;\n};\n\nconst SelectionToolbarContext = createContext<SelectionInfo | null>(null);\n\nexport const useSelectionToolbarInfo = () =>\n useContext(SelectionToolbarContext);\n\nexport namespace SelectionToolbarPrimitiveRoot {\n export type Element = ComponentRef<typeof Primitive.div>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.div>;\n}\n\n/**\n * A floating toolbar that appears when text is selected within a message.\n *\n * Listens for browser selection changes, validates that the selection is\n * within a single message, and renders a positioned portal near the\n * selection. Prevents mousedown from clearing the selection.\n *\n * @example\n * ```tsx\n * <SelectionToolbarPrimitive.Root>\n * <SelectionToolbarPrimitive.Quote>Quote</SelectionToolbarPrimitive.Quote>\n * </SelectionToolbarPrimitive.Root>\n * ```\n */\nexport const SelectionToolbarPrimitiveRoot = forwardRef<\n SelectionToolbarPrimitiveRoot.Element,\n SelectionToolbarPrimitiveRoot.Props\n>(({ onMouseDown, style, ...props }, forwardedRef) => {\n const [info, setInfo] = useState<SelectionInfo | null>(null);\n const threadRootRef = useThreadRootElementRef();\n const warnedAboutMissingThreadRootRef = useRef(false);\n\n useEffect(() => {\n // Read the selection on the next frame so the browser has settled it.\n let pendingFrame: number | null = null;\n let isMouseDragging = false;\n\n const checkSelection = () => {\n if (pendingFrame !== null) cancelAnimationFrame(pendingFrame);\n pendingFrame = requestAnimationFrame(() => {\n pendingFrame = null;\n const sel = window.getSelection();\n if (!sel || sel.isCollapsed) {\n setInfo(null);\n return;\n }\n\n const text = sel.toString().trim();\n if (!text) {\n setInfo(null);\n return;\n }\n\n if (threadRootRef && !threadRootRef.current) {\n if (\n process.env.NODE_ENV !== \"production\" &&\n !warnedAboutMissingThreadRootRef.current\n ) {\n warnedAboutMissingThreadRootRef.current = true;\n console.warn(\n \"[SelectionToolbarPrimitive.Root] ThreadPrimitive.Root did not provide a DOM element, so the selection cannot be scoped to its thread. Ensure a custom root child forwards its ref.\",\n );\n }\n }\n\n const messageId = getSelectionMessageId(sel, threadRootRef?.current);\n if (!messageId) {\n setInfo(null);\n return;\n }\n\n const range = sel.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n setInfo({ text, messageId, rect });\n });\n };\n\n const handleSelectionChange = () => {\n const sel = window.getSelection();\n if (!sel || sel.isCollapsed) {\n if (pendingFrame !== null) {\n cancelAnimationFrame(pendingFrame);\n pendingFrame = null;\n }\n setInfo(null);\n return;\n }\n\n if (!isMouseDragging) checkSelection();\n };\n\n const handleScroll = () => {\n if (pendingFrame !== null) {\n cancelAnimationFrame(pendingFrame);\n pendingFrame = null;\n }\n setInfo(null);\n };\n\n const handleMouseDown = () => {\n isMouseDragging = true;\n };\n\n const handleMouseUp = () => {\n isMouseDragging = false;\n checkSelection();\n };\n\n const handleMouseCancel = () => {\n isMouseDragging = false;\n };\n\n document.addEventListener(\"mousedown\", handleMouseDown, true);\n document.addEventListener(\"mouseup\", handleMouseUp, true);\n document.addEventListener(\"dragend\", handleMouseUp, true);\n // A context menu can consume the mouseup of the press that opened it.\n document.addEventListener(\"contextmenu\", handleMouseCancel, true);\n window.addEventListener(\"blur\", handleMouseCancel);\n document.addEventListener(\"selectionchange\", handleSelectionChange);\n document.addEventListener(\"scroll\", handleScroll, true);\n\n return () => {\n if (pendingFrame !== null) cancelAnimationFrame(pendingFrame);\n document.removeEventListener(\"mousedown\", handleMouseDown, true);\n document.removeEventListener(\"mouseup\", handleMouseUp, true);\n document.removeEventListener(\"dragend\", handleMouseUp, true);\n document.removeEventListener(\"contextmenu\", handleMouseCancel, true);\n window.removeEventListener(\"blur\", handleMouseCancel);\n document.removeEventListener(\"selectionchange\", handleSelectionChange);\n document.removeEventListener(\"scroll\", handleScroll, true);\n };\n }, [threadRootRef]);\n\n if (!info) return null;\n\n const positionStyle: React.CSSProperties = {\n position: \"fixed\",\n top: `${info.rect.top - 8}px`,\n left: `${info.rect.left + info.rect.width / 2}px`,\n transform: \"translate(-50%, -100%)\",\n zIndex: 50,\n ...style,\n };\n\n return createPortal(\n <SelectionToolbarContext.Provider value={info}>\n <Primitive.div\n {...props}\n ref={forwardedRef}\n style={positionStyle}\n onMouseDown={composeEventHandlers(onMouseDown, (e) => {\n // Prevent mousedown from clearing the text selection\n e.preventDefault();\n })}\n />\n </SelectionToolbarContext.Provider>,\n document.body,\n );\n});\n\nSelectionToolbarPrimitiveRoot.displayName = \"SelectionToolbarPrimitive.Root\";\n"],"mappings":";;;;;;;;;;AAwBA,MAAMoB,0BAA0Bd,cAAoC,IAAI;AAExE,MAAae,gCAA0B;CAAA,OACrCb,WAAWY,uBAAuB;AAAC;;;;;;;;;;;;;;;AAqBrC,MAAaE,gCAAgCf,YAG3CmB,IAAAC,iBAAA;CAAA,MAAAC,IAAA3B,EAAA,EAAA;CAAA,IAAA4B;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAH,EAAA,OAAAF,IAAA;EAAC,CAAA,CAAAG,aAAAE,OAAA,GAAAD,SAAAJ;EAAgCE,EAAA,KAAAF;EAAAE,EAAA,KAAAC;EAAAD,EAAA,KAAAE;EAAAF,EAAA,KAAAG;CAAA,OAAA;EAAAF,cAAAD,EAAA;EAAAE,QAAAF,EAAA;EAAAG,QAAAH,EAAA;CAAA;CACjC,MAAA,CAAAI,MAAAC,WAAwBtB,SAA+B,IAAI;CAC3D,MAAAuB,gBAAsBpB,wBAAwB;CAC9C,MAAAqB,kCAAwCzB,OAAO,KAAK;CAAE,IAAA0B;CAAA,IAAAC;CAAA,IAAAT,EAAA,OAAAM,eAAA;EAE5CE,WAAA;GAER,IAAAE,eAAkC;GAClC,IAAAC,kBAAsB;GAEtB,MAAAC,uBAAuB;IACrB,IAAIF,iBAAiB,MAAMG,qBAAqBH,YAAY;IAC5DA,eAAeI,4BAAsB;KACnCJ,eAAeA;KACf,MAAAK,MAAYC,OAAMC,aAAc;KAChC,IAAI,CAACF,OAAOA,IAAGG,aAAY;MACzBb,QAAQ,IAAI;MAAC;KAAA;KAIf,MAAAjB,OAAa2B,IAAGI,SAAU,CAAC,CAAAC,KAAM;KACjC,IAAI,CAAChC,MAAI;MACPiB,QAAQ,IAAI;MAAC;KAAA;KAIf,IAAIC,iBAAA,CAAkBA,cAAae,SAE/BC;UAAAA,QAAOC,IAAIC,aAAc,gBAAzB,CACCjB,gCAA+Bc,SAAQ;OAExCd,gCAA+Bc,UAAW;OAC1CI,QAAOC,KACL,oLACF;MAAC;;KAIL,MAAArC,YAAkBJ,sBAAsB8B,KAAKT,eAAae,OAAS;KACnE,IAAI,CAAChC,WAAS;MACZgB,QAAQ,IAAI;MAAC;KAAA;KAKf,MAAAf,OADcyB,IAAGa,WAAY,CAChBD,CAAK,CAAAE,sBAAuB;KACzCxB,QAAQ;MAAAjB;MAAAC;MAAAC;KAAwB,CAAC;IAAC,CACnC;GAnCW;GAsCd,MAAAwC,8BAA8B;IAC5B,MAAAC,QAAYf,OAAMC,aAAc;IAChC,IAAI,CAACF,SAAOA,MAAGG,aAAY;KACzB,IAAIR,iBAAiB,MAAI;MACvBG,qBAAqBH,YAAY;MACjCA,eAAeA;KAAH;KAEdL,QAAQ,IAAI;KAAC;IAAA;IAIf,IAAI,CAACM,iBAAiBC,eAAe;GAAE;GAGzC,MAAAoB,qBAAqB;IACnB,IAAItB,iBAAiB,MAAI;KACvBG,qBAAqBH,YAAY;KACjCA,eAAeA;IAAH;IAEdL,QAAQ,IAAI;GAAC;GAGf,MAAA4B,wBAAwB;IACtBtB,kBAAkBA;GAAH;GAGjB,MAAAuB,sBAAsB;IACpBvB,kBAAkBA;IAClBC,eAAe;GAAC;GAGlB,MAAAuB,0BAA0B;IACxBxB,kBAAkBA;GAAH;GAGjByB,SAAQC,iBAAkB,aAAaJ,iBAAiB,IAAI;GAC5DG,SAAQC,iBAAkB,WAAWH,eAAe,IAAI;GACxDE,SAAQC,iBAAkB,WAAWH,eAAe,IAAI;GAExDE,SAAQC,iBAAkB,eAAeF,mBAAmB,IAAI;GAChEnB,OAAMqB,iBAAkB,QAAQF,iBAAiB;GACjDC,SAAQC,iBAAkB,mBAAmBP,qBAAqB;GAClEM,SAAQC,iBAAkB,UAAUL,cAAc,IAAI;GAAC,aAEhD;IACL,IAAItB,iBAAiB,MAAMG,qBAAqBH,YAAY;IAC5D0B,SAAQE,oBAAqB,aAAaL,iBAAiB,IAAI;IAC/DG,SAAQE,oBAAqB,WAAWJ,eAAe,IAAI;IAC3DE,SAAQE,oBAAqB,WAAWJ,eAAe,IAAI;IAC3DE,SAAQE,oBAAqB,eAAeH,mBAAmB,IAAI;IACnEnB,OAAMsB,oBAAqB,QAAQH,iBAAiB;IACpDC,SAAQE,oBAAqB,mBAAmBR,qBAAqB;IACrEM,SAAQE,oBAAqB,UAAUN,cAAc,IAAI;GAAC;EAC3D;EACAvB,KAAA,CAACH,aAAa;EAACN,EAAA,KAAAM;EAAAN,EAAA,KAAAQ;EAAAR,EAAA,KAAAS;CAAA,OAAA;EAAAD,KAAAR,EAAA;EAAAS,KAAAT,EAAA;CAAA;CAnGlBnB,UAAU2B,IAmGPC,EAAe;CAElB,IAAI,CAACL,MAAI,OAAS;CAIX,MAAAmC,KAAA,GAAGnC,KAAId,KAAKkD,MAAO,EAAC;CACnB,MAAAC,KAAA,GAAGrC,KAAId,KAAKoD,OAAQtC,KAAId,KAAKqD,QAAS,EAAC;CAAI,IAAAC;CAAA,IAAA5C,EAAA,OAAAG,SAAAH,EAAA,OAAAuC,MAAAvC,EAAA,OAAAyC,IAAA;EAHRG,KAAA;GAAAC,UAC/B;GAAOL,KACZD;GAAwBG,MACvBD;GAA2CK,WACtC;GAAwBC,QAC3B;GAAE,GACP5C;EACL;EAACH,EAAA,KAAAG;EAAAH,EAAA,KAAAuC;EAAAvC,EAAA,KAAAyC;EAAAzC,EAAA,MAAA4C;CAAA,OAAAA,KAAA5C,EAAA;CAPD,MAAAgD,gBAA2CJ;CAOzC,IAAAK;CAAA,IAAAjD,EAAA,QAAAC,aAAA;EAQiBgD,KAAA1E,qBAAqB0B,aAAaiD,KAG9C;EAAClD,EAAA,MAAAC;EAAAD,EAAA,MAAAiD;CAAA,OAAAA,KAAAjD,EAAA;CAAA,IAAAmD;CAAA,IAAAnD,EAAA,QAAAD,gBAAAC,EAAA,QAAAgD,iBAAAhD,EAAA,QAAAE,SAAAF,EAAA,QAAAiD,IAAA;EAPJE,KAAA,oBAAAO,YAAA,KAAA;GAAA,GACMxD;GACCH,KAAAA;GACEiD,OAAAA;GACM,aAAAC;EAGX,CAAA;EACFjD,EAAA,MAAAD;EAAAC,EAAA,MAAAgD;EAAAhD,EAAA,MAAAE;EAAAF,EAAA,MAAAiD;EAAAjD,EAAA,MAAAmD;CAAA,OAAAA,KAAAnD,EAAA;CAAA,IAAAoD;CAAA,IAAApD,EAAA,QAAAI,QAAAJ,EAAA,QAAAmD,IAAA;EAVCC,KAAApE,aACL,oBAAA,wBAAA,UAAA;GAAyCoB,OAAAA;GACvC+C,UAAAA;EASF,CAAA,GACAf,SAAQiB,IACV;EAACrD,EAAA,MAAAI;EAAAJ,EAAA,MAAAmD;EAAAnD,EAAA,MAAAoD;CAAA,OAAAA,KAAApD,EAAA;CAAA,OAbMoD;AAaN,CACF;AAED1D,8BAA8B4D,cAAc;AArI1C,SAAAJ,MAAAK,GAAA;CA6HQA,EAACC,eAAgB;AAAC"}
1
+ {"version":3,"file":"SelectionToolbarRoot.js","names":["c","_c","Primitive","composeEventHandlers","ComponentPropsWithoutRef","ComponentRef","createContext","forwardRef","useContext","useEffect","useRef","useState","createPortal","getSelectionMessageId","useThreadRootElementRef","SelectionInfo","text","messageId","rect","DOMRect","SelectionToolbarContext","useSelectionToolbarInfo","SelectionToolbarPrimitiveRoot","Element","div","Props","t0","forwardedRef","$","onMouseDown","props","style","info","setInfo","threadRootRef","warnedAboutMissingThreadRootRef","t1","t2","pendingFrame","isMouseDragging","checkSelection","cancelAnimationFrame","requestAnimationFrame","sel","window","getSelection","isCollapsed","toString","trim","current","process","env","NODE_ENV","console","warn","range","getRangeAt","getBoundingClientRect","handleSelectionChange","sel_0","handleScroll","handleMouseDown","handleMouseUp","handleMouseCancel","handleWindowBlur","document","addEventListener","removeEventListener","t3","top","t4","left","width","t5","position","transform","zIndex","positionStyle","t6","_temp","t7","t8","body","displayName","e","preventDefault","_c","Primitive"],"sources":["../../../src/primitives/selectionToolbar/SelectionToolbarRoot.tsx"],"sourcesContent":["\"use client\";\n\nimport { Primitive } from \"../../utils/Primitive\";\nimport { composeEventHandlers } from \"radix-ui/internal\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { getSelectionMessageId } from \"../../utils/getSelectionMessageId\";\nimport { useThreadRootElementRef } from \"../thread/ThreadRootElementContext\";\n\ntype SelectionInfo = {\n text: string;\n messageId: string;\n rect: DOMRect;\n};\n\nconst SelectionToolbarContext = createContext<SelectionInfo | null>(null);\n\nexport const useSelectionToolbarInfo = () =>\n useContext(SelectionToolbarContext);\n\nexport namespace SelectionToolbarPrimitiveRoot {\n export type Element = ComponentRef<typeof Primitive.div>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.div>;\n}\n\n/**\n * A floating toolbar that appears when text is selected within a message.\n *\n * Listens for browser selection changes, validates that the selection is\n * within a single message, and renders a positioned portal near the\n * selection. Prevents mousedown from clearing the selection.\n *\n * @example\n * ```tsx\n * <SelectionToolbarPrimitive.Root>\n * <SelectionToolbarPrimitive.Quote>Quote</SelectionToolbarPrimitive.Quote>\n * </SelectionToolbarPrimitive.Root>\n * ```\n */\nexport const SelectionToolbarPrimitiveRoot = forwardRef<\n SelectionToolbarPrimitiveRoot.Element,\n SelectionToolbarPrimitiveRoot.Props\n>(({ onMouseDown, style, ...props }, forwardedRef) => {\n const [info, setInfo] = useState<SelectionInfo | null>(null);\n const threadRootRef = useThreadRootElementRef();\n const warnedAboutMissingThreadRootRef = useRef(false);\n\n useEffect(() => {\n // Read the selection on the next frame so the browser has settled it.\n let pendingFrame: number | null = null;\n let isMouseDragging = false;\n\n const checkSelection = () => {\n if (pendingFrame !== null) cancelAnimationFrame(pendingFrame);\n pendingFrame = requestAnimationFrame(() => {\n pendingFrame = null;\n const sel = window.getSelection();\n if (!sel || sel.isCollapsed) {\n setInfo(null);\n return;\n }\n\n const text = sel.toString().trim();\n if (!text) {\n setInfo(null);\n return;\n }\n\n if (threadRootRef && !threadRootRef.current) {\n if (\n process.env.NODE_ENV !== \"production\" &&\n !warnedAboutMissingThreadRootRef.current\n ) {\n warnedAboutMissingThreadRootRef.current = true;\n console.warn(\n \"[SelectionToolbarPrimitive.Root] ThreadPrimitive.Root did not provide a DOM element, so the selection cannot be scoped to its thread. Ensure a custom root child forwards its ref.\",\n );\n }\n }\n\n const messageId = getSelectionMessageId(sel, threadRootRef?.current);\n if (!messageId) {\n setInfo(null);\n return;\n }\n\n const range = sel.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n setInfo({ text, messageId, rect });\n });\n };\n\n const handleSelectionChange = () => {\n const sel = window.getSelection();\n if (!sel || sel.isCollapsed) {\n if (pendingFrame !== null) {\n cancelAnimationFrame(pendingFrame);\n pendingFrame = null;\n }\n setInfo(null);\n return;\n }\n\n if (!isMouseDragging) checkSelection();\n };\n\n const handleScroll = () => {\n if (pendingFrame !== null) {\n cancelAnimationFrame(pendingFrame);\n pendingFrame = null;\n }\n setInfo(null);\n };\n\n const handleMouseDown = () => {\n isMouseDragging = true;\n };\n\n const handleMouseUp = () => {\n isMouseDragging = false;\n checkSelection();\n };\n\n const handleMouseCancel = () => {\n isMouseDragging = false;\n };\n\n const handleWindowBlur = () => {\n if (isMouseDragging) handleMouseUp();\n };\n\n document.addEventListener(\"mousedown\", handleMouseDown, true);\n document.addEventListener(\"mouseup\", handleMouseUp, true);\n document.addEventListener(\"dragend\", handleMouseUp, true);\n // A context menu can consume the mouseup of the press that opened it.\n document.addEventListener(\"contextmenu\", handleMouseCancel, true);\n window.addEventListener(\"blur\", handleWindowBlur);\n document.addEventListener(\"selectionchange\", handleSelectionChange);\n document.addEventListener(\"scroll\", handleScroll, true);\n\n return () => {\n if (pendingFrame !== null) cancelAnimationFrame(pendingFrame);\n document.removeEventListener(\"mousedown\", handleMouseDown, true);\n document.removeEventListener(\"mouseup\", handleMouseUp, true);\n document.removeEventListener(\"dragend\", handleMouseUp, true);\n document.removeEventListener(\"contextmenu\", handleMouseCancel, true);\n window.removeEventListener(\"blur\", handleWindowBlur);\n document.removeEventListener(\"selectionchange\", handleSelectionChange);\n document.removeEventListener(\"scroll\", handleScroll, true);\n };\n }, [threadRootRef]);\n\n if (!info) return null;\n\n const positionStyle: React.CSSProperties = {\n position: \"fixed\",\n top: `${info.rect.top - 8}px`,\n left: `${info.rect.left + info.rect.width / 2}px`,\n transform: \"translate(-50%, -100%)\",\n zIndex: 50,\n ...style,\n };\n\n return createPortal(\n <SelectionToolbarContext.Provider value={info}>\n <Primitive.div\n {...props}\n ref={forwardedRef}\n style={positionStyle}\n onMouseDown={composeEventHandlers(onMouseDown, (e) => {\n // Prevent mousedown from clearing the text selection\n e.preventDefault();\n })}\n />\n </SelectionToolbarContext.Provider>,\n document.body,\n );\n});\n\nSelectionToolbarPrimitiveRoot.displayName = \"SelectionToolbarPrimitive.Root\";\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadViewport.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadViewport.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,iCAA8B;AAClD,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,wBAAwB,EAI9B,MAAM,OAAO,CAAC;AAiBf,yBAAiB,uBAAuB,CAAC;IACvC,KAAY,OAAO,GAAG,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;IACzD,KAAY,KAAK,GAAG,wBAAwB,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,GAAG;QACnE;;;;;WAKG;QACH,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjC;;;;WAIG;QACH,UAAU,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;QAE1C;;;;WAIG;QACH,qBAAqB,CAAC,EAAE;YACtB;;;;eAIG;YACH,UAAU,CAAC,EAAE,MAAM,CAAC;YACpB;;;;eAIG;YACH,aAAa,CAAC,EAAE,MAAM,CAAC;SACxB,CAAC;QAEF;;;;WAIG;QACH,wBAAwB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAE/C;;;;WAIG;QACH,0BAA0B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjD;;;;WAIG;QACH,4BAA4B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KACpD,CAAC;CACH;AA2GD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,uBAAuB;;;;;IAnLhC;;;;;OAKG;iBACU,OAAO,GAAG,SAAS;IAEhC;;;;OAIG;iBACU,KAAK,GAAG,QAAQ,GAAG,SAAS;IAEzC;;;;OAIG;4BACqB;QACtB;;;;WAIG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB;;;;WAIG;QACH,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB;IAED;;;;OAIG;+BACwB,OAAO,GAAG,SAAS;IAE9C;;;;OAIG;iCAC0B,OAAO,GAAG,SAAS;IAEhD;;;;OAIG;mCAC4B,OAAO,GAAG,SAAS;kDAwIpD,CAAC"}
1
+ {"version":3,"file":"ThreadViewport.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadViewport.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,iCAA8B;AAClD,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,wBAAwB,EAG9B,MAAM,OAAO,CAAC;AAkBf,yBAAiB,uBAAuB,CAAC;IACvC,KAAY,OAAO,GAAG,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;IACzD,KAAY,KAAK,GAAG,wBAAwB,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,GAAG;QACnE;;;;;WAKG;QACH,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjC;;;;WAIG;QACH,UAAU,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;QAE1C;;;;WAIG;QACH,qBAAqB,CAAC,EAAE;YACtB;;;;eAIG;YACH,UAAU,CAAC,EAAE,MAAM,CAAC;YACpB;;;;eAIG;YACH,aAAa,CAAC,EAAE,MAAM,CAAC;SACxB,CAAC;QAEF;;;;WAIG;QACH,wBAAwB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAE/C;;;;WAIG;QACH,0BAA0B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjD;;;;WAIG;QACH,4BAA4B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KACpD,CAAC;CACH;AA2GD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,uBAAuB;;;;;IAnLhC;;;;;OAKG;iBACU,OAAO,GAAG,SAAS;IAEhC;;;;OAIG;iBACU,KAAK,GAAG,QAAQ,GAAG,SAAS;IAEzC;;;;OAIG;4BACqB;QACtB;;;;WAIG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB;;;;WAIG;QACH,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB;IAED;;;;OAIG;+BACwB,OAAO,GAAG,SAAS;IAE9C;;;;OAIG;iCAC0B,OAAO,GAAG,SAAS;IAEhD;;;;OAIG;mCAC4B,OAAO,GAAG,SAAS;kDAwIpD,CAAC"}
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { useThreadViewport, useThreadViewportStore } from "../../context/react/ThreadViewportContext.js";
3
3
  import { ThreadPrimitiveViewportProvider } from "../../context/providers/ThreadViewportProvider.js";
4
+ import { useIsomorphicLayoutEffect } from "../../utils/useIsomorphicLayoutEffect.js";
4
5
  import { Primitive as Primitive$1 } from "../../utils/Primitive.js";
5
6
  import { useManagedRef } from "../../utils/hooks/useManagedRef.js";
6
7
  import { useThreadViewportAutoScroll } from "./useThreadViewportAutoScroll.js";
@@ -8,7 +9,7 @@ import { useSizeHandle } from "../../utils/hooks/useSizeHandle.js";
8
9
  import { useTopAnchorReserve } from "./topAnchor/useTopAnchorReserve.js";
9
10
  import { getActiveTopAnchorAnchorId, getActiveTopAnchorTargetId, isTopAnchorTurnValid } from "./topAnchor/topAnchorTurn.js";
10
11
  import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
11
- import { forwardRef, useLayoutEffect } from "@assistant-ui/tap/react-shim";
12
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
12
13
  import { useAuiState } from "@assistant-ui/store";
13
14
  import { jsx } from "react/jsx-runtime";
14
15
  import { useComposedRefs } from "radix-ui/internal";
@@ -93,7 +94,7 @@ const useTopAnchorTurn = (enabled) => {
93
94
  t4 = $[13];
94
95
  t5 = $[14];
95
96
  }
96
- useLayoutEffect(t4, t5);
97
+ useIsomorphicLayoutEffect(t4, t5);
97
98
  let t6;
98
99
  let t7;
99
100
  if ($[15] !== activeTurn || $[16] !== threadViewportStore) {
@@ -113,7 +114,7 @@ const useTopAnchorTurn = (enabled) => {
113
114
  t6 = $[17];
114
115
  t7 = $[18];
115
116
  }
116
- useLayoutEffect(t6, t7);
117
+ useIsomorphicLayoutEffect(t6, t7);
117
118
  };
118
119
  const ThreadPrimitiveViewportScrollable = forwardRef((t0, forwardedRef) => {
119
120
  const $ = c(18);
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadViewport.js","names":["c","_c","useComposedRefs","Primitive","ComponentRef","forwardRef","ComponentPropsWithoutRef","useCallback","useLayoutEffect","useMemo","useAuiState","useManagedRef","useThreadViewportAutoScroll","ThreadPrimitiveViewportProvider","useSizeHandle","useThreadViewport","useThreadViewportStore","useTopAnchorReserve","getActiveTopAnchorAnchorId","getActiveTopAnchorTargetId","isTopAnchorTurnValid","ThreadPrimitiveViewport","Element","div","Props","autoScroll","turnAnchor","topAnchorMessageClamp","tallerThan","visibleHeight","scrollToBottomOnRunStart","scrollToBottomOnInitialize","scrollToBottomOnThreadSwitch","useViewportSizeRef","register","_temp","getHeight","_temp2","useViewportElementRef","registerViewportElement","_temp3","useTopAnchorTurn","enabled","$","threadViewportStore","t0","s","thread","activeAnchorId","t1","s_0","activeTargetId","topAnchorTurn","_temp4","t2","bb0","t3","anchorId","targetId","activeTurn","s_2","messages","topAnchorTurnIsValid","t4","t5","getState","setTopAnchorTurn","t6","t7","state","current","ThreadPrimitiveViewportScrollable","forwardedRef","children","rest","autoScrollRef","viewportSizeRef","viewportElementRef","topAnchorEnabled","ref","displayName","props","registerViewport","el","clientHeight","s_1","getHeight","_c","Primitive"],"sources":["../../../src/primitives/thread/ThreadViewport.tsx"],"sourcesContent":["\"use client\";\n\nimport { useComposedRefs } from \"radix-ui/internal\";\nimport { Primitive } from \"../../utils/Primitive\";\nimport {\n type ComponentRef,\n forwardRef,\n type ComponentPropsWithoutRef,\n useCallback,\n useLayoutEffect,\n useMemo,\n} from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\nimport { useManagedRef } from \"../../utils/hooks/useManagedRef\";\nimport { useThreadViewportAutoScroll } from \"./useThreadViewportAutoScroll\";\nimport { ThreadPrimitiveViewportProvider } from \"../../context/providers/ThreadViewportProvider\";\nimport { useSizeHandle } from \"../../utils/hooks/useSizeHandle\";\nimport {\n useThreadViewport,\n useThreadViewportStore,\n} from \"../../context/react/ThreadViewportContext\";\nimport { useTopAnchorReserve } from \"./topAnchor/useTopAnchorReserve\";\nimport {\n getActiveTopAnchorAnchorId,\n getActiveTopAnchorTargetId,\n isTopAnchorTurnValid,\n} from \"./topAnchor/topAnchorTurn\";\n\nexport namespace ThreadPrimitiveViewport {\n export type Element = ComponentRef<typeof Primitive.div>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.div> & {\n /**\n * Whether to automatically scroll to the bottom when new messages are added.\n * When enabled, the viewport will automatically scroll to show the latest content.\n *\n * Default false if `turnAnchor` is \"top\", otherwise defaults to true.\n */\n autoScroll?: boolean | undefined;\n\n /**\n * Controls scroll anchoring behavior for new messages.\n * - \"bottom\" (default): Messages anchor at the bottom, classic chat behavior.\n * - \"top\": New user messages anchor at the top of the viewport for a focused reading experience.\n */\n turnAnchor?: \"top\" | \"bottom\" | undefined;\n\n /**\n * Clamps tall user messages so the assistant response stays in view.\n *\n * @default { tallerThan: \"10em\", visibleHeight: \"6em\" }\n */\n topAnchorMessageClamp?: {\n /**\n * Clamp messages taller than this. Supports `px`, `em`, and `rem`.\n *\n * @default \"10em\"\n */\n tallerThan?: string;\n /**\n * Visible portion of clamped messages. Supports `px`, `em`, and `rem`.\n *\n * @default \"6em\"\n */\n visibleHeight?: string;\n };\n\n /**\n * Whether to scroll to bottom when a new run starts.\n *\n * Defaults to true.\n */\n scrollToBottomOnRunStart?: boolean | undefined;\n\n /**\n * Whether to scroll to bottom when thread history is first loaded.\n *\n * Defaults to true.\n */\n scrollToBottomOnInitialize?: boolean | undefined;\n\n /**\n * Whether to scroll to bottom when switching to a different thread.\n *\n * Defaults to true.\n */\n scrollToBottomOnThreadSwitch?: boolean | undefined;\n };\n}\n\nconst useViewportSizeRef = () => {\n const register = useThreadViewport((s) => s.registerViewport);\n const getHeight = useCallback((el: HTMLElement) => el.clientHeight, []);\n return useSizeHandle(register, getHeight);\n};\n\nconst useViewportElementRef = () => {\n const registerViewportElement = useThreadViewport(\n (s) => s.registerViewportElement,\n );\n\n return useManagedRef(registerViewportElement);\n};\n\nconst useTopAnchorTurn = (enabled: boolean) => {\n const threadViewportStore = useThreadViewportStore();\n const activeAnchorId = useAuiState((s) => {\n if (!enabled) return undefined;\n return getActiveTopAnchorAnchorId(s.thread);\n });\n const activeTargetId = useAuiState((s) => {\n if (!enabled) return undefined;\n return getActiveTopAnchorTargetId(s.thread);\n });\n const topAnchorTurn = useThreadViewport((s) => s.topAnchorTurn);\n const activeTurn = useMemo(() => {\n if (!activeAnchorId || !activeTargetId) return null;\n return { anchorId: activeAnchorId, targetId: activeTargetId };\n }, [activeAnchorId, activeTargetId]);\n\n const topAnchorTurnIsValid = useAuiState(\n (s) =>\n enabled &&\n !!topAnchorTurn &&\n isTopAnchorTurnValid(topAnchorTurn, s.thread.messages),\n );\n\n useLayoutEffect(() => {\n if (!topAnchorTurn || topAnchorTurnIsValid) return;\n\n threadViewportStore.getState().setTopAnchorTurn(null);\n }, [threadViewportStore, topAnchorTurn, topAnchorTurnIsValid]);\n\n useLayoutEffect(() => {\n if (!activeTurn) return;\n\n const state = threadViewportStore.getState();\n const current = state.topAnchorTurn;\n if (\n current?.anchorId === activeTurn.anchorId &&\n current.targetId === activeTurn.targetId\n ) {\n return;\n }\n\n state.setTopAnchorTurn(activeTurn);\n }, [activeTurn, threadViewportStore]);\n};\n\nconst ThreadPrimitiveViewportScrollable = forwardRef<\n ThreadPrimitiveViewport.Element,\n ThreadPrimitiveViewport.Props\n>(\n (\n {\n autoScroll,\n scrollToBottomOnRunStart,\n scrollToBottomOnInitialize,\n scrollToBottomOnThreadSwitch,\n children,\n ...rest\n },\n forwardedRef,\n ) => {\n const autoScrollRef = useThreadViewportAutoScroll<HTMLDivElement>({\n autoScroll,\n scrollToBottomOnRunStart,\n scrollToBottomOnInitialize,\n scrollToBottomOnThreadSwitch,\n });\n const viewportSizeRef = useViewportSizeRef();\n const viewportElementRef = useViewportElementRef();\n const threadViewportStore = useThreadViewportStore();\n const turnAnchor = threadViewportStore.getState().turnAnchor;\n const topAnchorEnabled = turnAnchor === \"top\";\n useTopAnchorTurn(topAnchorEnabled);\n useTopAnchorReserve(topAnchorEnabled);\n const ref = useComposedRefs(\n forwardedRef,\n autoScrollRef,\n viewportSizeRef,\n viewportElementRef,\n );\n\n return (\n <Primitive.div {...rest} ref={ref}>\n {children}\n </Primitive.div>\n );\n },\n);\n\nThreadPrimitiveViewportScrollable.displayName =\n \"ThreadPrimitive.ViewportScrollable\";\n\n/**\n * A scrollable viewport container for thread messages.\n *\n * This component provides a scrollable area for displaying thread messages with\n * automatic scrolling capabilities. It manages the viewport state and provides\n * context for child components to access viewport-related functionality.\n *\n * @example\n * ```tsx\n * <ThreadPrimitive.Viewport turnAnchor=\"top\">\n * <ThreadPrimitive.Messages>\n * {() => <MyMessage />}\n * </ThreadPrimitive.Messages>\n * </ThreadPrimitive.Viewport>\n * ```\n */\nexport const ThreadPrimitiveViewport = forwardRef<\n ThreadPrimitiveViewport.Element,\n ThreadPrimitiveViewport.Props\n>(({ turnAnchor, topAnchorMessageClamp, ...props }, ref) => {\n return (\n <ThreadPrimitiveViewportProvider\n options={{ turnAnchor, topAnchorMessageClamp }}\n >\n <ThreadPrimitiveViewportScrollable {...props} ref={ref} />\n </ThreadPrimitiveViewportProvider>\n );\n});\n\nThreadPrimitiveViewport.displayName = \"ThreadPrimitive.Viewport\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"ThreadViewport.js","names":["c","_c","useComposedRefs","Primitive","ComponentRef","forwardRef","ComponentPropsWithoutRef","useCallback","useMemo","useAuiState","useManagedRef","useThreadViewportAutoScroll","ThreadPrimitiveViewportProvider","useSizeHandle","useThreadViewport","useThreadViewportStore","useTopAnchorReserve","useIsomorphicLayoutEffect","getActiveTopAnchorAnchorId","getActiveTopAnchorTargetId","isTopAnchorTurnValid","ThreadPrimitiveViewport","Element","div","Props","autoScroll","turnAnchor","topAnchorMessageClamp","tallerThan","visibleHeight","scrollToBottomOnRunStart","scrollToBottomOnInitialize","scrollToBottomOnThreadSwitch","useViewportSizeRef","register","_temp","getHeight","_temp2","useViewportElementRef","registerViewportElement","_temp3","useTopAnchorTurn","enabled","$","threadViewportStore","t0","s","thread","activeAnchorId","t1","s_0","activeTargetId","topAnchorTurn","_temp4","t2","bb0","t3","anchorId","targetId","activeTurn","s_2","messages","topAnchorTurnIsValid","t4","t5","getState","setTopAnchorTurn","t6","t7","state","current","ThreadPrimitiveViewportScrollable","forwardedRef","children","rest","autoScrollRef","viewportSizeRef","viewportElementRef","topAnchorEnabled","ref","displayName","props","registerViewport","el","clientHeight","s_1","getHeight","_c","Primitive"],"sources":["../../../src/primitives/thread/ThreadViewport.tsx"],"sourcesContent":["\"use client\";\n\nimport { useComposedRefs } from \"radix-ui/internal\";\nimport { Primitive } from \"../../utils/Primitive\";\nimport {\n type ComponentRef,\n forwardRef,\n type ComponentPropsWithoutRef,\n useCallback,\n useMemo,\n} from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\nimport { useManagedRef } from \"../../utils/hooks/useManagedRef\";\nimport { useThreadViewportAutoScroll } from \"./useThreadViewportAutoScroll\";\nimport { ThreadPrimitiveViewportProvider } from \"../../context/providers/ThreadViewportProvider\";\nimport { useSizeHandle } from \"../../utils/hooks/useSizeHandle\";\nimport {\n useThreadViewport,\n useThreadViewportStore,\n} from \"../../context/react/ThreadViewportContext\";\nimport { useTopAnchorReserve } from \"./topAnchor/useTopAnchorReserve\";\nimport { useIsomorphicLayoutEffect } from \"../../utils/useIsomorphicLayoutEffect\";\nimport {\n getActiveTopAnchorAnchorId,\n getActiveTopAnchorTargetId,\n isTopAnchorTurnValid,\n} from \"./topAnchor/topAnchorTurn\";\n\nexport namespace ThreadPrimitiveViewport {\n export type Element = ComponentRef<typeof Primitive.div>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.div> & {\n /**\n * Whether to automatically scroll to the bottom when new messages are added.\n * When enabled, the viewport will automatically scroll to show the latest content.\n *\n * Default false if `turnAnchor` is \"top\", otherwise defaults to true.\n */\n autoScroll?: boolean | undefined;\n\n /**\n * Controls scroll anchoring behavior for new messages.\n * - \"bottom\" (default): Messages anchor at the bottom, classic chat behavior.\n * - \"top\": New user messages anchor at the top of the viewport for a focused reading experience.\n */\n turnAnchor?: \"top\" | \"bottom\" | undefined;\n\n /**\n * Clamps tall user messages so the assistant response stays in view.\n *\n * @default { tallerThan: \"10em\", visibleHeight: \"6em\" }\n */\n topAnchorMessageClamp?: {\n /**\n * Clamp messages taller than this. Supports `px`, `em`, and `rem`.\n *\n * @default \"10em\"\n */\n tallerThan?: string;\n /**\n * Visible portion of clamped messages. Supports `px`, `em`, and `rem`.\n *\n * @default \"6em\"\n */\n visibleHeight?: string;\n };\n\n /**\n * Whether to scroll to bottom when a new run starts.\n *\n * Defaults to true.\n */\n scrollToBottomOnRunStart?: boolean | undefined;\n\n /**\n * Whether to scroll to bottom when thread history is first loaded.\n *\n * Defaults to true.\n */\n scrollToBottomOnInitialize?: boolean | undefined;\n\n /**\n * Whether to scroll to bottom when switching to a different thread.\n *\n * Defaults to true.\n */\n scrollToBottomOnThreadSwitch?: boolean | undefined;\n };\n}\n\nconst useViewportSizeRef = () => {\n const register = useThreadViewport((s) => s.registerViewport);\n const getHeight = useCallback((el: HTMLElement) => el.clientHeight, []);\n return useSizeHandle(register, getHeight);\n};\n\nconst useViewportElementRef = () => {\n const registerViewportElement = useThreadViewport(\n (s) => s.registerViewportElement,\n );\n\n return useManagedRef(registerViewportElement);\n};\n\nconst useTopAnchorTurn = (enabled: boolean) => {\n const threadViewportStore = useThreadViewportStore();\n const activeAnchorId = useAuiState((s) => {\n if (!enabled) return undefined;\n return getActiveTopAnchorAnchorId(s.thread);\n });\n const activeTargetId = useAuiState((s) => {\n if (!enabled) return undefined;\n return getActiveTopAnchorTargetId(s.thread);\n });\n const topAnchorTurn = useThreadViewport((s) => s.topAnchorTurn);\n const activeTurn = useMemo(() => {\n if (!activeAnchorId || !activeTargetId) return null;\n return { anchorId: activeAnchorId, targetId: activeTargetId };\n }, [activeAnchorId, activeTargetId]);\n\n const topAnchorTurnIsValid = useAuiState(\n (s) =>\n enabled &&\n !!topAnchorTurn &&\n isTopAnchorTurnValid(topAnchorTurn, s.thread.messages),\n );\n\n useIsomorphicLayoutEffect(() => {\n if (!topAnchorTurn || topAnchorTurnIsValid) return;\n\n threadViewportStore.getState().setTopAnchorTurn(null);\n }, [threadViewportStore, topAnchorTurn, topAnchorTurnIsValid]);\n\n useIsomorphicLayoutEffect(() => {\n if (!activeTurn) return;\n\n const state = threadViewportStore.getState();\n const current = state.topAnchorTurn;\n if (\n current?.anchorId === activeTurn.anchorId &&\n current.targetId === activeTurn.targetId\n ) {\n return;\n }\n\n state.setTopAnchorTurn(activeTurn);\n }, [activeTurn, threadViewportStore]);\n};\n\nconst ThreadPrimitiveViewportScrollable = forwardRef<\n ThreadPrimitiveViewport.Element,\n ThreadPrimitiveViewport.Props\n>(\n (\n {\n autoScroll,\n scrollToBottomOnRunStart,\n scrollToBottomOnInitialize,\n scrollToBottomOnThreadSwitch,\n children,\n ...rest\n },\n forwardedRef,\n ) => {\n const autoScrollRef = useThreadViewportAutoScroll<HTMLDivElement>({\n autoScroll,\n scrollToBottomOnRunStart,\n scrollToBottomOnInitialize,\n scrollToBottomOnThreadSwitch,\n });\n const viewportSizeRef = useViewportSizeRef();\n const viewportElementRef = useViewportElementRef();\n const threadViewportStore = useThreadViewportStore();\n const turnAnchor = threadViewportStore.getState().turnAnchor;\n const topAnchorEnabled = turnAnchor === \"top\";\n useTopAnchorTurn(topAnchorEnabled);\n useTopAnchorReserve(topAnchorEnabled);\n const ref = useComposedRefs(\n forwardedRef,\n autoScrollRef,\n viewportSizeRef,\n viewportElementRef,\n );\n\n return (\n <Primitive.div {...rest} ref={ref}>\n {children}\n </Primitive.div>\n );\n },\n);\n\nThreadPrimitiveViewportScrollable.displayName =\n \"ThreadPrimitive.ViewportScrollable\";\n\n/**\n * A scrollable viewport container for thread messages.\n *\n * This component provides a scrollable area for displaying thread messages with\n * automatic scrolling capabilities. It manages the viewport state and provides\n * context for child components to access viewport-related functionality.\n *\n * @example\n * ```tsx\n * <ThreadPrimitive.Viewport turnAnchor=\"top\">\n * <ThreadPrimitive.Messages>\n * {() => <MyMessage />}\n * </ThreadPrimitive.Messages>\n * </ThreadPrimitive.Viewport>\n * ```\n */\nexport const ThreadPrimitiveViewport = forwardRef<\n ThreadPrimitiveViewport.Element,\n ThreadPrimitiveViewport.Props\n>(({ turnAnchor, topAnchorMessageClamp, ...props }, ref) => {\n return (\n <ThreadPrimitiveViewportProvider\n options={{ turnAnchor, topAnchorMessageClamp }}\n >\n <ThreadPrimitiveViewportScrollable {...props} ref={ref} />\n </ThreadPrimitiveViewportProvider>\n );\n});\n\nThreadPrimitiveViewport.displayName = \"ThreadPrimitive.Viewport\";\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { useThreadViewportStore } from "../../../context/react/ThreadViewportContext.js";
3
+ import { useIsomorphicLayoutEffect } from "../../../utils/useIsomorphicLayoutEffect.js";
3
4
  import { mountTopAnchorReserve } from "./mountTopAnchorReserve.js";
4
5
  import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
5
- import { useLayoutEffect } from "@assistant-ui/tap/react-shim";
6
6
  //#region src/primitives/thread/topAnchor/useTopAnchorReserve.ts
7
7
  /**
8
8
  * Mounts the top-turn-anchor reserve element against the active
@@ -28,7 +28,7 @@ const useTopAnchorReserve = (enabled) => {
28
28
  t0 = $[2];
29
29
  t1 = $[3];
30
30
  }
31
- useLayoutEffect(t0, t1);
31
+ useIsomorphicLayoutEffect(t0, t1);
32
32
  };
33
33
  //#endregion
34
34
  export { useTopAnchorReserve };
@@ -1 +1 @@
1
- {"version":3,"file":"useTopAnchorReserve.js","names":["c","_c","useLayoutEffect","useThreadViewportStore","mountTopAnchorReserve","useTopAnchorReserve","enabled","$","threadViewportStore","t0","t1","_c"],"sources":["../../../../src/primitives/thread/topAnchor/useTopAnchorReserve.ts"],"sourcesContent":["\"use client\";\n\nimport { useLayoutEffect } from \"react\";\nimport { useThreadViewportStore } from \"../../../context/react/ThreadViewportContext\";\nimport { mountTopAnchorReserve } from \"./mountTopAnchorReserve\";\n\n/**\n * Mounts the top-turn-anchor reserve element against the active\n * `ThreadViewport` store. Call this from inside the scrollable viewport so\n * the reserve `<div>` is appended next to the streaming assistant message.\n */\nexport const useTopAnchorReserve = (enabled: boolean) => {\n const threadViewportStore = useThreadViewportStore();\n\n useLayoutEffect(() => {\n if (!enabled) return;\n return mountTopAnchorReserve(threadViewportStore);\n }, [enabled, threadViewportStore]);\n};\n"],"mappings":";;;;;;;;;;;AAWA,MAAaK,uBAAsBC,YAAA;CAAA,MAAAC,IAAAN,EAAA,CAAA;CACjC,MAAAO,sBAA4BL,uBAAuB;CAAE,IAAAM;CAAA,IAAAC;CAAA,IAAAH,EAAA,OAAAD,WAAAC,EAAA,OAAAC,qBAAA;EAErCC,WAAA;GACd,IAAI,CAACH,SAAO;GAAS,OACdF,sBAAsBI,mBAAmB;EAAC;EAChDE,KAAA,CAACJ,SAASE,mBAAmB;EAACD,EAAA,KAAAD;EAAAC,EAAA,KAAAC;EAAAD,EAAA,KAAAE;EAAAF,EAAA,KAAAG;CAAA,OAAA;EAAAD,KAAAF,EAAA;EAAAG,KAAAH,EAAA;CAAA;CAHjCL,gBAAgBO,IAGbC,EAA8B;AAAC"}
1
+ {"version":3,"file":"useTopAnchorReserve.js","names":["c","_c","useIsomorphicLayoutEffect","useThreadViewportStore","mountTopAnchorReserve","useTopAnchorReserve","enabled","$","threadViewportStore","t0","t1","_c"],"sources":["../../../../src/primitives/thread/topAnchor/useTopAnchorReserve.ts"],"sourcesContent":["\"use client\";\n\nimport { useIsomorphicLayoutEffect } from \"../../../utils/useIsomorphicLayoutEffect\";\nimport { useThreadViewportStore } from \"../../../context/react/ThreadViewportContext\";\nimport { mountTopAnchorReserve } from \"./mountTopAnchorReserve\";\n\n/**\n * Mounts the top-turn-anchor reserve element against the active\n * `ThreadViewport` store. Call this from inside the scrollable viewport so\n * the reserve `<div>` is appended next to the streaming assistant message.\n */\nexport const useTopAnchorReserve = (enabled: boolean) => {\n const threadViewportStore = useThreadViewportStore();\n\n useIsomorphicLayoutEffect(() => {\n if (!enabled) return;\n return mountTopAnchorReserve(threadViewportStore);\n }, [enabled, threadViewportStore]);\n};\n"],"mappings":";;;;;;;;;;;AAWA,MAAaK,uBAAsBC,YAAA;CAAA,MAAAC,IAAAN,EAAA,CAAA;CACjC,MAAAO,sBAA4BL,uBAAuB;CAAE,IAAAM;CAAA,IAAAC;CAAA,IAAAH,EAAA,OAAAD,WAAAC,EAAA,OAAAC,qBAAA;EAE3BC,WAAA;GACxB,IAAI,CAACH,SAAO;GAAS,OACdF,sBAAsBI,mBAAmB;EAAC;EAChDE,KAAA,CAACJ,SAASE,mBAAmB;EAACD,EAAA,KAAAD;EAAAC,EAAA,KAAAC;EAAAD,EAAA,KAAAE;EAAAF,EAAA,KAAAG;CAAA,OAAA;EAAAD,KAAAF,EAAA;EAAAG,KAAAH,EAAA;CAAA;CAHjCL,0BAA0BO,IAGvBC,EAA8B;AAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useThreadViewportAutoScroll.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/useThreadViewportAutoScroll.ts"],"names":[],"mappings":"AAGA,OAAO,EAAwC,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AA+F/E,yBAAiB,2BAA2B,CAAC;IAC3C,KAAY,OAAO,GAAG;QACpB;;;;;WAKG;QACH,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjC;;;;WAIG;QACH,wBAAwB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAE/C;;;;WAIG;QACH,0BAA0B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjD;;;;WAIG;QACH,4BAA4B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KACpD,CAAC;CACH;AAED,eAAO,MAAM,2BAA2B,GAAI,QAAQ,SAAS,WAAW,EAAE,qGAKvE,2BAA2B,CAAC,OAAO,KAAG,WAAW,CAAC,QAAQ,CAwS5D,CAAC"}
1
+ {"version":3,"file":"useThreadViewportAutoScroll.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/useThreadViewportAutoScroll.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AAwH9D,yBAAiB,2BAA2B,CAAC;IAC3C,KAAY,OAAO,GAAG;QACpB;;;;;WAKG;QACH,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjC;;;;WAIG;QACH,wBAAwB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAE/C;;;;WAIG;QACH,0BAA0B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjD;;;;WAIG;QACH,4BAA4B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KACpD,CAAC;CACH;AAED,eAAO,MAAM,2BAA2B,GAAI,QAAQ,SAAS,WAAW,EAAE,qGAKvE,2BAA2B,CAAC,OAAO,KAAG,WAAW,CAAC,QAAQ,CA+Y5D,CAAC"}