Skip to content

Commit 7b32255

Browse files
docs: example of multiple themes
1 parent 704bea9 commit 7b32255

File tree

19 files changed

+478
-0
lines changed

19 files changed

+478
-0
lines changed

README.md

+144
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,150 @@ module.exports = {
911911
};
912912
```
913913

914+
### Multiple Themes
915+
916+
**webpack.config.js**
917+
918+
```js
919+
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
920+
921+
module.exports = {
922+
entry: "./src/index.js",
923+
module: {
924+
rules: [
925+
{
926+
test: /\.s[ac]ss$/i,
927+
oneOf: [
928+
{
929+
resourceQuery: "?dark",
930+
use: [
931+
Self.loader,
932+
"css-loader",
933+
{
934+
loader: "sass-loader",
935+
options: {
936+
additionalData: `@use 'dark-theme/vars' as vars;`,
937+
},
938+
},
939+
],
940+
},
941+
{
942+
use: [
943+
Self.loader,
944+
"css-loader",
945+
{
946+
loader: "sass-loader",
947+
options: {
948+
additionalData: `@use 'light-theme/vars' as vars;`,
949+
},
950+
},
951+
],
952+
},
953+
],
954+
},
955+
],
956+
},
957+
plugins: [
958+
new Self({
959+
filename: "[name].css",
960+
attributes: {
961+
id: "theme",
962+
},
963+
}),
964+
],
965+
};
966+
```
967+
968+
**src/index.js**
969+
970+
```js
971+
import "./style.scss";
972+
973+
let theme = "light";
974+
const themes = {};
975+
976+
themes[theme] = document.querySelector("#theme");
977+
978+
async function loadTheme(newTheme) {
979+
// eslint-disable-next-line no-console
980+
console.log(`CHANGE THEME - ${newTheme}`);
981+
982+
const themeElement = document.querySelector("#theme");
983+
984+
if (themeElement) {
985+
themeElement.remove();
986+
}
987+
988+
if (themes[newTheme]) {
989+
// eslint-disable-next-line no-console
990+
console.log(`THEME ALREADY LOADED - ${newTheme}`);
991+
992+
document.head.appendChild(themes[newTheme]);
993+
994+
return;
995+
}
996+
997+
if (newTheme === "dark") {
998+
// eslint-disable-next-line no-console
999+
console.log(`LOADING THEME - ${newTheme}`);
1000+
1001+
import(/* webpackChunkName: "dark" */ "./style.scss?dark").then(() => {
1002+
themes[newTheme] = document.querySelector("#theme");
1003+
1004+
// eslint-disable-next-line no-console
1005+
console.log(`LOADED - ${newTheme}`);
1006+
});
1007+
}
1008+
}
1009+
1010+
document.onclick = () => {
1011+
if (theme === "light") {
1012+
theme = "dark";
1013+
} else {
1014+
theme = "light";
1015+
}
1016+
1017+
loadTheme(theme);
1018+
};
1019+
```
1020+
1021+
**src/dark-theme/\_vars.scss**
1022+
1023+
```scss
1024+
$background: black;
1025+
```
1026+
1027+
**src/light-theme/\_vars.scss**
1028+
1029+
```scss
1030+
$background: white;
1031+
```
1032+
1033+
**src/styles.scss**
1034+
1035+
```scss
1036+
body {
1037+
background-color: vars.$background;
1038+
}
1039+
```
1040+
1041+
**public/index.html**
1042+
1043+
```html
1044+
<!DOCTYPE html>
1045+
<html lang="en">
1046+
<head>
1047+
<meta charset="UTF-8" />
1048+
<meta name="viewport" content="width=device-width, initial-scale=1" />
1049+
<title>Document</title>
1050+
<link id="theme" rel="stylesheet" type="text/css" href="./main.css" />
1051+
</head>
1052+
<body>
1053+
<script src="./main.js"></script>
1054+
</body>
1055+
</html>
1056+
```
1057+
9141058
### Media Query Plugin
9151059

9161060
If you'd like to extract the media queries from the extracted CSS (so mobile users don't need to load desktop or tablet specific CSS anymore) you should use one of the following plugins:

package-lock.json

+85
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@
7171
"memfs": "^3.0.2",
7272
"npm-run-all": "^4.1.5",
7373
"prettier": "^2.3.2",
74+
"sass": "^1.39.0",
75+
"sass-loader": "^12.1.0",
7476
"standard-version": "^9.3.0",
7577
"webpack": "^5.48.0",
7678
"webpack-cli": "^4.7.2",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
body {
2+
background-color: black;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
body {
2+
background-color: white;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<title>Document</title>
7+
<link id="theme" rel="stylesheet" type="text/css" href="./main.css">
8+
</head>
9+
<body>
10+
<script src="./main.js"></script>
11+
</body>
12+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
$background: black;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/* eslint-env browser */
2+
import "./style.scss";
3+
4+
let theme = "light";
5+
const themes = {};
6+
7+
themes[theme] = document.querySelector("#theme");
8+
9+
async function loadTheme(newTheme) {
10+
// eslint-disable-next-line no-console
11+
console.log(`CHANGE THEME - ${newTheme}`);
12+
13+
const themeElement = document.querySelector("#theme");
14+
15+
if (themeElement) {
16+
themeElement.remove();
17+
}
18+
19+
if (themes[newTheme]) {
20+
// eslint-disable-next-line no-console
21+
console.log(`THEME ALREADY LOADED - ${newTheme}`);
22+
23+
document.head.appendChild(themes[newTheme]);
24+
25+
return;
26+
}
27+
28+
if (newTheme === "dark") {
29+
// eslint-disable-next-line no-console
30+
console.log(`LOADING THEME - ${newTheme}`);
31+
32+
// eslint-disable-next-line import/no-unresolved
33+
import(/* webpackChunkName: "dark" */ "./style.scss?dark").then(() => {
34+
themes[newTheme] = document.querySelector("#theme");
35+
36+
// eslint-disable-next-line no-console
37+
console.log(`LOADED - ${newTheme}`);
38+
});
39+
}
40+
}
41+
42+
document.onclick = () => {
43+
if (theme === "light") {
44+
theme = "dark";
45+
} else {
46+
theme = "light";
47+
}
48+
49+
loadTheme(theme);
50+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
$background: white;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
body {
2+
background-color: vars.$background;
3+
}

0 commit comments

Comments
 (0)