react-native-gifted-chat 2.8.2-alpha.6 → 2.9.0-alpha.0

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 (53) hide show
  1. package/README.md +26 -26
  2. package/package.json +2 -1
  3. package/src/Actions.tsx +1 -1
  4. package/src/Bubble/index.tsx +12 -14
  5. package/src/Bubble/styles.ts +1 -1
  6. package/src/Bubble/types.ts +4 -5
  7. package/src/Color.ts +1 -1
  8. package/src/Composer.tsx +1 -1
  9. package/src/Day/styles.ts +1 -1
  10. package/src/GiftedAvatar.tsx +1 -1
  11. package/src/GiftedChat/index.tsx +6 -38
  12. package/src/GiftedChat/types.ts +2 -2
  13. package/src/InputToolbar.tsx +22 -13
  14. package/src/LoadEarlierMessages.tsx +1 -1
  15. package/src/Message/index.tsx +6 -8
  16. package/src/MessageAudio.tsx +1 -1
  17. package/src/MessageContainer/components/DayAnimated/index.tsx +1 -3
  18. package/src/MessageContainer/components/Item/index.tsx +8 -10
  19. package/src/MessageContainer/index.tsx +4 -6
  20. package/src/MessageContainer/styles.ts +1 -1
  21. package/src/MessageVideo.tsx +1 -1
  22. package/src/QuickReplies.tsx +1 -1
  23. package/src/Send.tsx +1 -1
  24. package/src/SystemMessage.tsx +1 -1
  25. package/src/Time.tsx +5 -5
  26. package/src/TypingIndicator/index.tsx +1 -3
  27. package/src/TypingIndicator/styles.ts +1 -1
  28. package/src/__tests__/Actions.test.tsx +1 -1
  29. package/src/__tests__/Avatar.test.tsx +7 -2
  30. package/src/__tests__/Bubble.test.tsx +3 -7
  31. package/src/__tests__/Color.test.tsx +1 -1
  32. package/src/__tests__/Composer.test.tsx +1 -1
  33. package/src/__tests__/Day.test.tsx +3 -3
  34. package/src/__tests__/DayAnimated.test.tsx +5 -11
  35. package/src/__tests__/GiftedAvatar.test.tsx +1 -1
  36. package/src/__tests__/GiftedChat.test.tsx +1 -1
  37. package/src/__tests__/InputToolbar.test.tsx +1 -1
  38. package/src/__tests__/LoadEarlier.test.tsx +2 -2
  39. package/src/__tests__/Message.test.tsx +5 -11
  40. package/src/__tests__/MessageContainer.test.tsx +4 -4
  41. package/src/__tests__/MessageImage.test.tsx +2 -2
  42. package/src/__tests__/MessageText.test.tsx +3 -2
  43. package/src/__tests__/Send.test.tsx +1 -1
  44. package/src/__tests__/SystemMessage.test.tsx +1 -1
  45. package/src/__tests__/Time.test.tsx +1 -1
  46. package/src/__tests__/__snapshots__/Bubble.test.tsx.snap +1 -1
  47. package/src/__tests__/__snapshots__/Day.test.tsx.snap +96 -2
  48. package/src/__tests__/__snapshots__/InputToolbar.test.tsx.snap +1 -1
  49. package/src/__tests__/__snapshots__/Message.test.tsx.snap +41 -2
  50. package/src/__tests__/__snapshots__/MessageText.test.tsx.snap +1 -1
  51. package/src/__tests__/data.ts +1 -1
  52. package/src/index.ts +19 -1
  53. package/src/utils.ts +22 -1
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
- <p align="center" >
2
- <p align="center" >
1
+ <p align="center">
2
+ <p align="center">
3
3
  <a href="https://reactnative.gallery/FaridSafi/gifted-chat">
4
4
     <img alt="react-native-gifted-chat" src="https://thumbs.gfycat.com/AbsoluteSadDobermanpinscher-size_restricted.gif" width="260" height="510" />
5
5
  </a>
@@ -382,44 +382,44 @@ interface QuickReplies {
382
382
  - `activityIndicatorStyle` - Custom style for the loading indicator
383
383
  - `activityIndicatorColor` - Color of the loading indicator (default: 'white')
384
384
  - `activityIndicatorSize` - Size of the loading indicator (default: 'small')
385
- - **`renderLoading`** _(Function)_ - Render a loading view when initializing
386
- - **`renderLoadEarlier`** _(Function)_ - Custom "Load earlier messages" button
387
- - **`renderAvatar`** _(Function)_ - Custom message avatar; set to `null` to not render any avatar for the message
385
+ - **`renderLoading`** _(Component | Function)_ - Render a loading view when initializing
386
+ - **`renderLoadEarlier`** _(Component | Function)_ - Custom "Load earlier messages" button
387
+ - **`renderAvatar`** _(Component | Function)_ - Custom message avatar; set to `null` to not render any avatar for the message
388
388
  - **`showUserAvatar`** _(Bool)_ - Whether to render an avatar for the current user; default is `false`, only show avatars for other users
389
389
  - **`showAvatarForEveryMessage`** _(Bool)_ - When false, avatars will only be displayed when a consecutive message is from the same user on the same day; default is `false`
390
390
  - **`onPressAvatar`** _(Function(`user`))_ - Callback when a message avatar is tapped
391
391
  - **`onLongPressAvatar`** _(Function(`user`))_ - Callback when a message avatar is long-pressed
392
392
  - **`renderAvatarOnTop`** _(Bool)_ - Render the message avatar at the top of consecutive messages, rather than the bottom; default is `false`
393
- - **`renderBubble`** _(Function)_ - Custom message bubble
394
- - **`renderTicks`** _(Function(`message`))_ - Custom ticks indicator to display message status
395
- - **`renderSystemMessage`** _(Function)_ - Custom system message
393
+ - **`renderBubble`** _(Component | Function)_ - Custom message bubble
394
+ - **`renderTicks`** _(Component | Function(`message`))_ - Custom ticks indicator to display message status
395
+ - **`renderSystemMessage`** _(Component | Function)_ - Custom system message
396
396
  - **`onPressMessage`** _(Function(`context`, `message`))_ - Callback when a message bubble is pressed
397
397
  - **`onLongPressMessage`** _(Function(`context`, `message`))_ - Callback when a message bubble is long-pressed (see [example using `showActionSheetWithOptions()`](https://github.com/FaridSafi/react-native-gifted-chat/blob/master@%7B2017-09-25%7D/src/Bubble.js#L96-L119))
398
398
  - **`inverted`** _(Bool)_ - Reverses display order of `messages`; default is `true`
399
399
  - **`renderUsernameOnMessage`** _(Bool)_ - Indicate whether to show the user's username inside the message bubble; default is `false`
400
- - **`renderUsername`** _(Function)_ - Custom Username container
401
- - **`renderMessage`** _(Function)_ - Custom message container
402
- - **`renderMessageText`** _(Function)_ - Custom message text
403
- - **`renderMessageImage`** _(Function)_ - Custom message image
404
- - **`renderMessageVideo`** _(Function)_ - Custom message video
405
- - **`renderMessageAudio`** _(Function)_ - Custom message audio
400
+ - **`renderUsername`** _(Component | Function)_ - Custom Username container
401
+ - **`renderMessage`** _(Component | Function)_ - Custom message container
402
+ - **`renderMessageText`** _(Component | Function)_ - Custom message text
403
+ - **`renderMessageImage`** _(Component | Function)_ - Custom message image
404
+ - **`renderMessageVideo`** _(Component | Function)_ - Custom message video
405
+ - **`renderMessageAudio`** _(Component | Function)_ - Custom message audio
406
406
  - **`imageProps`** _(Object)_ - Extra props to be passed to the [`<Image>`](https://reactnative.dev/docs/image.html) component created by the default `renderMessageImage`
407
407
  - **`imageStyle`** _(Object)_ - Custom style for message images
408
408
  - **`videoProps`** _(Object)_ - Extra props to be passed to the video component created by the required `renderMessageVideo`
409
409
  - **`isCustomViewBottom`** _(Bool)_ - Determine whether renderCustomView is displayed before or after the text, image and video views; default is `false`
410
- - **`renderCustomView`** _(Function)_ - Custom view inside the bubble
411
- - **`renderDay`** _(Function)_ - Custom day above a message
412
- - **`renderTime`** _(Function)_ - Custom time inside a message
410
+ - **`renderCustomView`** _(Component | Function)_ - Custom view inside the bubble
411
+ - **`renderDay`** _(Component | Function)_ - Custom day above a message
412
+ - **`renderTime`** _(Component | Function)_ - Custom time inside a message
413
413
  - **`timeTextStyle`** _(Object)_ - Custom text style for time inside messages (supports left/right styles)
414
- - **`renderFooter`** _(Function)_ - Custom footer component on the ListView, e.g. `'User is typing...'`; see [App.tsx](/example/App.tsx) for an example. Overrides default typing indicator that triggers when `isTyping` is true.
415
- - **`renderTypingIndicator`** _(Function)_ - Custom typing indicator component
416
- - **`renderChatEmpty`** _(Function)_ - Custom component to render in the ListView when messages are empty
417
- - **`renderChatFooter`** _(Function)_ - Custom component to render below the MessageContainer (separate from the ListView)
418
- - **`renderInputToolbar`** _(Function)_ - Custom message composer container
419
- - **`renderComposer`** _(Function)_ - Custom text input message composer
420
- - **`renderActions`** _(Function)_ - Custom action button on the left of the message composer
421
- - **`renderSend`** _(Function)_ - Custom send button; you can pass children to the original `Send` component quite easily, for example, to use a custom icon ([example](https://github.com/FaridSafi/react-native-gifted-chat/pull/487))
422
- - **`renderAccessory`** _(Function)_ - Custom second line of actions below the message composer
414
+ - **`renderFooter`** _(Component | Function)_ - Custom footer component on the ListView, e.g. `'User is typing...'`; see [App.tsx](/example/App.tsx) for an example. Overrides default typing indicator that triggers when `isTyping` is true.
415
+ - **`renderTypingIndicator`** _(Component | Function)_ - Custom typing indicator component
416
+ - **`renderChatEmpty`** _(Component | Function)_ - Custom component to render in the ListView when messages are empty
417
+ - **`renderChatFooter`** _(Component | Function)_ - Custom component to render below the MessageContainer (separate from the ListView)
418
+ - **`renderInputToolbar`** _(Component | Function)_ - Custom message composer container
419
+ - **`renderComposer`** _(Component | Function)_ - Custom text input message composer
420
+ - **`renderActions`** _(Component | Function)_ - Custom action button on the left of the message composer
421
+ - **`renderSend`** _(Component | Function)_ - Custom send button; you can pass children to the original `Send` component quite easily, for example, to use a custom icon ([example](https://github.com/FaridSafi/react-native-gifted-chat/pull/487))
422
+ - **`renderAccessory`** _(Component | Function)_ - Custom second line of actions below the message composer
423
423
  - **`onPressActionButton`** _(Function)_ - Callback when the Action button is pressed (if set, the default `actionSheet` will not be used)
424
424
  - **`actionSheet`** _(Function)_ - Custom action sheet interface for showing action options
425
425
  - **`actions`** _(Array)_ - Custom action options for the input toolbar action button; array of objects with `title` (string) and `action` (function) properties
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-gifted-chat",
3
- "version": "2.8.2-alpha.6",
3
+ "version": "2.9.0-alpha.0",
4
4
  "description": "The most complete chat UI for React Native",
5
5
  "keywords": [
6
6
  "android",
@@ -80,6 +80,7 @@
80
80
  "@typescript-eslint/parser": "^8.46.4",
81
81
  "babel-jest": "^29.7.0",
82
82
  "eslint": "^9.18.0",
83
+ "eslint-import-resolver-typescript": "^4.4.4",
83
84
  "eslint-plugin-import": "^2.32.0",
84
85
  "eslint-plugin-jest": "^28.11.0",
85
86
  "eslint-plugin-perfectionist": "^4.15.1",
package/src/Actions.tsx CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  ViewStyle,
8
8
  TextStyle,
9
9
  } from 'react-native'
10
- import Color from './Color'
10
+ import { Color } from './Color'
11
11
  import { TouchableOpacity } from './components/TouchableOpacity'
12
12
  import { useChatContext } from './GiftedChatContext'
13
13
 
@@ -15,14 +15,14 @@ import stylesCommon from '../styles'
15
15
 
16
16
  import { Time } from '../Time'
17
17
  import { IMessage } from '../types'
18
- import { isSameUser, isSameDay } from '../utils'
18
+ import { isSameUser, isSameDay, renderComponentOrElement } from '../utils'
19
19
 
20
20
  import styles from './styles'
21
21
  import { BubbleProps, RenderMessageTextProps } from './types'
22
22
 
23
23
  export * from './types'
24
24
 
25
- const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessage>): JSX.Element => {
25
+ export const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessage>): JSX.Element => {
26
26
  const {
27
27
  currentMessage,
28
28
  nextMessage,
@@ -109,7 +109,7 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
109
109
  } = props
110
110
 
111
111
  if (props.renderQuickReplies)
112
- return props.renderQuickReplies(quickReplyProps)
112
+ return renderComponentOrElement(props.renderQuickReplies, quickReplyProps)
113
113
 
114
114
  return (
115
115
  <QuickReplies
@@ -150,9 +150,9 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
150
150
  const combinedProps = { ...messageTextPropsRest, ...messageTextProps } as RenderMessageTextProps<TMessage>
151
151
 
152
152
  if (props.renderMessageText)
153
- return props.renderMessageText(combinedProps)
153
+ return renderComponentOrElement(props.renderMessageText, combinedProps)
154
154
 
155
- return <MessageText {...combinedProps} />
155
+ return <MessageText {...combinedProps as any} />
156
156
  }
157
157
 
158
158
  return null
@@ -169,7 +169,7 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
169
169
  } = props
170
170
 
171
171
  if (props.renderMessageImage)
172
- return props.renderMessageImage(messageImageProps)
172
+ return renderComponentOrElement(props.renderMessageImage, messageImageProps)
173
173
 
174
174
  return <MessageImage {...messageImageProps} />
175
175
  }
@@ -190,7 +190,7 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
190
190
  } = props
191
191
 
192
192
  if (props.renderMessageVideo)
193
- return props.renderMessageVideo(messageVideoProps)
193
+ return renderComponentOrElement(props.renderMessageVideo, messageVideoProps)
194
194
 
195
195
  return <MessageVideo />
196
196
  }, [props, currentMessage])
@@ -208,7 +208,7 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
208
208
  } = props
209
209
 
210
210
  if (props.renderMessageAudio)
211
- return props.renderMessageAudio(messageAudioProps)
211
+ return renderComponentOrElement(props.renderMessageAudio, messageAudioProps)
212
212
 
213
213
  return <MessageAudio />
214
214
  }, [props, currentMessage])
@@ -220,7 +220,7 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
220
220
  } = props
221
221
 
222
222
  if (renderTicks && currentMessage)
223
- return renderTicks(currentMessage)
223
+ return renderComponentOrElement(renderTicks, currentMessage)
224
224
 
225
225
  if (
226
226
  user &&
@@ -271,7 +271,7 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
271
271
  } = props
272
272
 
273
273
  if (props.renderTime)
274
- return props.renderTime(timeProps)
274
+ return renderComponentOrElement(props.renderTime, timeProps)
275
275
 
276
276
  return <Time {...timeProps} />
277
277
  }
@@ -289,7 +289,7 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
289
289
  return null
290
290
 
291
291
  if (renderUsername)
292
- return renderUsername(currentMessage.user)
292
+ return renderComponentOrElement(renderUsername, currentMessage.user)
293
293
 
294
294
  return (
295
295
  <View style={styles.content.usernameView}>
@@ -313,7 +313,7 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
313
313
 
314
314
  const renderCustomView = useCallback(() => {
315
315
  if (props.renderCustomView)
316
- return props.renderCustomView(props)
316
+ return renderComponentOrElement(props.renderCustomView, props)
317
317
 
318
318
  return null
319
319
  }, [props])
@@ -378,5 +378,3 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
378
378
  </View>
379
379
  )
380
380
  }
381
-
382
- export default Bubble
@@ -1,5 +1,5 @@
1
1
  import { StyleSheet } from 'react-native'
2
- import Color from '../Color'
2
+ import { Color } from '../Color'
3
3
 
4
4
  const styles = {
5
5
  left: StyleSheet.create({
@@ -5,7 +5,7 @@ import {
5
5
  TextStyle,
6
6
  } from 'react-native'
7
7
  import { MessageImageProps } from '../MessageImage'
8
- import { MessageTextProps, MessageOption } from '../MessageText'
8
+ import { MessageTextProps } from '../MessageText'
9
9
  import { QuickRepliesProps } from '../QuickReplies'
10
10
  import { TimeProps } from '../Time'
11
11
  import {
@@ -18,7 +18,7 @@ import {
18
18
  MessageAudioProps,
19
19
  } from '../types'
20
20
 
21
-
21
+
22
22
  export type RenderMessageImageProps<TMessage extends IMessage> = Omit<
23
23
  BubbleProps<TMessage>,
24
24
  'containerStyle' | 'wrapperStyle'
@@ -39,10 +39,10 @@ export type RenderMessageAudioProps<TMessage extends IMessage> = Omit<
39
39
 
40
40
  export type RenderMessageTextProps<TMessage extends IMessage> = Omit<
41
41
  BubbleProps<TMessage>,
42
- 'containerStyle' | 'wrapperStyle' | 'options'
42
+ 'containerStyle' | 'wrapperStyle'
43
43
  > &
44
44
  MessageTextProps<TMessage>
45
-
45
+
46
46
 
47
47
  export interface BubbleProps<TMessage extends IMessage> {
48
48
  user?: User
@@ -54,7 +54,6 @@ export interface BubbleProps<TMessage extends IMessage> {
54
54
  currentMessage: TMessage
55
55
  nextMessage?: TMessage
56
56
  previousMessage?: TMessage
57
- options?: MessageOption[]
58
57
  containerStyle?: LeftRightStyle<ViewStyle>
59
58
  wrapperStyle?: LeftRightStyle<ViewStyle>
60
59
  textStyle?: LeftRightStyle<TextStyle>
package/src/Color.ts CHANGED
@@ -1,4 +1,4 @@
1
- export default {
1
+ export const Color = {
2
2
  defaultColor: '#b2b2b2',
3
3
  backgroundTransparent: 'transparent',
4
4
  defaultBlue: '#0084ff',
package/src/Composer.tsx CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  TextInputContentSizeChangeEventData,
9
9
  useColorScheme,
10
10
  } from 'react-native'
11
- import Color from './Color'
11
+ import { Color } from './Color'
12
12
  import { MIN_COMPOSER_HEIGHT } from './Constant'
13
13
  import stylesCommon from './styles'
14
14
 
package/src/Day/styles.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { StyleSheet } from 'react-native'
2
- import Color from '../Color'
2
+ import { Color } from '../Color'
3
3
 
4
4
  export default StyleSheet.create({
5
5
  container: {
@@ -8,7 +8,7 @@ import {
8
8
  ImageStyle,
9
9
  TextStyle,
10
10
  } from 'react-native'
11
- import Color from './Color'
11
+ import { Color } from './Color'
12
12
  import { TouchableOpacity } from './components/TouchableOpacity'
13
13
  import stylesCommon from './styles'
14
14
  import { User } from './types'
@@ -28,29 +28,15 @@ import Animated, {
28
28
  runOnJS,
29
29
  } from 'react-native-reanimated'
30
30
  import { SafeAreaProvider } from 'react-native-safe-area-context'
31
- import { Actions } from '../Actions'
32
- import { Avatar } from '../Avatar'
33
- import Bubble from '../Bubble'
34
- import { Composer } from '../Composer'
35
31
  import { MAX_COMPOSER_HEIGHT, MIN_COMPOSER_HEIGHT, TEST_ID } from '../Constant'
36
- import { Day } from '../Day'
37
- import { GiftedAvatar } from '../GiftedAvatar'
38
32
  import { GiftedChatContext } from '../GiftedChatContext'
39
33
  import { InputToolbar } from '../InputToolbar'
40
- import { LoadEarlierMessages } from '../LoadEarlierMessages'
41
- import Message from '../Message'
42
- import MessageContainer, { AnimatedList } from '../MessageContainer'
43
- import { MessageImage } from '../MessageImage'
44
- import { MessageText } from '../MessageText'
45
- import { Send } from '../Send'
34
+ import { MessageContainer, AnimatedList } from '../MessageContainer'
46
35
  import stylesCommon from '../styles'
47
- import { SystemMessage } from '../SystemMessage'
48
- import { Time } from '../Time'
49
-
50
36
  import {
51
37
  IMessage,
52
38
  } from '../types'
53
- import * as utils from '../utils'
39
+ import { renderComponentOrElement } from '../utils'
54
40
  import styles from './styles'
55
41
  import { GiftedChatProps } from './types'
56
42
 
@@ -200,7 +186,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
200
186
  forwardRef={messageContainerRef}
201
187
  isTyping={isTyping}
202
188
  />
203
- {renderChatFooter?.()}
189
+ {renderComponentOrElement(renderChatFooter, {})}
204
190
  </View>
205
191
  )
206
192
  }, [
@@ -315,7 +301,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
315
301
  }
316
302
 
317
303
  if (renderInputToolbar)
318
- return renderInputToolbar(inputToolbarProps)
304
+ return renderComponentOrElement(renderInputToolbar, inputToolbarProps)
319
305
 
320
306
  return <InputToolbar {...inputToolbarProps} />
321
307
  }, [
@@ -406,7 +392,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
406
392
  </Animated.View>
407
393
  )
408
394
  : (
409
- renderLoading?.()
395
+ renderComponentOrElement(renderLoading, {})
410
396
  )}
411
397
  </View>
412
398
  </ActionSheetProvider>
@@ -452,24 +438,6 @@ GiftedChatWrapper.prepend = <TMessage extends IMessage>(
452
438
  : messages.concat(currentMessages)
453
439
  }
454
440
 
455
- export * from '../types'
456
-
457
441
  export {
458
- GiftedChatWrapper as GiftedChat,
459
- Actions,
460
- Avatar,
461
- Bubble,
462
- SystemMessage,
463
- MessageImage,
464
- MessageText,
465
- Composer,
466
- Day,
467
- InputToolbar,
468
- LoadEarlierMessages,
469
- Message,
470
- MessageContainer,
471
- Send,
472
- Time,
473
- GiftedAvatar,
474
- utils
442
+ GiftedChatWrapper as GiftedChat
475
443
  }
@@ -129,8 +129,8 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
129
129
  renderTime?(props: TimeProps<TMessage>): React.ReactNode
130
130
  /* Custom component to render below the MessageContainer (separate from the ListView) */
131
131
  renderChatFooter?(): React.ReactNode
132
- /* Custom message composer container */
133
- renderInputToolbar?(props: InputToolbarProps<TMessage>): React.ReactNode
132
+ /* Custom message composer container. Can be a component, element, render function, or null */
133
+ renderInputToolbar?: React.ComponentType<InputToolbarProps<TMessage>> | React.ReactElement | ((props: InputToolbarProps<TMessage>) => React.ReactNode) | null
134
134
  /* Custom text input message composer */
135
135
  renderComposer?(props: ComposerProps): React.ReactNode
136
136
  /* Custom action button on the left of the message composer */
@@ -2,10 +2,11 @@ import React, { useMemo } from 'react'
2
2
  import { StyleSheet, View, StyleProp, ViewStyle, useColorScheme } from 'react-native'
3
3
 
4
4
  import { Actions, ActionsProps } from './Actions'
5
- import Color from './Color'
5
+ import { Color } from './Color'
6
6
  import { Composer, ComposerProps } from './Composer'
7
7
  import { Send, SendProps } from './Send'
8
8
  import { IMessage } from './types'
9
+ import { renderComponentOrElement } from './utils'
9
10
 
10
11
  export interface InputToolbarProps<TMessage extends IMessage> {
11
12
  actions?: Array<{ title: string, action: () => void }>
@@ -41,7 +42,7 @@ export function InputToolbar<TMessage extends IMessage = IMessage> (
41
42
  const colorScheme = useColorScheme()
42
43
 
43
44
  const actionsFragment = useMemo(() => {
44
- const props = {
45
+ const actionsProps = {
45
46
  onPressActionButton,
46
47
  actions,
47
48
  actionSheetOptionTintColor,
@@ -50,9 +51,13 @@ export function InputToolbar<TMessage extends IMessage = IMessage> (
50
51
  containerStyle,
51
52
  }
52
53
 
53
- return (
54
- renderActions?.(props) || (onPressActionButton && <Actions {...props} />)
55
- )
54
+ if (renderActions)
55
+ return renderComponentOrElement(renderActions, actionsProps)
56
+
57
+ if (onPressActionButton)
58
+ return <Actions {...actionsProps} />
59
+
60
+ return null
56
61
  }, [
57
62
  renderActions,
58
63
  onPressActionButton,
@@ -64,15 +69,19 @@ export function InputToolbar<TMessage extends IMessage = IMessage> (
64
69
  ])
65
70
 
66
71
  const composerFragment = useMemo(() => {
67
- return (
68
- renderComposer?.(props as ComposerProps) || (
69
- <Composer {...(props as ComposerProps)} />
70
- )
71
- )
72
+ const composerProps = props as ComposerProps
73
+
74
+ if (renderComposer)
75
+ return renderComponentOrElement(renderComposer, composerProps)
76
+
77
+ return <Composer {...composerProps} />
72
78
  }, [renderComposer, props])
73
79
 
74
80
  const sendFragment = useMemo(() => {
75
- return renderSend?.(props) || <Send {...props} />
81
+ if (renderSend)
82
+ return renderComponentOrElement(renderSend, props)
83
+
84
+ return <Send {...props} />
76
85
  }, [renderSend, props])
77
86
 
78
87
  const accessoryFragment = useMemo(() => {
@@ -81,13 +90,13 @@ export function InputToolbar<TMessage extends IMessage = IMessage> (
81
90
 
82
91
  return (
83
92
  <View style={[styles.accessory, props.accessoryStyle]}>
84
- {renderAccessory(props)}
93
+ {renderComponentOrElement(renderAccessory, props)}
85
94
  </View>
86
95
  )
87
96
  }, [renderAccessory, props])
88
97
 
89
98
  return (
90
- <View style={[styles.container, styles[`container_${colorScheme}`], containerStyle]}>
99
+ <View style={[styles.container, colorScheme === 'dark' && styles.container_dark, containerStyle]}>
91
100
  <View style={[styles.primary, props.primaryStyle]}>
92
101
  {actionsFragment}
93
102
  {composerFragment}
@@ -8,7 +8,7 @@ import {
8
8
  ViewStyle,
9
9
  TextStyle,
10
10
  } from 'react-native'
11
- import Color from './Color'
11
+ import { Color } from './Color'
12
12
  import { TouchableOpacity } from './components/TouchableOpacity'
13
13
  import stylesCommon from './styles'
14
14
 
@@ -1,18 +1,18 @@
1
- import React, { memo, useCallback } from 'react'
1
+ import React, { useCallback } from 'react'
2
2
  import { View } from 'react-native'
3
3
 
4
4
  import { Avatar } from '../Avatar'
5
- import Bubble from '../Bubble'
5
+ import { Bubble } from '../Bubble'
6
6
  import { SystemMessage } from '../SystemMessage'
7
7
 
8
8
  import { IMessage } from '../types'
9
- import { isSameUser } from '../utils'
9
+ import { isSameUser, renderComponentOrElement } from '../utils'
10
10
  import styles from './styles'
11
11
  import { MessageProps } from './types'
12
12
 
13
13
  export * from './types'
14
14
 
15
- const Message: React.FC<MessageProps<IMessage>> = (props: MessageProps<IMessage>) => {
15
+ export const Message = <TMessage extends IMessage = IMessage>(props: MessageProps<TMessage>) => {
16
16
  const {
17
17
  currentMessage,
18
18
  renderBubble: renderBubbleProp,
@@ -35,7 +35,7 @@ const Message: React.FC<MessageProps<IMessage>> = (props: MessageProps<IMessage>
35
35
  } = props
36
36
 
37
37
  if (renderBubbleProp)
38
- return renderBubbleProp(rest)
38
+ return renderComponentOrElement(renderBubbleProp, rest)
39
39
 
40
40
  return <Bubble {...rest} />
41
41
  }, [props, renderBubbleProp])
@@ -50,7 +50,7 @@ const Message: React.FC<MessageProps<IMessage>> = (props: MessageProps<IMessage>
50
50
  } = props
51
51
 
52
52
  if (renderSystemMessageProp)
53
- return renderSystemMessageProp(rest)
53
+ return renderComponentOrElement(renderSystemMessageProp, rest)
54
54
 
55
55
  return <SystemMessage {...rest} />
56
56
  }, [props, renderSystemMessageProp])
@@ -111,5 +111,3 @@ const Message: React.FC<MessageProps<IMessage>> = (props: MessageProps<IMessage>
111
111
  </View>
112
112
  )
113
113
  }
114
-
115
- export default memo(Message)
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from 'react'
2
2
  import { View, Text, StyleSheet } from 'react-native'
3
- import Color from './Color'
3
+ import { Color } from './Color'
4
4
 
5
5
  const styles = StyleSheet.create({
6
6
  container: {
@@ -11,7 +11,7 @@ import { DayAnimatedProps } from './types'
11
11
 
12
12
  export * from './types'
13
13
 
14
- const DayAnimated = ({ scrolledY, daysPositions, listHeight, renderDay, messages, isLoading, ...rest }: DayAnimatedProps) => {
14
+ export const DayAnimated = ({ scrolledY, daysPositions, listHeight, renderDay, messages, isLoading, ...rest }: DayAnimatedProps) => {
15
15
  const opacity = useSharedValue(0)
16
16
  const fadeOutOpacityTimeoutId = useSharedValue<ReturnType<typeof setTimeout> | undefined>(undefined)
17
17
  const containerHeight = useSharedValue(0)
@@ -145,5 +145,3 @@ const DayAnimated = ({ scrolledY, daysPositions, listHeight, renderDay, messages
145
145
  </Animated.View>
146
146
  )
147
147
  }
148
-
149
- export default DayAnimated
@@ -1,8 +1,8 @@
1
- import React, { forwardRef, useCallback, useMemo } from 'react'
1
+ import React, { useCallback, useMemo } from 'react'
2
2
  import { LayoutChangeEvent, View } from 'react-native'
3
3
  import Animated, { interpolate, useAnimatedStyle, useDerivedValue, useSharedValue } from 'react-native-reanimated'
4
4
  import { Day } from '../../../Day'
5
- import Message, { MessageProps } from '../../../Message'
5
+ import { Message,MessageProps } from '../../../Message'
6
6
  import { IMessage } from '../../../types'
7
7
  import { isSameDay } from '../../../utils'
8
8
  import { DaysPositions } from '../../types'
@@ -68,7 +68,7 @@ export const useRelativeScrolledPositionToBottomOfDay = (
68
68
  return relativeScrolledPositionToBottomOfDay
69
69
  }
70
70
 
71
- const DayWrapper = forwardRef<View, MessageProps<IMessage>>((props, ref) => {
71
+ const DayWrapper = <TMessage extends IMessage>(props: MessageProps<TMessage>) => {
72
72
  const {
73
73
  renderDay: renderDayProp,
74
74
  currentMessage,
@@ -87,7 +87,7 @@ const DayWrapper = forwardRef<View, MessageProps<IMessage>>((props, ref) => {
87
87
  } = props
88
88
 
89
89
  return (
90
- <View ref={ref}>
90
+ <View>
91
91
  {
92
92
  renderDayProp
93
93
  ? renderDayProp({ ...rest, createdAt: currentMessage.createdAt })
@@ -95,9 +95,9 @@ const DayWrapper = forwardRef<View, MessageProps<IMessage>>((props, ref) => {
95
95
  }
96
96
  </View>
97
97
  )
98
- })
98
+ }
99
99
 
100
- const Item = <TMessage extends IMessage>(props: ItemProps<TMessage>) => {
100
+ export const Item = <TMessage extends IMessage>(props: ItemProps<TMessage>) => {
101
101
  const {
102
102
  renderMessage: renderMessageProp,
103
103
  scrolledY,
@@ -146,15 +146,13 @@ const Item = <TMessage extends IMessage>(props: ItemProps<TMessage>) => {
146
146
  style={style}
147
147
  onLayout={handleLayoutDayContainer}
148
148
  >
149
- <DayWrapper {...rest as MessageProps<TMessage>} />
149
+ <DayWrapper<TMessage> {...rest as MessageProps<TMessage>} />
150
150
  </Animated.View>
151
151
  {
152
152
  renderMessageProp
153
153
  ? renderMessageProp(rest as MessageProps<TMessage>)
154
- : <Message {...rest as MessageProps<TMessage>} />
154
+ : <Message<TMessage> {...rest as MessageProps<TMessage>} />
155
155
  }
156
156
  </View>
157
157
  )
158
158
  }
159
-
160
- export default Item
@@ -15,11 +15,11 @@ import { ReanimatedScrollEvent } from '../reanimatedCompat'
15
15
 
16
16
  import stylesCommon from '../styles'
17
17
  import { IMessage } from '../types'
18
- import TypingIndicator from '../TypingIndicator'
18
+ import { TypingIndicator } from '../TypingIndicator'
19
19
  import { isSameDay, useCallbackThrottled } from '../utils'
20
- import DayAnimated from './components/DayAnimated'
20
+ import { DayAnimated } from './components/DayAnimated'
21
21
 
22
- import Item from './components/Item'
22
+ import { Item } from './components/Item'
23
23
  import { ItemProps } from './components/Item/types'
24
24
  import styles from './styles'
25
25
  import { MessageContainerProps, DaysPositions } from './types'
@@ -29,7 +29,7 @@ export * from './types'
29
29
 
30
30
  const AnimatedFlatList = Animated.createAnimatedComponent(FlatList) as React.ComponentType<any>
31
31
 
32
- function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageContainerProps<TMessage>) {
32
+ export const MessageContainer = <TMessage extends IMessage>(props: MessageContainerProps<TMessage>) => {
33
33
  const {
34
34
  messages = [],
35
35
  user,
@@ -420,5 +420,3 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
420
420
  </View>
421
421
  )
422
422
  }
423
-
424
- export default MessageContainer
@@ -1,5 +1,5 @@
1
1
  import { StyleSheet } from 'react-native'
2
- import Color from '../Color'
2
+ import { Color } from '../Color'
3
3
 
4
4
  export default StyleSheet.create({
5
5
  containerAlignTop: {