feat(darkmode): initial support for dark mode toggle

This commit is contained in:
Jimmy Cai 2020-12-23 17:15:17 +01:00
parent df74fe5f19
commit a3d191f818
No known key found for this signature in database
GPG Key ID: 3EA408E527F37B18
12 changed files with 150 additions and 20 deletions

View File

@ -0,0 +1,26 @@
[data-scheme="dark"] {
#dark-mode-toggle {
color: var(--accent-color);
font-weight: 700;
.icon-tabler-toggle-left {
display: none;
}
.icon-tabler-toggle-right {
display: unset;
}
}
}
#dark-mode-toggle {
margin-top: auto;
color: var(--body-text-color);
display: flex;
align-items: center;
cursor: pointer;
.icon-tabler-toggle-right {
display: none;
}
}

View File

@ -3,11 +3,6 @@
* https://xyproto.github.io/splash/docs/monokai.html * https://xyproto.github.io/splash/docs/monokai.html
*/ */
:root {
--pre-text-color: #f8f8f2;
--pre-background-color: #272822;
}
/* Background */ /* Background */
.chroma { .chroma {
color: #f8f8f2; color: #f8f8f2;

View File

@ -2,10 +2,6 @@
* Style: monokailight * Style: monokailight
* https://xyproto.github.io/splash/docs/monokailight.html * https://xyproto.github.io/splash/docs/monokailight.html
*/ */
:root {
--pre-text-color: #272822;
--pre-background-color: #fafafa;
}
/* Background */ /* Background */
.chroma { .chroma {

View File

@ -129,6 +129,8 @@
margin-top: var(--sidebar-element-separation); margin-top: var(--sidebar-element-separation);
margin-bottom: 0; margin-bottom: 0;
overflow-y: auto; overflow-y: auto;
flex-grow: 1;
font-size: 1.5rem;
@media (min-width: $on-desktop-large) { @media (min-width: $on-desktop-large) {
margin-top: 30px; margin-top: 30px;
@ -192,7 +194,6 @@
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
color: var(--body-text-color); color: var(--body-text-color);
font-size: 1.5rem;
@media (max-width: $on-desktop-large) { @media (max-width: $on-desktop-large) {
font-size: 1.4rem; font-size: 1.4rem;

View File

@ -19,6 +19,7 @@
@import "partials/pagination.scss"; @import "partials/pagination.scss";
@import "partials/sidebar.scss"; @import "partials/sidebar.scss";
@import "partials/base.scss"; @import "partials/base.scss";
@import "partials/darkmode.scss";
@import "partials/layout/archives.scss"; @import "partials/layout/archives.scss";
@import "partials/layout/article.scss"; @import "partials/layout/article.scss";
@import "partials/layout/list.scss"; @import "partials/layout/list.scss";

View File

@ -1,6 +1,18 @@
$defaultTagBackgrounds: #8ea885, #df7988, #0177b8, #ffb900, #6b69d6; $defaultTagBackgrounds: #8ea885, #df7988, #0177b8, #ffb900, #6b69d6;
$defaultTagColors: #fff, #fff, #fff, #fff, #fff; $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
[data-scheme="light"] {
--pre-text-color: #272822;
--pre-background-color: #fafafa;
@import "partials/highlight/light.scss";
}
[data-scheme="dark"] {
--pre-text-color: #f8f8f2;
--pre-background-color: #272822;
@import "partials/highlight/dark.scss";
}
/* /*
* Global style * Global style
*/ */
@ -13,7 +25,6 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
--main-top-padding: 50px; --main-top-padding: 50px;
} }
--body-background: #f5f5fa; --body-background: #f5f5fa;
--accent-color: #34495e; --accent-color: #34495e;
@ -25,7 +36,7 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
--section-separation: 40px; --section-separation: 40px;
@media (prefers-color-scheme: dark) { [data-scheme="dark"] {
--body-background: #303030; --body-background: #303030;
--accent-color: #ecf0f1; --accent-color: #ecf0f1;
--accent-color-darker: #bdc3c7; --accent-color-darker: #bdc3c7;
@ -72,7 +83,7 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
--small-card-padding: 25px 20px; --small-card-padding: 25px 20px;
} }
@media (prefers-color-scheme: dark) { [data-scheme="dark"] {
--card-background: #424242; --card-background: #424242;
--card-background-selected: rgba(255, 255, 255, 0.16); --card-background-selected: rgba(255, 255, 255, 0.16);
--card-text-color-main: rgba(255, 255, 255, 0.9); --card-text-color-main: rgba(255, 255, 255, 0.9);
@ -116,7 +127,7 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
--table-border-color: #dadada; --table-border-color: #dadada;
--tr-even-background-color: #efefee; --tr-even-background-color: #efefee;
@media (prefers-color-scheme: dark) { [data-scheme="dark"] {
--code-background-color: #272822; --code-background-color: #272822;
--code-text-color: rgba(255, 255, 255, 0.9); --code-text-color: rgba(255, 255, 255, 0.9);

76
assets/ts/darkmode.ts Normal file
View File

@ -0,0 +1,76 @@
type colorScheme = 'light' | 'dark' | 'auto';
class StackDarkMode {
private localStorageKey = 'StackColorScheme';
private currentScheme: colorScheme;
private systemPreferScheme: colorScheme;
constructor(toggleEl: HTMLElement) {
this.bindMatchMedia();
this.currentScheme = this.getSavedScheme();
this.setBodyClass();
this.bindClick(toggleEl);
}
private saveScheme() {
localStorage.setItem(this.localStorageKey, this.currentScheme);
}
private bindClick(toggleEl) {
toggleEl.addEventListener('click', (e) => {
if (this.isDark()) {
/// Disable dark mode
this.currentScheme = 'light';
}
else {
this.currentScheme = 'dark';
}
this.setBodyClass();
if (this.currentScheme == this.systemPreferScheme) {
/// Set to auto
this.currentScheme = 'auto';
}
this.saveScheme();
})
}
private isDark() {
return (this.currentScheme == 'dark' || this.currentScheme == 'auto' && this.preferDarkMode);
}
private setBodyClass() {
if (document.body.style.transition == '')
document.body.style.setProperty('transition', 'background-color .3s ease');
if (this.isDark()) {
document.body.dataset.scheme = 'dark';
}
else {
document.body.dataset.scheme = 'light';
}
}
private getSavedScheme(): colorScheme {
const savedScheme = localStorage.getItem(this.localStorageKey);
if (savedScheme == 'light' || savedScheme == 'dark' || savedScheme == 'auto') return savedScheme;
else return 'auto';
}
private bindMatchMedia() {
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (e.matches) {
this.systemPreferScheme = 'dark';
}
else {
this.systemPreferScheme = 'light';
}
this.setBodyClass();
});
}
}
export default StackDarkMode;

View File

@ -9,6 +9,7 @@ import StackGallery from "ts/gallery";
import { getColor } from 'ts/color'; import { getColor } from 'ts/color';
import menu from 'ts/menu'; import menu from 'ts/menu';
import createElement from 'ts/createElement'; import createElement from 'ts/createElement';
import StackDarkMode from 'ts/darkmode';
let Stack = { let Stack = {
init: () => { init: () => {
@ -52,6 +53,8 @@ let Stack = {
observer.observe(articleTile) observer.observe(articleTile)
} }
new StackDarkMode(document.getElementById('dark-mode-toggle'));
} }
} }

View File

@ -5,7 +5,27 @@
{{- block "head" . -}}{{ end }} {{- block "head" . -}}{{ end }}
</head> </head>
<body class="{{ block `body-class` . }}{{ end }}"> <body class="{{ block `body-class` . }}{{ end }}">
<div class="container flex on-phone--column align-items--flex-start {{ if .Site.Params.widgets.enabled }}extended{{ else }}compact{{ end }} {{ block `container-class` . }}{{end}}"> <script>
(function() {
const colorSchemeKey = 'StackColorScheme';
const colorSchemeItem = localStorage.getItem(colorSchemeKey);
const supportDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches === true;
if (colorSchemeItem == 'dark' || !colorSchemeItem && supportDarkMode || colorSchemeItem === 'auto' && supportDarkMode) {
/**
* Enable dark mode if:
* 1. If dark mode is set already (in local storage)
* 2. No color scheme preference is set in localstorage, and user's browser indicates preference for dark mode
* 3. Auto mode & prefere color scheme is dark
*/
document.body.dataset.scheme = 'dark';
} else {
document.body.dataset.scheme = 'light';
}
})();
</script>
<div class="container flex on-phone--column {{ if .Site.Params.widgets.enabled }}extended{{ else }}compact{{ end }} {{ block `container-class` . }}{{end}}">
{{ partial "sidebar/left.html" . }} {{ partial "sidebar/left.html" . }}
<main class="main full-width"> <main class="main full-width">
{{- block "main" . }}{{- end }} {{- block "main" . }}{{- end }}

View File

@ -1,4 +0,0 @@
{{- $light := resources.Get "css/highlight/light.css" | minify -}}
{{- $dark := resources.Get "css/highlight/dark.css" | minify -}}
<link rel="stylesheet" href="{{ $light.RelPermalink }}" media="(prefers-color-scheme: light)">
<link rel="stylesheet" href="{{ $dark.RelPermalink }}" media="(prefers-color-scheme: dark)">

View File

@ -1,4 +1,3 @@
{{ partialCached "footer/components/script.html" . }} {{ partialCached "footer/components/script.html" . }}
{{ partialCached "footer/components/custom-font.html" . }} {{ partialCached "footer/components/custom-font.html" . }}
{{ partialCached "footer/components/highlight.html" . }}
{{ partial "footer/custom.html" . }} {{ partial "footer/custom.html" . }}

View File

@ -45,5 +45,11 @@
</a> </a>
</li> </li>
{{ end }} {{ end }}
<li id="dark-mode-toggle">
{{ partial "helper/icon" "toggle-left" }}
{{ partial "helper/icon" "toggle-right" }}
<span>Dark Mode</span>
</li>
</ol> </ol>
</aside> </aside>