gsmig
gsmig

Reputation: 100

Dynamically update CSS variables definitions in Tailwindcss during runtime

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.

Upvotes: 3

Views: 5228

Answers (2)

alexandre_anicio
alexandre_anicio

Reputation: 199

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.

Upvotes: 0

gsmig
gsmig

Reputation: 100

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>

Upvotes: 2

Related Questions