Slim Shady
Slim Shady

Reputation: 384

Importing different SCSS files based on a state variable

I have this state variable:

this.state = {
    theme: "light"
}

This state gets added to a divs class name so it becomes <div class name=`app ${this.state.theme}`>

I also have three scss files: App.scss, LightTheme.scss and DarkTheme.scss. The app.scss has to import one of the theme scss files, because they have some color variables that make up the theme.

I tried to use scss's if statement but I discovered that scss can't be used to check if an element contains a particular class name or not.

Importing the theme files with JavaScript also doesn't work because the app.scss will have undefined variables.

Any thoughts?

Upvotes: 1

Views: 1298

Answers (2)

Becky
Becky

Reputation: 5585

Can't you import App.scss in to LightTheme.scss and also in to DarkTheme.scss as the first line?

@import "../../App.scss";  /*add path to App.scss*/

Then you can call either LightTheme.scss or DarkTheme.scss which should work as you're expecting.


EDIT

"All my styles are in app.scss. The theme files only contain color variables."

  1. Create a new file light-theme.scss

  2. Add these 2 line in it.

    @import "../../LightTheme.scss";  /*variables*/
    @import "../../App.scss";  /*styles*/
    
  3. Create another new file dark-theme.scss

  4. Add these 2 line in it.

    @import "../../DarkTheme.scss";  /*variables*/
    @import "../../App.scss";  /*styles*/
    

Now just call light-theme.scss or dark-theme.scss as you planned.

Upvotes: 1

Yuan-Hao Chiang
Yuan-Hao Chiang

Reputation: 2603

You can import the three files and add the theme class the very first div inside your App.js, something like this:

function App() {

  return (
    <div className={`App theme-${this.state.theme}`}>
    ...
    </div>
  );
}

You would import all three scss files and then, inside, say DarkTheme.scss you can do as follows:

// ThemeDark.scss
.theme-dark {

  h1 {
    color: white;
  }

  .navigation {
     background-color: darkblue;
  }
}
// ThemeLight.scss
.theme-light {

  h1 {
    color: black;
  }

  .navigation {
     background-color: lightgray;
  }
}

Et cetera. In my case, I always use the light version as default always imported, but it might be a good division to do it as you suggest, and have a theme-neutral css file:

// App.scss
h1 {
   font-size: 2em;
}

.navigation {
   position: absolute;
}

Upvotes: 1

Related Questions