From 290c2ff4c55b40503e3f1eede9916ad84146345e Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 22 Dec 2025 21:01:58 +0530 Subject: [PATCH] feat: add bubble border --- .../dashboard/assets/scss/_next-colors.scss | 14 +++++ .../components-next/message/bubbles/Base.vue | 10 ++-- app/javascript/react-components/doc.md | 53 +++++++++++++++++-- .../src/styles/bubble-overrides.css | 15 ++++++ 4 files changed, 84 insertions(+), 8 deletions(-) diff --git a/app/javascript/dashboard/assets/scss/_next-colors.scss b/app/javascript/dashboard/assets/scss/_next-colors.scss index 3bc13573f..51ade3df5 100644 --- a/app/javascript/dashboard/assets/scss/_next-colors.scss +++ b/app/javascript/dashboard/assets/scss/_next-colors.scss @@ -119,6 +119,13 @@ --bubble-bot-bg: var(--solid-iris); --bubble-bot-text: var(--slate-12); + // Bubble border customization + --bubble-border-width: 0; + --bubble-agent-border: var(--blue-6); + --bubble-user-border: var(--slate-6); + --bubble-private-border: var(--amber-6); + --bubble-bot-border: var(--iris-6); + // Bubble spacing (ratio of 1 = default, 1.5 = 50% larger, 0.5 = 50% smaller) --bubble-spacing-ratio: 1; --bubble-radius: calc(0.75rem * var(--bubble-spacing-ratio)); @@ -269,6 +276,13 @@ --bubble-bot-bg: var(--solid-iris); --bubble-bot-text: var(--slate-12); + // Bubble border customization + --bubble-border-width: 0; + --bubble-agent-border: var(--blue-6); + --bubble-user-border: var(--slate-6); + --bubble-private-border: var(--amber-6); + --bubble-bot-border: var(--iris-6); + // Bubble spacing (inherited from light mode, can be overridden) --bubble-spacing-ratio: 1; --bubble-radius: calc(0.75rem * var(--bubble-spacing-ratio)); diff --git a/app/javascript/dashboard/components-next/message/bubbles/Base.vue b/app/javascript/dashboard/components-next/message/bubbles/Base.vue index 627d8a0b9..bfdf98fa1 100644 --- a/app/javascript/dashboard/components-next/message/bubbles/Base.vue +++ b/app/javascript/dashboard/components-next/message/bubbles/Base.vue @@ -20,16 +20,16 @@ const { t } = useI18n(); const varaintBaseMap = { [MESSAGE_VARIANTS.AGENT]: - 'bg-[rgb(var(--bubble-agent-bg))] text-[rgb(var(--bubble-agent-text))]', + 'bg-[rgb(var(--bubble-agent-bg))] text-[rgb(var(--bubble-agent-text))] border-[length:var(--bubble-border-width)] border-[rgb(var(--bubble-agent-border))]', [MESSAGE_VARIANTS.PRIVATE]: - 'bg-[rgb(var(--bubble-private-bg))] text-[rgb(var(--bubble-private-text))] [&_.prosemirror-mention-node]:font-semibold', + 'bg-[rgb(var(--bubble-private-bg))] text-[rgb(var(--bubble-private-text))] border-[length:var(--bubble-border-width)] border-[rgb(var(--bubble-private-border))] [&_.prosemirror-mention-node]:font-semibold', [MESSAGE_VARIANTS.USER]: - 'bg-[rgb(var(--bubble-user-bg))] text-[rgb(var(--bubble-user-text))]', + 'bg-[rgb(var(--bubble-user-bg))] text-[rgb(var(--bubble-user-text))] border-[length:var(--bubble-border-width)] border-[rgb(var(--bubble-user-border))]', [MESSAGE_VARIANTS.ACTIVITY]: 'bg-n-alpha-1 text-n-slate-11 text-sm', [MESSAGE_VARIANTS.BOT]: - 'bg-[rgb(var(--bubble-bot-bg))] text-[rgb(var(--bubble-bot-text))]', + 'bg-[rgb(var(--bubble-bot-bg))] text-[rgb(var(--bubble-bot-text))] border-[length:var(--bubble-border-width)] border-[rgb(var(--bubble-bot-border))]', [MESSAGE_VARIANTS.TEMPLATE]: - 'bg-[rgb(var(--bubble-bot-bg))] text-[rgb(var(--bubble-bot-text))]', + 'bg-[rgb(var(--bubble-bot-bg))] text-[rgb(var(--bubble-bot-text))] border-[length:var(--bubble-border-width)] border-[rgb(var(--bubble-bot-border))]', [MESSAGE_VARIANTS.ERROR]: 'bg-n-ruby-4 text-n-ruby-12', [MESSAGE_VARIANTS.EMAIL]: 'w-full', [MESSAGE_VARIANTS.UNSUPPORTED]: diff --git a/app/javascript/react-components/doc.md b/app/javascript/react-components/doc.md index 815cc3173..452badfb2 100644 --- a/app/javascript/react-components/doc.md +++ b/app/javascript/react-components/doc.md @@ -449,6 +449,16 @@ The Web Component supports runtime theming via CSS custom properties. These vari |----------|-------------|---------| | `--chatwoot-bubble-spacing-ratio` | Scale factor for border radius | `1` | +#### Border + +| Variable | Description | Default | +|----------|-------------|---------| +| `--chatwoot-bubble-border-width` | Border width (0 = invisible) | `0` | +| `--chatwoot-bubble-agent-border` | Agent message border color | `--blue-6` | +| `--chatwoot-bubble-user-border` | User message border color | `--slate-6` | +| `--chatwoot-bubble-private-border` | Private note border color | `--amber-6` | +| `--chatwoot-bubble-bot-border` | Bot message border color | `--iris-6` | + ### Usage Examples #### Option 1: Global CSS @@ -459,6 +469,8 @@ The Web Component supports runtime theming via CSS custom properties. These vari --chatwoot-bubble-agent-bg: 59 130 246; /* Blue */ --chatwoot-bubble-user-bg: 243 244 246; /* Light gray */ --chatwoot-bubble-spacing-ratio: 1.5; /* 50% more rounded */ + --chatwoot-bubble-border-width: 1px; /* Add borders */ + --chatwoot-bubble-agent-border: 59 130 246; /* Blue border */ } ``` @@ -472,6 +484,8 @@ function App() { '--chatwoot-bubble-agent-bg': '59 130 246', '--chatwoot-bubble-user-bg': '243 244 246', '--chatwoot-bubble-spacing-ratio': '1.5', + '--chatwoot-bubble-border-width': '1px', + '--chatwoot-bubble-agent-border': '59 130 246', }} > @@ -488,12 +502,16 @@ function App() { function App() { const [theme, setTheme] = useState({ '--chatwoot-bubble-agent-bg': '59 130 246', + '--chatwoot-bubble-border-width': '1px', + '--chatwoot-bubble-agent-border': '59 130 246', }); return (
@@ -505,12 +523,37 @@ function App() { } ``` +#### Option 4: Borders Only + +```jsx +function App() { + return ( +
+ + + +
+ ); +} +``` + ### How It Works ``` ┌─────────────────────────────────────────────────────────────────┐ │ Consumer's CSS │ -│ :root { --chatwoot-bubble-agent-bg: 59 130 246; } │ +│ :root { │ +│ --chatwoot-bubble-agent-bg: 59 130 246; │ +│ --chatwoot-bubble-border-width: 1px; │ +│ } │ └─────────────────────────────────────────────────────────────────┘ │ ▼ (CSS inheritance) @@ -519,12 +562,16 @@ function App() { │ bubble-overrides.css: │ │ --bubble-agent-bg: var(--chatwoot-bubble-agent-bg, │ │ var(--solid-blue)); │ +│ --bubble-border-width: var(--chatwoot-bubble-border-width, │ +│ 0); │ └─────────────────────────────────────────────────────────────────┘ │ ▼ (used by components) ┌─────────────────────────────────────────────────────────────────┐ │ Base.vue │ -│ class="bg-[rgb(var(--bubble-agent-bg))]" │ +│ class="bg-[rgb(var(--bubble-agent-bg))] │ +│ border-[length:var(--bubble-border-width)] │ +│ border-[rgb(var(--bubble-agent-border))]" │ └─────────────────────────────────────────────────────────────────┘ ``` diff --git a/app/javascript/react-components/src/styles/bubble-overrides.css b/app/javascript/react-components/src/styles/bubble-overrides.css index fce9bcc5c..67c5c9787 100644 --- a/app/javascript/react-components/src/styles/bubble-overrides.css +++ b/app/javascript/react-components/src/styles/bubble-overrides.css @@ -13,6 +13,13 @@ * --chatwoot-bubble-private-text: Private note text * --chatwoot-bubble-bot-bg: Bot message background * --chatwoot-bubble-bot-text: Bot message text + * --chatwoot-bubble-agent-border: Agent message border color + * --chatwoot-bubble-user-border: User message border color + * --chatwoot-bubble-private-border: Private note border color + * --chatwoot-bubble-bot-border: Bot message border color + * + * BORDER: + * --chatwoot-bubble-border-width: Border width in px (0 = invisible, default: 0) * * SPACING: * --chatwoot-bubble-spacing-ratio: Scale factor for border radius (1 = default) @@ -21,6 +28,7 @@ * :root { * --chatwoot-bubble-agent-bg: 59 130 246; * --chatwoot-bubble-user-bg: 243 244 246; + * --chatwoot-bubble-border-width: 1px; * --chatwoot-bubble-spacing-ratio: 1.5; * } */ @@ -52,6 +60,13 @@ --bubble-bot-status: var(--chatwoot-bubble-bot-status, var(--slate-10)); --bubble-bot-status-read: var(--chatwoot-bubble-bot-status-read, 126 182 255); + /* Border customization */ + --bubble-border-width: var(--chatwoot-bubble-border-width, 0); + --bubble-agent-border: var(--chatwoot-bubble-agent-border, var(--blue-6)); + --bubble-user-border: var(--chatwoot-bubble-user-border, var(--slate-6)); + --bubble-private-border: var(--chatwoot-bubble-private-border, var(--amber-6)); + --bubble-bot-border: var(--chatwoot-bubble-bot-border, var(--iris-6)); + /* Spacing - 1 = default */ --bubble-spacing-ratio: var(--chatwoot-bubble-spacing-ratio, 1); }