Skip to content

Commit

Permalink
feat: support prefers color scheme in color modes (#186)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmjuanes authored Sep 11, 2022
1 parent cffbdb5 commit 8cfabab
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 7 deletions.
16 changes: 15 additions & 1 deletion docs/color-modes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,24 @@ setColorMode("dark");

## Enable Dark mode automatically

You can easily enable the dark (or light) color mode automatically based on the user color preference using the `prefers-color-scheme` media.
You can easily enable the dark (or light) color mode automatically based on the user color preference using the `prefers-color-scheme` [media query](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme).

Note that not all browsers supports the `prefers-color-scheme` media. You can check the browser compatibility there: https://caniuse.com/prefers-color-scheme.

### Using the useColorModesMediaQuery flag

We alsp provide an additional flag called `useColorModesMediaQuery` to automatically use the `prefers-color-scheme` media query to enable the color mode based on the user configuration.

Just set to `true` the `useColorModesMediaQuery` in your configuration file (note that the `useColorModes` flag **is also required**):

```js
export default {
useColorModes: true, // Required!!!
useColorModesMediaQuery: true,
// ...other configuration
};
```

### Using JavaScript

You can use the [`matchMedia`](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia) function of JavaScript to check if the document matches the `(prefers-color-scheme: dark)` media query and enable the dark color mode based on the user preference.
Expand Down
2 changes: 2 additions & 0 deletions docs/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ Use the configuration flags to enable or disable some features of **siimple**:
- `useBorderBox`: adds a global `box-sizing: border-box`. Default is `true`.
- `useCssVariables`: uses CSS variables for some theme scale values (colors and font families). Default is `false`.
- `useColorModes`: allows to use color modes defined in the `colorModes` field of your configuration. Default is `false`.
- `useColorModesMediaQuery`: allows to use the `prefers-color-scheme` media query to set the color mode to apply. Note that `useColorModes` flag should be also enabled. Default is `false`.

Flags are defined in the first level of the configuration object:

Expand All @@ -183,6 +184,7 @@ export default {
useBorderBox: true,
useCssVariables: false,
useColorModes: false,
useColorModesMediaQuery: false,
// ...other configuration
};
```
Expand Down
8 changes: 4 additions & 4 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from "path";
import autoprefixer from "autoprefixer";
// import path from "path";
// import autoprefixer from "autoprefixer";
import gulp from "gulp";
import postcss from "gulp-postcss";
// import postcss from "gulp-postcss";
import rename from "gulp-rename";
import CleanCSS from "clean-css";
import through from "through2";
Expand Down Expand Up @@ -65,7 +65,7 @@ gulp.task("icons:sprite", () => {
gulp.task("css", () => {
return gulp.src("siimple*/siimple.config.js", {base: "./"})
.pipe(siimple())
.pipe(postcss([autoprefixer()]))
// .pipe(postcss([autoprefixer()]))
.pipe(minify({
"compatibility": "*",
"level": 2,
Expand Down
9 changes: 7 additions & 2 deletions packages/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -328,9 +328,14 @@ export const buildVariables = config => {
// Build color modes
export const buildColorModes = config => {
const result = Object.keys(config.colorModes || {}).map(name => {
const selector = `html[data-color-mode="${name}"]`;
const variables = buildCssVariables(cssVariablesNames["colors"], config.colorModes[name]);
return wrapRule(selector, variables.join(""), "");
// Use the prefers-color-scheme media query instead
if (config.useColorModesMediaQuery && (name === "light" || name === "dark")) {
const rootVariables = wrapRule(":root", variables.join(""), "");
return wrapRule(`@media (prefers-color-scheme: ${name})`, rootVariables);
}
// Default selector
return wrapRule(`html[data-color-mode="${name}"]`, variables.join(""), "");
});
return result.filter(item => !!item).join("\n");
};
Expand Down
21 changes: 21 additions & 0 deletions test/build.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,5 +184,26 @@ describe("buildColorModes", () => {
expect(css[0]).toBe(`html[data-color-mode="dark"] {--siimple-color-primary:black;--siimple-color-secondary:white;}`);
expect(css[1]).toBe(`html[data-color-mode="light"] {--siimple-color-primary:white;--siimple-color-secondary:black;}`);
});

it("should use the prefers-color-scheme media query when enabled", () => {
const config = {
useColorModes: true,
useColorModesMediaQuery: true,
colorModes: {
dark: {
primary: "black",
secondary: "white",
},
light: {
primary: "white",
secondary: "black",
},
},
};
const css = buildColorModes(config).split("\n");
expect(css).toHaveLength(2);
expect(css[0]).toBe(`@media (prefers-color-scheme: dark) {:root {--siimple-color-primary:black;--siimple-color-secondary:white;}}`);
expect(css[1]).toBe(`@media (prefers-color-scheme: light) {:root {--siimple-color-primary:white;--siimple-color-secondary:black;}}`);
});
});

0 comments on commit 8cfabab

Please sign in to comment.