feat(darkmode): add <select> for color scheme

Fix highlight style
This commit is contained in:
Jimmy Cai 2020-09-19 23:25:49 +02:00
parent 12e3e668b7
commit 6ef674bec7
No known key found for this signature in database
GPG Key ID: 3EA408E527F37B18
12 changed files with 899 additions and 84 deletions

View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brightness" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z"/>
<circle cx="12" cy="12" r="9" />
<line x1="12" y1="3" x2="12" y2="21" />
<path d="M12 9l4.65 -4.65" />
<path d="M12 14.3l7.37 -7.37" />
<path d="M12 19.6l8.85 -8.85" />
</svg>

After

Width:  |  Height:  |  Size: 460 B

View File

@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-toggle-left" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z"/>
<circle cx="8" cy="12" r="2" />
<rect x="2" y="6" width="20" height="12" rx="6" />
</svg>

Before

Width:  |  Height:  |  Size: 369 B

View File

@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-toggle-right" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z"/>
<circle cx="16" cy="12" r="2" />
<rect x="2" y="6" width="20" height="12" rx="6" />
</svg>

Before

Width:  |  Height:  |  Size: 371 B

View File

@ -0,0 +1,385 @@
/*
* Style: monokai
* https://xyproto.github.io/splash/docs/monokai.html
*/
/* Background */
.chroma {
color: #f8f8f2;
background-color: #272822
}
/* Other */
.chroma .x {}
/* Error */
.chroma .err {
color: #960050;
background-color: #1e0010
}
/* LineTableTD */
.chroma .lntd {
vertical-align: top;
padding: 0;
margin: 0;
border: 0;
}
/* LineTable */
.chroma .lntable {
border-spacing: 0;
padding: 0;
margin: 0;
border: 0;
width: auto;
overflow: auto;
display: block;
}
/* LineHighlight */
.chroma .hl {
display: block;
width: 100%;
background-color: #ffffcc
}
/* LineNumbersTable */
.chroma .lnt {
margin-right: 0.4em;
padding: 0 0.4em 0 0.4em;
color: #7f7f7f
}
/* LineNumbers */
.chroma .ln {
margin-right: 0.4em;
padding: 0 0.4em 0 0.4em;
color: #7f7f7f
}
/* Keyword */
.chroma .k {
color: #66d9ef
}
/* KeywordConstant */
.chroma .kc {
color: #66d9ef
}
/* KeywordDeclaration */
.chroma .kd {
color: #66d9ef
}
/* KeywordNamespace */
.chroma .kn {
color: #f92672
}
/* KeywordPseudo */
.chroma .kp {
color: #66d9ef
}
/* KeywordReserved */
.chroma .kr {
color: #66d9ef
}
/* KeywordType */
.chroma .kt {
color: #66d9ef
}
/* Name */
.chroma .n {}
/* NameAttribute */
.chroma .na {
color: #a6e22e
}
/* NameBuiltin */
.chroma .nb {}
/* NameBuiltinPseudo */
.chroma .bp {}
/* NameClass */
.chroma .nc {
color: #a6e22e
}
/* NameConstant */
.chroma .no {
color: #66d9ef
}
/* NameDecorator */
.chroma .nd {
color: #a6e22e
}
/* NameEntity */
.chroma .ni {}
/* NameException */
.chroma .ne {
color: #a6e22e
}
/* NameFunction */
.chroma .nf {
color: #a6e22e
}
/* NameFunctionMagic */
.chroma .fm {}
/* NameLabel */
.chroma .nl {}
/* NameNamespace */
.chroma .nn {}
/* NameOther */
.chroma .nx {
color: #a6e22e
}
/* NameProperty */
.chroma .py {}
/* NameTag */
.chroma .nt {
color: #f92672
}
/* NameVariable */
.chroma .nv {}
/* NameVariableClass */
.chroma .vc {}
/* NameVariableGlobal */
.chroma .vg {}
/* NameVariableInstance */
.chroma .vi {}
/* NameVariableMagic */
.chroma .vm {}
/* Literal */
.chroma .l {
color: #ae81ff
}
/* LiteralDate */
.chroma .ld {
color: #e6db74
}
/* LiteralString */
.chroma .s {
color: #e6db74
}
/* LiteralStringAffix */
.chroma .sa {
color: #e6db74
}
/* LiteralStringBacktick */
.chroma .sb {
color: #e6db74
}
/* LiteralStringChar */
.chroma .sc {
color: #e6db74
}
/* LiteralStringDelimiter */
.chroma .dl {
color: #e6db74
}
/* LiteralStringDoc */
.chroma .sd {
color: #e6db74
}
/* LiteralStringDouble */
.chroma .s2 {
color: #e6db74
}
/* LiteralStringEscape */
.chroma .se {
color: #ae81ff
}
/* LiteralStringHeredoc */
.chroma .sh {
color: #e6db74
}
/* LiteralStringInterpol */
.chroma .si {
color: #e6db74
}
/* LiteralStringOther */
.chroma .sx {
color: #e6db74
}
/* LiteralStringRegex */
.chroma .sr {
color: #e6db74
}
/* LiteralStringSingle */
.chroma .s1 {
color: #e6db74
}
/* LiteralStringSymbol */
.chroma .ss {
color: #e6db74
}
/* LiteralNumber */
.chroma .m {
color: #ae81ff
}
/* LiteralNumberBin */
.chroma .mb {
color: #ae81ff
}
/* LiteralNumberFloat */
.chroma .mf {
color: #ae81ff
}
/* LiteralNumberHex */
.chroma .mh {
color: #ae81ff
}
/* LiteralNumberInteger */
.chroma .mi {
color: #ae81ff
}
/* LiteralNumberIntegerLong */
.chroma .il {
color: #ae81ff
}
/* LiteralNumberOct */
.chroma .mo {
color: #ae81ff
}
/* Operator */
.chroma .o {
color: #f92672
}
/* OperatorWord */
.chroma .ow {
color: #f92672
}
/* Punctuation */
.chroma .p {}
/* Comment */
.chroma .c {
color: #75715e
}
/* CommentHashbang */
.chroma .ch {
color: #75715e
}
/* CommentMultiline */
.chroma .cm {
color: #75715e
}
/* CommentSingle */
.chroma .c1 {
color: #75715e
}
/* CommentSpecial */
.chroma .cs {
color: #75715e
}
/* CommentPreproc */
.chroma .cp {
color: #75715e
}
/* CommentPreprocFile */
.chroma .cpf {
color: #75715e
}
/* Generic */
.chroma .g {}
/* GenericDeleted */
.chroma .gd {
color: #f92672
}
/* GenericEmph */
.chroma .ge {
font-style: italic
}
/* GenericError */
.chroma .gr {}
/* GenericHeading */
.chroma .gh {}
/* GenericInserted */
.chroma .gi {
color: #a6e22e
}
/* GenericOutput */
.chroma .go {}
/* GenericPrompt */
.chroma .gp {}
/* GenericStrong */
.chroma .gs {
font-weight: bold
}
/* GenericSubheading */
.chroma .gu {
color: #75715e
}
/* GenericTraceback */
.chroma .gt {}
/* GenericUnderline */
.chroma .gl {}
/* TextWhitespace */
.chroma .w {}

View File

@ -0,0 +1,407 @@
/*
* Style: monokailight
* https://xyproto.github.io/splash/docs/monokailight.html
*/
/* Background */
.chroma {
color: #272822;
background-color: #fafafa;
}
/* Other */
.chroma .x {}
/* Error */
.chroma .err {
color: #960050;
background-color: #1e0010
}
/* LineTableTD */
.chroma .lntd {
vertical-align: top;
padding: 0;
margin: 0;
border: 0;
}
/* LineTable */
.chroma .lntable {
border-spacing: 0;
padding: 0;
margin: 0;
border: 0;
width: auto;
overflow: auto;
display: block;
}
/* LineHighlight */
.chroma .hl {
display: block;
width: 100%;
background-color: #ffffcc
}
/* LineNumbersTable */
.chroma .lnt {
margin-right: 0.4em;
padding: 0 0.4em 0 0.4em;
color: #7f7f7f
}
/* LineNumbers */
.chroma .ln {
margin-right: 0.4em;
padding: 0 0.4em 0 0.4em;
color: #7f7f7f
}
/* Keyword */
.chroma .k {
color: #00a8c8
}
/* KeywordConstant */
.chroma .kc {
color: #00a8c8
}
/* KeywordDeclaration */
.chroma .kd {
color: #00a8c8
}
/* KeywordNamespace */
.chroma .kn {
color: #f92672
}
/* KeywordPseudo */
.chroma .kp {
color: #00a8c8
}
/* KeywordReserved */
.chroma .kr {
color: #00a8c8
}
/* KeywordType */
.chroma .kt {
color: #00a8c8
}
/* Name */
.chroma .n {
color: #111111
}
/* NameAttribute */
.chroma .na {
color: #75af00
}
/* NameBuiltin */
.chroma .nb {
color: #111111
}
/* NameBuiltinPseudo */
.chroma .bp {
color: #111111
}
/* NameClass */
.chroma .nc {
color: #75af00
}
/* NameConstant */
.chroma .no {
color: #00a8c8
}
/* NameDecorator */
.chroma .nd {
color: #75af00
}
/* NameEntity */
.chroma .ni {
color: #111111
}
/* NameException */
.chroma .ne {
color: #75af00
}
/* NameFunction */
.chroma .nf {
color: #75af00
}
/* NameFunctionMagic */
.chroma .fm {
color: #111111
}
/* NameLabel */
.chroma .nl {
color: #111111
}
/* NameNamespace */
.chroma .nn {
color: #111111
}
/* NameOther */
.chroma .nx {
color: #75af00
}
/* NameProperty */
.chroma .py {
color: #111111
}
/* NameTag */
.chroma .nt {
color: #f92672
}
/* NameVariable */
.chroma .nv {
color: #111111
}
/* NameVariableClass */
.chroma .vc {
color: #111111
}
/* NameVariableGlobal */
.chroma .vg {
color: #111111
}
/* NameVariableInstance */
.chroma .vi {
color: #111111
}
/* NameVariableMagic */
.chroma .vm {
color: #111111
}
/* Literal */
.chroma .l {
color: #ae81ff
}
/* LiteralDate */
.chroma .ld {
color: #d88200
}
/* LiteralString */
.chroma .s {
color: #d88200
}
/* LiteralStringAffix */
.chroma .sa {
color: #d88200
}
/* LiteralStringBacktick */
.chroma .sb {
color: #d88200
}
/* LiteralStringChar */
.chroma .sc {
color: #d88200
}
/* LiteralStringDelimiter */
.chroma .dl {
color: #d88200
}
/* LiteralStringDoc */
.chroma .sd {
color: #d88200
}
/* LiteralStringDouble */
.chroma .s2 {
color: #d88200
}
/* LiteralStringEscape */
.chroma .se {
color: #8045ff
}
/* LiteralStringHeredoc */
.chroma .sh {
color: #d88200
}
/* LiteralStringInterpol */
.chroma .si {
color: #d88200
}
/* LiteralStringOther */
.chroma .sx {
color: #d88200
}
/* LiteralStringRegex */
.chroma .sr {
color: #d88200
}
/* LiteralStringSingle */
.chroma .s1 {
color: #d88200
}
/* LiteralStringSymbol */
.chroma .ss {
color: #d88200
}
/* LiteralNumber */
.chroma .m {
color: #ae81ff
}
/* LiteralNumberBin */
.chroma .mb {
color: #ae81ff
}
/* LiteralNumberFloat */
.chroma .mf {
color: #ae81ff
}
/* LiteralNumberHex */
.chroma .mh {
color: #ae81ff
}
/* LiteralNumberInteger */
.chroma .mi {
color: #ae81ff
}
/* LiteralNumberIntegerLong */
.chroma .il {
color: #ae81ff
}
/* LiteralNumberOct */
.chroma .mo {
color: #ae81ff
}
/* Operator */
.chroma .o {
color: #f92672
}
/* OperatorWord */
.chroma .ow {
color: #f92672
}
/* Punctuation */
.chroma .p {
color: #111111
}
/* Comment */
.chroma .c {
color: #75715e
}
/* CommentHashbang */
.chroma .ch {
color: #75715e
}
/* CommentMultiline */
.chroma .cm {
color: #75715e
}
/* CommentSingle */
.chroma .c1 {
color: #75715e
}
/* CommentSpecial */
.chroma .cs {
color: #75715e
}
/* CommentPreproc */
.chroma .cp {
color: #75715e
}
/* CommentPreprocFile */
.chroma .cpf {
color: #75715e
}
/* Generic */
.chroma .g {}
/* GenericDeleted */
.chroma .gd {}
/* GenericEmph */
.chroma .ge {
font-style: italic
}
/* GenericError */
.chroma .gr {}
/* GenericHeading */
.chroma .gh {}
/* GenericInserted */
.chroma .gi {}
/* GenericOutput */
.chroma .go {}
/* GenericPrompt */
.chroma .gp {}
/* GenericStrong */
.chroma .gs {
font-weight: bold
}
/* GenericSubheading */
.chroma .gu {}
/* GenericTraceback */
.chroma .gt {}
/* GenericUnderline */
.chroma .gl {}
/* TextWhitespace */
.chroma .w {}

View File

@ -207,29 +207,29 @@
}
}
.theme-dark {
#dark-mode-toggle {
[data-scheme="dark"] {
#schemeSelectItem {
color: var(--accent-color);
font-weight: 700;
.icon-tabler-toggle-left {
display: none;
}
.icon-tabler-toggle-right {
display: unset;
}
}
}
#dark-mode-toggle {
#schemeSelectItem {
margin-top: auto;
color: var(--body-text-color);
display: flex;
align-items: center;
cursor: pointer;
}
.icon-tabler-toggle-right {
display: none;
#schemeSelect {
background: transparent;
border: 0;
color: var(--body-text-color);
padding: 0;
appearance: none;
option {
color: var(--card-text-color-main);
background-color: var(--card-background);
}
}

View File

@ -1,6 +1,18 @@
$defaultTagBackgrounds: #8ea885, #df7988, #0177b8, #ffb900, #6b69d6;
$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
*/
@ -20,7 +32,7 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
--section-separation: 40px;
.theme-dark {
[data-scheme="dark"] {
--body-background: #303030;
--accent-color: #ecf0f1;
--accent-color-darker: #bdc3c7;
@ -64,7 +76,7 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
--small-card-padding: 25px;
.theme-dark {
[data-scheme="dark"] {
--card-background: #424242;
--card-background-selected: rgba(255, 255, 255, 0.16);
--card-text-color-main: rgba(255, 255, 255, 0.9);
@ -108,7 +120,7 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
--table-border-color: #dadada;
--tr-even-background-color: #efefee;
.theme-dark {
[data-scheme="dark"] {
--code-background-color: #272822;
--code-text-color: rgba(255, 255, 255, 0.9);

View File

@ -1,58 +1,68 @@
export default () => {
const toggleDarkMode = document.getElementById('dark-mode-toggle');
const darkModeKey = 'StackDarkMode';
const darkModeItem = localStorage.getItem(darkModeKey);
const darkModeEnabled = localStorage.getItem(darkModeKey) === 'true';
const supportDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches === true;
const mql = window.matchMedia('(prefers-color-scheme: dark)');
type colorScheme = 'light' | 'dark' | 'auto';
let darkMode = false;
const colorSchemeKey = 'StackColorScheme';
const mql = window.matchMedia('(prefers-color-scheme: dark)');
const schemeSelect = document.getElementById('schemeSelect') as HTMLSelectElement;
if (darkModeItem && darkModeEnabled || !darkModeItem && 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
*/
darkMode = true;
}
const supportDarkMode = () => {
return window.matchMedia('(prefers-color-scheme: dark)').matches === true;
}
const setBodyClass = () => {
if (darkMode) {
document.body.classList.add('theme-dark');
const saveScheme = (scheme: colorScheme) => {
localStorage.setItem(colorSchemeKey, scheme);
}
const getScheme = () => {
return localStorage.getItem(colorSchemeKey) as colorScheme;
};
const setScheme = (scheme: colorScheme) => {
if (scheme === 'auto') {
if (supportDarkMode()) {
document.body.dataset.scheme = 'dark';
}
else {
document.body.classList.remove('theme-dark');
document.body.dataset.scheme = 'light';
}
}
const mediaQueryListener = (e) => {
darkMode = e.matches;
setBodyClass();
else {
document.body.dataset.scheme = scheme;
}
}
let listening = false;
if (!darkModeItem) {
/**
* If no dark mode preference is set in local storage, listen to browser color preference change
*/
mql.addEventListener('change', mediaQueryListener);
listening = true;
}
const mediaQueryListener = (e) => {
setScheme('auto');
}
export default () => {
document.body.style.setProperty('transition', 'background-color .3s ease');
toggleDarkMode.addEventListener('click', (e) => {
darkMode = !darkMode;
setBodyClass();
localStorage.setItem(darkModeKey, darkMode.toString());
if (!getScheme()) {
/// First time visiting
setScheme('auto');
saveScheme('auto')
mql.addEventListener('change', mediaQueryListener);
}
else {
setScheme(getScheme());
}
if (listening) {
schemeSelect.value = getScheme();
schemeSelect.addEventListener('change', (e) => {
const value = schemeSelect.value as colorScheme;
setScheme(value);
saveScheme(value);
if (value === 'auto') {
mql.addEventListener('change', mediaQueryListener);
}
else {
/**
* Remove listener once user set color preference in website
*/
mql.removeEventListener('change', mediaQueryListener);
listening = false;
}
})
}

View File

@ -4,13 +4,19 @@
<body class="{{ block `body-class` . }}{{ end }}">
<script>
(function() {
const darkModeKey = 'StackDarkMode';
const darkModeItem = localStorage.getItem(darkModeKey);
const darkModeEnabled = localStorage.getItem(darkModeKey) === 'true';
const colorSchemeKey = 'StackColorScheme';
const colorSchemeItem = localStorage.getItem(colorSchemeKey);
const supportDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches === true;
if(darkModeItem && darkModeEnabled || !darkModeItem && supportDarkMode){
document.body.classList.add('theme-dark');
if (colorSchemeItem && 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
*/
document.body.dataset.scheme = 'dark';
} else {
document.body.dataset.scheme = 'light';
}
})();
</script>

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.Permalink }}" media="(prefers-color-scheme: light)">
<link rel="stylesheet" href="{{ $dark.Permalink }}" media="(prefers-color-scheme: dark)">

View File

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

View File

@ -40,10 +40,14 @@
</li>
{{ end }}
<li id="dark-mode-toggle">
{{ (resources.Get "icons/toggle-left.svg").Content | safeHTML }}
{{ (resources.Get "icons/toggle-right.svg").Content | safeHTML }}
<span>{{ T "darkModeToggle" }}</span>
<li id="schemeSelectItem">
{{ (resources.Get "icons/brightness.svg").Content | safeHTML }}
<select id="schemeSelect">
<option value="light">Light Theme</option>
<option value="dark">Dark Theme</option>
<option value="auto">Auto</option>
</select>
</li>
</ol>
</aside>