FaridSafi/react-native-gifted-chat

Question Regarding customising Input Toolbar Design

pavanmehta91 opened this issue ยท 29 comments

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} />
     }
}

Thanks

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

nadbm commented

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.

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

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

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}
        />
      }
    </>
  );

@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 ?

@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

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;