@axiom-core/vue-adapter
v0.1.1
Published
Official Axiom Design System adapter for Vue 3
Readme
@axiom-core/vue-adapter
The official Axiom Design System adapter for Vue 3. Connects @axiom-core/runtime-engine resolved themes to Vue applications by providing a provider component, deterministic CSS variable injection, and reactive theme updates through the Vue Composition API.
Responsibilities
- Provider component — exposes the current resolved theme to the Vue component tree via
provide/inject - CSS variable injection — emits deterministic CSS custom properties into the DOM using
@axiom-core/css-bridgeand@axiom-core/dom-injector - Reactive theme updates — watches the theme manager and triggers re-injection when the resolved theme changes
- SSR support — renders a
<style>tag on the server via@axiom-core/ssr-utilsfor hydration-safe style delivery
This package does not contain runtime composition logic. Theme composition is handled by @axiom-core/runtime-engine.
Installation
Installation
pnpm add @axiom-core/runtime-engine
pnpm add @axiom-core/vue-adapterVue 3 is a peer dependency:
pnpm add vueUsage
Base Entry — Pre-Resolved Theme
Use the base entry when you have a pre-resolved theme (e.g., statically exported JSON) and do not need runtime axis switching:
<script setup>
import { AxiomProvider } from '@axiom-core/vue-adapter';
import resolvedTheme from './theme.resolved.json';
</script>
<template>
<AxiomProvider :resolvedTheme="resolvedTheme" scope="global">
<YourApp />
</AxiomProvider>
</template>Runtime Entry — Dynamic Theme Composition
Use the runtime entry when you need dynamic axis switching (e.g., light/dark mode toggle, brand switching, density control):
<script setup>
import { AxiomProviderRuntime } from '@axiom-core/vue-adapter/runtime';
import { createThemeManager } from '@axiom-core/runtime-engine';
import { enterprisePrimitives } from '@axiom-core/primitives';
import { baseSemantic, semanticAxes } from '@axiom-core/semantic-baseline';
const manager = createThemeManager({
primitives: enterprisePrimitives,
baseSemantic,
registry: semanticAxes,
initialConfig: { mode: 'light' },
});
</script>
<template>
<AxiomProviderRuntime :manager="manager">
<YourApp />
</AxiomProviderRuntime>
</template>Provider Setup
AxiomProvider (base) and AxiomProviderRuntime (runtime) are both Vue 3 components that call Vue's provide() to make the Axiom context available to all descendant components.
Props — AxiomProvider (base entry)
| Prop | Type | Required | Description |
|---|---|---|---|
| resolvedTheme | ResolvedSemanticTokens | Yes | Pre-resolved theme object. All token references must already be resolved to primitive values. |
| scope | string | No | CSS scope identifier. Defaults to 'global'. Use unique values for nested scoped providers. |
| mode | 'dev' \| 'prod' | No | CSS variable naming mode. dev = readable names, prod = hashed names. |
Props — AxiomProviderRuntime (runtime entry)
| Prop | Type | Required | Description |
|---|---|---|---|
| manager | ThemeManager | Yes | A theme manager created by createThemeManager() from @axiom-core/runtime-engine. |
| scope | string | No | CSS scope identifier. |
| mode | 'dev' \| 'prod' | No | CSS variable naming mode. |
Reactive Updates
The Vue adapter integrates with Vue's reactivity system. When using the runtime entry, axis changes propagate automatically:
<script setup>
import { useAxiomTheme } from '@axiom-core/vue-adapter';
const { resolvedTheme, config, updateAxis } = useAxiomTheme();
function toggleDarkMode() {
updateAxis('mode', config.value.mode === 'light' ? 'dark' : 'light');
}
</script>
<template>
<button @click="toggleDarkMode">Toggle Dark Mode</button>
</template>useAxiomTheme() Composable
Returns reactive Axiom context from the nearest AxiomProvider ancestor.
| Return Value | Type | Description |
|---|---|---|
| resolvedTheme | Ref<ResolvedSemanticTokens> | Reactive resolved theme. Updates automatically when axes change. |
| config | Ref<ThemeConfig> | Reactive axis configuration. |
| updateAxis | (axis: ThemeAxis, value: string) => void | Updates a single axis (e.g., 'mode', 'brand') and triggers re-injection. |
Variable Name Modes
| Mode | Variable Format | Use Case |
|---|---|---|
| dev | --axiom-surface-background | Human-readable names. Easier to debug in Vue DevTools. |
| prod | --ax-a1b2c3 | Hashed names. Shorter, collision-free, minimal footprint. |
CSS variable values are identical in both modes. Only the property names differ.
SSR Compatibility
vue-adapter is fully compatible with Vue SSR (Nuxt, renderToString, etc.). Use renderAxiomStyles to produce a <style> tag for injection into the server-rendered HTML:
import { renderAxiomStyles } from '@axiom-core/vue-adapter';
const { cssText, attributes } = renderAxiomStyles({
resolvedTheme,
mode: 'prod',
scope: 'global',
});
const html = `
<!DOCTYPE html>
<html>
<head>
<style id="axiom-ssr">${cssText}</style>
</head>
<body>${appHtml}</body>
</html>
`;On hydration, the client-side provider detects the existing SSR style tag and skips the initial injection to avoid a flash of unstyled content.
Nuxt Integration
// plugins/axiom.ts
import { defineNuxtPlugin } from '#app';
import { createThemeManager } from '@axiom-core/runtime-engine';
import { enterprisePrimitives } from '@axiom-core/primitives';
import { baseSemantic, semanticAxes } from '@axiom-core/semantic-baseline';
export default defineNuxtPlugin(() => {
const manager = createThemeManager({
primitives: enterprisePrimitives,
baseSemantic,
registry: semanticAxes,
initialConfig: { mode: 'light' },
});
return { provide: { axiomManager: manager } };
});Bundle Entries
| Import Path | Contents | When to Use |
|---|---|---|
| @axiom-core/vue-adapter | Provider + composables (no runtime engine) | Pre-resolved themes |
| @axiom-core/vue-adapter/runtime | Above + AxiomProviderRuntime component | Dynamic theme composition |
Peer Dependencies
| Package | Version |
|---|---|
| vue | >=3 |
| @axiom-core/runtime-engine | >=0.1.0 (optional — only for runtime entry) |
| @axiom-core/core-engine | >=0.1.0 (optional — only for runtime entry) |
License
MIT
