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

Documentation for custom styles #5

Open
chloe-schoreisz opened this issue Jul 8, 2021 · 21 comments
Open

Documentation for custom styles #5

chloe-schoreisz opened this issue Jul 8, 2021 · 21 comments
Assignees
Labels
documentation Improvements or additions to documentation

Comments

@chloe-schoreisz
Copy link

I would love to see some documentations on how to stylized the different components (eg. colors, fonts, change of icons, etc)

@supersnager supersnager added the documentation Improvements or additions to documentation label Jul 21, 2021
@chloe-schoreisz
Copy link
Author

chloe-schoreisz commented Aug 2, 2021

For anyone looking, we figured out a way:
We created our own main.scss file, that looks like this:

@charset "utf-8";
@import "./variables";
@import "./helpers/mixins";
@import "./helpers/functions";
@import "@chatscope/chat-ui-kit-styles/themes/default/main.scss";
  • mixins and functions are copy pasted from @chatscope/chat-ui-kit-styles/themes/helpers/mixins and @chatscope/chat-ui-kit-styles/themes/helpers/functions.
  • variables is initially copy pasted from @chatscope/chat-ui-kit-styles/themes/variables, and then updated with the appropriate colors for the different component (keeping the !default for the color variables)
  • We then imported the main.scss into our app (we're using nextjs, which supports scss direct imports)
    ⚠️ I'm still getting issues for stylizing the send button and the input box.

This will work if your app supports scss. You should compile this to css if it doesn't.

@supersnager supersnager self-assigned this Sep 13, 2021
@supersnager
Copy link
Contributor

@chloe-schoreisz Thank you for your explanation. It's awesome that somebody helps me maintaining the project :)

And here is the solution that I use in my projects based on Create React App.

Assuming your app supports scss (e.g. CRA, NEXTjs).

project_root/src/themes/default/_chat-overrides.scss:

/* The path depends on the current location of the scss file */
@import "../../../node_modules/@chatscope/chat-ui-kit-styles/themes/default/variables";

// Here you can override variables from the imported file above. Check its source for a list of available variables
$main-container-border: 0;
$color-text: red;
$conversation-color: pink;

// ... and so on 

project_root/src/themes/default/main.scss:

@charset "utf-8";
@import "./chat-overrides";
@import "../../../node_modules/@chatscope/chat-ui-kit-styles/themes/default/main";

// ... any other imports 

project_root/src/App.js:

import './themes/default/main.scss';
import MyApp from "./MyApp"

function App() {
 return (<MyApp />);
}
export default App;

@supersnager
Copy link
Contributor

@chloe-schoreisz

I'm still getting issues for stylizing the send button and the input box

What's your issue with styling these items??

@chloe-schoreisz
Copy link
Author

chloe-schoreisz commented Sep 23, 2021

I was trying to obtain a specific color for the SendButton through the custom scss file. I could not change it from there, and I tried all the variables. The only way I was able to change the color was by implementing my own CustomMessageInput, and hardcode the color in the styling.

// CustomMessageInput.tsx

                         <MessageInput
				ref={...}
				onSend={sendMessage}
				onChange={(_: string, textContent: string) => {
					setMessageInputValue(textContent);
				}}
				value={messageInputValue}
				sendButton={false}
				attachButton={false}
			/>
			<SendButton
				onClick={() => sendMessage(messageInputValue)}
				style={{
					color: '#0C3276',
					backgroundColor: '#C7FED2',
					width: '48px',
					height: '45px'
					
				}}
			/>

@chloe-schoreisz
Copy link
Author

I was also trying to update the icon of the send button, but couldn't find a way

@supersnager
Copy link
Contributor

supersnager commented Sep 23, 2021

@chloe-schoreisz Your solution is fine, especially when there is a need to make more changes than simply color change.

However, the send button color should be changeable by overriding $send-button-color variable

$button-send-color: $button-color;
but now I see there is a bug 😅 (missing !default) I will fix fixed it in here: #8

@sh1ggy
Copy link

sh1ggy commented Mar 26, 2023

Just gave this a try in NextJS with my own project and ran into some issues with the styles not applying despite following the instructions that @supersnager laid out so thought it would be good to share here. The import of the variables.scss file in your custom.scss styles should be happening after your actual custom variables are assigned. We referred to this article to figure this out. Unfortunately, we weren't able to get modular styles to work (in attempts to follow NextJS conventions), having to import and apply the styles globally on _app.tsx.

$color-text: red;

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

Not sure if this is a quirk of NextJS, but would be interested to know. Thank you!

@axelferdinand
Copy link

/* The path depends on the current location of the scss file */
@import "../../../node_modules/@chatscope/chat-ui-kit-styles/themes/default/variables";

// Here you can override variables from the imported file above. Check its source for a list of available variables
$main-container-border: 0;
$color-text: red;
$conversation-color: pink;

Using this approach, I manage to change some of the variables (i.e. the default font family), but only if i replace !default with !important, and that's not possible with all variables (i.e. the color variables – they throw an error if I use !important – do you know a way around?

@supersnager
Copy link
Contributor

@axelferdinand Please share the code (e.g. your _chat-overrides.scss ), how do you override values?
!default and !important are used for different things, when overriding, you don't use !default.

@axelferdinand
Copy link

axelferdinand commented May 5, 2023

@supersnager Sure!

_chat-overrides.scss

// Default font family
//

$default-font-family: 'Clan', Helvetica, sans-serif !important;

// Colors
//

$color-primary: #000 !default;
$color-primary-light: #FFF !default;
$color-primary-dark: #000 !default;
$color-primary-dark: #000 !default;

main.scss

@charset "utf-8";

@font-face {
  font-family: 'Clan';
  src: url('fonts/ClanOffc-News.woff2') format('woff2');
       font-weight: normal;
       font-style: normal;
}

@font-face {
  font-family: 'Clan';
  src: url('fonts/ClanOffc-Bold.woff2') format('woff2');
       font-weight: bold;
       font-style: bold;
}

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

_app.txt

import type { AppProps } from "next/app";
import { FpjsProvider } from "@fingerprintjs/fingerprintjs-pro-react";
import { configureAbly } from "@ably-labs/react-hooks";
import '../themes/default/main.scss';

const prefix = process.env.API_ROOT || "";

const clientId =
  Math.random().toString(36).substring(2, 15) +
  Math.random().toString(36).substring(2, 15);

configureAbly({
  authUrl: `${prefix}/api/createTokenRequest?clientId=${clientId}`,
  clientId: clientId,
});

const fpjsPublicApiKey = process.env.FINGERPRINT as string;

export default function App({ Component, pageProps }: AppProps) {
  return (
    <FpjsProvider
      loadOptions={{
        apiKey: fpjsPublicApiKey,
      }}
    >
      <Component {...pageProps} />
    </FpjsProvider>
  );
}

index.txs

import Head from "next/head";
import { useState } from "react";
import { useVisitorData } from "@fingerprintjs/fingerprintjs-pro-react";
import ReactMarkdown from "react-markdown";
import * as timeago from "timeago.js";

import styles from "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";

import {
  MainContainer,
  ChatContainer,
  MessageList,
  Message,
  MessageInput,
  ConversationHeader,
  TypingIndicator,
} from "@chatscope/chat-ui-kit-react";

import { useChannel } from "@ably-labs/react-hooks";
import { Types } from "ably";

type ConversationEntry = {
  message: string;
  speaker: "bot" | "user";
  date: Date;
  id?: string;
};

type request = {
  prompt: string;
};

const updateChatbotMessage = (
  conversation: ConversationEntry[],
  message: Types.Message
): ConversationEntry[] => {
  const interactionId = message.data.interactionId;

  const updatedConversation = conversation.reduce(
    (acc: ConversationEntry[], e: ConversationEntry) => [
      ...acc,
      e.id === interactionId
        ? { ...e, message: e.message + message.data.token }
        : e,
    ],
    []
  );

  return conversation.some((e) => e.id === interactionId)
    ? updatedConversation
    : [
        ...updatedConversation,
        {
          id: interactionId,
          message: message.data.token,
          speaker: "bot",
          date: new Date(),
        },
      ];
};

export default function Home() {
  const [text, setText] = useState("");
  const [extendedResult, updateExtendedResult] = useState(false);
  const [conversation, setConversation] = useState<ConversationEntry[]>([]);
  const [botIsTyping, setBotIsTyping] = useState(false);
  const [statusMessage, setStatusMessage] = useState("Skriv spørsmålet ditt...");

  const { isLoading, data: visitorData } = useVisitorData(
    { extendedResult },
    { immediate: true }
  );

  useChannel(visitorData?.visitorId! || "default", (message) => {
    switch (message.data.event) {
      case "response":
        setConversation((state) => updateChatbotMessage(state, message));
        break;
      case "status":
        setStatusMessage(message.data.message);
        break;
      case "responseEnd":
      default:
        setBotIsTyping(false);
        setStatusMessage("Waiting for query...");
    }
  });

  const submit = async () => {
    setConversation((state) => [
      ...state,
      {
        message: text,
        speaker: "user",
        date: new Date(),
      },
    ]);
    try {
      setBotIsTyping(true);
      const response = await fetch("/api/chat", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ prompt: text, userId: visitorData?.visitorId }),
      });

      await response.json();
    } catch (error) {
      console.error("Error submitting message:", error);
    } finally {
      setBotIsTyping(false);
    }
    setText("");
  };

  return (
    <>
      <Head>
        <title>Virke</title>
        <meta name="description" content="Generated by create next app" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main className={styles.main}>
        <div
          style={{ position: "relative", height: "98vh", overflow: "hidden" }}
        >
          <MainContainer>
            <ChatContainer>
              <ConversationHeader>
                <ConversationHeader.Actions></ConversationHeader.Actions>
                <ConversationHeader.Content
                  userName="Få hjelp med det juridiske innholdet på virke.no"
                  info={statusMessage}
                />
              </ConversationHeader>

              <MessageList
                typingIndicator={
                  botIsTyping ? (
                    <TypingIndicator content="Vi jobber med saken..." />
                  ) : null
                }
              >
                {conversation.map((entry, index) => {
                  return (
                    <Message
                      key={index}
                      style={{ width: "90%" }}
                      model={{
                        type: "custom",
                        sender: entry.speaker,
                        position: "single",
                        direction:
                          entry.speaker === "bot" ? "incoming" : "outgoing",
                      }}
                    >
                      <Message.CustomContent>
                        <ReactMarkdown>{entry.message}</ReactMarkdown>
                      </Message.CustomContent>
                      <Message.Footer
                        sentTime={timeago.format(entry.date)}
                        sender={entry.speaker === "bot" ? "Virke" : "Du"}
                      />
                    </Message>
                  );
                })}
              </MessageList>
              <MessageInput
                placeholder="Skriv her..."
                onSend={submit}
                onChange={(e, text) => {
                  setText(text);
                }}
                sendButton={true}
                autoFocus
                disabled={isLoading}
              />
            </ChatContainer>
          </MainContainer>
        </div>
      </main>
    </>
  );
}

@supersnager
Copy link
Contributor

@axelferdinand

Try to remove !default in _chat-overrides.scss

Change this:

$color-primary: #000 !default;
$color-primary-light: #FFF !default;
$color-primary-dark: #000 !default;
$color-primary-dark: #000 !default;

to this:

$color-primary: #000;
$color-primary-light: #FFF;
$color-primary-dark: #000;
$color-primary-dark: #000;

@axelferdinand
Copy link

@supersnager I tried that, but it didn't work, unfortunately.

My console says this:

wait  - compiling...
event - compiled successfully in 426 ms (434 modules)

...but the colors (or other variables) doesn't update. This is the only thing that will update:

$default-font-family: 'Clan', Helvetica, sans-serif !important;

@supersnager
Copy link
Contributor

@axelferdinand I think I have found the source of the problem.

Try to remove the following line from the index.tsx:

import styles from "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";

and remove className from:

<main className={styles.main}>

Your example is not working because you import main.scss which includes:

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

and next you import @chatscope/chat-ui-kit-styles/dist/default/styles.min.css
The import of the minimized styles overrides a theme imported earlier.

After importing main.scss all chatscope styles are ready because the theme is built in your app.
So importing @chatscope/chat-ui-kit-styles/dist/default/styles.min.css is not necessary.

BTW in the @chatscope/chat-ui-kit-styles/dist/default/styles.min.css there is no "main" class.

@axelferdinand
Copy link

@supersnager That did indeed work!! Thank you so much!!

@dolce-emmy
Copy link

dolce-emmy commented May 26, 2023

Hello I was wondering if there is any way possible to style the chat-ui-kit using the tailwind? I tried with the MainContainer, ChatContainer, MessageList and it worked... However when I tried to style the MessageInput and the MessageSeperator using tailwind I couldn't... so I was wondering if you can help me with that please?

@supersnager
Copy link
Contributor

@dolce-emmy What exactly do you want to do?

@abuvanth
Copy link

I want dark theme

@FatGuyy
Copy link

FatGuyy commented Oct 29, 2023

I want dark theme

Me too. It'd be nice to just add a dark mode functionality in the kit itself
@supersnager

@hhussein97
Copy link

Any updated guide on how to change the style?

@ragib1803
Copy link

ragib1803 commented Mar 7, 2024

Just take these classnames to your styles.css and change accordingly. This overrides the default styles.

div .cs-message-list__typing-indicator-container div {
color: #6d4700;
}

div .cs-main-container,
div .cs-chat-container .cs-message-input {
border: 0px;
}

div .cs-message--incoming .cs-message__content,
div .cs-chat-container .cs-message-input,
div .ps__thumb-y,
div .ps__rail-y:hover .ps__thumb-y,
div .ps__rail-y:active .ps__thumb-y {
background-color: #ffc436;
}

div .cs-message-input__content-editor,
div .cs-message-input__content-editor-wrapper,
div .cs-message-list,
div .ps__rail-y:hover,
div .ps .ps__rail-y:hover,
div .ps__rail-y {
background-color: #ffebbb;
}

div .cs-message--outgoing .cs-message__content {
background-color: #ffa552;
}

div .cs-typing-indicator__dot {
background-color: #6d4700;
}

Kari-C added a commit to Kari-C/langchain-supabase-chatbot-stack that referenced this issue Jul 27, 2024
Must do all this to over-ride the default styles.
chatscope/chat-ui-kit-styles#5
@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
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

10 participants