So I have a new React Project where im trying SCSS for the styling part. Im basically a SCSS noob as I've always used Css. I went online to find tutorials on how to do it and i got this code in the end:
// _themes.scss
$themes: (
light: (
color-background: #FAFAFA,
color-card: #FFF
),
dark: (
color-background: #37474F,
color-card: #212121
)
);
// _mixins.scss
@mixin theme-aware($key, $color) {
@each $theme-name, $theme-color in $themes {
.theme-#{$theme-name} & {
#{$key}: map.get(map.get($themes, $theme-name), $color)
}
}
}
//App.module.scss
@import "../../assets/themes/mixins";
.container {
width: 100%;
height: 100%;
@include theme-aware('background', 'color-background');
}
Now I've tried about everything:
Here is what I know and understand so far:
What am I not understanding? The tutorial i saw online used node-scss and worked, so far is the only difference i can find
EDIT:: I finally found the issue. It does work IF I dont use React Router. My App.tsx:
export default function App() {
const dispatch = useDispatch()
const session = useSelector(sessionSelector)
const theme = useSelector(themeSelector)
useEffect(() => {
document.documentElement.className = '';
document.documentElement.classList.add(`theme-${theme.name}`)
}, [theme])
return (
<div>
<Home />
<Routes>
<Route path={paths.home} element={<Outlet />}>
<Route element={<RequireAuth roles={["SUPER"]} />}>
</Route>
<Route element={<RequireAuth roles={["SUPER", "ADMIN"]} />}>
</Route>
<Route element={<RequireAuth roles={["SUPER"]} />}>
</Route>
</Route>
</Routes>
</div>
)
}
As you can see, I apply the scss theme to the document itself. It does work in my component and all colors change, but the routes do not recognize the class. To fix it i applied the style to the body like:
@import "./assets/themes/mixins";
* {
@include theme-aware('background', 'color-background');
}
You didn't use .scss extension in react if you don't use JavaScript then make sure add that language extension..
@import
"../../assets/themes/_mixins.scss";
Or
If your mixin scss file name not contain (_) underscore then use this
@import
"../../assets/themes/mixins.scss;
The problem is there in _mixins.scss
, you need to import of sass:map
to use map.get
or else you can also use map-get
directly without importing sass:map
and I have replaced hyphen in .theme-#{$theme-name}
in mixins.scss
with underscore .theme_#{$theme-name}
. With these two changes in the code you provided the appropriate theme is getting applied.
// _themes.scss
$themes: (
light: (
color-background: #FAFAFA,
color-card: #FFF
),
dark: (
color-background: #37474F,
color-card: #212121
)
);
// _mixins.scss
@use "sass:map";
@import "./themes";
@mixin theme-aware($key, $color) {
@each $theme-name, $theme-color in $themes {
.theme_#{$theme-name} & {
#{$key}: map.get(map.get($themes, $theme-name), $color);
}
}
}
//App.module.scss
@import "./mixins";
.container {
width: 100%;
height: 100%;
@include theme-aware('background-color','color-background');
}
//App.module.scss
import styles from "./app.module.scss";
export default function App() {
return (
<div className={styles.theme_dark}>
<div className={styles.container}>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
</div>
);
}
Working Example you can find here:- https://codesandbox.io/s/customised-theme-6dvt04?file=/src/_mixins.scss
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.