Theming
Qafka has three layers of theming, applied in order — base theme → dashboard config → code-level override. You can stop at any layer.
Built-in Base Themes
Two built-in starting points:
// projectId, endUserId, …
<Qafka theme="light" />
<Qafka theme="dark" />The base theme provides every required token (colors, spacing, typography, shadows, animation). Higher layers only need to specify what they want to change.
Both themes are also available as named exports, along with a getTheme helper, if you want to read or extend one directly instead of going through the theme prop:
import { lightTheme, darkTheme, getTheme } from '@qafka/react-native'
const theme = getTheme('dark') // same as darkThemeDashboard-Configured Theme
Each project has a chat theme editor in the dashboard. Anything you set there is loaded automatically when the SDK initializes — no extra prop required:
<Qafka projectId="proj_abc123" endUserId="anonymous" />The dashboard editor lets non-developers tweak:
- Container background, paddings, border radius
- User & AI message bubble colors, padding, max width, border radius
- Input field background, border, text, send button
- Font size, weight, line height
- Branding (web widget) — assistant name, logo, and avatar
These overrides are merged on top of the chosen base theme (light or dark). For greeting and initial message, see Dashboard › AI Behavior; for the theme editor itself, see Dashboard › Chat Theme.
Replacing the Base Theme Entirely (customTheme)
When neither built-in theme is a good starting point, pass customTheme — a full Theme object that replaces the base theme entirely, before the dashboard theme and themeOverride are applied on top:
import { Theme } from '@qafka/react-native'
const myTheme: Theme = {
colors: { /* all 28 tokens */ },
spacing: { /* ... */ },
borderRadius: { /* ... */ },
typography: { /* ... */ },
shadows: { /* ... */ },
animation: { /* ... */ },
messages: { /* ... */ },
}
// projectId, endUserId, …
<Qafka customTheme={myTheme} />Unlike themeOverride, customTheme is not a partial — it must satisfy the full Theme interface. Use themeOverride for incremental tweaks and customTheme when you’re building a theme from scratch (e.g. generating one from a design system’s tokens).
Code-Level Overrides (themeOverride)
When you need fine-grained control that the dashboard doesn’t expose — or per-screen variations — pass themeOverride. It accepts a deep-partial of the full Theme interface, so you only specify what you want to change.
<Qafka
// projectId, endUserId, …
themeOverride={{
colors: {
userBubble: '#007AFF',
userBubbleText: '#FFFFFF',
aiBubble: '#F0F0F0',
aiBubbleText: '#000000',
background: '#FFFFFF',
inputBackground: '#F5F5F5',
},
typography: {
fontFamily: 'Inter',
fontSize: { md: 15, lg: 17 },
},
borderRadius: { lg: 16, xl: 24 },
spacing: { md: 14 },
messages: {
user: { padding: 12, maxWidth: 75 },
ai: { padding: 12, maxWidth: 85 },
},
}}
/>Override Surface
themeOverride is a DeepPartial<Theme> — every category and every key is optional. Available top-level slots:
| Slot | What it controls |
|---|---|
colors | 28 named tokens — primary, primaryLight, primaryDark, background, surface, overlay, text, textSecondary, textLight, textInverse, userBubble, userBubbleText, aiBubble, aiBubbleText, border, divider, error, success, warning, info, inputBackground, inputBorder, inputPlaceholder, buttonBackground, buttonText, buttonDisabled, badge, badgeText |
spacing | xs, sm, md, lg, xl, xxl |
borderRadius | sm, md, lg, xl, full |
typography | fontFamily, fontSize.{xs,sm,md,lg,xl,xxl}, fontWeight.{regular,medium,semibold,bold}, lineHeight.{tight,normal,relaxed}, plus optional fonts map for per-weight Android font files (regular, medium, semibold, bold, italic, light, code) |
shadows | small, medium, large (RN-style shadow + elevation objects) |
animation | duration.{fast,normal,slow}, easing.{easeIn,easeOut,easeInOut} |
messages | Per-bubble overrides: user.{padding,maxWidth}, ai.{padding,maxWidth} (maxWidth is a percentage) |
For the full type, import it:
import { ThemeOverride } from '@qafka/react-native'Theme Priority
Themes are applied in this order — last wins:
- Base theme —
light,dark(viatheme), or a full replacement (viacustomTheme) - Dashboard theme — loaded automatically for the active project
themeOverrideprop — highest priority, deep-merged on top