Skip to content

Commit

Permalink
feat: add useTheme() and useThemeProvider()
Browse files Browse the repository at this point in the history
  • Loading branch information
manuelodelain committed Mar 1, 2024
1 parent a12933a commit 31b9613
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
3 changes: 3 additions & 0 deletions app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default defineAppConfig({
themes: ['light', 'dark'],
})
18 changes: 18 additions & 0 deletions composables/use-theme-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { provide } from 'vue'
import type { ComputedRef, InjectionKey } from 'vue'
import { type Theme, useTheme } from '~/composables/use-theme'
import type { ThemeOptions } from '~/composables/use-theme'

export const THEME_PROVIDER_KEY: InjectionKey<ComputedRef<Theme | 'light'>> = Symbol('themeProviderKey')

export function useThemeProvider(options?: ThemeOptions) {
const { activeTheme, themeClass } = useTheme(options)

const providedTheme = computed(() => {
return activeTheme.value
})

provide(THEME_PROVIDER_KEY, providedTheme)

return { providedTheme, activeTheme, themeClass }
}
30 changes: 30 additions & 0 deletions composables/use-theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { inject } from 'vue'
import type { MaybeRefOrGetter } from 'vue'
import { THEME_PROVIDER_KEY } from '~/composables/use-theme-provider'
import appConfig from '~/app.config'

export type Theme = (typeof appConfig)['themes'][number]

export interface ThemeProps {
theme?: Theme | false | null
}

export interface ThemeOptions {
props?: ThemeProps
preferredTheme?: MaybeRefOrGetter<Theme | false | null>
}

export function useTheme(options?: ThemeOptions) {
const injectedTheme = inject(THEME_PROVIDER_KEY, null)
const $style = useCssModule()

const activeTheme = computed(() => {
return toValue(options?.preferredTheme) || options?.props?.theme || injectedTheme?.value || 'light'
})

const themeClass = computed(() => {
return activeTheme.value && !!$style && $style['root--theme-' + activeTheme.value]
})

return { activeTheme, themeClass }
}

0 comments on commit 31b9613

Please sign in to comment.