From 2ab22ec4dc267e1780beef339e6fbb37b369874a Mon Sep 17 00:00:00 2001 From: Maksim Nedoshev Date: Mon, 1 May 2023 06:57:12 +0300 Subject: [PATCH 1/3] fix: refactor nuxt module plugin ts types --- packages/nuxt/nuxt.shim.d.ts | 15 +++++++++++++++ packages/nuxt/src/runtime/plugin.ts | 11 ++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/nuxt/nuxt.shim.d.ts b/packages/nuxt/nuxt.shim.d.ts index a546b53335..b6ad41afb5 100644 --- a/packages/nuxt/nuxt.shim.d.ts +++ b/packages/nuxt/nuxt.shim.d.ts @@ -2,7 +2,22 @@ declare module '#app' { export * from 'nuxt/app' } +declare module '#app/components/nuxt-link' { + export * from 'nuxt/dist/app/components/nuxt-link.ts' + export { default as default } from 'nuxt/dist/app/components/nuxt-link.ts' +} + // Path to vuestic-ui main, so it is not required to build vuestic before working with packages/nuxt declare module 'vuestci-ui' { export * from 'vuestic-ui/src/main' +} + +declare module '#imports' { + export * from 'nuxt/dist/head/runtime/composables.ts' +} + +declare module '#vuestic-config' { + import { GlobalConfig } from 'vuestic-ui' + var gc: GlobalConfig | undefined + export default gc } \ No newline at end of file diff --git a/packages/nuxt/src/runtime/plugin.ts b/packages/nuxt/src/runtime/plugin.ts index feaf2f3bd4..98be07c875 100644 --- a/packages/nuxt/src/runtime/plugin.ts +++ b/packages/nuxt/src/runtime/plugin.ts @@ -8,15 +8,12 @@ import { } from 'vuestic-ui' import { markRaw, computed } from 'vue' -import type { VuesticOptions } from '../types' -// @ts-ignore: nuxt import alias import { defineNuxtPlugin } from '#app' -// @ts-ignore: direct nuxt-link import +import { useHead } from '#imports' import NuxtLink from '#app/components/nuxt-link' -// @ts-ignore: use-config-file import alias import configFromFile from '#vuestic-config' -// @ts-ignore: use-head import alias -import { useHead } from '#imports' + +import type { VuesticOptions } from '../types' function getGlobalProperty (app, key) { return app.config.globalProperties[key] @@ -32,7 +29,7 @@ export default defineNuxtPlugin((nuxtApp) => { /** 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) }, - // TODO: Would be nice to tree-shake plugins, but they're small so we don't cant for now. + // 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: { BreakpointConfigPlugin, From b896d2a46b71052986dfcc51ac1a66438757b798 Mon Sep 17 00:00:00 2001 From: Maksim Nedoshev Date: Mon, 1 May 2023 08:43:47 +0300 Subject: [PATCH 2/3] feat(nuxt): save theme in cookies --- packages/docs/composables/useTheme.ts | 20 ++---------------- packages/docs/config/vuestic-config.ts | 5 ----- packages/docs/layouts/default.vue | 3 +-- packages/nuxt/src/module.ts | 1 + packages/nuxt/src/runtime/plugin.ts | 28 ++++++++++++++++++++------ packages/nuxt/src/types.ts | 13 ++++++------ 6 files changed, 33 insertions(+), 37 deletions(-) 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 } From 94edc1e58696213c3f1b5f69984036cda4aa424f Mon Sep 17 00:00:00 2001 From: Maksim Nedoshev Date: Mon, 1 May 2023 08:45:23 +0300 Subject: [PATCH 3/3] chore(docs): remove useTheme --- .../docs/components/layout/header/ThemeSwitch.vue | 6 ++---- packages/docs/composables/useTheme.ts | 12 ------------ 2 files changed, 2 insertions(+), 16 deletions(-) delete mode 100644 packages/docs/composables/useTheme.ts diff --git a/packages/docs/components/layout/header/ThemeSwitch.vue b/packages/docs/components/layout/header/ThemeSwitch.vue index 561e31ce0b..3e6e3cd806 100644 --- a/packages/docs/components/layout/header/ThemeSwitch.vue +++ b/packages/docs/components/layout/header/ThemeSwitch.vue @@ -25,13 +25,11 @@ import { computed } from 'vue' import { useColors } from 'vuestic-ui' -const { currentPresetName } = useColors() - -const { setTheme } = useTheme() +const { currentPresetName, applyPreset } = useColors() const isDark = computed({ get: () => currentPresetName.value === 'dark', - set: (value) => setTheme(value ? 'dark' : 'light'), + set: (value) => applyPreset(value ? 'dark' : 'light'), }) diff --git a/packages/docs/composables/useTheme.ts b/packages/docs/composables/useTheme.ts deleted file mode 100644 index 9d2737ed41..0000000000 --- a/packages/docs/composables/useTheme.ts +++ /dev/null @@ -1,12 +0,0 @@ -export const useTheme = () => { - const { applyPreset } = useColors() - - const setTheme = (theme?: string) => { - if (theme === undefined) { return } - applyPreset(theme) - } - - return { - setTheme - } -}