๐ฌ Gifted Chat
The most complete chat UI for React Native
Sponsor
Coding Bootcamp in Paris co-founded by Farid Safi
Click to learn more
Scalable chat API/Server written in Go
API Tour | React Native Gifted tutorial
Features
react-native-webable (ASAP: #1284)- Write with TypeScript (since 0.8.0)
- Fully customizable components
- Composer actions (to attach photos, etc.)
- Load earlier messages
- Copy messages to clipboard
- Touchable links using react-native-parsed-text
- Avatar as user's initials
- Localized dates
- Multi-line TextInput
- InputToolbar avoiding keyboard
- Redux support
- System message
- Quick Reply messages (bot)
Dependency
- Use version
0.2.xfor RN>= 0.44.0 - Use version
0.1.xfor RN>= 0.40.0 - Use version
0.0.10for RN< 0.40.0
Installation
- Using npm:
npm install react-native-gifted-chat --save - Using Yarn:
yarn add react-native-gifted-chat
You have a question ?
- Please check this readme and may find a response
- Please ask on StackOverflow first: https://stackoverflow.com/questions/tagged/react-native-gifted-chat
- Find response on existing issues
- Try to keep issues for issues
Example
import React from 'react' import { GiftedChat } from 'react-native-gifted-chat' class Example extends React.Component { state = { messages: [], } componentWillMount() { this.setState({ messages: [ { _id: 1, text: 'Hello developer', createdAt: new Date(), user: { _id: 2, name: 'React Native', avatar: 'https://placeimg.com/140/140/any', }, }, ], }) } onSend(messages = []) { this.setState(previousState => ({ messages: GiftedChat.append(previousState.messages, messages), })) } render() { return ( <GiftedChat messages={this.state.messages} onSend={messages => this.onSend(messages)} user={{ _id: 1, }} /> ) } }Advanced example
See example/App.js for a working demo!
"Slack" example
See the files in example-slack-message for an example of how to override the default UI to make something that looks more like Slack -- with usernames displayed and all messages on the left.
Message object
e.g. Chat Message
{ _id: 1, text: 'My message', createdAt: new Date(Date.UTC(2016, 5, 11, 17, 20, 0)), user: { _id: 2, name: 'React Native', avatar: 'https://facebook.github.io/react/img/logo_og.png', }, image: 'https://facebook.github.io/react/img/logo_og.png', // You can also add a video prop: video: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4', // Any additional custom parameters are passed through }e.g. System Message
{ _id: 1, text: 'This is a system message', createdAt: new Date(Date.UTC(2016, 5, 11, 17, 20, 0)), system: true, // Any additional custom parameters are passed through }e.g. Chat Message with Quick Reply options
See PR #1211
interface Reply { title: string value: string messageId?: any } interface QuickReplies { type: 'radio' | 'checkbox' values: Reply[] keepIt?: boolean } { _id: 1, text: 'This is a quick reply. Do you love Gifted Chat? (radio) KEEP IT', createdAt: new Date(), quickReplies: { type: 'radio', // or 'checkbox', keepIt: true, values: [ { title: '๐ Yes', value: 'yes', }, { title: '๐ท Yes, let me show you with a picture!', value: 'yes_picture', }, { title: '๐ Nope. What?', value: 'no', }, ], }, user: { _id: 2, name: 'React Native', }, }, { _id: 2, text: 'This is a quick reply. Do you love Gifted Chat? (checkbox)', createdAt: new Date(), quickReplies: { type: 'checkbox', // or 'radio', values: [ { title: 'Yes', value: 'yes', }, { title: 'Yes, let me show you with a picture!', value: 'yes_picture', }, { title: 'Nope. What?', value: 'no', }, ], }, user: { _id: 2, name: 'React Native', }, }Props
messages(Array) - Messages to displaytext(String) - Input text; default isundefined, but if specified, it will override GiftedChat's internal state (e.g. for redux; see notes below)placeholder(String) - Placeholder whentextis empty; default is'Type a message...'messageIdGenerator(Function) - Generate an id for new messages. Defaults to UUID v4, generated by uuiduser(Object) - User sending the messages:{ _id, name, avatar }onSend(Function) - Callback when sending a messagealwaysShowSend(Bool) - Always show send button in input text composer; defaultfalse, show only when text input is not emptylocale(String) - Locale to localize the datestimeFormat(String) - Format to use for rendering times; default is'LT'dateFormat(String) - Format to use for rendering dates; default is'll'isAnimated(Bool) - Animates the view when the keyboard appearsloadEarlier(Bool) - Enables the "Load earlier messages" buttononLoadEarlier(Function) - Callback when loading earlier messagesisLoadingEarlier(Bool) - Display anActivityIndicatorwhen loading earlier messagesrenderLoading(Function) - Render a loading view when initializingrenderLoadEarlier(Function) - Custom "Load earlier messages" buttonrenderAvatar(Function) - Custom message avatar; set tonullto not render any avatar for the messageshowUserAvatar(Bool) - Whether to render an avatar for the current user; default isfalse, only show avatars for other usersshowAvatarForEveryMessage(Bool) - When false, avatars will only be displayed when a consecutive message is from the same user on the same day; default isfalseonPressAvatar(Function(user)) - Callback when a message avatar is tappedrenderAvatarOnTop(Bool) - Render the message avatar at the top of consecutive messages, rather than the bottom; default isfalserenderBubble(Function) - Custom message bubblerenderSystemMessage(Function) - Custom system messageonLongPress(Function(context,message)) - Callback when a message bubble is long-pressed; default is to show an ActionSheet with "Copy Text" (see example usingshowActionSheetWithOptions())inverted(Bool) - Reverses display order ofmessages; default istruerenderUsernameOnMessage(Bool) - Indicate whether to show the user's username inside the message bubble; default isfalserenderMessage(Function) - Custom message containerrenderMessageText(Function) - Custom message textrenderMessageImage(Function) - Custom message imagerenderMessageVideo(Function) - Custom message videoimageProps(Object) - Extra props to be passed to the<Image>component created by the defaultrenderMessageImagevideoProps(Object) - Extra props to be passed to the<Video>component created by the defaultrenderMessageVideolightboxProps(Object) - Extra props to be passed to theMessageImage's LightboxisCustomViewBottom(Bool) - Determine wether renderCustomView is displayed before or after the text, image and video views; default isfalserenderCustomView(Function) - Custom view inside the bubblerenderDay(Function) - Custom day above a messagerenderTime(Function) - Custom time inside a messagerenderFooter(Function) - Custom footer component on the ListView, e.g.'User is typing...'; see example/App.js for an examplerenderChatFooter(Function) - Custom component to render below the MessageContainer (separate from the ListView)renderInputToolbar(Function) - Custom message composer containerrenderComposer(Function) - Custom text input message composerrenderActions(Function) - Custom action button on the left of the message composerrenderSend(Function) - Custom send button; you can pass children to the originalSendcomponent quite easily, for example to use a custom icon (example)renderAccessory(Function) - Custom second line of actions below the message composeronPressActionButton(Function) - Callback when the Action button is pressed (if set, the defaultactionSheetwill not be used)bottomOffset(Integer) - Distance of the chat from the bottom of the screen (e.g. useful if you display a tab bar)minInputToolbarHeight(Integer) - Minimum height of the input toolbar; default is44listViewProps(Object) - Extra props to be passed to the messages<ListView>; some props can't be overridden, see the code inMessageContainer.render()for detailstextInputProps(Object) - Extra props to be passed to the<TextInput>keyboardShouldPersistTaps(Enum) - Determines whether the keyboard should stay visible after a tap; see<ScrollView>docsonInputTextChanged(Function) - Callback when the input text changesmaxInputLength(Integer) - Max message composer TextInput lengthparsePatterns(Function) - Custom parse patterns for react-native-parsed-text used to linkify message content (like URLs and phone numbers), e.g.:
<GiftedChat parsePatterns={(linkStyle) => [ { type: 'phone', style: linkStyle, onPress: this.onPressPhoneNumber }, { pattern: /#(\w+)/, style: { ...linkStyle, styles.hashtag }, onPress: this.onPressHashtag }, ]} />extraData(Object) - Extra props for re-rendering FlatList on demand. This will be useful for rendering footer etc.minComposerHeight(Object) - Custom min height of the composer.maxComposerHeight(Object) - Custom max height of the composer.
scrollToBottom(Bool) - Enables the scrollToBottom Component (Default is false)scrollToBottomComponent(Function) - Custom Scroll To Bottom Component containerscrollToBottomOffset(Integer) - Custom Height Offset upon which to begin showing Scroll To Bottom Component (Default is 200)scrollToBottomStyle(Object) - Custom style for Bottom Component containeralignTop(Boolean) Controls whether or not the message bubbles appear at the top of the chat (Default is false - bubbles align to bottom)onQuickReply(Function) - Callback when sending a quick reply (to backend server)renderQuickReply(Function) - Custom all quick reply viewquickReplyStyle(StyleProp) - Custom quick reply view stylerenderQuickReplySend(Function) - Custom quick reply send viewshouldUpdateMessage(Function) - Lets the message component know when to update outside of normal cases.
Imperative methods
focusTextInput()- Open the keyboard and focus the text input box
Notes for Redux
The messages prop should work out-of-the-box with Redux. In most cases this is all you need.
If you decide to specify a text prop, GiftedChat will no longer manage its own internal text state and will defer entirely to your prop. This is great for using a tool like Redux, but there's one extra step you'll need to take: simply implement onInputTextChanged to receive typing events and reset events (e.g. to clear the text onSend):
<GiftedChat text={customText} onInputTextChanged={text => this.setCustomText(text)} /* ... */ />Notes for Android
If you are using Create React Native App / Expo, no Android specific installation steps are required -- you can skip this section. Otherwise we recommend modifying your project configuration as follows.
-
Make sure you have
android:windowSoftInputMode="adjustResize"in yourAndroidManifest.xml:<activity android:name=".MainActivity" android:label="@string/app_name" android:windowSoftInputMode="adjustResize" android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
-
For Expo, there are almost 2 solutions to fix it:
- adding KeyboardAvoidingView after GiftedChat see this comment
- adding an opaque background status bar on app.json https://docs.expo.io/versions/latest/guides/configuration.html#androidstatusbar
-
If you plan to use
GiftedChatinside aModal, see #200.
Notes for local development
- Install
yarn add -g expo-cli expo start
Questions
- How can I set Bubble color for each user?
- How can I pass style props to InputToolbar design and customize it's color and other styles properties?
- How can I change the color of the message box?
- Is there a way to manually dismiss the keyboard?
- I want to implement a popover that pops right after clicking on a specific avatar, what is the best implementation in this case and how?
- Why TextInput is hidden on Android?
- How to use renderLoading?
- Can I use MySql to save the message?
License
Author
Feel free to ask me questions on Twitter @FaridSafi!
Contributors
- Kevin Cooper cooperka
- Kfir Golan kfiroo
- Bruno Cascio brunocascio
- Xavier Carpentier xcarpentier
- more
Hire an expert!
Looking for a ReactNative freelance expert with more than 12 years experience? Contact Xavier from hisย website!