czon 0.4.2 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ssg/ContentPage.js +29 -5
- package/dist/ssg/IndexPage.js +15 -1
- package/dist/ssg/RedirectPage.js +15 -1
- package/dist/ssg/RootPage.js +15 -1
- package/dist/ssg/components/CZONHeader.js +4 -1
- package/dist/ssg/components/DarkModeSwitch.js +149 -0
- package/dist/ssg/components/LanguageSwitch.js +54 -8
- package/dist/ssg/style.js +94 -51
- package/dist/utils/convertMarkdownToHtml.js +1 -1
- package/package.json +1 -1
package/dist/ssg/ContentPage.js
CHANGED
|
@@ -31,7 +31,21 @@ const ContentPage = props => {
|
|
|
31
31
|
react_1.default.createElement("title", null, title),
|
|
32
32
|
react_1.default.createElement("meta", { name: "description", content: `tags: ${tags.join(', ')}` }),
|
|
33
33
|
react_1.default.createElement("script", { src: "https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4", defer: true }),
|
|
34
|
-
react_1.default.createElement("style", null, style_1.style)
|
|
34
|
+
react_1.default.createElement("style", null, style_1.style),
|
|
35
|
+
react_1.default.createElement("script", { dangerouslySetInnerHTML: {
|
|
36
|
+
__html: `
|
|
37
|
+
(function() {
|
|
38
|
+
const saved = localStorage.getItem('theme');
|
|
39
|
+
const theme = saved || 'auto';
|
|
40
|
+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
41
|
+
const isDark = theme === 'auto' ? prefersDark : theme === 'dark';
|
|
42
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
43
|
+
if (isDark) {
|
|
44
|
+
document.documentElement.classList.add('dark');
|
|
45
|
+
}
|
|
46
|
+
})();
|
|
47
|
+
`,
|
|
48
|
+
} })),
|
|
35
49
|
react_1.default.createElement("body", null,
|
|
36
50
|
react_1.default.createElement(PageLayout_1.PageLayout, { header: react_1.default.createElement(CZONHeader_1.CZONHeader, { ctx: props.ctx, lang: props.lang, file: props.file }), navigator: react_1.default.createElement("nav", { className: "sidebar hidden md:block" },
|
|
37
51
|
react_1.default.createElement(Navigator_1.Navigator, { ctx: props.ctx, file: props.file, lang: props.lang })), main: react_1.default.createElement("main", { className: "content" },
|
|
@@ -64,11 +78,10 @@ const ContentPage = props => {
|
|
|
64
78
|
`),
|
|
65
79
|
react_1.default.createElement("script", { id: "mermaid-lib", src: "https://cdn.jsdelivr.net/npm/mermaid@11.4.0/dist/mermaid.min.js", defer: true }),
|
|
66
80
|
react_1.default.createElement("script", null, `
|
|
67
|
-
|
|
68
|
-
console.log('Mermaid loaded');
|
|
81
|
+
function runMermaid() {
|
|
69
82
|
mermaid.initialize({
|
|
70
83
|
startOnLoad: true,
|
|
71
|
-
theme: 'default',
|
|
84
|
+
theme: document.documentElement.classList.contains('dark') ? 'dark' : 'default',
|
|
72
85
|
securityLevel: 'strict',
|
|
73
86
|
flowchart: {
|
|
74
87
|
useMaxWidth: true,
|
|
@@ -87,6 +100,13 @@ const ContentPage = props => {
|
|
|
87
100
|
barGap: 4,
|
|
88
101
|
},
|
|
89
102
|
});
|
|
103
|
+
mermaid.run().catch(err => {
|
|
104
|
+
console.error('Mermaid render error:', err);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
document.getElementById('mermaid-lib').addEventListener('load', () => {
|
|
108
|
+
console.log('Mermaid loaded');
|
|
109
|
+
runMermaid();
|
|
90
110
|
});
|
|
91
111
|
`),
|
|
92
112
|
react_1.default.createElement("script", null, `
|
|
@@ -113,7 +133,11 @@ const ContentPage = props => {
|
|
|
113
133
|
// 延迟一点,确保首屏渲染完成
|
|
114
134
|
setTimeout(() => {
|
|
115
135
|
loadCSS("https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css", 'katex-css');
|
|
116
|
-
|
|
136
|
+
const isDark = document.documentElement.classList.contains('dark');
|
|
137
|
+
const hljsTheme = isDark
|
|
138
|
+
? "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github-dark.min.css"
|
|
139
|
+
: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github.min.css";
|
|
140
|
+
loadCSS(hljsTheme, 'hljs-css');
|
|
117
141
|
}, 300);
|
|
118
142
|
}
|
|
119
143
|
|
package/dist/ssg/IndexPage.js
CHANGED
|
@@ -28,7 +28,21 @@ const IndexPage = props => {
|
|
|
28
28
|
props.lang),
|
|
29
29
|
react_1.default.createElement("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }),
|
|
30
30
|
react_1.default.createElement("meta", { name: "description", content: `Index page for language ${props.lang}` }),
|
|
31
|
-
react_1.default.createElement("style", null, style_1.style)
|
|
31
|
+
react_1.default.createElement("style", null, style_1.style),
|
|
32
|
+
react_1.default.createElement("script", { dangerouslySetInnerHTML: {
|
|
33
|
+
__html: `
|
|
34
|
+
(function() {
|
|
35
|
+
const saved = localStorage.getItem('theme');
|
|
36
|
+
const theme = saved || 'auto';
|
|
37
|
+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
38
|
+
const isDark = theme === 'auto' ? prefersDark : theme === 'dark';
|
|
39
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
40
|
+
if (isDark) {
|
|
41
|
+
document.documentElement.classList.add('dark');
|
|
42
|
+
}
|
|
43
|
+
})();
|
|
44
|
+
`,
|
|
45
|
+
} })),
|
|
32
46
|
react_1.default.createElement("body", null,
|
|
33
47
|
react_1.default.createElement(PageLayout_1.PageLayout, { header: react_1.default.createElement(CZONHeader_1.CZONHeader, { ctx: props.ctx, lang: props.lang }), navigator: undefined, main: react_1.default.createElement("div", { className: "p-6 max-w-3xl mx-auto" },
|
|
34
48
|
react_1.default.createElement("div", null,
|
package/dist/ssg/RedirectPage.js
CHANGED
|
@@ -14,7 +14,21 @@ const RedirectPage = props => {
|
|
|
14
14
|
react_1.default.createElement("meta", { httpEquiv: "X-UA-Compatible", content: "IE=edge" }),
|
|
15
15
|
react_1.default.createElement("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }),
|
|
16
16
|
react_1.default.createElement("meta", { httpEquiv: "refresh", content: `0; url=${toURL}` }),
|
|
17
|
-
react_1.default.createElement("title", null, "Redirecting...")
|
|
17
|
+
react_1.default.createElement("title", null, "Redirecting..."),
|
|
18
|
+
react_1.default.createElement("script", { dangerouslySetInnerHTML: {
|
|
19
|
+
__html: `
|
|
20
|
+
(function() {
|
|
21
|
+
const saved = localStorage.getItem('theme');
|
|
22
|
+
const theme = saved || 'auto';
|
|
23
|
+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
24
|
+
const isDark = theme === 'auto' ? prefersDark : theme === 'dark';
|
|
25
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
26
|
+
if (isDark) {
|
|
27
|
+
document.documentElement.classList.add('dark');
|
|
28
|
+
}
|
|
29
|
+
})();
|
|
30
|
+
`,
|
|
31
|
+
} })),
|
|
18
32
|
react_1.default.createElement("body", null,
|
|
19
33
|
react_1.default.createElement("p", null,
|
|
20
34
|
"Redirecting to ",
|
package/dist/ssg/RootPage.js
CHANGED
|
@@ -25,7 +25,21 @@ const RootPage = props => {
|
|
|
25
25
|
react_1.default.createElement("title", null, "CZON Multilingual Site Navigator"),
|
|
26
26
|
react_1.default.createElement("meta", { name: "description", content: "Select your preferred language to explore our content." }),
|
|
27
27
|
props.ctx.site.options.langs.map(lang => (react_1.default.createElement("link", { rel: "alternate", hrefLang: lang, href: `${lang}/index.html` }))),
|
|
28
|
-
react_1.default.createElement("link", { rel: "alternate", hrefLang: "x-default", href: `${props.ctx.site.options.langs[0]}/index.html` })
|
|
28
|
+
react_1.default.createElement("link", { rel: "alternate", hrefLang: "x-default", href: `${props.ctx.site.options.langs[0]}/index.html` }),
|
|
29
|
+
react_1.default.createElement("script", { dangerouslySetInnerHTML: {
|
|
30
|
+
__html: `
|
|
31
|
+
(function() {
|
|
32
|
+
const saved = localStorage.getItem('theme');
|
|
33
|
+
const theme = saved || 'auto';
|
|
34
|
+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
35
|
+
const isDark = theme === 'auto' ? prefersDark : theme === 'dark';
|
|
36
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
37
|
+
if (isDark) {
|
|
38
|
+
document.documentElement.classList.add('dark');
|
|
39
|
+
}
|
|
40
|
+
})();
|
|
41
|
+
`,
|
|
42
|
+
} })),
|
|
29
43
|
react_1.default.createElement("body", null,
|
|
30
44
|
react_1.default.createElement("h1", null, "Welcome to CZON Multilingual Site"),
|
|
31
45
|
react_1.default.createElement("p", null, "Please select your preferred language if automatic redirection does not work:"),
|
|
@@ -5,12 +5,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.CZONHeader = void 0;
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const DarkModeSwitch_1 = require("./DarkModeSwitch");
|
|
8
9
|
const LanguageSwitch_1 = require("./LanguageSwitch");
|
|
9
10
|
const CZONHeader = props => {
|
|
10
11
|
return (react_1.default.createElement("header", { className: "czon-header py-4 border-b flex justify-between items-center px-6" },
|
|
11
12
|
react_1.default.createElement("h1", { className: "text-2xl font-bold" },
|
|
12
13
|
react_1.default.createElement("a", { href: "index.html" }, "CZON")),
|
|
13
|
-
|
|
14
|
+
react_1.default.createElement("div", { className: "flex items-center gap-4" },
|
|
15
|
+
react_1.default.createElement(DarkModeSwitch_1.DarkModeSwitch, null),
|
|
16
|
+
props.lang && react_1.default.createElement(LanguageSwitch_1.LanguageSwitch, { ctx: props.ctx, lang: props.lang, file: props.file }))));
|
|
14
17
|
};
|
|
15
18
|
exports.CZONHeader = CZONHeader;
|
|
16
19
|
//# sourceMappingURL=CZONHeader.js.map
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DarkModeSwitch = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const style = `
|
|
9
|
+
.dark-mode-switch-container {
|
|
10
|
+
position: relative;
|
|
11
|
+
display: inline-block;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.dark-mode-switch-trigger {
|
|
15
|
+
transition: all 0.2s ease;
|
|
16
|
+
cursor: pointer;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.dark-mode-switch-trigger:hover {
|
|
20
|
+
box-shadow: 0 2px 4px var(--shadow-color);
|
|
21
|
+
background: var(--tag-bg);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.dark-mode-icon {
|
|
25
|
+
width: 1.25rem;
|
|
26
|
+
height: 1.25rem;
|
|
27
|
+
transition: all 0.2s ease;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
[data-theme="light"] .icon-sun { display: block; }
|
|
31
|
+
[data-theme="light"] .icon-moon { display: none; }
|
|
32
|
+
[data-theme="light"] .icon-auto { display: none; }
|
|
33
|
+
|
|
34
|
+
[data-theme="dark"] .icon-sun { display: none; }
|
|
35
|
+
[data-theme="dark"] .icon-moon { display: block; }
|
|
36
|
+
[data-theme="dark"] .icon-auto { display: none; }
|
|
37
|
+
|
|
38
|
+
[data-theme="auto"] .icon-sun { display: none; }
|
|
39
|
+
[data-theme="auto"] .icon-moon { display: none; }
|
|
40
|
+
[data-theme="auto"] .icon-auto { display: block; }
|
|
41
|
+
`;
|
|
42
|
+
const DarkModeSwitch = () => {
|
|
43
|
+
return (react_1.default.createElement("div", { className: "dark-mode-switch-container relative inline-block" },
|
|
44
|
+
react_1.default.createElement("style", null, style),
|
|
45
|
+
react_1.default.createElement("input", { id: "theme-toggle", type: "checkbox", className: "hidden", "aria-hidden": "true" }),
|
|
46
|
+
react_1.default.createElement("label", { htmlFor: "theme-toggle", className: "dark-mode-switch-trigger p-2 rounded-full flex items-center justify-center transition-colors", "aria-label": "Toggle theme", role: "button", tabIndex: 0 },
|
|
47
|
+
react_1.default.createElement("svg", { className: "dark-mode-icon icon-sun", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" },
|
|
48
|
+
react_1.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" })),
|
|
49
|
+
react_1.default.createElement("svg", { className: "dark-mode-icon icon-moon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" },
|
|
50
|
+
react_1.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" })),
|
|
51
|
+
react_1.default.createElement("svg", { className: "dark-mode-icon icon-auto", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" },
|
|
52
|
+
react_1.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" }))),
|
|
53
|
+
react_1.default.createElement("script", null, `
|
|
54
|
+
(function() {
|
|
55
|
+
const STORAGE_KEY = 'theme';
|
|
56
|
+
const toggle = document.getElementById('theme-toggle');
|
|
57
|
+
const html = document.documentElement;
|
|
58
|
+
const label = document.querySelector('label[for="theme-toggle"]');
|
|
59
|
+
|
|
60
|
+
function updateHljsTheme(isDark) {
|
|
61
|
+
const link = document.getElementById('hljs-css');
|
|
62
|
+
if (link) {
|
|
63
|
+
const url = isDark
|
|
64
|
+
? "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github-dark.min.css"
|
|
65
|
+
: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github.min.css";
|
|
66
|
+
link.href = url;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function updateMermaidTheme(isDark) {
|
|
71
|
+
if (typeof mermaid !== 'undefined') {
|
|
72
|
+
document.querySelectorAll('.mermaid').forEach(el => {
|
|
73
|
+
const pre = el;
|
|
74
|
+
const content = pre.getAttribute('data-mermaid-content');
|
|
75
|
+
if (content) {
|
|
76
|
+
pre.style.visibility = 'visible';
|
|
77
|
+
pre.textContent = decodeURIComponent(content);
|
|
78
|
+
delete pre.dataset.processed;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
runMermaid();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
window.updateMermaidTheme = updateMermaidTheme;
|
|
85
|
+
|
|
86
|
+
function applyTheme(theme) {
|
|
87
|
+
localStorage.setItem(STORAGE_KEY, theme);
|
|
88
|
+
html.setAttribute('data-theme', theme);
|
|
89
|
+
|
|
90
|
+
let isDark;
|
|
91
|
+
if (theme === 'auto') {
|
|
92
|
+
isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
93
|
+
} else {
|
|
94
|
+
isDark = theme === 'dark';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (isDark) {
|
|
98
|
+
html.classList.add('dark');
|
|
99
|
+
if (toggle) toggle.checked = true;
|
|
100
|
+
} else {
|
|
101
|
+
html.classList.remove('dark');
|
|
102
|
+
if (toggle) toggle.checked = false;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
updateHljsTheme(isDark);
|
|
106
|
+
updateMermaidTheme(isDark);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function cycleTheme() {
|
|
110
|
+
const current = html.getAttribute('data-theme') || 'auto';
|
|
111
|
+
const next = current === 'light' ? 'dark' : current === 'dark' ? 'auto' : 'light';
|
|
112
|
+
applyTheme(next);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function initTheme() {
|
|
116
|
+
const saved = localStorage.getItem(STORAGE_KEY);
|
|
117
|
+
const theme = saved || 'auto';
|
|
118
|
+
applyTheme(theme);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (document.readyState === 'loading') {
|
|
122
|
+
document.addEventListener('DOMContentLoaded', initTheme);
|
|
123
|
+
} else {
|
|
124
|
+
initTheme();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
document.addEventListener('click', function(e) {
|
|
128
|
+
if (label && label.contains(e.target)) {
|
|
129
|
+
e.preventDefault();
|
|
130
|
+
cycleTheme();
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
|
|
135
|
+
if (html.getAttribute('data-theme') === 'auto') {
|
|
136
|
+
if (e.matches) {
|
|
137
|
+
html.classList.add('dark');
|
|
138
|
+
} else {
|
|
139
|
+
html.classList.remove('dark');
|
|
140
|
+
}
|
|
141
|
+
updateHljsTheme(e.matches);
|
|
142
|
+
updateMermaidTheme(e.matches);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
})();
|
|
146
|
+
`)));
|
|
147
|
+
};
|
|
148
|
+
exports.DarkModeSwitch = DarkModeSwitch;
|
|
149
|
+
//# sourceMappingURL=DarkModeSwitch.js.map
|
|
@@ -16,15 +16,20 @@ const style = `
|
|
|
16
16
|
|
|
17
17
|
.language-switch-trigger {
|
|
18
18
|
transition: all 0.2s ease;
|
|
19
|
+
background: var(--ls-bg-primary);
|
|
20
|
+
border-color: var(--ls-border-color);
|
|
21
|
+
color: var(--ls-text-primary);
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
.language-switch-trigger:hover {
|
|
22
25
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
26
|
+
background: var(--ls-bg-hover);
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
.language-switch-icon {
|
|
26
30
|
transition: transform 0.2s ease;
|
|
27
31
|
max-width: 1rem;
|
|
32
|
+
color: var(--ls-text-secondary);
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
.language-switch-dropdown {
|
|
@@ -53,18 +58,62 @@ const style = `
|
|
|
53
58
|
|
|
54
59
|
.language-switch-option {
|
|
55
60
|
transition: all 0.15s ease;
|
|
61
|
+
background: var(--ls-bg-primary);
|
|
62
|
+
color: var(--ls-text-secondary);
|
|
56
63
|
}
|
|
57
64
|
|
|
58
65
|
.language-switch-option:hover {
|
|
59
66
|
transform: translateY(-1px);
|
|
60
67
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
68
|
+
background: var(--ls-bg-hover);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.language-switch-option.active {
|
|
72
|
+
background: var(--ls-bg-active);
|
|
73
|
+
color: var(--ls-text-active);
|
|
61
74
|
}
|
|
62
75
|
|
|
63
76
|
.language-switch-option:focus {
|
|
64
77
|
outline: 2px solid #3b82f6;
|
|
65
78
|
outline-offset: 2px;
|
|
66
79
|
}
|
|
80
|
+
|
|
81
|
+
.language-switch-info {
|
|
82
|
+
border-color: var(--ls-border-color);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.language-switch-count {
|
|
86
|
+
color: var(--ls-text-muted);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
html.dark .language-switch-trigger {
|
|
90
|
+
background: var(--bg-secondary);
|
|
91
|
+
border-color: var(--border-color);
|
|
92
|
+
color: var(--text-primary);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
html.dark .language-switch-trigger:hover {
|
|
96
|
+
background: var(--border-color);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
html.dark .language-switch-dropdown {
|
|
100
|
+
background: var(--bg-secondary);
|
|
101
|
+
border-color: var(--border-color);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
html.dark .language-switch-option:hover {
|
|
105
|
+
background: var(--border-color);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
html.dark .language-switch-option.active {
|
|
109
|
+
background: var(--border-color);
|
|
110
|
+
color: var(--text-primary);
|
|
111
|
+
}
|
|
67
112
|
`;
|
|
113
|
+
const triggerClasses = 'language-switch-trigger px-4 py-2 border rounded-md flex items-center gap-2 text-sm font-medium focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors';
|
|
114
|
+
const dropdownClasses = 'language-switch-dropdown absolute top-full mt-1 w-96 md:w-2xl lg:w-3xl max-h-96 overflow-y-auto border rounded-md shadow-lg z-50';
|
|
115
|
+
const optionActiveClasses = 'language-switch-option active font-semibold';
|
|
116
|
+
const optionInactiveClasses = 'language-switch-option';
|
|
68
117
|
const LanguageSwitch = props => {
|
|
69
118
|
// 获取当前语言名称
|
|
70
119
|
const currentLangName = languages_1.LANGUAGE_NAMES[props.lang] || props.lang;
|
|
@@ -78,25 +127,22 @@ const LanguageSwitch = props => {
|
|
|
78
127
|
return (react_1.default.createElement("div", { className: "language-switch-container relative inline-block" },
|
|
79
128
|
react_1.default.createElement("style", null, style),
|
|
80
129
|
react_1.default.createElement("input", { id: "language-switch-toggle", type: "checkbox", className: "hidden", "aria-hidden": "true" }),
|
|
81
|
-
react_1.default.createElement("label", { htmlFor: "language-switch-toggle", className:
|
|
130
|
+
react_1.default.createElement("label", { htmlFor: "language-switch-toggle", className: triggerClasses, "aria-label": `Language switcher. Current language: ${currentLangName}`, "aria-haspopup": "true", "aria-expanded": "false", "aria-controls": "language-dropdown" },
|
|
82
131
|
react_1.default.createElement("span", { className: "text-sm font-medium" }, currentLangName),
|
|
83
132
|
react_1.default.createElement("svg", { className: "language-switch-icon w-4 h-4 transition-transform", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true" },
|
|
84
133
|
react_1.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }))),
|
|
85
|
-
react_1.default.createElement("div", { id: "language-dropdown", className:
|
|
134
|
+
react_1.default.createElement("div", { id: "language-dropdown", className: dropdownClasses, role: "menu", "aria-label": "Available languages" },
|
|
86
135
|
react_1.default.createElement("div", { className: "p-4" },
|
|
87
136
|
react_1.default.createElement("div", { className: "language-switch-grid grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-2" }, languages.map(lang => {
|
|
88
137
|
const langName = languages_1.LANGUAGE_NAMES[lang] || lang;
|
|
89
138
|
const isActive = lang === props.lang;
|
|
90
139
|
return (react_1.default.createElement("a", { key: lang, href: getLanguageLink(lang), className: `
|
|
91
|
-
|
|
92
|
-
${isActive
|
|
93
|
-
? 'bg-blue-100 text-blue-700 font-semibold'
|
|
94
|
-
: 'text-gray-700 hover:bg-gray-100'}
|
|
140
|
+
${isActive ? optionActiveClasses : optionInactiveClasses} block px-3 py-2 rounded text-center
|
|
95
141
|
transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500
|
|
96
142
|
`, role: "menuitem", "aria-current": isActive ? 'page' : undefined, lang: lang }, langName));
|
|
97
143
|
})),
|
|
98
|
-
react_1.default.createElement("div", { className: "language-switch-info mt-3 pt-3 border-t
|
|
99
|
-
react_1.default.createElement("p", { className: "language-switch-count text-xs text-
|
|
144
|
+
react_1.default.createElement("div", { className: "language-switch-info mt-3 pt-3 border-t" },
|
|
145
|
+
react_1.default.createElement("p", { className: "language-switch-count text-xs text-center" },
|
|
100
146
|
languages.length,
|
|
101
147
|
" languages available"))))));
|
|
102
148
|
};
|
package/dist/ssg/style.js
CHANGED
|
@@ -2,27 +2,65 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.style = void 0;
|
|
4
4
|
exports.style = `
|
|
5
|
+
@custom-variant dark (&:where(.dark, .dark *));
|
|
6
|
+
|
|
7
|
+
:root {
|
|
8
|
+
--bg-primary: #ffffff;
|
|
9
|
+
--bg-secondary: #f8f9fa;
|
|
10
|
+
--text-primary: #333333;
|
|
11
|
+
--text-secondary: #6c757d;
|
|
12
|
+
--border-color: #e9ecef;
|
|
13
|
+
--code-bg: #f8f9fa;
|
|
14
|
+
--link-color: #007bff;
|
|
15
|
+
--sidebar-bg: #ffffff;
|
|
16
|
+
--tag-bg: #e9ecef;
|
|
17
|
+
--tag-text: #495057;
|
|
18
|
+
--shadow-color: rgba(0, 0, 0, 0.1);
|
|
19
|
+
--primary-color: #007bff;
|
|
20
|
+
--text-on-primary: #ffffff;
|
|
21
|
+
}
|
|
5
22
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
23
|
+
html.dark {
|
|
24
|
+
--bg-primary: #1a1a1a;
|
|
25
|
+
--bg-secondary: #262626;
|
|
26
|
+
--text-primary: #e5e5e5;
|
|
27
|
+
--text-secondary: #a3a3a3;
|
|
28
|
+
--border-color: #404040;
|
|
29
|
+
--code-bg: #333333;
|
|
30
|
+
--link-color: #60a5fa;
|
|
31
|
+
--sidebar-bg: #262626;
|
|
32
|
+
--tag-bg: #404040;
|
|
33
|
+
--tag-text: #d4d4d4;
|
|
34
|
+
--shadow-color: rgba(0, 0, 0, 0.5);
|
|
35
|
+
--primary-color: #3b82f6;
|
|
36
|
+
--text-on-primary: #ffffff;
|
|
37
|
+
}
|
|
12
38
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
39
|
+
html, body {
|
|
40
|
+
margin: 0;
|
|
41
|
+
padding: 0;
|
|
42
|
+
width: 100%;
|
|
43
|
+
height: 100%;
|
|
44
|
+
}
|
|
16
45
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
46
|
+
html[lang='ar-SA'] {
|
|
47
|
+
direction: rtl;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
html.dark body {
|
|
51
|
+
color: var(--text-primary);
|
|
52
|
+
background: var(--bg-secondary);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
html:not(.dark) body {
|
|
56
|
+
color: var(--text-primary);
|
|
57
|
+
background: var(--bg-secondary);
|
|
58
|
+
}
|
|
21
59
|
|
|
22
60
|
.sidebar {
|
|
23
61
|
width: 280px;
|
|
24
|
-
background:
|
|
25
|
-
border-right: 1px solid
|
|
62
|
+
background: var(--sidebar-bg);
|
|
63
|
+
border-right: 1px solid var(--border-color);
|
|
26
64
|
padding: 2rem 1rem;
|
|
27
65
|
overflow-y: auto;
|
|
28
66
|
|
|
@@ -32,17 +70,17 @@ exports.style = `
|
|
|
32
70
|
.sidebar-header {
|
|
33
71
|
margin-bottom: 2rem;
|
|
34
72
|
padding-bottom: 1rem;
|
|
35
|
-
border-bottom: 1px solid
|
|
73
|
+
border-bottom: 1px solid var(--border-color);
|
|
36
74
|
}
|
|
37
75
|
|
|
38
76
|
.sidebar-header h1 {
|
|
39
77
|
font-size: 1.5rem;
|
|
40
78
|
font-weight: 600;
|
|
41
|
-
color:
|
|
79
|
+
color: var(--text-primary);
|
|
42
80
|
}
|
|
43
81
|
|
|
44
82
|
.sidebar-header p {
|
|
45
|
-
color:
|
|
83
|
+
color: var(--text-secondary);
|
|
46
84
|
font-size: 0.875rem;
|
|
47
85
|
margin-top: 0.5rem;
|
|
48
86
|
}
|
|
@@ -54,20 +92,20 @@ exports.style = `
|
|
|
54
92
|
.nav-link {
|
|
55
93
|
display: block;
|
|
56
94
|
padding: 0.5rem 1rem;
|
|
57
|
-
color:
|
|
95
|
+
color: var(--text-secondary);
|
|
58
96
|
text-decoration: none;
|
|
59
97
|
border-radius: 4px;
|
|
60
98
|
transition: all 0.2s;
|
|
61
99
|
}
|
|
62
100
|
|
|
63
101
|
.nav-link:hover {
|
|
64
|
-
background:
|
|
65
|
-
color:
|
|
102
|
+
background: var(--border-color);
|
|
103
|
+
color: var(--text-primary);
|
|
66
104
|
}
|
|
67
105
|
|
|
68
106
|
.nav-link.active {
|
|
69
|
-
background:
|
|
70
|
-
color:
|
|
107
|
+
background: var(--primary-color);
|
|
108
|
+
color: var(--text-on-primary);
|
|
71
109
|
}
|
|
72
110
|
|
|
73
111
|
.nav-submenu {
|
|
@@ -77,11 +115,11 @@ exports.style = `
|
|
|
77
115
|
}
|
|
78
116
|
|
|
79
117
|
blockquote {
|
|
80
|
-
border-left: 4px solid
|
|
118
|
+
border-left: 4px solid var(--link-color);
|
|
81
119
|
padding: 0.5rem 1rem;
|
|
82
120
|
margin: 1rem 0;
|
|
83
|
-
background:
|
|
84
|
-
color:
|
|
121
|
+
background: var(--code-bg);
|
|
122
|
+
color: var(--text-primary);
|
|
85
123
|
}
|
|
86
124
|
|
|
87
125
|
.content {
|
|
@@ -94,18 +132,18 @@ exports.style = `
|
|
|
94
132
|
.content-header {
|
|
95
133
|
margin-bottom: 2rem;
|
|
96
134
|
padding-bottom: 1rem;
|
|
97
|
-
border-bottom: 1px solid
|
|
135
|
+
border-bottom: 1px solid var(--border-color);
|
|
98
136
|
}
|
|
99
137
|
|
|
100
138
|
.content-header h1 {
|
|
101
139
|
font-size: 2.5rem;
|
|
102
140
|
font-weight: 700;
|
|
103
|
-
color:
|
|
141
|
+
color: var(--text-primary);
|
|
104
142
|
margin-bottom: 0.5rem;
|
|
105
143
|
}
|
|
106
144
|
|
|
107
145
|
.content-header .meta {
|
|
108
|
-
color:
|
|
146
|
+
color: var(--text-secondary);
|
|
109
147
|
font-size: 0.875rem;
|
|
110
148
|
}
|
|
111
149
|
|
|
@@ -117,19 +155,19 @@ exports.style = `
|
|
|
117
155
|
.content-body h1 {
|
|
118
156
|
font-size: 2rem;
|
|
119
157
|
margin: 2rem 0 1rem;
|
|
120
|
-
color:
|
|
158
|
+
color: var(--text-primary);
|
|
121
159
|
}
|
|
122
160
|
|
|
123
161
|
.content-body h2 {
|
|
124
162
|
font-size: 1.75rem;
|
|
125
163
|
margin: 1.75rem 0 0.875rem;
|
|
126
|
-
color:
|
|
164
|
+
color: var(--text-primary);
|
|
127
165
|
}
|
|
128
166
|
|
|
129
167
|
.content-body h3 {
|
|
130
168
|
font-size: 1.5rem;
|
|
131
169
|
margin: 1.5rem 0 0.75rem;
|
|
132
|
-
color:
|
|
170
|
+
color: var(--text-primary);
|
|
133
171
|
}
|
|
134
172
|
|
|
135
173
|
.content-body p {
|
|
@@ -146,23 +184,24 @@ exports.style = `
|
|
|
146
184
|
}
|
|
147
185
|
|
|
148
186
|
.content-body blockquote {
|
|
149
|
-
border-left: 4px solid
|
|
187
|
+
border-left: 4px solid var(--link-color);
|
|
150
188
|
padding: 0.5rem 1rem;
|
|
151
189
|
margin: 1rem 0;
|
|
152
|
-
background:
|
|
153
|
-
color:
|
|
190
|
+
background: var(--code-bg);
|
|
191
|
+
color: var(--text-primary);
|
|
154
192
|
}
|
|
155
193
|
|
|
156
194
|
.content-body code {
|
|
157
|
-
background:
|
|
195
|
+
background: var(--code-bg);
|
|
158
196
|
padding: 0.2rem 0.4rem;
|
|
159
197
|
border-radius: 3px;
|
|
160
198
|
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
|
161
199
|
font-size: 0.875em;
|
|
200
|
+
color: var(--text-primary);
|
|
162
201
|
}
|
|
163
202
|
|
|
164
203
|
.content-body pre {
|
|
165
|
-
background:
|
|
204
|
+
background: var(--code-bg);
|
|
166
205
|
padding: 1rem;
|
|
167
206
|
border-radius: 6px;
|
|
168
207
|
overflow-x: auto;
|
|
@@ -182,13 +221,13 @@ exports.style = `
|
|
|
182
221
|
|
|
183
222
|
.content-body th,
|
|
184
223
|
.content-body td {
|
|
185
|
-
border: 1px solid
|
|
224
|
+
border: 1px solid var(--border-color);
|
|
186
225
|
padding: 0.75rem;
|
|
187
226
|
text-align: left;
|
|
188
227
|
}
|
|
189
228
|
|
|
190
229
|
.content-body th {
|
|
191
|
-
background:
|
|
230
|
+
background: var(--code-bg);
|
|
192
231
|
font-weight: 600;
|
|
193
232
|
}
|
|
194
233
|
|
|
@@ -199,8 +238,12 @@ exports.style = `
|
|
|
199
238
|
margin: 1rem 0;
|
|
200
239
|
}
|
|
201
240
|
|
|
241
|
+
html.dark .content-body img {
|
|
242
|
+
filter: brightness(0.85) contrast(1.1);
|
|
243
|
+
}
|
|
244
|
+
|
|
202
245
|
a {
|
|
203
|
-
color:
|
|
246
|
+
color: var(--link-color);
|
|
204
247
|
text-decoration: none;
|
|
205
248
|
}
|
|
206
249
|
|
|
@@ -211,8 +254,8 @@ exports.style = `
|
|
|
211
254
|
.footer {
|
|
212
255
|
margin-top: 3rem;
|
|
213
256
|
padding-top: 2rem;
|
|
214
|
-
border-top: 1px solid
|
|
215
|
-
color:
|
|
257
|
+
border-top: 1px solid var(--border-color);
|
|
258
|
+
color: var(--text-secondary);
|
|
216
259
|
font-size: 0.875rem;
|
|
217
260
|
text-align: center;
|
|
218
261
|
}
|
|
@@ -227,8 +270,8 @@ exports.style = `
|
|
|
227
270
|
}
|
|
228
271
|
|
|
229
272
|
.tag-item {
|
|
230
|
-
background:
|
|
231
|
-
color:
|
|
273
|
+
background: var(--tag-bg);
|
|
274
|
+
color: var(--tag-text);
|
|
232
275
|
padding: 0.25rem 0.5rem;
|
|
233
276
|
border-radius: 4px;
|
|
234
277
|
font-size: 0.875rem;
|
|
@@ -241,7 +284,7 @@ exports.style = `
|
|
|
241
284
|
height: auto;
|
|
242
285
|
position: static;
|
|
243
286
|
border-right: none;
|
|
244
|
-
border-bottom: 1px solid
|
|
287
|
+
border-bottom: 1px solid var(--border-color);
|
|
245
288
|
}
|
|
246
289
|
|
|
247
290
|
.content {
|
|
@@ -253,15 +296,15 @@ exports.style = `
|
|
|
253
296
|
/* Mermaid diagram styles */
|
|
254
297
|
.mermaid-diagram {
|
|
255
298
|
margin: 1.5rem 0;
|
|
256
|
-
border: 1px solid
|
|
299
|
+
border: 1px solid var(--border-color);
|
|
257
300
|
border-radius: 6px;
|
|
258
301
|
overflow: hidden;
|
|
259
|
-
background:
|
|
302
|
+
background: var(--bg-primary);
|
|
260
303
|
}
|
|
261
304
|
|
|
262
305
|
.mermaid-placeholder {
|
|
263
306
|
padding: 2rem;
|
|
264
|
-
background:
|
|
307
|
+
background: var(--code-bg);
|
|
265
308
|
min-height: 200px;
|
|
266
309
|
display: flex;
|
|
267
310
|
align-items: center;
|
|
@@ -270,15 +313,15 @@ exports.style = `
|
|
|
270
313
|
}
|
|
271
314
|
|
|
272
315
|
.mermaid-loading {
|
|
273
|
-
color:
|
|
316
|
+
color: var(--text-secondary);
|
|
274
317
|
font-style: italic;
|
|
275
318
|
font-size: 0.875rem;
|
|
276
319
|
}
|
|
277
320
|
|
|
278
321
|
.mermaid-error {
|
|
279
|
-
color: #
|
|
322
|
+
color: #f87171;
|
|
280
323
|
padding: 1rem;
|
|
281
|
-
background:
|
|
324
|
+
background: rgba(248, 113, 113, 0.1);
|
|
282
325
|
border-radius: 4px;
|
|
283
326
|
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
|
284
327
|
font-size: 0.875rem;
|
|
@@ -40,7 +40,7 @@ const convertMarkdownToHtml = (mdContent) => {
|
|
|
40
40
|
const chartId = 'mermaid-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9);
|
|
41
41
|
return `
|
|
42
42
|
<div class="mermaid-diagram" data-mermaid-id="${chartId}">
|
|
43
|
-
<pre class="mermaid">${escapeHtml(codeText)}</pre>
|
|
43
|
+
<pre class="mermaid" data-mermaid-content="${encodeURIComponent(codeText)}">${escapeHtml(codeText)}</pre>
|
|
44
44
|
</div>
|
|
45
45
|
`;
|
|
46
46
|
}
|