diff --git a/packages/docs/composables/useTheme.ts b/packages/docs/composables/useTheme.ts index 80c312491d..9d2737ed41 100644 --- a/packages/docs/composables/useTheme.ts +++ b/packages/docs/composables/useTheme.ts @@ -1,25 +1,9 @@ export const useTheme = () => { - const colorMode = useColorMode() - const cookie = useCookie('vuestic-theme') - const { applyPreset } = useColors() const setTheme = (theme?: string) => { - if (theme) { - colorMode.preference = theme - applyPreset(theme) - cookie.value = theme - return - } - - if (cookie.value) { - applyPreset(cookie.value) - return - } - - if (!colorMode.unknown) { - applyPreset(colorMode.value) - } + if (theme === undefined) { return } + applyPreset(theme) } return { diff --git a/packages/docs/config/vuestic-config.ts b/packages/docs/config/vuestic-config.ts index f6811ea31d..095418595a 100644 --- a/packages/docs/config/vuestic-config.ts +++ b/packages/docs/config/vuestic-config.ts @@ -11,10 +11,6 @@ const VaButtonLandingHeader = { 'hover-opacity': '1', } -// const cookie = useCookie('vuestic-theme') - -const theme = 'light' - export const VuesticConfig = defineVuesticConfig({ icons, components: { @@ -39,7 +35,6 @@ export const VuesticConfig = defineVuesticConfig({ }, }, colors: { - currentPresetName: theme, presets: { light: { secondary: '#666E75', diff --git a/packages/docs/layouts/default.vue b/packages/docs/layouts/default.vue index 7112e02d9f..f9532a739c 100644 --- a/packages/docs/layouts/default.vue +++ b/packages/docs/layouts/default.vue @@ -26,14 +26,13 @@ import { useColors } from 'vuestic-ui' import { useDocsScroll } from '../composables/useDocsScroll'; -const colorMode = useColorMode() const cookie = useCookie('vuestic-theme') const { applyPreset } = useColors() const breakpoints = useBreakpoint() const isSidebarVisible = ref(!breakpoints.smDown) -applyPreset(cookie.value || colorMode.preference) +applyPreset(cookie.value || 'light') watch(() => breakpoints.smDown, (newValue, oldValue) => { if (newValue && !oldValue) { diff --git a/packages/nuxt/src/module.ts b/packages/nuxt/src/module.ts index 05c570897d..d4435d327e 100644 --- a/packages/nuxt/src/module.ts +++ b/packages/nuxt/src/module.ts @@ -22,6 +22,7 @@ export default defineNuxtModule({ config: {}, css: ['smart-helpers', 'typography'], fonts: true, + themeCookieKey: 'vuestic-theme', }, setup (options) { diff --git a/packages/nuxt/src/runtime/plugin.ts b/packages/nuxt/src/runtime/plugin.ts index 98be07c875..4ad9706841 100644 --- a/packages/nuxt/src/runtime/plugin.ts +++ b/packages/nuxt/src/runtime/plugin.ts @@ -5,10 +5,12 @@ import { VaModalPlugin, ColorsClassesPlugin, BreakpointConfigPlugin, + type GlobalConfig, + type PartialGlobalConfig } from 'vuestic-ui' -import { markRaw, computed } from 'vue' +import { markRaw, computed, watch, type Ref } from 'vue' -import { defineNuxtPlugin } from '#app' +import { defineNuxtPlugin, useCookie } from '#app' import { useHead } from '#imports' import NuxtLink from '#app/components/nuxt-link' import configFromFile from '#vuestic-config' @@ -19,16 +21,24 @@ function getGlobalProperty (app, key) { return app.config.globalProperties[key] } -export default defineNuxtPlugin((nuxtApp) => { +export default defineNuxtPlugin(async (nuxtApp) => { const { vueApp: app } = nuxtApp // It's important to use `, because TS will compile qoutes to " and JSON will not be parsed... - const { config }: VuesticOptions = JSON.parse(`<%= options.value %>`) - const userConfig = configFromFile || config + const moduleOptions: VuesticOptions = JSON.parse(`<%= options.value %>`) + const themeCookie = useCookie(moduleOptions.themeCookieKey) + const userConfig = configFromFile || moduleOptions.config || {} + const configWithColors: PartialGlobalConfig = { + ...userConfig, + colors: { + currentPresetName: themeCookie.value || userConfig.colors?.currentPresetName, + ...userConfig.colors, + } + } /** Use tree-shaking by default and do not register any component. Components will be registered by nuxt in use-components. */ app.use(createVuesticEssential({ - config: { ...userConfig, routerComponent: markRaw(NuxtLink) }, + config: { ...configWithColors, routerComponent: markRaw(NuxtLink) }, // TODO: Would be nice to tree-shake plugins, but they're small so we can let it be for now. // Should be synced with create-vuestic.ts plugins: { @@ -63,4 +73,10 @@ export default defineNuxtPlugin((nuxtApp) => { } })) } + + // Watch for preset name change and update cookie + const { globalConfig } = getGlobalProperty(app, '$vaConfig') as { globalConfig: Ref } + watch(() => globalConfig.value.colors.currentPresetName, (newTheme) => { + themeCookie.value = newTheme + }, { immediate: true }) }) diff --git a/packages/nuxt/src/types.ts b/packages/nuxt/src/types.ts index 63fdfefe9e..a1c0e66fbb 100644 --- a/packages/nuxt/src/types.ts +++ b/packages/nuxt/src/types.ts @@ -32,11 +32,12 @@ export interface VuesticOptions { * @see https://vuestic.dev/en/getting-started/installation#assets-installation */ fonts: boolean -} -/** Declare Vuestic module options in NuxtConfig */ - declare module '@nuxt/schema' { - interface NuxtConfig { - vuestic?: Partial - } + + /** + * Vuestic will automatically store its theme in cookies. If you want to change the key, you can do it here. + * + * @default 'vuestic-theme' + */ + themeCookieKey: string }