-
-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* manage color mode state * theming storybook for dark mode * testing * color mode guide and README
- Loading branch information
Showing
25 changed files
with
768 additions
and
178 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* | ||
This hook is meant to: | ||
- remember, with local storage, which color mode has been selected by the user | ||
- toggle psb color_mode on the HTML root element (which will change colors of the storybook itself, | ||
not the component's colors) | ||
- push to the storybook the selected color mode, and the actual color mode (when selected value | ||
is system, it will send dark or light depending on the browser current prefers-color-scheme). | ||
*/ | ||
|
||
let self; | ||
|
||
export const ColorModeHook = { | ||
mounted() { | ||
self = this; | ||
window.addEventListener("psb:set-color-mode", this.onSetColorMode); | ||
|
||
window | ||
.matchMedia("(prefers-color-scheme: dark)") | ||
.addEventListener("change", () => { | ||
const selectedMode = this.selectedColorMode(); | ||
const actualMode = this.actualColorMode(selectedMode); | ||
this.pushEvent("psb-set-color-mode", { | ||
selected_mode: selectedMode, | ||
mode: actualMode, | ||
}); | ||
this.toggleColorModeClass(actualMode); | ||
}); | ||
}, | ||
|
||
destroyed() { | ||
window.removeEventListener("psb:set-color-mode", onSetColorMode); | ||
}, | ||
|
||
selectedColorMode() { | ||
return localStorage.getItem("psb_selected_color_mode") || "system"; | ||
}, | ||
|
||
actualColorMode(selectedMode) { | ||
if ( | ||
selectedMode == "system" && | ||
window.matchMedia("(prefers-color-scheme: dark)").matches | ||
) { | ||
return "dark"; | ||
} else if (selectedMode == "dark") { | ||
return "dark"; | ||
} else { | ||
return "light"; | ||
} | ||
}, | ||
toggleColorModeClass: (mode) => { | ||
if (mode == "dark") { | ||
document.documentElement.classList.add("psb-dark"); | ||
} else { | ||
document.documentElement.classList.remove("psb-dark"); | ||
} | ||
}, | ||
onSetColorMode: (e) => { | ||
const selectedMode = e.detail.mode || "system"; | ||
localStorage.setItem("psb_selected_color_mode", selectedMode); | ||
const actualMode = self.actualColorMode(selectedMode); | ||
self.pushEvent("psb-set-color-mode", { | ||
selected_mode: selectedMode, | ||
mode: actualMode, | ||
}); | ||
self.toggleColorModeClass(actualMode); | ||
}, | ||
}; | ||
|
||
const selectedMode = ColorModeHook.selectedColorMode(); | ||
const actualMode = ColorModeHook.actualColorMode(selectedMode); | ||
ColorModeHook.toggleColorModeClass(actualMode); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,4 +30,5 @@ module.exports = { | |
}, | ||
important: ".psb", | ||
prefix: "psb-", | ||
darkMode: "selector", | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# Color modes | ||
|
||
The storybook can support color modes: _dark_, _light_ and _system_. | ||
|
||
- The storybook style itself is styled based on the selected color mode | ||
- Your components will be wrapped in a div with a custom dark class. | ||
|
||
The different modes are handled as such: | ||
|
||
- when `dark`, the `dark` class (or custom dark class) is added on your components sandbox | ||
- when `light`, no class is set | ||
- when `system`, it will add the `dark` class if your system prefers dark (cf. `prefers-color-scheme`) | ||
|
||
## Setup | ||
|
||
First you need enable `color_mode` support. | ||
|
||
```elixir | ||
use PhoenixStorybook, | ||
# ... | ||
color_mode: true | ||
``` | ||
|
||
This will add a new color theme picker in the storybook header. At this time you should be able | ||
to render the storybook with the new mode. | ||
|
||
## Component rendering | ||
|
||
Whenever a component of yours is rendered in the storybook, it's wrapped under a sandbox element (read [sandboxing guide](sandboxing.md)) | ||
|
||
If the current color_mode is dark (or system with your system being dark), then the sandbox will carry a `dark` css class. When in light mode, no class is set. | ||
|
||
You can customize the default dark class: | ||
|
||
```elixir | ||
use PhoenixStorybook, | ||
# ... | ||
color_mode_sandbox_dark_class: "my-dark", | ||
``` | ||
|
||
## Tailwind setup | ||
|
||
If you use Tailwind for your own components, then update your `tailwind.config.js` accordingly. | ||
|
||
```js | ||
module.exports = { | ||
// ... | ||
darkMode: "selector", | ||
}; | ||
``` | ||
|
||
A custom dark class can be used like this: | ||
|
||
```js | ||
module.exports = { | ||
// ... | ||
darkMode: ["selector", ".my-dark"], | ||
}; | ||
``` | ||
|
||
In your own application, when setting the dark mode class to your DOM, make sure it is added on | ||
(or under) your sandbox/important element. | ||
|
||
```html | ||
<html class="storybook-demo-sandbox dark"> | ||
... | ||
</html> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.