yariksav / vuetify-dialog

Easy dialogs in Vuetify.js framework
MIT License
195 stars 48 forks source link

Nuxt plugin breaks theme #107

Closed snelg closed 3 years ago

snelg commented 3 years ago

This one's much easier to demonstrate than explain:

https://codesandbox.io/s/vuetify-dialog-nuxt-theme-break-lkx7g

An explanation of the problem is in included in the demonstration itself, but here's a slightly longer version.

One of my Nuxt projects includes a "theme switching" feature, where the user can switch to different color palettes while using the site. In the code, I do this palette change by simply changing the values of $vuetify.theme.currentTheme.primary, $vuetify.theme.currentTheme.secondary, etc. This method is specifically described in the Vuetify documentation on dynamic theme customization

That's been working fine for a while. I added vuetify-dialog to the project, and that works great as well :) But at some point I realized that after any call to $dialog.* (e.g. $dialog.notify.info('Hi!') ), the palette changing no longer works.

The codesandbox demonstration is a minimal installation of Nuxt + Vuetify + vuetify-dialog that demonstrates the problem.

yariksav commented 3 years ago

Sorry @snelg , I didn't read properly and, now I understand your problem. I even don't imagine why this problem is, maybe you will help with your investigation. Vuetify-dialog doesn't touch any vuetify params, Seems to that $vuetify.theme... loose reactivity somehow

yariksav commented 3 years ago

Can you try to write this issue to vuetify team? Maybe they will help... at least with advice. I suppose problem will be in framework logic, but I don't know for sure how. They know how works framework inside. I see that reactivity works (text color changes)

yariksav commented 3 years ago

As I investigated vuetify changes own style block in header, and after dialog shows - it stoped to do this

image

and they make observation by $root component.

https://github.com/vuetifyjs/vuetify/blob/56f5668d27b6ac0a52c792fb9745164155faa8e3/packages/vuetify/src/services/theme/index.ts#L240

vuetify-dialog has own $root component, because it shows independetly of App.

and it do this.unwatch() when dialog hides (and destroy own $root component by itself)

Vuetify team should rebuild this logic to many $root components

And sorry, I cannot remake this logic in vuetify-dialog, because it's core and it's main approach - independence of app

Otherway you may remake dialogs in your project to other lib (or native vuetify code)

snelg commented 3 years ago

I also reached that conclusion. I just noticed this from the Vuetify docs "Vuetify doesn’t support multiple isolated Vuetify instances on a page. v-app can exist anywhere inside the body of your app, however, there should only be one and it must be the parent of ALL Vuetify components."

Oh, well.

I do have a hacky workaround: Every time I change a theme color, if I also trigger the reactivity of $vuetify.theme.dark by setting it to its own current value, then vuetify does rebuild that <style> header.

$vuetify.theme.dark = $vuetify.theme.dark

I prefer clean solutions, but I can live with hacky workarounds when necessary :)

yariksav commented 3 years ago

Yeah This hack works because of https://github.com/vuetifyjs/vuetify/blob/56f5668d27b6ac0a52c792fb9745164155faa8e3/packages/vuetify/src/services/theme/index.ts#L118

  public setTheme (theme: 'light' | 'dark', value: object) {
    this.themes[theme] = Object.assign(this.themes[theme], value)
    --> this.applyTheme()
  }

Just target is to call applyTheme() method somehow.

Maybe then better to call

this.$vuetify.application.framework.theme.applyTheme();

after change theme. see https://codesandbox.io/s/vuetify-dialog-nuxt-theme-break-forked-v01yx?file=/pages/index.vue

I close this issue because it cannot be fixed and we have solution