@assistant-ui/react-native 0.1.29 → 0.1.31

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 (133) hide show
  1. package/dist/index.d.ts +2 -2
  2. package/dist/primitives/actionBar/ActionBarCopy.d.ts +1 -8
  3. package/dist/primitives/actionBar/ActionBarCopy.d.ts.map +1 -1
  4. package/dist/primitives/actionBar/ActionBarCopy.js.map +1 -1
  5. package/dist/primitives/actionBar/ActionBarEdit.d.ts +1 -6
  6. package/dist/primitives/actionBar/ActionBarEdit.d.ts.map +1 -1
  7. package/dist/primitives/actionBar/ActionBarFeedbackNegative.d.ts +1 -5
  8. package/dist/primitives/actionBar/ActionBarFeedbackNegative.d.ts.map +1 -1
  9. package/dist/primitives/actionBar/ActionBarFeedbackNegative.js.map +1 -1
  10. package/dist/primitives/actionBar/ActionBarFeedbackPositive.d.ts +1 -5
  11. package/dist/primitives/actionBar/ActionBarFeedbackPositive.d.ts.map +1 -1
  12. package/dist/primitives/actionBar/ActionBarFeedbackPositive.js.map +1 -1
  13. package/dist/primitives/actionBar/ActionBarReload.d.ts +1 -6
  14. package/dist/primitives/actionBar/ActionBarReload.d.ts.map +1 -1
  15. package/dist/primitives/actionBar.d.ts +0 -2
  16. package/dist/primitives/attachment/AttachmentName.d.ts +0 -1
  17. package/dist/primitives/attachment/AttachmentName.d.ts.map +1 -1
  18. package/dist/primitives/attachment/AttachmentName.js.map +1 -1
  19. package/dist/primitives/attachment/AttachmentRemove.d.ts +1 -5
  20. package/dist/primitives/attachment/AttachmentRemove.d.ts.map +1 -1
  21. package/dist/primitives/attachment/AttachmentRoot.d.ts +1 -5
  22. package/dist/primitives/attachment/AttachmentRoot.d.ts.map +1 -1
  23. package/dist/primitives/attachment/AttachmentThumb.d.ts +0 -1
  24. package/dist/primitives/attachment/AttachmentThumb.d.ts.map +1 -1
  25. package/dist/primitives/attachment/AttachmentThumb.js.map +1 -1
  26. package/dist/primitives/attachment.d.ts +0 -2
  27. package/dist/primitives/branchPicker/BranchPickerCount.d.ts +0 -1
  28. package/dist/primitives/branchPicker/BranchPickerCount.d.ts.map +1 -1
  29. package/dist/primitives/branchPicker/BranchPickerCount.js.map +1 -1
  30. package/dist/primitives/branchPicker/BranchPickerNext.d.ts +1 -6
  31. package/dist/primitives/branchPicker/BranchPickerNext.d.ts.map +1 -1
  32. package/dist/primitives/branchPicker/BranchPickerNumber.d.ts +0 -1
  33. package/dist/primitives/branchPicker/BranchPickerNumber.d.ts.map +1 -1
  34. package/dist/primitives/branchPicker/BranchPickerNumber.js.map +1 -1
  35. package/dist/primitives/branchPicker/BranchPickerPrevious.d.ts +1 -6
  36. package/dist/primitives/branchPicker/BranchPickerPrevious.d.ts.map +1 -1
  37. package/dist/primitives/branchPicker.d.ts +0 -2
  38. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.d.ts +1 -5
  39. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.d.ts.map +1 -1
  40. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.d.ts +1 -5
  41. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.d.ts.map +1 -1
  42. package/dist/primitives/chainOfThought.d.ts +0 -2
  43. package/dist/primitives/composer/ComposerAddAttachment.d.ts +1 -6
  44. package/dist/primitives/composer/ComposerAddAttachment.d.ts.map +1 -1
  45. package/dist/primitives/composer/ComposerAttachments.d.ts +3 -16
  46. package/dist/primitives/composer/ComposerAttachments.d.ts.map +1 -1
  47. package/dist/primitives/composer/ComposerAttachments.js.map +1 -1
  48. package/dist/primitives/composer/ComposerCancel.d.ts +1 -6
  49. package/dist/primitives/composer/ComposerCancel.d.ts.map +1 -1
  50. package/dist/primitives/composer/ComposerInput.d.ts +1 -8
  51. package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
  52. package/dist/primitives/composer/ComposerInput.js +15 -2
  53. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  54. package/dist/primitives/composer/ComposerRoot.d.ts +1 -5
  55. package/dist/primitives/composer/ComposerRoot.d.ts.map +1 -1
  56. package/dist/primitives/composer/ComposerSend.d.ts +1 -6
  57. package/dist/primitives/composer/ComposerSend.d.ts.map +1 -1
  58. package/dist/primitives/composer.d.ts +3 -5
  59. package/dist/primitives/composer.js.map +1 -1
  60. package/dist/primitives/error/ErrorMessage.d.ts +1 -5
  61. package/dist/primitives/error/ErrorMessage.d.ts.map +1 -1
  62. package/dist/primitives/error/ErrorMessage.js.map +1 -1
  63. package/dist/primitives/error/ErrorRoot.d.ts +1 -5
  64. package/dist/primitives/error/ErrorRoot.d.ts.map +1 -1
  65. package/dist/primitives/error/index.d.ts +0 -2
  66. package/dist/primitives/message/MessageAttachments.d.ts +2 -9
  67. package/dist/primitives/message/MessageAttachments.d.ts.map +1 -1
  68. package/dist/primitives/message/MessageAttachments.js.map +1 -1
  69. package/dist/primitives/message/MessageContent.d.ts +1 -10
  70. package/dist/primitives/message/MessageContent.d.ts.map +1 -1
  71. package/dist/primitives/message/MessageIf.d.ts +1 -8
  72. package/dist/primitives/message/MessageIf.d.ts.map +1 -1
  73. package/dist/primitives/message/MessageIf.js.map +1 -1
  74. package/dist/primitives/message/MessageParts.d.ts +0 -1
  75. package/dist/primitives/message/MessageParts.d.ts.map +1 -1
  76. package/dist/primitives/message/MessageRoot.d.ts +1 -5
  77. package/dist/primitives/message/MessageRoot.d.ts.map +1 -1
  78. package/dist/primitives/message.d.ts +3 -5
  79. package/dist/primitives/message.js.map +1 -1
  80. package/dist/primitives/suggestion/SuggestionDescription.d.ts +1 -5
  81. package/dist/primitives/suggestion/SuggestionDescription.d.ts.map +1 -1
  82. package/dist/primitives/suggestion/SuggestionDescription.js.map +1 -1
  83. package/dist/primitives/suggestion/SuggestionTitle.d.ts +1 -5
  84. package/dist/primitives/suggestion/SuggestionTitle.d.ts.map +1 -1
  85. package/dist/primitives/suggestion/SuggestionTitle.js.map +1 -1
  86. package/dist/primitives/suggestion/SuggestionTrigger.d.ts +1 -8
  87. package/dist/primitives/suggestion/SuggestionTrigger.d.ts.map +1 -1
  88. package/dist/primitives/suggestion.d.ts +0 -2
  89. package/dist/primitives/thread/ThreadEmpty.d.ts +1 -4
  90. package/dist/primitives/thread/ThreadEmpty.d.ts.map +1 -1
  91. package/dist/primitives/thread/ThreadIf.d.ts +1 -6
  92. package/dist/primitives/thread/ThreadIf.d.ts.map +1 -1
  93. package/dist/primitives/thread/ThreadIf.js.map +1 -1
  94. package/dist/primitives/thread/ThreadMessages.d.ts +14 -12
  95. package/dist/primitives/thread/ThreadMessages.d.ts.map +1 -1
  96. package/dist/primitives/thread/ThreadMessages.js +376 -33
  97. package/dist/primitives/thread/ThreadMessages.js.map +1 -1
  98. package/dist/primitives/thread/ThreadRoot.d.ts +1 -5
  99. package/dist/primitives/thread/ThreadRoot.d.ts.map +1 -1
  100. package/dist/primitives/thread/ThreadSuggestion.d.ts +3 -10
  101. package/dist/primitives/thread/ThreadSuggestion.d.ts.map +1 -1
  102. package/dist/primitives/thread.d.ts +3 -5
  103. package/dist/primitives/thread.js +3 -2
  104. package/dist/primitives/thread.js.map +1 -1
  105. package/dist/primitives/threadList/ThreadListItems.d.ts +1 -5
  106. package/dist/primitives/threadList/ThreadListItems.d.ts.map +1 -1
  107. package/dist/primitives/threadList/ThreadListNew.d.ts +1 -5
  108. package/dist/primitives/threadList/ThreadListNew.d.ts.map +1 -1
  109. package/dist/primitives/threadList/ThreadListRoot.d.ts +1 -5
  110. package/dist/primitives/threadList/ThreadListRoot.d.ts.map +1 -1
  111. package/dist/primitives/threadList.d.ts +0 -2
  112. package/dist/primitives/threadListItem/ThreadListItemArchive.d.ts +1 -5
  113. package/dist/primitives/threadListItem/ThreadListItemArchive.d.ts.map +1 -1
  114. package/dist/primitives/threadListItem/ThreadListItemDelete.d.ts +1 -5
  115. package/dist/primitives/threadListItem/ThreadListItemDelete.d.ts.map +1 -1
  116. package/dist/primitives/threadListItem/ThreadListItemRoot.d.ts +1 -5
  117. package/dist/primitives/threadListItem/ThreadListItemRoot.d.ts.map +1 -1
  118. package/dist/primitives/threadListItem/ThreadListItemTrigger.d.ts +1 -5
  119. package/dist/primitives/threadListItem/ThreadListItemTrigger.d.ts.map +1 -1
  120. package/dist/primitives/threadListItem/ThreadListItemUnarchive.d.ts +1 -5
  121. package/dist/primitives/threadListItem/ThreadListItemUnarchive.d.ts.map +1 -1
  122. package/dist/primitives/threadListItem.d.ts +0 -2
  123. package/package.json +9 -9
  124. package/src/index.ts +2 -0
  125. package/src/primitives/composer/ComposerAttachments.tsx +3 -15
  126. package/src/primitives/composer/ComposerInput.test.tsx +106 -8
  127. package/src/primitives/composer/ComposerInput.tsx +21 -2
  128. package/src/primitives/composer.ts +2 -0
  129. package/src/primitives/message/MessageAttachments.tsx +3 -8
  130. package/src/primitives/message.ts +2 -0
  131. package/src/primitives/thread/ThreadMessages.test.tsx +444 -10
  132. package/src/primitives/thread/ThreadMessages.tsx +320 -29
  133. package/src/primitives/thread.ts +2 -0
@@ -1,13 +1,28 @@
1
1
  import {
2
2
  type ComponentType,
3
3
  type FC,
4
+ type ForwardedRef,
4
5
  type ReactNode,
6
+ type RefObject,
7
+ forwardRef,
5
8
  memo,
6
9
  useCallback,
10
+ useEffect,
11
+ useRef,
7
12
  } from "react";
8
- import { FlatList, type FlatListProps } from "react-native";
13
+ import {
14
+ FlatList,
15
+ type FlatListProps,
16
+ type LayoutChangeEvent,
17
+ type NativeScrollEvent,
18
+ type NativeSyntheticEvent,
19
+ } from "react-native";
9
20
  import type { MessageState, ThreadMessage } from "@assistant-ui/core";
10
- import { RenderChildrenWithAccessor, useAuiState } from "@assistant-ui/store";
21
+ import {
22
+ RenderChildrenWithAccessor,
23
+ useAuiEvent,
24
+ useAuiState,
25
+ } from "@assistant-ui/store";
11
26
  import { MessageByIndexProvider } from "@assistant-ui/core/react";
12
27
 
13
28
  type MessageComponents =
@@ -43,13 +58,22 @@ type MessagesContent =
43
58
  components?: never;
44
59
  };
45
60
 
46
- export type ThreadMessagesProps = Omit<
61
+ export type ThreadMessagesFlatListProps = Omit<
47
62
  FlatListProps<ThreadMessage>,
48
63
  "data" | "renderItem" | "children"
49
64
  > &
50
- MessagesContent;
65
+ MessagesContent & {
66
+ autoScroll?: boolean | undefined;
67
+ scrollToBottomOnRunStart?: boolean | undefined;
68
+ scrollToBottomOnInitialize?: boolean | undefined;
69
+ scrollToBottomOnThreadSwitch?: boolean | undefined;
70
+ };
71
+
72
+ /** @deprecated Use ThreadMessagesFlatListProps instead. */
73
+ export type ThreadMessagesProps = ThreadMessagesFlatListProps;
51
74
 
52
75
  const DEFAULT_SYSTEM_MESSAGE = () => null;
76
+ const AT_BOTTOM_THRESHOLD = 4;
53
77
 
54
78
  const getComponent = (
55
79
  components: MessageComponents,
@@ -154,36 +178,303 @@ const ThreadMessageByChildren = memo(
154
178
  );
155
179
  ThreadMessageByChildren.displayName = "ThreadPrimitive.MessageByChildren";
156
180
 
157
- export const ThreadMessages = ({
158
- components,
159
- children,
160
- ...flatListProps
161
- }: ThreadMessagesProps) => {
162
- const messages = useAuiState((s) => s.thread.messages);
163
-
164
- const renderItem = useCallback(
165
- ({ index }: { item: ThreadMessage; index: number }) => {
166
- if (children) {
167
- return (
168
- <ThreadMessageByChildren index={index}>
169
- {children}
170
- </ThreadMessageByChildren>
171
- );
181
+ const setForwardedRef = <T,>(ref: ForwardedRef<T>, value: T | null) => {
182
+ if (typeof ref === "function") {
183
+ ref(value);
184
+ } else if (ref) {
185
+ ref.current = value;
186
+ }
187
+ };
188
+
189
+ const useComposedFlatListRef = (
190
+ forwardedRef: ForwardedRef<FlatList<ThreadMessage>>,
191
+ ) => {
192
+ const flatListRef = useRef<FlatList<ThreadMessage> | null>(null);
193
+
194
+ const setFlatListRef = useCallback(
195
+ (node: FlatList<ThreadMessage> | null) => {
196
+ flatListRef.current = node;
197
+ setForwardedRef(forwardedRef, node);
198
+ },
199
+ [forwardedRef],
200
+ );
201
+
202
+ return [flatListRef, setFlatListRef] as const;
203
+ };
204
+
205
+ const useThreadMessagesFlatListAutoScroll = ({
206
+ flatListRef,
207
+ hasMessages,
208
+ autoScroll = true,
209
+ scrollToBottomOnRunStart = true,
210
+ scrollToBottomOnInitialize = true,
211
+ scrollToBottomOnThreadSwitch = true,
212
+ }: {
213
+ flatListRef: RefObject<FlatList<ThreadMessage> | null>;
214
+ hasMessages: boolean;
215
+ autoScroll?: boolean | undefined;
216
+ scrollToBottomOnRunStart?: boolean | undefined;
217
+ scrollToBottomOnInitialize?: boolean | undefined;
218
+ scrollToBottomOnThreadSwitch?: boolean | undefined;
219
+ }) => {
220
+ const metricsRef = useRef({
221
+ contentHeight: 0,
222
+ viewportHeight: 0,
223
+ scrollY: 0,
224
+ });
225
+ const isAtBottomRef = useRef(true);
226
+ const lastScrollEventYRef = useRef(0);
227
+ const initializeScrollRequestedRef = useRef(false);
228
+ const pendingScrollToBottomRef = useRef<false | { animated: boolean }>(false);
229
+
230
+ const updateIsAtBottom = useCallback(() => {
231
+ const { contentHeight, scrollY, viewportHeight } = metricsRef.current;
232
+ isAtBottomRef.current =
233
+ contentHeight <= viewportHeight ||
234
+ contentHeight - scrollY - viewportHeight <= AT_BOTTOM_THRESHOLD;
235
+ }, []);
236
+
237
+ // Commanding a scroll records the intended position immediately; the
238
+ // native scroll echo is bridged and throttled, so waiting for it lets a
239
+ // fast stream observe stale metrics and drop out of following.
240
+ const scrollToBottom = useCallback(
241
+ (animated: boolean) => {
242
+ const { contentHeight, viewportHeight } = metricsRef.current;
243
+ metricsRef.current.scrollY = Math.max(0, contentHeight - viewportHeight);
244
+ isAtBottomRef.current = true;
245
+ flatListRef.current?.scrollToEnd({ animated });
246
+ },
247
+ [flatListRef],
248
+ );
249
+
250
+ const handleLayout = useCallback(
251
+ (event: LayoutChangeEvent) => {
252
+ metricsRef.current.viewportHeight = event.nativeEvent.layout.height;
253
+ updateIsAtBottom();
254
+ },
255
+ [updateIsAtBottom],
256
+ );
257
+
258
+ const handleScroll = useCallback(
259
+ (event: NativeSyntheticEvent<NativeScrollEvent>) => {
260
+ const { contentOffset, contentSize, layoutMeasurement } =
261
+ event.nativeEvent;
262
+ const previousEventY = lastScrollEventYRef.current;
263
+ const wasPinnedToBottom = isAtBottomRef.current;
264
+ lastScrollEventYRef.current = contentOffset.y;
265
+ metricsRef.current = {
266
+ contentHeight: contentSize.height,
267
+ viewportHeight: layoutMeasurement.height,
268
+ scrollY: contentOffset.y,
269
+ };
270
+ updateIsAtBottom();
271
+ const upwardMove = contentOffset.y < previousEventY;
272
+ // Only a deliberate upward move unpins or cancels a pending scroll.
273
+ // Gestures are detected echo-to-echo because a commanded scroll
274
+ // optimistically moves the tracked position ahead of its ascending
275
+ // animation echoes, and those echoes must not unpin mid-flight.
276
+ if (wasPinnedToBottom && !upwardMove) {
277
+ isAtBottomRef.current = true;
278
+ }
279
+ if (!isAtBottomRef.current && upwardMove) {
280
+ pendingScrollToBottomRef.current = false;
172
281
  }
173
- return <ThreadMessageByIndex index={index} components={components!} />;
174
282
  },
175
- [components, children],
283
+ [updateIsAtBottom],
176
284
  );
177
285
 
178
- const keyExtractor = useCallback((item: ThreadMessage) => item.id, []);
286
+ const handleContentSizeChange = useCallback(
287
+ (_width: number, height: number) => {
288
+ const metrics = metricsRef.current;
289
+ const previousContentHeight = metrics.contentHeight;
290
+ const wasAtBottom = isAtBottomRef.current;
291
+ metrics.contentHeight = height;
292
+ updateIsAtBottom();
179
293
 
180
- return (
181
- <FlatList
182
- data={messages as unknown as ThreadMessage[]}
183
- renderItem={renderItem}
184
- keyExtractor={keyExtractor}
185
- {...flatListProps}
186
- />
294
+ // FlatList.scrollToEnd is a no-op before the list has measured, so the
295
+ // initialize and thread-switch scrolls land on the next content-size
296
+ // event, once real metrics exist.
297
+ const pendingScroll = pendingScrollToBottomRef.current;
298
+ if (pendingScroll) {
299
+ pendingScrollToBottomRef.current = false;
300
+ scrollToBottom(pendingScroll.animated);
301
+ return;
302
+ }
303
+
304
+ if (!autoScroll) return;
305
+ if (!wasAtBottom) return;
306
+ if (previousContentHeight === 0) return;
307
+ if (height <= previousContentHeight) return;
308
+
309
+ scrollToBottom(false);
310
+ },
311
+ [autoScroll, scrollToBottom, updateIsAtBottom],
187
312
  );
313
+
314
+ useEffect(() => {
315
+ if (!scrollToBottomOnInitialize) return;
316
+ if (!hasMessages) {
317
+ initializeScrollRequestedRef.current = false;
318
+ return;
319
+ }
320
+ if (initializeScrollRequestedRef.current) return;
321
+
322
+ initializeScrollRequestedRef.current = true;
323
+ pendingScrollToBottomRef.current = { animated: false };
324
+ scrollToBottom(false);
325
+ }, [hasMessages, scrollToBottom, scrollToBottomOnInitialize]);
326
+
327
+ useAuiEvent("thread.runStart", () => {
328
+ if (!scrollToBottomOnRunStart) return;
329
+ pendingScrollToBottomRef.current = { animated: true };
330
+ scrollToBottom(true);
331
+ });
332
+
333
+ useAuiEvent("threadListItem.switchedTo", () => {
334
+ if (!scrollToBottomOnThreadSwitch) return;
335
+ initializeScrollRequestedRef.current = false;
336
+ lastScrollEventYRef.current = 0;
337
+ pendingScrollToBottomRef.current = { animated: false };
338
+ scrollToBottom(false);
339
+ });
340
+
341
+ return {
342
+ handleLayout,
343
+ handleScroll,
344
+ handleContentSizeChange,
345
+ };
188
346
  };
347
+
348
+ export const ThreadMessagesFlatList = forwardRef<
349
+ FlatList<ThreadMessage>,
350
+ ThreadMessagesFlatListProps
351
+ >(
352
+ (
353
+ {
354
+ autoScroll,
355
+ components,
356
+ children,
357
+ onContentSizeChange,
358
+ onLayout,
359
+ onScroll,
360
+ scrollEventThrottle,
361
+ scrollToBottomOnInitialize,
362
+ scrollToBottomOnRunStart,
363
+ scrollToBottomOnThreadSwitch,
364
+ ...flatListProps
365
+ },
366
+ forwardedRef,
367
+ ) => {
368
+ const messages = useAuiState((s) => s.thread.messages);
369
+ const [flatListRef, setFlatListRef] = useComposedFlatListRef(forwardedRef);
370
+ const {
371
+ handleContentSizeChange: handleAutoScrollContentSizeChange,
372
+ handleLayout: handleAutoScrollLayout,
373
+ handleScroll: handleAutoScrollScroll,
374
+ } = useThreadMessagesFlatListAutoScroll({
375
+ flatListRef,
376
+ hasMessages: messages.length > 0,
377
+ autoScroll,
378
+ scrollToBottomOnInitialize,
379
+ scrollToBottomOnRunStart,
380
+ scrollToBottomOnThreadSwitch,
381
+ });
382
+
383
+ const renderItem = useCallback(
384
+ ({ index }: { item: ThreadMessage; index: number }) => {
385
+ if (children) {
386
+ return (
387
+ <ThreadMessageByChildren index={index}>
388
+ {children}
389
+ </ThreadMessageByChildren>
390
+ );
391
+ }
392
+ return <ThreadMessageByIndex index={index} components={components!} />;
393
+ },
394
+ [components, children],
395
+ );
396
+
397
+ const keyExtractor = useCallback((item: ThreadMessage) => item.id, []);
398
+
399
+ const scrollTracking =
400
+ (autoScroll ?? true) ||
401
+ (scrollToBottomOnInitialize ?? true) ||
402
+ (scrollToBottomOnRunStart ?? true) ||
403
+ (scrollToBottomOnThreadSwitch ?? true);
404
+
405
+ const handleLayout = useCallback(
406
+ (event: LayoutChangeEvent) => {
407
+ handleAutoScrollLayout(event);
408
+ onLayout?.(event);
409
+ },
410
+ [handleAutoScrollLayout, onLayout],
411
+ );
412
+
413
+ const handleScroll = useCallback(
414
+ (event: NativeSyntheticEvent<NativeScrollEvent>) => {
415
+ handleAutoScrollScroll(event);
416
+ onScroll?.(event);
417
+ },
418
+ [handleAutoScrollScroll, onScroll],
419
+ );
420
+
421
+ const handleContentSizeChange = useCallback(
422
+ (width: number, height: number) => {
423
+ handleAutoScrollContentSizeChange(width, height);
424
+ onContentSizeChange?.(width, height);
425
+ },
426
+ [handleAutoScrollContentSizeChange, onContentSizeChange],
427
+ );
428
+
429
+ return (
430
+ <FlatList
431
+ ref={setFlatListRef}
432
+ data={messages as unknown as ThreadMessage[]}
433
+ renderItem={renderItem}
434
+ keyExtractor={keyExtractor}
435
+ {...(scrollTracking
436
+ ? {
437
+ onContentSizeChange: handleContentSizeChange,
438
+ onLayout: handleLayout,
439
+ onScroll: handleScroll,
440
+ scrollEventThrottle: scrollEventThrottle ?? 16,
441
+ }
442
+ : {
443
+ ...(onContentSizeChange && { onContentSizeChange }),
444
+ ...(onLayout && { onLayout }),
445
+ ...(onScroll && { onScroll }),
446
+ ...(scrollEventThrottle !== undefined && { scrollEventThrottle }),
447
+ })}
448
+ {...flatListProps}
449
+ />
450
+ );
451
+ },
452
+ );
453
+ ThreadMessagesFlatList.displayName = "ThreadPrimitive.MessagesFlatList";
454
+
455
+ /** @deprecated Use ThreadPrimitive.MessagesFlatList instead. */
456
+ export const ThreadMessages = forwardRef<
457
+ FlatList<ThreadMessage>,
458
+ ThreadMessagesProps
459
+ >(
460
+ (
461
+ {
462
+ autoScroll = false,
463
+ scrollToBottomOnInitialize = false,
464
+ scrollToBottomOnRunStart = false,
465
+ scrollToBottomOnThreadSwitch = false,
466
+ ...props
467
+ },
468
+ ref,
469
+ ) => (
470
+ <ThreadMessagesFlatList
471
+ ref={ref}
472
+ autoScroll={autoScroll}
473
+ scrollToBottomOnInitialize={scrollToBottomOnInitialize}
474
+ scrollToBottomOnRunStart={scrollToBottomOnRunStart}
475
+ scrollToBottomOnThreadSwitch={scrollToBottomOnThreadSwitch}
476
+ {...props}
477
+ />
478
+ ),
479
+ );
189
480
  ThreadMessages.displayName = "ThreadPrimitive.Messages";
@@ -3,6 +3,8 @@ export {
3
3
  type ThreadRootProps as RootProps,
4
4
  } from "./thread/ThreadRoot";
5
5
  export {
6
+ ThreadMessagesFlatList as MessagesFlatList,
7
+ type ThreadMessagesFlatListProps as MessagesFlatListProps,
6
8
  ThreadMessages as Messages,
7
9
  type ThreadMessagesProps as MessagesProps,
8
10
  } from "./thread/ThreadMessages";