3

What I am trying to do?

I have a component library website where I want to show the different color themes. I have a select box where the user can switch between different themes.

I have two css files, lets name them watermelon and blueberry.

// blueberry/index/.css
:root {
--color-1: indigo;
}
// watermelon/index/.css
:root {
--color-1: green;
}

and on my tailwind.config.js

//tailwind.config.js
theme: {
 extend: {
  color: {
   primary: "var(--color-1)"

Whats happening on the code

I have a watcher on selectedTheme, so everytime value changes, I import the correct theme css file.

import { ref, watch } from "vue"

export default {
  setup() {
    const selectedTheme = ref("watermelon")
    const themeOptions = [
      { name: "Blueberry", value: "blueberry" },
      { name: "Watermelon", value: "watermelon" },
    ]
    async function importTheme(theme) {
      try {
        await import(`../themes/${theme}/index.css`)
      } catch (error) {
        console.log(error)
      }
    }
    watch(
      selectedTheme,
      async newValue => {
        console.log("changing", newValue)
        await importTheme(newValue)
      },
      { immediate: true }
    )
    return { themeOptions, selectedTheme }
  },
}
</script>
<style>
#app {
  font-family: "Poppins", sans-serif;
}
</style>

What is happening right now

On the first switch -> The theme is switched from watermelon to blueberry -> component color changes from green to indigo.

On second switch and after -> nothing happens, component color does not change.

I'm not sure what's happening here. Can someone enlighten me or point me to the right direction?

What is supposed to happen

Switching works even after the first. Switch from green to indigo and then back to green.

6
  • Does the console show the change? Commented Feb 10, 2021 at 9:09
  • @Dan, yep it does Commented Feb 10, 2021 at 9:19
  • @Dan my thought process right now is that whenever I import the new index.css, it overrides the previously imported index.css because the css variables have the same name. 1. On the first switch -> The theme is switched from watermelon to blueberry -> component color changes from green to blue. 2. On second switch and after -> nothing happens, component color does not change. Commented Feb 10, 2021 at 9:30
  • I'm guessing that once a CSS module is loaded, future reloads of that module are ignored. Since unloading a CSS module is no trivial task, I would suggest rethinking the pattern. For example, your themes could have differently named classes. Or you could use a root element that changes class based on selectedTheme, and then each theme defines styles like: .indigo .mydiv {} Commented Feb 10, 2021 at 10:49
  • 1
    You're welcome. Yeah, something like <div :class="selectedTheme"> would be sufficient Commented Feb 10, 2021 at 11:03

2 Answers 2

2

What I ended up doing was declaring css variables like so:

.blueberry-theme {
 --color-1:indigo;
}

and

.watermelon-theme {
 --color-1: green;
}

and on the vue component watcher, I add a class to root element div using document.documentElement.className everytime selectedTheme is changed:

Example: if Blueberry is selected, "blueberry-theme" class is applied on the root div element.

<template>
  <Select :options="themeOptions" v-model="selectedTheme" />
</template>

<script>
import { ref, watch } from "vue"
export default {
  setup() {
    const selectedTheme = ref("blueberry-theme")

    const themeOptions = [
      { name: "Blueberry", value: "blueberry-theme" },
      { name: "Watermelon", value: "watermelon-theme" },
    ]

    function setTheme(theme) {
      document.documentElement.className = theme
    }

    watch(
      selectedTheme,
      async newValue => {
        await setTheme(newValue)
      },
      { immediate: true }
    )

    return { themeOptions, selectedTheme }
  },
}
</script>
Sign up to request clarification or add additional context in comments.

Comments

0

Not sure if is what you want, but you can change css variables dynamically by doing:

  if (typeof window !== 'undefined') {
      document.documentElement.style.setProperty('--color-1', someCoolColor)
  }

and this would be reflefect into tailwind styles that uses this variable.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.