feat: add dark/light theme.

This commit is contained in:
jaywcjlove 2022-10-01 02:29:00 +08:00
parent cc877c2c3c
commit 53de582bb9
6 changed files with 198 additions and 121 deletions

3
scripts/assets/moon.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" class="dark" height="1em" width="1em">
<path d="M12 11.807A9.002 9.002 0 0 1 10.049 2a9.942 9.942 0 0 0-5.12 2.735c-3.905 3.905-3.905 10.237 0 14.142 3.906 3.906 10.237 3.905 14.143 0a9.946 9.946 0 0 0 2.735-5.119A9.003 9.003 0 0 1 12 11.807z"/>
</svg>

After

Width:  |  Height:  |  Size: 335 B

3
scripts/assets/sun.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="light" height="1em" width="1em">
<path d="M6.995 12c0 2.761 2.246 5.007 5.007 5.007s5.007-2.246 5.007-5.007-2.246-5.007-5.007-5.007S6.995 9.239 6.995 12zM11 19h2v3h-2zm0-17h2v3h-2zm-9 9h3v2H2zm17 0h3v2h-3zM5.637 19.778l-1.414-1.414 2.121-2.121 1.414 1.414zM16.242 6.344l2.122-2.122 1.414 1.414-2.122 2.122zM6.344 7.759 4.223 5.637l1.415-1.414 2.12 2.122zm13.434 10.605-1.414 1.414-2.122-2.122 1.414-1.414z"/>
</svg>

After

Width:  |  Height:  |  Size: 505 B

View File

@ -10,7 +10,7 @@ import { header } from './nodes/header.mjs';
import { rehypeUrls } from './utils/rehypeUrls.mjs';
import { tooltips } from './utils/tooltips.mjs';
import { homeCardIcons } from './utils/homeCardIcons.mjs';
import { getTocsTree } from './utils/getTocsTree.mjs'
import { getTocsTree } from './utils/getTocsTree.mjs';
const favicon = `data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20height%3D%221em%22%20width%3D%221em%22%3E%20%3Cpath%20opacity%3D%22.4%22%20d%3D%22m21.66%2010.44-.98%204.18c-.84%203.61-2.5%205.07-5.62%204.77-.5-.04-1.04-.13-1.62-.27l-1.68-.4c-4.17-.99-5.46-3.05-4.48-7.23l.98-4.19c.2-.85.44-1.59.74-2.2%201.17-2.42%203.16-3.07%206.5-2.28l1.67.39c4.19.98%205.47%203.05%204.49%207.23Z%22%20fill%3D%22%23777%22%2F%3E%20%3Cpath%20d%3D%22M15.06%2019.39c-.62.42-1.4.77-2.35%201.08l-1.58.52c-3.97%201.28-6.06.21-7.35-3.76L2.5%2013.28c-1.28-3.97-.22-6.07%203.75-7.35l1.58-.52c.41-.13.8-.24%201.17-.31-.3.61-.54%201.35-.74%202.2l-.98%204.19c-.98%204.18.31%206.24%204.48%207.23l1.68.4c.58.14%201.12.23%201.62.27Zm2.43-8.88c-.06%200-.12-.01-.19-.02l-4.85-1.23a.75.75%200%200%201%20.37-1.45l4.85%201.23a.748.748%200%200%201-.18%201.47Z%22%20fill%3D%22%23999%22%20%2F%3E%20%3Cpath%20d%3D%22M14.56%2013.89c-.06%200-.12-.01-.19-.02l-2.91-.74a.75.75%200%200%201%20.37-1.45l2.91.74c.4.1.64.51.54.91-.08.34-.38.56-.72.56Z%22%20fill%3D%22%23999%22%20%2F%3E%20%3C%2Fsvg%3E`;

View File

@ -1,18 +1,22 @@
import path from 'path';
import { github, editor } from './logo.mjs';
import { getSVGNode } from '../utils/getSVGNode.mjs';
import { darkMode } from '../utils/darkMode.mjs';
const ICONS_PATH = path.resolve(process.cwd(), 'scripts/assets/quickreference.svg')
export function header({ homePath, githubURL = '' }) {
const svgNode = getSVGNode(ICONS_PATH)
const data = [
{
menu: true,
href: githubURL,
target: '__blank',
label: '编辑',
children: [editor]
},
...darkMode(),
{
menu: true,
href: 'https://github.com/jaywcjlove/reference',
target: '__blank',
children: [github]
@ -59,7 +63,8 @@ export function header({ homePath, githubURL = '' }) {
properties: {
class: ['menu'],
},
children: data.map(({ href, label, children = [], ...props }) => {
children: data.map(({ href, label, menu, children = [], ...props }) => {
if (!menu) return { children, ...props };
const childs = {
type: 'element',
tagName: 'a',

View File

@ -6,9 +6,114 @@ body {
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";
}
[data-color-mode*='dark'] body .dark {
display: none;
}
[data-color-mode*='dark'] body .light {
display: block;
}
[data-color-mode*='light'] body .dark {
display: block;
}
[data-color-mode*='light'] body .light {
display: none;
}
[data-color-mode*='light'], [data-color-mode*='light'] body {
--color-prettylights-syntax-comment: #b1bac3;
--color-prettylights-syntax-constant: #0550ae;
--color-prettylights-syntax-entity: #8250df;
--color-prettylights-syntax-storage-modifier-import: #24292f;
--color-prettylights-syntax-entity-tag: #116329;
--color-prettylights-syntax-keyword: #cf222e;
--color-prettylights-syntax-string: #0a3069;
--color-prettylights-syntax-variable: #953800;
--color-prettylights-syntax-brackethighlighter-unmatched: #82071e;
--color-prettylights-syntax-invalid-illegal-text: #f6f8fa;
--color-prettylights-syntax-invalid-illegal-bg: #82071e;
--color-prettylights-syntax-carriage-return-text: #f6f8fa;
--color-prettylights-syntax-carriage-return-bg: #cf222e;
--color-prettylights-syntax-string-regexp: #116329;
--color-prettylights-syntax-markup-list: #3b2300;
--color-prettylights-syntax-markup-heading: #0550ae;
--color-prettylights-syntax-markup-italic: #24292f;
--color-prettylights-syntax-markup-bold: #24292f;
--color-prettylights-syntax-markup-deleted-text: #82071e;
--color-prettylights-syntax-markup-deleted-bg: #FFEBE9;
--color-prettylights-syntax-markup-inserted-text: #116329;
--color-prettylights-syntax-markup-inserted-bg: #dafbe1;
--color-prettylights-syntax-markup-changed-text: #953800;
--color-prettylights-syntax-markup-changed-bg: #ffd8b5;
--color-prettylights-syntax-markup-ignored-text: #eaeef2;
--color-prettylights-syntax-markup-ignored-bg: #0550ae;
--color-prettylights-syntax-meta-diff-range: #8250df;
--color-prettylights-syntax-brackethighlighter-angle: #57606a;
--color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f;
--color-prettylights-syntax-constant-other-reference-link: #0a3069;
--color-fg-default: #24292f;
--color-fg-muted: #57606a;
--color-fg-subtle: #6e7781;
--color-canvas-default: #f1f5f9;
--color-canvas-subtle: #fff;
--color-bg-subtle: #f8f9fa;
--color-border-default: #d0d7de;
--color-border-muted: #ececec94;
--color-neutral-muted: rgba(175,184,193,0.2);
--color-accent-fg: #0969da;
--color-accent-emphasis: #0969da;
--color-attention-subtle: #fff8c5;
--color-danger-fg: #cf222e;
}
[data-color-mode*='dark'], [data-color-mode*='dark'] body {
--color-prettylights-syntax-comment: #8b949e;
--color-prettylights-syntax-constant: #79c0ff;
--color-prettylights-syntax-entity: #d2a8ff;
--color-prettylights-syntax-storage-modifier-import: #c9d1d9;
--color-prettylights-syntax-entity-tag: #7ee787;
--color-prettylights-syntax-keyword: #ff7b72;
--color-prettylights-syntax-string: #a5d6ff;
--color-prettylights-syntax-variable: #ffa657;
--color-prettylights-syntax-brackethighlighter-unmatched: #f85149;
--color-prettylights-syntax-invalid-illegal-text: #f0f6fc;
--color-prettylights-syntax-invalid-illegal-bg: #8e1519;
--color-prettylights-syntax-carriage-return-text: #f0f6fc;
--color-prettylights-syntax-carriage-return-bg: #b62324;
--color-prettylights-syntax-string-regexp: #7ee787;
--color-prettylights-syntax-markup-list: #f2cc60;
--color-prettylights-syntax-markup-heading: #1f6feb;
--color-prettylights-syntax-markup-italic: #c9d1d9;
--color-prettylights-syntax-markup-bold: #c9d1d9;
--color-prettylights-syntax-markup-deleted-text: #ffdcd7;
--color-prettylights-syntax-markup-deleted-bg: #67060c;
--color-prettylights-syntax-markup-inserted-text: #aff5b4;
--color-prettylights-syntax-markup-inserted-bg: #033a16;
--color-prettylights-syntax-markup-changed-text: #ffdfb6;
--color-prettylights-syntax-markup-changed-bg: #5a1e02;
--color-prettylights-syntax-markup-ignored-text: #c9d1d9;
--color-prettylights-syntax-markup-ignored-bg: #1158c7;
--color-prettylights-syntax-meta-diff-range: #d2a8ff;
--color-prettylights-syntax-brackethighlighter-angle: #8b949e;
--color-prettylights-syntax-sublimelinter-gutter-mark: #484f58;
--color-prettylights-syntax-constant-other-reference-link: #a5d6ff;
--color-fg-default: #c9d1d9;
--color-fg-muted: #8b949e;
--color-fg-subtle: #94a3b8;
--color-canvas-default: #0f172a;
--color-canvas-subtle: #1e293b;
--color-bg-subtle: rgb(15 23 42/0.3);
--color-border-default: #404f5f;
--color-border-muted: rgb(51 65 85/0.5);
--color-neutral-muted: rgb(51 65 85/0.3);
--color-accent-fg: #58a6ff;
--color-accent-emphasis: #1f6feb;
--color-attention-subtle: rgba(187,128,9,0.15);
--color-danger-fg: #f85149;
}
body {
background-color: rgb(15 23 42/1);
color: rgb(203 213 225/1);
color: var(--color-fg-default);
background-color: var(--color-canvas-default);
}
*, ::before, ::after {
@ -44,13 +149,13 @@ table {
}
table td:not(:last-child)>code, table td:not(:last-child)>del>code, ul li > code, kbd {
background-color: rgb(51 65 85/0.5);
color: rgb(203 213 225/1);
background-color: var(--color-neutral-muted);
color: var(--color-fg-subtle);
box-shadow: 0 0 #0000, 0 0 #0000, 0 0 #0000;
letter-spacing: 0.075rem;
padding: 0.1em 0.54em;
border: 1px solid rgb(204,204,204);
border-color: rgb(51 65 85/1);
border: 1px solid var(--color-border-muted);
border-color: var(--color-border-default);
line-height: 1.5;
font-family: Arial,Helvetica,sans-serif;
font-size: 12px;
@ -60,7 +165,7 @@ table td:not(:last-child)>code, table td:not(:last-child)>del>code, ul li > code
table tr+tr {
border-top: solid 1px #ececec94;
border-color: rgb(51 65 85/0.5);
border-color: var(--color-border-muted);
}
table td, table th {
padding: 9px 14px;
@ -86,8 +191,7 @@ table td:first-child>code {
}
table td:first-child>del>code {
text-decoration: inherit;
--text-opacity: 1;
color: rgb(244 67 54/var(--text-opacity));
color: var(--color-danger-fg);
}
table.show-header thead {
@ -251,11 +355,11 @@ a.text-grey {
font-size: 40px;
}
.header-nav .menu a:hover {
background-color: rgb(30 41 59/1);
.header-nav .menu a:hover, .header-nav .menu button:hover {
background-color: var(--color-neutral-muted);
}
.header-nav .menu a {
.header-nav .menu a, .header-nav .menu button {
padding-left: 0.75rem;
padding-right: 0.75rem;
padding-top: 0.5rem;
@ -270,9 +374,21 @@ a.text-grey {
.header-nav .menu a > span {
font-size: 0.9rem;
}
.header-nav .menu button {
font-family: inherit;
font-size: 100%;
font-weight: inherit;
line-height: inherit;
-webkit-appearance: button;
background-color: transparent;
background-image: none;
color: var(--color-fg-default);
cursor: pointer;
font-size: 18px;
}
.header-nav a, .header-nav a:visited {
color: rgb(209 213 219/1);
color: var(--color-fg-default);
line-height: 1.2;
gap: 0.3rem;
}
@ -284,7 +400,7 @@ a.text-grey {
}
.wrap-header.h1wrap .wrap-body {
color: rgb(71 85 105/1);
color: var(--color-fg-subtle);
}
.wrap-header.h1wrap > h1 {
@ -321,8 +437,7 @@ a.text-grey {
body:not(.home) .h2wrap > h2 a::after {
content: '#';
padding-right: 0.5rem;
--tw-text-opacity: 1;
color: rgb(16 185 129/var(--tw-text-opacity));
color: rgb(16 185 129/1);
}
.wrap-header.h3wrap {
@ -358,23 +473,25 @@ body:not(.home) .h2wrap > h2 a::after {
padding-right: 1rem;
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: rgb(148 163 184/1);
background-color: rgb(15 23 42/0.3);
color: var(--color-fg-subtle);
background-color: var(--color-bg-subtle);
}
.wrap-header.h3wrap > .wrap-body p:first-child:before {
background-color: rgb(15 23 42/0.3);
background-color: var(--color-bg-subtle);
color: rgb(30 41 59/0);
content: '-';
line-height: 1.75rem;
top: -4px;
line-height: 1.50rem;
top: 0;
position: absolute;
left: 0px;
width: 100%;
border-radius: 0.5rem 0.5rem 0 0;
}
.wrap-header.h3wrap > .wrap-body p:not(:first-child):last-child {
margin-top: auto;
border-radius: 0 0 0.5rem 0.5rem;
}
.wrap-header.h3wrap > .wrap-body {
@ -386,9 +503,9 @@ body:not(.home) .h2wrap > h2 a::after {
}
.h4wrap > h4 {
border-color: rgb(51 65 85/0.5);
background-color: rgb(51 65 85/0.3);
color: rgb(203 213 225/1);
border-color: transparent;
background-color: var(--color-neutral-muted);
color: var(--color-fg-default);
margin: 0px;
border-top-width: 1px;
@ -419,7 +536,7 @@ body:not(.home) .h2wrap > h2 a::after {
padding: 9px;
padding-left: 26px;
position: relative;
border-bottom: solid 1px rgb(51 65 85/0.5);
border-bottom: solid 1px var(--color-border-muted);
}
.h2wrap-body ul:not(.style-none)>li::before {
@ -449,7 +566,7 @@ body:not(.home) .h2wrap > h2 a::after {
}
.h3wrap hr {
border-bottom: 1px solid #475060;
border-bottom: 1px solid var(--color-border-default);
}
.h2wrap-body {
@ -460,8 +577,7 @@ body:not(.home) .h2wrap > h2 a::after {
}
.h2wrap-body > .wrap {
background-color: #1e293b;
color: rgb(203 213 225/1);
background-color: var(--color-canvas-subtle);
position: relative;
display: flex;
flex-direction: column;
@ -554,96 +670,6 @@ body:not(.home) .h2wrap > h2 a::after {
opacity: 1;
}
[data-color-mode*='light'], [data-color-mode*='light'] body {
--color-prettylights-syntax-comment: #6e7781;
--color-prettylights-syntax-constant: #0550ae;
--color-prettylights-syntax-entity: #8250df;
--color-prettylights-syntax-storage-modifier-import: #24292f;
--color-prettylights-syntax-entity-tag: #116329;
--color-prettylights-syntax-keyword: #cf222e;
--color-prettylights-syntax-string: #0a3069;
--color-prettylights-syntax-variable: #953800;
--color-prettylights-syntax-brackethighlighter-unmatched: #82071e;
--color-prettylights-syntax-invalid-illegal-text: #f6f8fa;
--color-prettylights-syntax-invalid-illegal-bg: #82071e;
--color-prettylights-syntax-carriage-return-text: #f6f8fa;
--color-prettylights-syntax-carriage-return-bg: #cf222e;
--color-prettylights-syntax-string-regexp: #116329;
--color-prettylights-syntax-markup-list: #3b2300;
--color-prettylights-syntax-markup-heading: #0550ae;
--color-prettylights-syntax-markup-italic: #24292f;
--color-prettylights-syntax-markup-bold: #24292f;
--color-prettylights-syntax-markup-deleted-text: #82071e;
--color-prettylights-syntax-markup-deleted-bg: #FFEBE9;
--color-prettylights-syntax-markup-inserted-text: #116329;
--color-prettylights-syntax-markup-inserted-bg: #dafbe1;
--color-prettylights-syntax-markup-changed-text: #953800;
--color-prettylights-syntax-markup-changed-bg: #ffd8b5;
--color-prettylights-syntax-markup-ignored-text: #eaeef2;
--color-prettylights-syntax-markup-ignored-bg: #0550ae;
--color-prettylights-syntax-meta-diff-range: #8250df;
--color-prettylights-syntax-brackethighlighter-angle: #57606a;
--color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f;
--color-prettylights-syntax-constant-other-reference-link: #0a3069;
--color-fg-default: #24292f;
--color-fg-muted: #57606a;
--color-fg-subtle: #6e7781;
--color-canvas-default: #ffffff;
--color-canvas-subtle: #f6f8fa;
--color-border-default: #d0d7de;
--color-border-muted: hsla(210,18%,87%,1);
--color-neutral-muted: rgba(175,184,193,0.2);
--color-accent-fg: #0969da;
--color-accent-emphasis: #0969da;
--color-attention-subtle: #fff8c5;
--color-danger-fg: #cf222e;
}
[data-color-mode*='dark'], [data-color-mode*='dark'] body {
--color-prettylights-syntax-comment: #8b949e;
--color-prettylights-syntax-constant: #79c0ff;
--color-prettylights-syntax-entity: #d2a8ff;
--color-prettylights-syntax-storage-modifier-import: #c9d1d9;
--color-prettylights-syntax-entity-tag: #7ee787;
--color-prettylights-syntax-keyword: #ff7b72;
--color-prettylights-syntax-string: #a5d6ff;
--color-prettylights-syntax-variable: #ffa657;
--color-prettylights-syntax-brackethighlighter-unmatched: #f85149;
--color-prettylights-syntax-invalid-illegal-text: #f0f6fc;
--color-prettylights-syntax-invalid-illegal-bg: #8e1519;
--color-prettylights-syntax-carriage-return-text: #f0f6fc;
--color-prettylights-syntax-carriage-return-bg: #b62324;
--color-prettylights-syntax-string-regexp: #7ee787;
--color-prettylights-syntax-markup-list: #f2cc60;
--color-prettylights-syntax-markup-heading: #1f6feb;
--color-prettylights-syntax-markup-italic: #c9d1d9;
--color-prettylights-syntax-markup-bold: #c9d1d9;
--color-prettylights-syntax-markup-deleted-text: #ffdcd7;
--color-prettylights-syntax-markup-deleted-bg: #67060c;
--color-prettylights-syntax-markup-inserted-text: #aff5b4;
--color-prettylights-syntax-markup-inserted-bg: #033a16;
--color-prettylights-syntax-markup-changed-text: #ffdfb6;
--color-prettylights-syntax-markup-changed-bg: #5a1e02;
--color-prettylights-syntax-markup-ignored-text: #c9d1d9;
--color-prettylights-syntax-markup-ignored-bg: #1158c7;
--color-prettylights-syntax-meta-diff-range: #d2a8ff;
--color-prettylights-syntax-brackethighlighter-angle: #8b949e;
--color-prettylights-syntax-sublimelinter-gutter-mark: #484f58;
--color-prettylights-syntax-constant-other-reference-link: #a5d6ff;
--color-fg-default: #c9d1d9;
--color-fg-muted: #8b949e;
--color-fg-subtle: #484f58;
--color-canvas-default: #0d1117;
--color-canvas-subtle: #161b22;
--color-border-default: #30363d;
--color-border-muted: #21262d;
--color-neutral-muted: rgba(110,118,129,0.4);
--color-accent-fg: #58a6ff;
--color-accent-emphasis: #1f6feb;
--color-attention-subtle: rgba(187,128,9,0.15);
--color-danger-fg: #f85149;
}
/* 代码高亮 Start */
.token.comment, .token.prolog, .token.doctype, .token.cdata {
color: var(--color-prettylights-syntax-comment);
@ -718,7 +744,7 @@ body:not(.home) .h2wrap > h2 a::after {
.footer-wrap {
margin-top: 3.5rem;
color: rgb(100 116 139/1);
background-color: rgb(30 41 59/1);
background-color: var(--color-canvas-subtle);
text-align: center;
}

View File

@ -0,0 +1,40 @@
import path from 'path';
import { getSVGNode } from './getSVGNode.mjs';
const scripts = `
const button = document.querySelector('#darkMode');
button.onclick = () => {
const theme = document.documentElement.dataset.colorMode;
document.documentElement.setAttribute('data-color-mode', theme === 'light' ? 'dark' : 'light');
}
`;
const ICONS_PATH = path.resolve(process.cwd(), 'scripts/assets');
export function darkMode() {
const iconSunPath = path.resolve(ICONS_PATH, `sun.svg`);
const iconMoonPath = path.resolve(ICONS_PATH, `moon.svg`);
const sunNode = getSVGNode(iconSunPath)
const moonNode = getSVGNode(iconMoonPath)
return [
{
type: 'element',
tagName: 'button',
properties: {
id: 'darkMode',
type: 'button'
},
children: [
...sunNode,
...moonNode
]
}, {
type: 'element',
tagName: 'script',
children: [{
type: 'text',
value: scripts,
}]
}
];
}