Skip to content

Commit

Permalink
Fix/dark theme blink (#3387)
Browse files Browse the repository at this point in the history
* fix: refactor nuxt module plugin ts types

* feat(nuxt): save theme in cookies

* chore(docs): remove useTheme
  • Loading branch information
m0ksem authored May 1, 2023
1 parent 29dfcd9 commit cf57c63
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 58 deletions.
6 changes: 2 additions & 4 deletions packages/docs/components/layout/header/ThemeSwitch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
})
</script>

Expand Down
28 changes: 0 additions & 28 deletions packages/docs/composables/useTheme.ts

This file was deleted.

5 changes: 0 additions & 5 deletions packages/docs/config/vuestic-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ const VaButtonLandingHeader = {
'hover-opacity': '1',
}

// const cookie = useCookie('vuestic-theme')

const theme = 'light'

export const VuesticConfig = defineVuesticConfig({
icons,
components: {
Expand All @@ -39,7 +35,6 @@ export const VuesticConfig = defineVuesticConfig({
},
},
colors: {
currentPresetName: theme,
presets: {
light: {
secondary: '#666E75',
Expand Down
3 changes: 1 addition & 2 deletions packages/docs/layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,14 @@
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)
const isOptionsVisible = ref(false)
applyPreset(cookie.value || colorMode.preference)
applyPreset(cookie.value || 'light')
watch(() => breakpoints.smDown, (newValue, oldValue) => {
if (newValue && !oldValue) {
Expand Down
15 changes: 15 additions & 0 deletions packages/nuxt/nuxt.shim.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
1 change: 1 addition & 0 deletions packages/nuxt/src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export default defineNuxtModule<VuesticOptions>({
config: {},
css: ['smart-helpers', 'typography'],
fonts: true,
themeCookieKey: 'vuestic-theme',
},

setup (options) {
Expand Down
39 changes: 26 additions & 13 deletions packages/nuxt/src/runtime/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,41 @@ 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 type { VuesticOptions } from '../types'
// @ts-ignore: nuxt import alias
import { defineNuxtPlugin } from '#app'
// @ts-ignore: direct nuxt-link import
import { defineNuxtPlugin, useCookie } from '#app'
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]
}

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) },
// TODO: Would be nice to tree-shake plugins, but they're small so we don't cant for now.
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: {
BreakpointConfigPlugin,
Expand Down Expand Up @@ -66,4 +73,10 @@ export default defineNuxtPlugin((nuxtApp) => {
}
}))
}

// Watch for preset name change and update cookie
const { globalConfig } = getGlobalProperty(app, '$vaConfig') as { globalConfig: Ref<GlobalConfig> }
watch(() => globalConfig.value.colors.currentPresetName, (newTheme) => {
themeCookie.value = newTheme
}, { immediate: true })
})
13 changes: 7 additions & 6 deletions packages/nuxt/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<VuesticOptions>
}

/**
* 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
}

0 comments on commit cf57c63

Please sign in to comment.