Reputation: 1006
I want to implement theming in my react application. Therefore I used this tutorial (sass-mixins).
But this doesn't work in combination with css-modules, since the the theming class is outside of the css-module I want to theme.
Does anyone have a workaround for this problem or another approach to theme a react application using sass?
App.js
const theme = require('../../Theming.sass)
<div class={theme['theme-dark'}>
<SearchBar/>
...
</div>
SearchBar.js
const styles = require('./SearchBar.scss)
const theme = require('../../Theming.sass)
<div class={styles.searchBar}>
...
</div>
SearchBar.scss
.searchBar {
@include themify($themes) {
color: themed('primary');
background: themed('secondary');
}
height: 3em;
overflow: hidden;
SearchBar.css (compiled)
.searchBar {
height: 3em;
overflow: hidden;
}
.theme-light .searchBar {
color: #fff;
background: #bfbfbf;
}
.theme-dark .searchBar {
color: #000;
background: #1a1a1a;
}
Theming.sass
.theme-dark { background: #000; }
.theme-light { background: #fff; }
$themes: (
light: (
primary: #fff,
secondary: #bfbfbf,
),
dark: (
primary: #000,
secondary: #1a1a1a,
),
);
@function themed($key) {
@return map-get($theme-map, $key);
}
@mixin themify($themes: $themes) {
@each $theme, $map in $themes {
.theme-#{$theme} & { /* HOW TO USE CSS-MODULES HERE ?*/
$theme-map: () !global;
@each $key, $submap in $map {
$value: map-get(map-get($themes, $theme), '#{$key}');
$theme-map: map-merge($theme-map, ($key: $value)) !global;
}
@content;
$theme-map: null !global;
}
}
}
Upvotes: 4
Views: 4087
Reputation: 81
I had a similar issue, I am using SASS with CSS modules in a React app and I ended up using the theme class as a global class and not using CSS modules because every time I used the mixin it added the module prefix to the style.
I added :global
to the theme class in the mixin:
@mixin themify($themes: $themes) {
@each $theme, $map in $themes {
:global(.theme-#{$theme}) & {
$theme-map: () !global;
@each $key, $submap in $map {
$value: map-get(map-get($themes, $theme), '#{$key}');
$theme-map: map-merge($theme-map, ($key: $value)) !global;
}
@content;
$theme-map: null !global;
}
}
}
And I specified the class directly in my JSX in App.js:
<div class="theme-dark">
<SearchBar/>
...
</div>
I hope this helps someone.
Upvotes: 8
Reputation: 12882
You also need to import .theme-dark
through css-modules.
Should be something like:
<div class={styles.themeDark}>
<SearchBar/>
...
</div>
You should also use sass-resources-loader for it: https://github.com/shakacode/sass-resources-loader
Upvotes: 1