Custom Theme
The theme controls design tokens such as colors and fonts. The theme argument of provideA2UI must be a full A2UITheme, not a flat object like { primaryColor, backgroundColor }:
export interface A2UITheme {
additionalStyles?: Record<string, any> // per-component inline styles / CSS variable overrides
components: Record<string, any> // utility class maps (including color-*)
elements?: Record<string, any> // native HTML element classes
markdown?: Record<string, string[]>
}The built-in implementation is exported as defaultTheme. Pass it as-is, or shallow-merge overrides on top of it.
Live Preview
Below is the live result of the theme-example.json message stream rendered through <A2UISurface> with customTheme injected:
Three Ways to Change Colors
Host CSS: --p-* / --n-*
→ color-* classes in components (e.g. color-bgc-p30)
theme.additionalStyles
→ inline :style overrides (Button gradients, Text heading colors, …)
createSurface.theme.primaryColor (protocol layer)
→ Surface root generates a --p-* ramp1. Host palette CSS variables (best for global primary color)
Utility classes such as color-bgc-p30 resolve to background-color: var(--p-30). Define the palette in your entry CSS:
:root {
--n-100: #ffffff;
--n-10: #1b1b1b;
--n-0: #000000;
--p-100: #ffffff;
--p-60: #8487ea;
--p-50: #6a6dcd;
--p-40: #5154b3;
--p-30: #383b99;
--p-10: #06006c;
--p-0: #000000;
}See the full palette in samples/client/gallery/src/styles.css.
2. theme.additionalStyles (per-component look)
The default theme already sets gradients and shadows on additionalStyles.Button / Text / Card. Override those fields to change the default look:
import { createApp } from 'vue'
import { provideA2UI, DEFAULT_CATALOG, defaultTheme } from 'a2ui-vue'
import type { A2UITheme } from 'a2ui-vue'
import App from './App.vue'
import 'a2ui-vue/dist/a2ui-vue.css'
import './a2ui-palette.css'
const customTheme: A2UITheme = {
...defaultTheme,
additionalStyles: {
...defaultTheme.additionalStyles,
Button: {
...defaultTheme.additionalStyles?.Button,
background: 'linear-gradient(135deg, #e11d48 0%, #f97316 100%)',
boxShadow: '0 4px 15px rgba(225, 29, 72, 0.35)',
'--p-30': '#e11d48',
},
Text: {
...defaultTheme.additionalStyles?.Text,
h1: {
color: 'transparent',
background: 'linear-gradient(135deg, #e11d48 0%, #f97316 100%)',
'-webkit-background-clip': 'text',
'background-clip': 'text',
'-webkit-text-fill-color': 'transparent',
},
h3: { color: '#e11d48' },
},
Card: {
background:
'radial-gradient(circle at top left, rgba(225, 29, 72, 0.12), transparent 40%), linear-gradient(135deg, rgba(255, 255, 255, 0.85), rgba(255, 247, 237, 0.9))',
},
},
}
const app = createApp(App)
provideA2UI({ app, catalog: DEFAULT_CATALOG, theme: customTheme })
app.mount('#app')Full example: packages/vue-renderer/src/examples/customTheme.ts.
3. theme.components.*.color-* (which token step to use)
For example, change Button’s 'color-bgc-p30': true to 'color-bgc-s30': true, or adjust Text’s 'color-c-n10', to bind a different palette step.
vs Protocol createSurface.theme
| Layer | Entry | Role |
|---|---|---|
| App theme | provideA2UI({ theme }) | App-wide A2UITheme: utility classes + additionalStyles |
| Surface theme | createSurface.theme.primaryColor / font | <A2UISurface> sets --p-* and --font-family on the root |
They can stack: the app theme maps components to tokens; the Surface theme can override the primary ramp for one surface.
Full guide, dual-color live preview, and examples-aligned JSON: Protocol Theme.
Try It in Examples
cd packages/vue-renderer
npm run dev- Custom Theme — app-level
customTheme.ts - Surface Theme — protocol
createSurface.theme
Or swap theme in main.ts for a global custom theme:
import { customTheme } from './customTheme'
provideA2UI({
app,
catalog: DEFAULT_CATALOG,
theme: customTheme,
})Text must resolve correctly
Button / Theme examples must use the v0.9 message stream (createSurface + updateComponents + processMessages) and render via A2UISurface. Passing a component tree directly to A2UiRenderer without a matching Surface leaves the binder unable to resolve Text, so button labels appear empty.
Related
- Protocol Theme —
createSurface.themeand dual-color preview - Core Concepts · Theme —
A2UIThemeoverview - Custom Components — extend Catalog component types
- Component List sample — minimal palette +
provideA2UIsetup