diff --git a/scripts/assets/moon.svg b/scripts/assets/moon.svg
new file mode 100644
index 0000000..80efdd2
--- /dev/null
+++ b/scripts/assets/moon.svg
@@ -0,0 +1,3 @@
+
diff --git a/scripts/assets/sun.svg b/scripts/assets/sun.svg
new file mode 100644
index 0000000..eeb7198
--- /dev/null
+++ b/scripts/assets/sun.svg
@@ -0,0 +1,3 @@
+
diff --git a/scripts/create.mjs b/scripts/create.mjs
index c5083f4..d7cab9e 100644
--- a/scripts/create.mjs
+++ b/scripts/create.mjs
@@ -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`;
diff --git a/scripts/nodes/header.mjs b/scripts/nodes/header.mjs
index 6d0e5a1..68f4e35 100644
--- a/scripts/nodes/header.mjs
+++ b/scripts/nodes/header.mjs
@@ -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',
diff --git a/scripts/style.css b/scripts/style.css
index cacf9e9..c5c636b 100644
--- a/scripts/style.css
+++ b/scripts/style.css
@@ -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;
}
diff --git a/scripts/utils/darkMode.mjs b/scripts/utils/darkMode.mjs
new file mode 100644
index 0000000..9f9ed25
--- /dev/null
+++ b/scripts/utils/darkMode.mjs
@@ -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,
+ }]
+ }
+ ];
+}