FaridSafi / react-native-gifted-chat

💬 The most complete chat UI for React Native

Home Page:https://gifted.chat

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question Regarding customising Input Toolbar Design

pavanmehta91 opened this issue · comments

commented

How to pass style props to Input Toolbar Design to customize it's color and other style properties

Additional Information

  • React Native version: 0.47
  • react-native-gifted-chat version: 0.3
  • Platform(s) (iOS, Android, or both?): Both

You could copy the InputToolbar.js in the src folder and render your Edited InputToolbar.js in the renderInputToolbar prop of the GiftedChat. Basically it will look like this.



<GiftedChat
     renderInputToolbar={this.renderInputToolbar} 
/>

renderInputToolbar(props){
     // Here you will return your custom InputToolbar.js file you copied before and include with your stylings, edits.
     return (){
          <InputToolbar {...props} />
     }
}

commented

Thanks

I close this issue but create a FAQ in readme to refer it: https://github.com/FaridSafi/react-native-gifted-chat#questions

I'll add on to the answer that the styles can be overridden without copying the whole component:

import { GiftedChat, InputToolbar } from 'react-native-gifted-chat'
//Note that I'm just importing the InputToolbar
<GiftedChat
     renderInputToolbar={this.renderInputToolbar} 
/>

  renderInputToolbar (props) {
     //Add the extra styles via containerStyle
    return <InputToolbar {...props} containerStyle={{borderTopWidth: 1.5, borderTopColor: '#333'}} />
  }

I am trying to hide input toolbar based on a state, below is my code:

<GiftedChat
messages={this.state.messages.reverse()}
renderInputToolbar={this.renderInputToolbar(this.state.toolbar)}
onSend={messages => this.onSend(messages)}
user={{
_id: 2,
}}
/>

renderInputToolbar(){
//if(this.state.toolbar){
return(
<InputToolbar {...props} />
);
//}
}

but I cannot access state in that method? what I am doing wrong? or how I can do that?

Hi,

For some reason, when i try to add a backgroundColor to my InputToolbar

<InputToolbar {...props} containerStyle={styles.messageInput} placeholder="Type your message here..." />
and
messageInput: { borderTopColor: '#222', backgroundColor: 'transparent', },

the text color does not change colors.
And so now my text still black which is the same color as my background color, so we cannot see the text anymore.

I tried adding a color: 'white' but containerStyle does not accept these kind of attributes.
I tried style={{color: 'white'}} but no luck as well.

Any help would be appreciated thank you

Hi,

For some reason, when i try to add a backgroundColor to my InputToolbar

<InputToolbar {...props} containerStyle={styles.messageInput} placeholder="Type your message here..." />
and
messageInput: { borderTopColor: '#222', backgroundColor: 'transparent', },

the text color does not change colors.
And so now my text still black which is the same color as my background color, so we cannot see the text anymore.

I tried adding a color: 'white' but containerStyle does not accept these kind of attributes.
I tried style={{color: 'white'}} but no luck as well.

Any help would be appreciated thank you

Hello, roykhoury,

Just use placeholderTextColor="#fff" if you need to change a placeholder text color or textInputStyle={{ color: "#fff" }} if you need to change users input text color.

Happy coding! ;)

@LPranulis glad to have found textInputStyle and so forth here. But it looks like they aren't props on InputToolbarProps; thusly, typescript complains. Am I missing something?

Hi,
For some reason, when i try to add a backgroundColor to my InputToolbar
<InputToolbar {...props} containerStyle={styles.messageInput} placeholder="Type your message here..." />
and
messageInput: { borderTopColor: '#222', backgroundColor: 'transparent', },
the text color does not change colors.
And so now my text still black which is the same color as my background color, so we cannot see the text anymore.
I tried adding a color: 'white' but containerStyle does not accept these kind of attributes.
I tried style={{color: 'white'}} but no luck as well.
Any help would be appreciated thank you

Hello, roykhoury,

Just use placeholderTextColor="#fff" if you need to change a placeholder text color or textInputStyle={{ color: "#fff" }} if you need to change users input text color.

Happy coding! ;)

This reply is outdated (or too vague). This is proper way to do it in the current version.
Import Composer from 'react-native-gifted-chat' and then
<GiftedChat renderInputToolbar={props => ( <InputToolbar {...props} containerStyle={{ backgroundColor: "black", }} renderComposer={props1 => ( <Composer {...props1} textInputStyle={{ color: "white"}} /> )} /> )} ... />

How to change placeholder styles?

In case someone doesn't understand how to use it with functional component here's my full code

import React, { useState, useCallback, useEffect } from 'react'
import { GiftedChat, InputToolbar } from 'react-native-gifted-chat'
import { StyleSheet } from 'react-native'

export default function ChatScreen() {
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    setMessages([
      {
        _id: 1,
        text: 'Hi, how are you?',
        createdAt: new Date(),
        user: {
          _id: 2,
          name: 'React Native',
          avatar: 'https://placeimg.com/140/140/any',
        },
      },
    ])
  }, [])

  const onSend = useCallback((messages = []) => {
    setMessages(previousMessages => GiftedChat.append(previousMessages, messages))
  }, [])

  function renderInputToolbar (props) {
    return (
      <InputToolbar {...props} containerStyle={styles.toolbar} />
    )
  }

  return (
    <>
    <GiftedChat
      renderInputToolbar={renderInputToolbar}
      messages={messages}
      onSend={messages => onSend(messages)}
      user={{
        _id: 1,
      }}
    />
    </>
  )
}

const styles = StyleSheet.create({
  toolbar: {
    borderRadius: 30
  }
})

Hello, how can I add icons e.g. a camera icon that lets a user upload a photo right before the input field?

Anyone can tell me , how can I add attachment or any icons inside my input ?
Screenshot 2022-04-19 at 5 24 14 PM

Anyone can tell me , how can I add attachment or any icons inside my input ?
Screenshot 2022-04-19 at 5 29 08 PM

Anyone can tell me , how can I add attachment or any icons inside my input ?

You can try with

renderActions={() => (
          <Actions
            onPressActionButton={}
            icon={() => (
              <Icon />
            )}
          />
        )

Anyone can tell me , how can I add attachment or any icons inside my input ?

You can try with

renderActions={() => (
          <Actions
            onPressActionButton={}
            icon={() => (
              <Icon />
            )}
          />
        )

Thank you so much, it is working

I am trying to making UI like this, But how can I do this, anyone have solution...?
Screenshot 2022-04-20 at 1 48 19 PM

Hey @Neha23Seraphic, You got any solution to design this? If Yes, can you share your code? Thank You.

commented

@Neha23Seraphic @Prasad-03 same here, it's look cool

How can we add react-native-controlled-mentions input in place of InputToolBar ?

commented

yes u can

Hello, how can I add icons e.g. a camera icon that lets a user upload a photo right before the input field?

Hey I am trying to do the same, did you find any solution?

const [text, setText] = useState('');

const onSend = (messages = []) => {
    let msg = composeMsg(messages.text);
    setMessages((previousMessages) => GiftedChat.append(previousMessages, [msg]));
    setText('');
  };

  const composeMsg = (text) => {
    let uuid = getNewUuid();
    let createdAt = new Date().toISOString();
    const msg = { _id: uuid, createdAt: createdAt, text: text, user: { _id: 1, name: 'User 1' } };
    return msg;
  };

const customtInputToolbar = () => {
    return (
      <View
        style={styles.customInputView}
      >
        <Composer
          placeholder="Type message here"
          text={text}
          onTextChanged={(val) => {
            setText(val);
          }}
          textInputStyle={styles.composerTxt}
        />
        <Send
          containerStyle={styles.sendBtnContainer}
          alwaysShowSend
          onSend={(mes) => onSend(mes)}
          text={text}
          label="Send"
        >
          <Image
            source={sendIcon}
            style={styles.sendIcon}
          />
        </Send>
      </View>
    );
  };

return (
    <>
        <GiftedChat
          messages={messages}
          textInputProps={{ color: 'black' }}
          renderAvatar={null}
          user={{
            _id: 1,
            name: 'User 1',
          }}
          renderInputToolbar={customtInputToolbar}
        />
      }
    </>
  );
commented

@KrishanMadushanka saving text state in ChatScreen make app super slow when u typing long text message

@KrishanMadushanka saving text state in ChatScreen make app super slow when u typing long text message

@fukemy how to avoid that ?

commented

@KrishanMadushanka saving text state in ChatScreen make app super slow when u typing long text message

@fukemy how to avoid that ?

giftedchat handle text inside, you dont need to handle it. if you still want to do it, just break composer to single class then implement text state to avoid re-render chatscreen

@KrishanMadushanka saving text state in ChatScreen make app super slow when u typing long text message

@fukemy how to avoid that ?

giftedchat handle text inside, you dont need to handle it. if you still want to do it, just break composer to single class then implement text state to avoid re-render chatscreen

I had to handle it since I needed a custom input tool bar

commented

I think inside renderInputToolbar you can using props.text

for those who are still struggling

import React, { useState, useEffect } from 'react';
import { TouchableOpacity, Keyboard, View, TextInput } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { Ionicons } from '@expo/vector-icons';
import { scale, verticalScale, moderateScale } from 'react-native-size-matters';

const CustomToolbar = (props) => {
const navigation = useNavigation();

const [keyboardVisible, setKeyboardVisible] = useState(false);
const [inputValue, setInputValue] = useState('');

useEffect(() => {
const keyboardDidShowListener = Keyboard.addListener(
'keyboardDidShow',
() => {
setKeyboardVisible(true);
}
);
const keyboardDidHideListener = Keyboard.addListener(
'keyboardDidHide',
() => {
setKeyboardVisible(false);
}
);

return () => {
  keyboardDidShowListener.remove();
  keyboardDidHideListener.remove();
};

}, []);

return (
<View style={{
flexDirection: 'row',
alignItems: 'center',
borderRadius: 30,
marginHorizontal: moderateScale(10),
marginBottom: keyboardVisible ? verticalScale(30) : 0,
}}>
<TouchableOpacity
style={{
marginLeft: 10,
marginRight: 10,
}}
onPress={() => navigation.goBack()}
>

  <TextInput
    style={{
      flex: 1,
      borderRadius: 30,
      padding: 10,
      backgroundColor: '#E5E5E5',
      marginRight: 10, 
    }}
    placeholder="Message"
    placeholderTextColor='#2f3c47'
    autoFocus={true}
    value={inputValue}
    onChangeText={(text) => setInputValue(text)}
  />

  <TouchableOpacity
    style={{ marginLeft: 8 }}
    onPress={() => {
      // Logic to send the message
      setInputValue('');  // Clear the input field after sending
    }}
    disabled={!inputValue.trim()}
  >
    <Ionicons
      name="arrow-up"
      size={28}
      color={inputValue.trim() ? '#2f3c47' : '#ccc'}
    />
  </TouchableOpacity>
</View>

);
};

export default CustomToolbar;