chatscope / chat-ui-kit-react

Build your own chat UI with React components in few minutes. Chat UI Kit from chatscope is an open source UI toolkit for developing web chat applications.
https://chatscope.io
MIT License
1.34k stars 116 forks source link

Disable Child type checking #60

Closed ngxson closed 2 years ago

ngxson commented 3 years ago

Hello.

I'm trying to do something like this:

const Header = ({loading, profile, openInfo, openMainMenu}) => {
  return <ConversationHeader>
    {loading ? (
      <>
        <ConversationHeader.Back onClick={openMainMenu} />
        <ConversationHeader.Content userName="Loading..." />        
      </>
    ) : (
      <>
        <ConversationHeader.Back onClick={openMainMenu} />
        <Avatar
          src={profile.profile_pic}
          name={profile.name}
          onClick={openConversationOnFB}
        />
        <ConversationHeader.Content userName={profile.name} />
        <ConversationHeader.Actions>
          <InfoButton onClick={openInfo} />
        </ConversationHeader.Actions>          
      </>
    )}
  </ConversationHeader>
}

However, it is not possible since React.Fragment does not accept as prop.
What can I do to disable allowedChildren in https://github.com/chatscope/chat-ui-kit-react/blob/master/src/components/utils.js ?

Thank you in advance.

supersnager commented 2 years ago

@ngxson Child type checking is done by propTypes and can't be disabled.

However, you can slightly modify the code to achieve your goal.

Solution 1: move <ConversationHeader /> into the condition

const Header = ({loading, profile, openInfo, openMainMenu}) => {
    if (loading) {
        return (
            <ConversationHeader>
                <ConversationHeader.Back onClick={openMainMenu}/>
                <ConversationHeader.Content userName="Loading..."/>
            </ConversationHeader>
        );
    } else {
        return (
            <ConversationHeader>
                <ConversationHeader.Back onClick={openMainMenu}/>
                <Avatar
                    src={profile.profile_pic}
                    name={profile.name}
                    onClick={openConversationOnFB}
                />
                <ConversationHeader.Content userName={profile.name}/>
                <ConversationHeader.Actions>
                    <InfoButton onClick={openInfo}/>
                </ConversationHeader.Actions>
            </ConversationHeader>
        );
    }
}

Solution 2: return <div /> with cs-conversation-header class name. Because ConversationHeader is only a container, this solution is safe for now, but be careful it can be potentially incompatible in future versions.

const Header = ({loading, profile, openInfo, openMainMenu}) => {
    return <div as={ConversationHeader} className="cs-conversation-header">
        {loading ? (
            <>
                <ConversationHeader.Back onClick={openMainMenu} />
                <ConversationHeader.Content userName="Loading..." />
            </>
        ) : (
            <>
                <ConversationHeader.Back onClick={openMainMenu} />
                <Avatar
                    src={profile.profile_pic}
                    name={profile.name}
                    onClick={openConversationOnFB}
                />
                <ConversationHeader.Content userName={profile.name} />
                <ConversationHeader.Actions>
                    <InfoButton onClick={openInfo} />
                </ConversationHeader.Actions>
            </>
        )}
    </div>
}

I hope this helps for now :)

Furthermore, I will try to make some changes to the <ConversationHeader /> to allow it to get React.Fragment as a child: #61 .