-
-
Notifications
You must be signed in to change notification settings - Fork 384
Issue 427 #824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue 427 #824
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -911,6 +911,150 @@ module.exports = { | |
}; | ||
``` | ||
|
||
### Multiple Themes | ||
|
||
**webpack.config.js** | ||
|
||
```js | ||
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); | ||
|
||
module.exports = { | ||
entry: "./src/index.js", | ||
module: { | ||
rules: [ | ||
{ | ||
test: /\.s[ac]ss$/i, | ||
oneOf: [ | ||
{ | ||
resourceQuery: "?dark", | ||
use: [ | ||
Self.loader, | ||
"css-loader", | ||
{ | ||
loader: "sass-loader", | ||
options: { | ||
additionalData: `@use 'dark-theme/vars' as vars;`, | ||
}, | ||
}, | ||
], | ||
}, | ||
{ | ||
use: [ | ||
Self.loader, | ||
"css-loader", | ||
{ | ||
loader: "sass-loader", | ||
options: { | ||
additionalData: `@use 'light-theme/vars' as vars;`, | ||
}, | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
plugins: [ | ||
new Self({ | ||
filename: "[name].css", | ||
attributes: { | ||
id: "theme", | ||
}, | ||
}), | ||
], | ||
}; | ||
``` | ||
|
||
**src/index.js** | ||
|
||
```js | ||
import "./style.scss"; | ||
|
||
let theme = "light"; | ||
const themes = {}; | ||
|
||
themes[theme] = document.querySelector("#theme"); | ||
|
||
async function loadTheme(newTheme) { | ||
// eslint-disable-next-line no-console | ||
console.log(`CHANGE THEME - ${newTheme}`); | ||
|
||
const themeElement = document.querySelector("#theme"); | ||
|
||
if (themeElement) { | ||
themeElement.remove(); | ||
} | ||
|
||
if (themes[newTheme]) { | ||
// eslint-disable-next-line no-console | ||
console.log(`THEME ALREADY LOADED - ${newTheme}`); | ||
|
||
document.head.appendChild(themes[newTheme]); | ||
|
||
return; | ||
} | ||
|
||
if (newTheme === "dark") { | ||
// eslint-disable-next-line no-console | ||
console.log(`LOADING THEME - ${newTheme}`); | ||
|
||
import(/* webpackChunkName: "dark" */ "./style.scss?dark").then(() => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the chunk name comment required here, or is it optional? If it's required, would there be any way to define it in the webpack config rather than the source? Just thinking out loud: It might be possible to use a pitching loader to expand a static There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is for tests and examples, for production I recommend to not use comments, because you will have less names for files, so you will send less bytes for client There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it, thank you. Would it make sense to revise this example to use production best practices? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Feel free to send a PR and fix it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can certainly fix the However, I don't actually know how to replace |
||
themes[newTheme] = document.querySelector("#theme"); | ||
|
||
// eslint-disable-next-line no-console | ||
console.log(`LOADED - ${newTheme}`); | ||
}); | ||
} | ||
} | ||
|
||
document.onclick = () => { | ||
if (theme === "light") { | ||
theme = "dark"; | ||
} else { | ||
theme = "light"; | ||
} | ||
|
||
loadTheme(theme); | ||
}; | ||
``` | ||
|
||
**src/dark-theme/\_vars.scss** | ||
|
||
```scss | ||
$background: black; | ||
``` | ||
|
||
**src/light-theme/\_vars.scss** | ||
|
||
```scss | ||
$background: white; | ||
``` | ||
|
||
**src/styles.scss** | ||
|
||
```scss | ||
body { | ||
background-color: vars.$background; | ||
} | ||
``` | ||
|
||
**public/index.html** | ||
|
||
```html | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<title>Document</title> | ||
<link id="theme" rel="stylesheet" type="text/css" href="./main.css" /> | ||
</head> | ||
<body> | ||
<script src="./main.js"></script> | ||
</body> | ||
</html> | ||
``` | ||
|
||
### Media Query Plugin | ||
|
||
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: | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
body { | ||
background-color: black; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
body { | ||
background-color: white; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<title>Document</title> | ||
<link id="theme" rel="stylesheet" type="text/css" href="./main.css"> | ||
</head> | ||
<body> | ||
<script src="./main.js"></script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
$background: black; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* eslint-env browser */ | ||
import "./style.scss"; | ||
|
||
let theme = "light"; | ||
const themes = {}; | ||
|
||
themes[theme] = document.querySelector("#theme"); | ||
|
||
async function loadTheme(newTheme) { | ||
// eslint-disable-next-line no-console | ||
console.log(`CHANGE THEME - ${newTheme}`); | ||
|
||
const themeElement = document.querySelector("#theme"); | ||
|
||
if (themeElement) { | ||
themeElement.remove(); | ||
} | ||
|
||
if (themes[newTheme]) { | ||
// eslint-disable-next-line no-console | ||
console.log(`THEME ALREADY LOADED - ${newTheme}`); | ||
|
||
document.head.appendChild(themes[newTheme]); | ||
|
||
return; | ||
} | ||
|
||
if (newTheme === "dark") { | ||
// eslint-disable-next-line no-console | ||
console.log(`LOADING THEME - ${newTheme}`); | ||
|
||
// eslint-disable-next-line import/no-unresolved | ||
import(/* webpackChunkName: "dark" */ "./style.scss?dark").then(() => { | ||
themes[newTheme] = document.querySelector("#theme"); | ||
|
||
// eslint-disable-next-line no-console | ||
console.log(`LOADED - ${newTheme}`); | ||
}); | ||
} | ||
} | ||
|
||
document.onclick = () => { | ||
if (theme === "light") { | ||
theme = "dark"; | ||
} else { | ||
theme = "light"; | ||
} | ||
|
||
loadTheme(theme); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
$background: white; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
body { | ||
background-color: vars.$background; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a reference to
Self
. Should it be like this?(same for next two occurrences)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is for tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I saw the tests. But this is the README right?