Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customize message bubble background color? #79

Closed
Hyffer opened this issue Dec 7, 2022 · 12 comments
Closed

Customize message bubble background color? #79

Hyffer opened this issue Dec 7, 2022 · 12 comments
Assignees
Labels
question Further information is requested styling

Comments

@Hyffer
Copy link

Hyffer commented Dec 7, 2022

Refer to documentation, there is no props to change the color of message bubble.

So if i want to implement this feature, which way is better? loading custom css file or using style tag in javascript? And is there some basic examples?

I know little about those front-end things. But i think it can be done by adding a param to Message or MessageGroup component. like:

<Message model={{
  message: "Hello",
  sentTime: "just now",
  sender: "Bob"
}}
 style=... (or className=...)
/>
@supersnager
Copy link
Contributor

supersnager commented Dec 7, 2022

@Hyffer Thank you for the question.

The simplest way is to add an inline style or class to the <Message/> component. Adding a class is preferred over style.
Almost all components pass props not used directly by the component to the main HTML element of the component (e.g. div).

You can also override scss variables (there are almost 400).
You can find more about overriding in the following issue: chatscope/chat-ui-kit-styles#5

Below is the excerpt from a (not yet published) tutorial about the chatscope styling
This is not exactly about the Message component, but the idea is the same:

...
You can pass the className property to each component. The name of the passed class will be appended to the main HTML element of the component as the last value.
The class can be defined in the CSS file or created dynamically with any css-in-js library.

Example.

Create a class .my-chat-container:

.my-chat-container {
  background-color: plum;
  height: 300px;
}

Add it to the like this:

<ChatContainer className="my-chat-container"></ChatContainer>

The HTML code generated by the component will be as follws:

<div class="cs-chat-container my-chat-container"></div>

The result of the above HTML code will be a rendering of a container with a background in a beautiful plum color.

This way, you can change the background color or margin of the main component element but not only.

By taking advantage of CSS inheritance you can also override styles of HTML elements that are deeper in the component structure.

Suppose you want to add a counter to the content of every message that has a .counted-message class.

/* Counter definition */
body {
 counter-reset: message;
}

/* Displaying the counter */
.counted-message .cs-message__html-content::before {
    counter-increment: message;
    content: counter(message);
    font-weight: bold;
    margin-right: 1rem;
}
const messages = [
{
  message: "Hi!",
},
{
  message: "What’s up buddy",
},
{
  message: "We haven't talked for a long time",
}
];
<>
{messages.map( (model,i) => <Message className="counted-message" key={i} model={model} />)}
</>

The result will be something like this:

image

Of course, there is no magic here, it’s just plain CSS inheritance. I’m sure you can handle it.

To find the class names of components' internal HTML elements, just use the inspector available in your browser’s dev tools.

However, I would like to use css-in-js, how to do it?

You are probably already using some sort of css-in-js library in your project. If so, you can do exactly the same as above.

If you are using the solution that allows you to create css classes, such as CSS Modules, JSS, Emotion, Linaria, etc, simply create your class and pass it in the className property to the component.

You can also use styled components, however, there is a small trap here.

Some components check the types of their child components. Inserting a non-allowed component will cause React to complain (red warning on the console).

You can read why this is the case in the chatscope documentation here: Changing component type to allow place it in container slot.
...

I hope this helps you a little :)

@supersnager supersnager added question Further information is requested styling labels Dec 7, 2022
@Hyffer
Copy link
Author

Hyffer commented Dec 8, 2022

I tried as described above, to reload css style of <ChatContainer/>. But encountered a problem. The height of chat container changed to 300px, but the background color did not turn into plum.

image

what I have done:

/*color.css*/
.my-chat-container {
  background-color: plum;
  height: 300px;
}
import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";
import "./color.css"
<ChatContainer style={chatContainerStyle} className="my-chat-container">
// chatContainerStyle controls visibilility
...
<ChatContainer>

packages are updated
"@chatscope/chat-ui-kit-react": "^1.9.8",
"@chatscope/chat-ui-kit-styles": "^1.4.0",

Am I getting something wrong?

@supersnager
Copy link
Contributor

@Hyffer please check the elements inside the .my-chat-container, probably some of these elements have the background color set.

@supersnager supersnager self-assigned this Feb 4, 2023
@mayankjain25
Copy link

@Hyffer Thank you for the question.

The simplest way is to add an inline style or class to the component. Adding a class is preferred over style. Almost all components pass props not used directly by the component to the main HTML element of the component (e.g. div).

You can also override scss variables (there are almost 400). You can find more about overriding in the following issue: chatscope/chat-ui-kit-styles#5

Below is the excerpt from a (not yet published) tutorial about the chatscope styling This is not exactly about the Message component, but the idea is the same:

... You can pass the className property to each component. The name of the passed class will be appended to the main HTML element of the component as the last value. The class can be defined in the CSS file or created dynamically with any css-in-js library.

Example.

Create a class .my-chat-container:

.my-chat-container {
  background-color: plum;
  height: 300px;
}

Add it to the like this:

<ChatContainer className="my-chat-container"></ChatContainer>

The HTML code generated by the component will be as follws:

<div class="cs-chat-container my-chat-container"></div>

The result of the above HTML code will be a rendering of a container with a background in a beautiful plum color.

This way, you can change the background color or margin of the main component element but not only.

By taking advantage of CSS inheritance you can also override styles of HTML elements that are deeper in the component structure.

Suppose you want to add a counter to the content of every message that has a .counted-message class.

/* Counter definition */
body {
 counter-reset: message;
}

/* Displaying the counter */
.counted-message .cs-message__html-content::before {
    counter-increment: message;
    content: counter(message);
    font-weight: bold;
    margin-right: 1rem;
}
const messages = [
{
  message: "Hi!",
},
{
  message: "What’s up buddy",
},
{
  message: "We haven't talked for a long time",
}
];
<>
{messages.map( (model,i) => <Message className="counted-message" key={i} model={model} />)}
</>

The result will be something like this:

image

Of course, there is no magic here, it’s just plain CSS inheritance. I’m sure you can handle it.

To find the class names of components' internal HTML elements, just use the inspector available in your browser’s dev tools.

However, I would like to use css-in-js, how to do it?

You are probably already using some sort of css-in-js library in your project. If so, you can do exactly the same as above.

If you are using the solution that allows you to create css classes, such as CSS Modules, JSS, Emotion, Linaria, etc, simply create your class and pass it in the className property to the component.

You can also use styled components, however, there is a small trap here.

Some components check the types of their child components. Inserting a non-allowed component will cause React to complain (red warning on the console).

You can read why this is the case in the chatscope documentation here: Changing component type to allow place it in container slot. ...

I hope this helps you a little :)

I tried using custom styling on the wrapper, but it only changes the background color of the particular message container, not the chat bubble itself. How can one change the color of only the bubble?

Here's my code:
image

And here's the output for your reference
image

@WeebNetsu
Copy link

I found by doing

.cs-message--outgoing .cs-message__content {
    background-color: #0f0 !important;
}

You can force the outgoing message color to be what you want, probably not the best solution, I do see people mentioning changing the variable contents in a SCSS file can also solve color issues chatscope/chat-ui-kit-styles#5
@mayankjain25

@mayankjain25
Copy link

@WeebNetsu indeed, thank you for the solution
Yes, I had to eventually move to the SCSS route only.
I would however request the team to introduce APIs to make the styling much more convenient than this

@supersnager
Copy link
Contributor

@mayankjain25 I know using styling library is convenient but the problem is that everyone uses a different css library like emotion, styled components, css modules and so on...
Forcing a user to install additional css library does not make sense, so the best (and the fastest) option is to use pure css.
However I know that styling on the fly can be a pain, e.g when you want to change the theme from light to dark, so I'm working on a solution that uses a combination of saas variables and native css variables var(--cs-....)
I'm also thinking about new properties that will allow you to directly style component parts... we will see :).

@Testing07102001
Copy link

i am facing some issues in styles ,even i have installed the styles it shows error like i given below:

ERROR in ./src/components/HomePage/Homepage.jsx 9:0-122
Module not found: Error: Can't resolve '@chatscope/chat-ui-kit-styles' in 'D:\copy of signup\myapp\src\components\HomePage'

@supersnager
Copy link
Contributor

@Testing07102001 How do you import styles?
It should be import styles from "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";

@Testing07102001
Copy link

thanks for your reply @supersnager . i have a another doubt , the UI is responsive but if the screen size is changed to mobile , the chat container is displaying first which contain a arrow or back button to go back to sidebar where the users list is present . but i want to display the sidebar first ,the when the screen size changed which contains the users .

@pimsmeets
Copy link

I ran into the same problem. What worked for me is conditionally applying styles in an useEffect directly to the cs-message__content div:

interface MessageWrapper {
  messageModel: MessageModel,
  isHighLighted?: boolean,
  // Other props
}

const [messages, setMessages] = useState<MessageWrapper[]>([]);

// ... Other code

const applyContentStyles = useCallback(() => {
    document.querySelectorAll('.cs-message .cs-message__content').forEach((content, index) => {
      const highlightedStyle = 'border: 2px solid #6ea9d7 !important; background-color: #b0d4f1 !important;';
      const currentStyle = content.getAttribute('style');

      if (messages[index].isHighLighted) {
        if (currentStyle !== highlightedStyle) {
          content.setAttribute('style', highlightedStyle);
        }
      } else {
        if (currentStyle) {
          content.setAttribute('style', '');
        }
      }
    });
  }, [messages]);

  useEffect(() => {
    applyContentStyles();
  }, [messages, applyContentStyles]); 

@jasonhargrove
Copy link

Next.js

// src/components/chat.scss

@charset "utf-8";

$color-text: white;
$blue: #2894CD;
$green: #61AD4A;
$message-content-incoming-bg-color: $blue;
$message-content-outgoing-bg-color: #444;
$color-secondary: #555;
$message-input-bg-color: white;
$message-input-content-editor-wrapper-bg-color: white;
$message-input-content-editor-color: black;
$button-attachment-color: white;
$button-send-color: $green;
$message-group-header-padding: 0.5rem;
$message-list-scroll-wrapper-padding: 1.2em 1.2em 0 0.8em;

@import "@chatscope/chat-ui-kit-styles/themes/default/variables";

@import "@chatscope/chat-ui-kit-styles/themes/default/main";

In your chat component:

import './chat.scss';

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested styling
Projects
None yet
Development

No branches or pull requests

7 participants