Summary
Migrate Vuetify's createTheme to use v0's useTheme under the hood, following the same pattern as the locale migration (vuetifyjs/vuetify#22753).
Feature Parity Analysis
Already at parity (no work needed)
| Feature |
Vuetify 3 |
v0 |
| Theme selection |
name ref + computed |
selectedId + select() |
| Multiple themes |
themes record |
themes record + registry |
| isDark |
Computed from current theme |
Computed from current theme |
| Theme cycling |
cycle() |
cycle() |
| CSS variable generation |
Inline in composable |
Via adapter generate() |
| SSR/head integration |
@unhead/vue fallback |
usehead/head provides |
| CSP nonce |
cspNonce option |
cspNonce on adapter |
v0 ahead of Vuetify 3
| Feature |
v0 |
Vuetify 3 |
| Lazy theme loading |
lazy: true |
Not supported |
| Adapter pattern |
Pluggable ThemeAdapter |
Monolithic |
| Token alias resolution |
createTokens + {palette.blue.500} |
Simple strings |
| Runtime registration |
register({ id, colors }) |
Not supported |
| Palette support |
palette option shared across themes |
Not supported |
v0 gaps (must fix before migration)
| Feature |
What it does |
Priority |
| RGB decomposition |
Store colors as R,G,B triplets for rgb(var(--v-theme-*)) and alpha compositing |
P1 |
Auto on-* colors |
Generate white/black foreground per color using APCA contrast |
P1 |
| System theme detection |
matchMedia('prefers-color-scheme') listener that resolves 'system' to 'light'/'dark' |
P1 |
| Scoped themes (provide/inject) |
provideTheme() for component subtree overrides |
P2 |
Vuetify-level only (custom adapter, not v0)
| Feature |
Description |
| Utility classes |
.bg-*, .text-*, .border-* CSS generation |
| Color variations |
lighten()/darken() via CIELAB color space |
| Theme variables |
variables: {} for opacities, overlay multipliers |
| CSS layers |
@layer vuetify-utilities { ... } |
| Overlay multipliers |
Luma-based multiplier CSS variables |
.v-theme--* classes |
Class-based theme selectors |
| Scoped CSS |
scope selector option for :where() wrapping |
Architecture
v0 owns the runtime:
- Theme selection (
createSingle)
- Token-based color storage and alias resolution (
createTokens)
- Lazy theme loading
- CSS variable generation via adapter pattern
isDark state
cycle() for theme switching
- Auto
on-* color generation (accessibility primitive)
- System theme detection (
prefers-color-scheme)
- Scoped theme context (provide/inject)
Vuetify provides a custom VuetifyThemeAdapter handling CSS concerns:
- RGB decomposition in CSS output (
--v-theme-primary: 24,103,192)
- Utility classes (
.bg-*, .text-*, .border-*)
- Color variations (lighten/darken)
- Theme variables (opacity values, overlay multipliers)
- CSS
@layer organization
.v-theme--* class-based selectors
- Scoped CSS via
scope selector
Tasks
v0-level
Vuetify-level
Reference Files
- v0 theme:
packages/0/src/composables/useTheme/index.ts
- v0 adapter:
packages/0/src/composables/useTheme/adapters/v0.ts
- Vuetify theme:
packages/vuetify/src/composables/theme.ts
- Vuetify color utils:
packages/vuetify/src/util/colorUtils.ts
- Vuetify APCA:
packages/vuetify/src/util/color/APCA.ts
- Vuetify CIELAB:
packages/vuetify/src/util/color/transformCIELAB.ts
Summary
Migrate Vuetify's
createThemeto use v0'suseThemeunder the hood, following the same pattern as the locale migration (vuetifyjs/vuetify#22753).Feature Parity Analysis
Already at parity (no work needed)
nameref + computedselectedId+select()themesrecordthemesrecord + registrycycle()cycle()generate()@unhead/vuefallbackusehead/headprovidescspNonceoptioncspNonceon adapterv0 ahead of Vuetify 3
lazy: trueThemeAdaptercreateTokens+{palette.blue.500}register({ id, colors })paletteoption shared across themesv0 gaps (must fix before migration)
R,G,Btriplets forrgb(var(--v-theme-*))and alpha compositingon-*colorsmatchMedia('prefers-color-scheme')listener that resolves'system'to'light'/'dark'provideTheme()for component subtree overridesVuetify-level only (custom adapter, not v0)
.bg-*,.text-*,.border-*CSS generationlighten()/darken()via CIELAB color spacevariables: {}for opacities, overlay multipliers@layer vuetify-utilities { ... }.v-theme--*classesscopeselector option for:where()wrappingArchitecture
v0 owns the runtime:
createSingle)createTokens)isDarkstatecycle()for theme switchingon-*color generation (accessibility primitive)prefers-color-scheme)Vuetify provides a custom
VuetifyThemeAdapterhandling CSS concerns:--v-theme-primary: 24,103,192).bg-*,.text-*,.border-*)@layerorganization.v-theme--*class-based selectorsscopeselectorTasks
v0-level
generate()outputsR,G,Bformaton-*color generation — APCA contrast utility'system'as valid default, media query listenerprovideTheme()pattern for subtree overridesVuetify-level
VuetifyThemeAdaptercreateThemecomposable to delegate to v0variables: {})@layersupport.v-theme--*class selectors + scoped CSSReference Files
packages/0/src/composables/useTheme/index.tspackages/0/src/composables/useTheme/adapters/v0.tspackages/vuetify/src/composables/theme.tspackages/vuetify/src/util/colorUtils.tspackages/vuetify/src/util/color/APCA.tspackages/vuetify/src/util/color/transformCIELAB.ts