mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
feat: shadow dom + minor css
This commit is contained in:
parent
a9070580bd
commit
6669361438
17
widget/.npmignore
Normal file
17
widget/.npmignore
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
src
|
||||||
|
node_modules
|
||||||
|
build
|
||||||
|
public
|
||||||
|
tests
|
||||||
|
Dockerfile
|
||||||
|
.dockerignore
|
||||||
|
.eslintrc.json
|
||||||
|
index.html
|
||||||
|
package.json
|
||||||
|
tsconfig.app.json
|
||||||
|
tsconfig.json
|
||||||
|
tsconfig.node.json
|
||||||
|
vite.config.ts
|
||||||
|
dist/index.html
|
||||||
|
dist/shadow.html
|
||||||
|
vite.svg
|
@ -1,6 +1,8 @@
|
|||||||
# Hexabot Live Chat Widget
|
# Hexabot Live Chat Widget
|
||||||
The [Hexabot](https://hexabot.ai/) Live Chat Widget is a React-based embeddable widget that allows users to integrate real-time chat functionality into their websites. It connects to the Hexabot API and facilitates seamless interaction between end-users and chatbots across multiple channels.
|
The [Hexabot](https://hexabot.ai/) Live Chat Widget is a React-based embeddable widget that allows users to integrate real-time chat functionality into their websites. It connects to the Hexabot API and facilitates seamless interaction between end-users and chatbots across multiple channels.
|
||||||
|
|
||||||
|
[Hexabot](https://hexabot.ai/) is an open-source chatbot / agent solution that allows users to create and manage AI-powered, multi-channel, and multilingual chatbots with ease. If you would like to learn more, please visit the [official github repo](https://github.com/Hexastack/Hexabot/).
|
||||||
|
|
||||||
## Key Features
|
## Key Features
|
||||||
- **Real-Time Chat:** Engage in real-time conversations with users directly through your website.
|
- **Real-Time Chat:** Engage in real-time conversations with users directly through your website.
|
||||||
- **Customizable:** Easily customize the widget's appearance and behavior to fit your brand and website.
|
- **Customizable:** Easily customize the widget's appearance and behavior to fit your brand and website.
|
||||||
@ -68,6 +70,40 @@ Once the widget is built, you can easily embed it into any webpage. Here's an ex
|
|||||||
```
|
```
|
||||||
Replace the values in apiUrl and token with your configuration details.
|
Replace the values in apiUrl and token with your configuration details.
|
||||||
|
|
||||||
|
To prevent the website css from conflicting with the chat widget css, we can leverage the shadow dom:
|
||||||
|
```js
|
||||||
|
<script crossorigin src="https://cdn.jsdelivr.net/npm/react@18/umd/react.production.min.js"></script>
|
||||||
|
<script crossorigin src="https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.production.min.js"></script>
|
||||||
|
<script src="<<WIDGET URL>>/hexabot-widget.umd.js"></script>
|
||||||
|
|
||||||
|
<div id="hb-chat-widget"></div>
|
||||||
|
<script>
|
||||||
|
// Create the shadow root and attach it to the widget container
|
||||||
|
const createElement = (tag, props = {}) => Object.assign(document.createElement(tag), props);
|
||||||
|
const shadowContainer = createElement("div");
|
||||||
|
document
|
||||||
|
.getElementById('hb-chat-widget')
|
||||||
|
.attachShadow({ mode: 'open' })
|
||||||
|
.append(
|
||||||
|
shadowContainer,
|
||||||
|
createElement("link", {
|
||||||
|
rel: "stylesheet",
|
||||||
|
href: "<<WIDGET URL>>/style.css"
|
||||||
|
});
|
||||||
|
);
|
||||||
|
|
||||||
|
// Render the widget inside the shadow root
|
||||||
|
ReactDOM.render(
|
||||||
|
React.createElement(HexabotWidget, {
|
||||||
|
apiUrl: 'https://api.yourdomain.com',
|
||||||
|
channel: 'offline',
|
||||||
|
token: 'token123',
|
||||||
|
}),
|
||||||
|
shadowContainer,
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
You can customize the look and feel of the chat widget by modifying the widget’s scss styles or behavior. The widget allows you to:
|
You can customize the look and feel of the chat widget by modifying the widget’s scss styles or behavior. The widget allows you to:
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "hexabot-widget",
|
"name": "hexabot-live-chat-widget",
|
||||||
"private": true,
|
"version": "2.0.0-rc.2",
|
||||||
"version": "2.0.0",
|
|
||||||
"description": "Hexabot is a solution for creating and managing chatbots across multiple channels, leveraging AI for advanced conversational capabilities. It provides a user-friendly interface for building, training, and deploying chatbots with integrated support for various messaging platforms.",
|
"description": "Hexabot is a solution for creating and managing chatbots across multiple channels, leveraging AI for advanced conversational capabilities. It provides a user-friendly interface for building, training, and deploying chatbots with integrated support for various messaging platforms.",
|
||||||
"author": "Hexastack",
|
"author": "Hexastack",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
"main": "dist/hexabot-widget.umd.js",
|
||||||
|
"style": "dist/style.css",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build",
|
||||||
@ -38,5 +39,9 @@
|
|||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
"vite": "^5.3.4",
|
"vite": "^5.3.4",
|
||||||
"vite-plugin-dts": "^4.0.2"
|
"vite-plugin-dts": "^4.0.2"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@rollup/rollup-darwin-arm64": "^4.24.0",
|
||||||
|
"@esbuild/darwin-arm64": "^0.24.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,15 +18,26 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="hb-chat-widget"></div>
|
<div id="hb-chat-widget"></div>
|
||||||
<script>
|
<script>
|
||||||
const el = React.createElement;
|
// Create the shadow root and attach it to the widget container
|
||||||
const domContainer = document.getElementById('hb-chat-widget');
|
const createElement = (tag, props = {}) => Object.assign(document.createElement(tag), props);
|
||||||
|
const shadowContainer = createElement("div");
|
||||||
|
document
|
||||||
|
.getElementById('hb-chat-widget')
|
||||||
|
.attachShadow({ mode: 'open' })
|
||||||
|
.append(
|
||||||
|
shadowContainer,
|
||||||
|
createElement("link", {
|
||||||
|
rel: "stylesheet",
|
||||||
|
href: "./style.css"
|
||||||
|
})
|
||||||
|
);
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
el(HexabotWidget, {
|
React.createElement(HexabotWidget, {
|
||||||
apiUrl: 'http://localhost:4000',
|
apiUrl: 'http://localhost:4000',
|
||||||
channel: 'offline',
|
channel: 'offline',
|
||||||
token: 'token123',
|
token: 'token123',
|
||||||
}),
|
}),
|
||||||
domContainer,
|
shadowContainer,
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
border-bottom-left-radius: 10px;
|
border-bottom-left-radius: 10px;
|
||||||
border-bottom-right-radius: 10px;
|
border-bottom-right-radius: 10px;
|
||||||
transition: background-color 0.2s ease, box-shadow 0.2s ease;
|
transition: background-color 0.2s ease, box-shadow 0.2s ease;
|
||||||
border-top: 1px solid #eaeaea;
|
border: 1px solid #eaeaea;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sc-user-input--text {
|
.sc-user-input--text {
|
||||||
|
@ -137,10 +137,7 @@ const UserInput: React.FC = () => {
|
|||||||
const uploading = outgoingMessageState === OutgoingMessageState.uploading;
|
const uploading = outgoingMessageState === OutgoingMessageState.uploading;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="sc-user-input-wrapper">
|
||||||
className="sc-user-input-wrapper"
|
|
||||||
style={{ fill: colors.userInput.text }}
|
|
||||||
>
|
|
||||||
{suggestions.length > 0 && <Suggestions />}
|
{suggestions.length > 0 && <Suggestions />}
|
||||||
|
|
||||||
{(file || uploading) && (
|
{(file || uploading) && (
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
padding: 0px;
|
padding: 0px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
opacity: .5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sc-user-input--emoji-icon-wrapper:focus {
|
.sc-user-input--emoji-icon-wrapper:focus {
|
||||||
@ -12,18 +13,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sc-user-input--emoji-icon {
|
.sc-user-input--emoji-icon {
|
||||||
width: 18px;
|
width: 20px;
|
||||||
height: 18px;
|
height: 20px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sc-user-input--emoji-icon-wrapper:focus .sc-user-input--emoji-icon path,
|
.sc-user-input--emoji-icon-wrapper:focus,
|
||||||
.sc-user-input--emoji-icon-wrapper:focus .sc-user-input--emoji-icon circle,
|
.sc-user-input--emoji-icon-wrapper:hover {
|
||||||
.sc-user-input--emoji-icon.active path,
|
opacity: 1;
|
||||||
.sc-user-input--emoji-icon.active circle,
|
|
||||||
.sc-user-input--emoji-icon:hover path,
|
|
||||||
.sc-user-input--emoji-icon:hover circle {
|
|
||||||
filter: contrast(15%);
|
|
||||||
}
|
}
|
@ -1,6 +1,12 @@
|
|||||||
.sc-user-input--file-wrapper {
|
.sc-user-input--file-wrapper {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
outline: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
opacity: .5;
|
||||||
}
|
}
|
||||||
.sc-user-input--file-icon-wrapper {
|
.sc-user-input--file-icon-wrapper {
|
||||||
background: none;
|
background: none;
|
||||||
@ -8,7 +14,7 @@
|
|||||||
padding: 0px;
|
padding: 0px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
outline: none;
|
outline: none;
|
||||||
cursor: pointer;
|
cursor: pointer !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sc-user-input--file-icon {
|
.sc-user-input--file-icon {
|
||||||
@ -19,6 +25,6 @@
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sc-user-input--file-icon:hover path {
|
.sc-user-input--file-wrapper:hover {
|
||||||
filter: contrast(15%);
|
opacity: 1
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
padding: 0px;
|
padding: 0px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
opacity: .5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sc-user-input--location-icon-wrapper:focus {
|
.sc-user-input--location-icon-wrapper:focus {
|
||||||
@ -11,20 +12,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sc-user-input--location-icon {
|
.sc-user-input--location-icon {
|
||||||
width: 16px;
|
width: 20px;
|
||||||
height: 16px;
|
height: 20px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sc-user-input--location-icon-wrapper:focus .sc-user-input--location-icon path,
|
.sc-user-input--location-icon-wrapper:hover {
|
||||||
.sc-user-input--location-icon-wrapper:focus
|
opacity: 1;
|
||||||
.sc-user-input--location-icon
|
|
||||||
circle,
|
|
||||||
.sc-user-input--location-icon.active path,
|
|
||||||
.sc-user-input--location-icon.active circle,
|
|
||||||
.sc-user-input--location-icon:hover path,
|
|
||||||
.sc-user-input--location-icon:hover circle {
|
|
||||||
filter: contrast(15%);
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ const EmojiIcon: FC<SVGProps<SVGSVGElement>> = ({
|
|||||||
x = '0',
|
x = '0',
|
||||||
y = '0',
|
y = '0',
|
||||||
className = 'sc-user-input--emoji-icon',
|
className = 'sc-user-input--emoji-icon',
|
||||||
viewBox = '0 0 37 37',
|
viewBox = '0 0 24 24',
|
||||||
...rest
|
...rest
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
@ -24,10 +24,11 @@ const EmojiIcon: FC<SVGProps<SVGSVGElement>> = ({
|
|||||||
viewBox={viewBox}
|
viewBox={viewBox}
|
||||||
{...rest}
|
{...rest}
|
||||||
>
|
>
|
||||||
<path d="M18.696 37.393C8.387 37.393 0 29.006 0 18.696 0 8.387 8.387 0 18.696 0c10.31 0 18.696 8.387 18.696 18.696.001 10.31-8.386 18.697-18.696 18.697zm0-35.393C9.49 2 2 9.49 2 18.696c0 9.206 7.49 16.696 16.696 16.696 9.206 0 16.696-7.49 16.696-16.696C35.393 9.49 27.902 2 18.696 2z" />
|
<circle cx="15.5" cy="9.5" r="1.5" />
|
||||||
<circle cx="12.379" cy="14.359" r="1.938" />
|
<circle cx="8.5" cy="9.5" r="1.5" />
|
||||||
<circle cx="24.371" cy="14.414" r="1.992" />
|
<circle cx="15.5" cy="9.5" r="1.5" />
|
||||||
<path d="M18.035 27.453c-5.748 0-8.342-4.18-8.449-4.357a1 1 0 011.71-1.038c.094.151 2.161 3.396 6.74 3.396 4.713 0 7.518-3.462 7.545-3.497a1 1 0 011.566 1.244c-.138.173-3.444 4.252-9.112 4.252z" />
|
<circle cx="8.5" cy="9.5" r="1.5" />
|
||||||
|
<path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2M12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8m0-2.5c2.33 0 4.32-1.45 5.12-3.5h-1.67c-.69 1.19-1.97 2-3.45 2s-2.75-.81-3.45-2H6.88c.8 2.05 2.79 3.5 5.12 3.5" />
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -12,7 +12,7 @@ const FileInputIcon: FC<SVGProps<SVGSVGElement>> = ({
|
|||||||
x = '0',
|
x = '0',
|
||||||
y = '0',
|
y = '0',
|
||||||
className = 'sc-user-input--file-icon',
|
className = 'sc-user-input--file-icon',
|
||||||
viewBox = '0 0 32 32',
|
viewBox = '0 0 24 24',
|
||||||
...rest
|
...rest
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
@ -24,10 +24,7 @@ const FileInputIcon: FC<SVGProps<SVGSVGElement>> = ({
|
|||||||
viewBox={viewBox}
|
viewBox={viewBox}
|
||||||
{...rest}
|
{...rest}
|
||||||
>
|
>
|
||||||
<path
|
<path d="M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6z" />{' '}
|
||||||
fill="currentColor"
|
|
||||||
d="M20.807 10.22l-2.03-2.029-10.15 10.148c-1.682 1.681-1.682 4.408 0 6.089s4.408 1.681 6.09 0l12.18-12.178a7.173 7.173 0 000-10.148 7.176 7.176 0 00-10.149 0L3.96 14.889l-.027.026c-3.909 3.909-3.909 10.245 0 14.153 3.908 3.908 10.246 3.908 14.156 0l.026-.027.001.001 8.729-8.728-2.031-2.029-8.729 8.727-.026.026a7.148 7.148 0 01-10.096 0 7.144 7.144 0 010-10.093l.028-.026-.001-.002L18.78 4.131c1.678-1.679 4.411-1.679 6.09 0s1.678 4.411 0 6.089L12.69 22.398c-.56.56-1.47.56-2.03 0a1.437 1.437 0 010-2.029L20.81 10.22z"
|
|
||||||
/>
|
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -13,7 +13,7 @@ const LocationIcon: FC<SVGProps<SVGSVGElement>> = ({
|
|||||||
y = '0',
|
y = '0',
|
||||||
className = 'sc-user-input--location-icon',
|
className = 'sc-user-input--location-icon',
|
||||||
version = '1.1',
|
version = '1.1',
|
||||||
viewBox = '0 0 32 32',
|
viewBox = '0 0 24 24',
|
||||||
...rest
|
...rest
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
@ -26,8 +26,7 @@ const LocationIcon: FC<SVGProps<SVGSVGElement>> = ({
|
|||||||
viewBox={viewBox}
|
viewBox={viewBox}
|
||||||
{...rest}
|
{...rest}
|
||||||
>
|
>
|
||||||
<path d="M16.002 17.746c3.309 0 6-2.692 6-6s-2.691-6-6-6-6 2.691-6 6 2.691 6 6 6zm0-11c2.758 0 5 2.242 5 5s-2.242 5-5 5-5-2.242-5-5 2.242-5 5-5z" />
|
<path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7m0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5" />
|
||||||
<path d="M16 0C9.382 0 4 5.316 4 12.001c0 7 6.001 14.161 10.376 19.194.016.02.718.805 1.586.805h.077c.867 0 1.57-.785 1.586-.805 4.377-5.033 10.377-12.193 10.377-19.194A11.971 11.971 0 0016 0zm.117 29.883c-.021.02-.082.064-.135.098-.01-.027-.084-.086-.129-.133C12.188 25.631 6 18.514 6 12.001 6 6.487 10.487 2 16 2c5.516 0 10.002 4.487 10.002 10.002 0 6.512-6.188 13.629-9.885 17.881z" />
|
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
margin: 2px;
|
margin: 2px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
font-size: 1rem;
|
font-size: .75rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,34 +11,34 @@ import { ColorState } from '../types/colors.types';
|
|||||||
const colors: Record<string, ColorState> = {
|
const colors: Record<string, ColorState> = {
|
||||||
orange: {
|
orange: {
|
||||||
header: {
|
header: {
|
||||||
bg: '#E6A23D',
|
bg: '#FF851B',
|
||||||
text: '#fff',
|
text: '#fff',
|
||||||
},
|
},
|
||||||
launcher: {
|
launcher: {
|
||||||
bg: '#E6A23D',
|
bg: '#FF851B',
|
||||||
},
|
},
|
||||||
messageList: {
|
messageList: {
|
||||||
bg: '#fff',
|
bg: '#fff',
|
||||||
},
|
},
|
||||||
sent: {
|
sent: {
|
||||||
bg: '#E6A23D',
|
bg: '#FF851B',
|
||||||
text: '#fff',
|
text: '#fff',
|
||||||
},
|
},
|
||||||
received: {
|
received: {
|
||||||
bg: '#eaeaea',
|
bg: '#eaeaea',
|
||||||
text: '#222222',
|
text: '#000',
|
||||||
},
|
},
|
||||||
userInput: {
|
userInput: {
|
||||||
bg: '#fff',
|
bg: '#fbfbfb',
|
||||||
text: '#212121',
|
text: '#000',
|
||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
bg: '#ffffff',
|
bg: '#ffffff',
|
||||||
text: '#E6A23D',
|
text: '#FF851B',
|
||||||
border: '#E6A23D',
|
border: '#FF851B',
|
||||||
},
|
},
|
||||||
messageStatus: {
|
messageStatus: {
|
||||||
bg: '#E6A23D',
|
bg: '#FF851B',
|
||||||
},
|
},
|
||||||
messageTime: {
|
messageTime: {
|
||||||
text: '#9C9C9C',
|
text: '#9C9C9C',
|
||||||
@ -46,139 +46,139 @@ const colors: Record<string, ColorState> = {
|
|||||||
},
|
},
|
||||||
red: {
|
red: {
|
||||||
header: {
|
header: {
|
||||||
bg: '#AB1251',
|
bg: '#FF4136',
|
||||||
text: '#fff',
|
text: '#fff',
|
||||||
},
|
},
|
||||||
launcher: {
|
launcher: {
|
||||||
bg: '#AB1251',
|
bg: '#FF4136',
|
||||||
},
|
},
|
||||||
messageList: {
|
messageList: {
|
||||||
bg: '#fff',
|
bg: '#fff',
|
||||||
},
|
},
|
||||||
sent: {
|
sent: {
|
||||||
bg: '#AB1251',
|
bg: '#FF4136',
|
||||||
text: '#fff',
|
text: '#fff',
|
||||||
},
|
},
|
||||||
received: {
|
received: {
|
||||||
bg: '#eaeaea',
|
bg: '#eaeaea',
|
||||||
text: '#222222',
|
text: '#000',
|
||||||
},
|
},
|
||||||
userInput: {
|
userInput: {
|
||||||
bg: '#fff',
|
bg: '#fbfbfb',
|
||||||
text: '#212121',
|
text: '#000',
|
||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
bg: '#ffffff',
|
bg: '#ffffff',
|
||||||
text: '#AB1251',
|
text: '#FF4136',
|
||||||
border: '#AB1251',
|
border: '#FF4136',
|
||||||
},
|
},
|
||||||
messageStatus: {
|
messageStatus: {
|
||||||
bg: '#AB1251',
|
bg: '#FF4136',
|
||||||
},
|
},
|
||||||
messageTime: {
|
messageTime: {
|
||||||
text: '#9C9C9C',
|
text: '#FF4136',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
green: {
|
green: {
|
||||||
header: {
|
header: {
|
||||||
bg: '#ABBD49',
|
bg: '#2ECC40',
|
||||||
text: '#fff',
|
text: '#fff',
|
||||||
},
|
},
|
||||||
launcher: {
|
launcher: {
|
||||||
bg: '#ABBD49',
|
bg: '#2ECC40',
|
||||||
},
|
},
|
||||||
messageList: {
|
messageList: {
|
||||||
bg: '#fff',
|
bg: '#fff',
|
||||||
},
|
},
|
||||||
sent: {
|
sent: {
|
||||||
bg: '#4CAF50',
|
bg: '#2ECC40',
|
||||||
text: '#fff',
|
text: '#fff',
|
||||||
},
|
},
|
||||||
received: {
|
received: {
|
||||||
bg: '#eaeaea',
|
bg: '#eaeaea',
|
||||||
text: '#222222',
|
text: '#000',
|
||||||
},
|
},
|
||||||
userInput: {
|
userInput: {
|
||||||
bg: '#fff',
|
bg: '#fbfbfb',
|
||||||
text: '#212121',
|
text: '#000',
|
||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
bg: '#ffffff',
|
bg: '#ffffff',
|
||||||
text: '#ABBD49',
|
text: '#2ECC40',
|
||||||
border: '#ABBD49',
|
border: '#2ECC40',
|
||||||
},
|
},
|
||||||
messageStatus: {
|
messageStatus: {
|
||||||
bg: '#ABBD49',
|
bg: '#2ECC40',
|
||||||
},
|
},
|
||||||
messageTime: {
|
messageTime: {
|
||||||
text: '#9C9C9C',
|
text: '#2ECC40',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
blue: {
|
blue: {
|
||||||
header: {
|
header: {
|
||||||
bg: '#108AA8',
|
bg: '#0074D9',
|
||||||
text: '#ffffff',
|
text: '#fff',
|
||||||
},
|
},
|
||||||
launcher: {
|
launcher: {
|
||||||
bg: '#108AA8',
|
bg: '#0074D9',
|
||||||
},
|
},
|
||||||
messageList: {
|
messageList: {
|
||||||
bg: '#ffffff',
|
bg: '#fff',
|
||||||
},
|
},
|
||||||
sent: {
|
sent: {
|
||||||
bg: '#108AA8',
|
bg: '#0074D9',
|
||||||
text: '#ffffff',
|
text: '#fff',
|
||||||
},
|
},
|
||||||
received: {
|
received: {
|
||||||
bg: '#eaeaea',
|
bg: '#eaeaea',
|
||||||
text: '#222222',
|
text: '#000',
|
||||||
},
|
},
|
||||||
userInput: {
|
userInput: {
|
||||||
bg: '#f4f7f9',
|
bg: '#fbfbfb',
|
||||||
text: '#565867',
|
text: '#000',
|
||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
bg: '#ffffff',
|
bg: '#ffffff',
|
||||||
text: '#108AA8',
|
text: '#0074D9',
|
||||||
border: '#108AA8',
|
border: '#0074D9',
|
||||||
},
|
},
|
||||||
messageStatus: {
|
messageStatus: {
|
||||||
bg: '#108AA8',
|
bg: '#0074D9',
|
||||||
},
|
},
|
||||||
messageTime: {
|
messageTime: {
|
||||||
text: '#9C9C9C',
|
text: '#0074D9',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
teal: {
|
teal: {
|
||||||
header: {
|
header: {
|
||||||
bg: '#279084',
|
bg: '#1BA089',
|
||||||
text: '#ffffff',
|
text: '#fff',
|
||||||
},
|
},
|
||||||
launcher: {
|
launcher: {
|
||||||
bg: '#279084',
|
bg: '#1BA089',
|
||||||
},
|
},
|
||||||
messageList: {
|
messageList: {
|
||||||
bg: '#ffffff',
|
bg: '#fff',
|
||||||
},
|
},
|
||||||
sent: {
|
sent: {
|
||||||
bg: '#279084',
|
bg: '#1BA089',
|
||||||
text: '#ffffff',
|
text: '#fff',
|
||||||
},
|
},
|
||||||
received: {
|
received: {
|
||||||
bg: '#eaeaea',
|
bg: '#eaeaea',
|
||||||
text: '#222222',
|
text: '#000',
|
||||||
},
|
},
|
||||||
userInput: {
|
userInput: {
|
||||||
bg: '#f4f7f9',
|
bg: '#fbfbfb',
|
||||||
text: '#565867',
|
text: '#000',
|
||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
bg: '#ffffff',
|
bg: '#ffffff',
|
||||||
text: '#279084',
|
text: '#1BA089',
|
||||||
border: '#279084',
|
border: '#1BA089',
|
||||||
},
|
},
|
||||||
messageStatus: {
|
messageStatus: {
|
||||||
bg: '#279084',
|
bg: '#1BA089',
|
||||||
},
|
},
|
||||||
messageTime: {
|
messageTime: {
|
||||||
text: '#9C9C9C',
|
text: '#9C9C9C',
|
||||||
@ -186,26 +186,26 @@ const colors: Record<string, ColorState> = {
|
|||||||
},
|
},
|
||||||
dark: {
|
dark: {
|
||||||
header: {
|
header: {
|
||||||
bg: '#34495e',
|
bg: '#000',
|
||||||
text: '#ecf0f1',
|
text: '#ecf0f1',
|
||||||
},
|
},
|
||||||
launcher: {
|
launcher: {
|
||||||
bg: '#34495e',
|
bg: '#000',
|
||||||
},
|
},
|
||||||
messageList: {
|
messageList: {
|
||||||
bg: '#2c3e50',
|
bg: '#FFF',
|
||||||
},
|
},
|
||||||
sent: {
|
sent: {
|
||||||
bg: '#7f8c8d',
|
bg: '#000',
|
||||||
text: '#ecf0f1',
|
text: '#FFF',
|
||||||
},
|
},
|
||||||
received: {
|
received: {
|
||||||
bg: '#95a5a6',
|
bg: '#F0F0F0',
|
||||||
text: '#ecf0f1',
|
text: '#000',
|
||||||
},
|
},
|
||||||
userInput: {
|
userInput: {
|
||||||
bg: '#34495e',
|
bg: '#FFF',
|
||||||
text: '#ecf0f1',
|
text: '#000',
|
||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
bg: '#2c3e50',
|
bg: '#2c3e50',
|
||||||
|
Loading…
Reference in New Issue
Block a user