Skip to content

[Audit] useTheme - ensure parity with Vuetify createTheme #103

@johnleider

Description

@johnleider

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

  • RGB decomposition — adapter generate() outputs R,G,B format
  • Auto on-* color generation — APCA contrast utility
  • System theme detection — 'system' as valid default, media query listener
  • Scoped theme context — provideTheme() pattern for subtree overrides

Vuetify-level

  • Design spec for theme migration
  • Implement VuetifyThemeAdapter
  • Migrate createTheme composable to delegate to v0
  • Color variations (lighten/darken shades)
  • Theme variables (variables: {})
  • CSS @layer support
  • .v-theme--* class selectors + scoped CSS

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions