create-zudo-doc 0.2.20 → 0.2.22
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/features/image-enlarge.d.ts +10 -2
- package/dist/features/image-enlarge.js +10 -2
- package/dist/scaffold.js +22 -22
- package/dist/zfb-config-gen.d.ts +16 -10
- package/dist/zfb-config-gen.js +34 -239
- package/package.json +1 -1
- package/templates/base/pages/lib/_body-end-islands.tsx +6 -13
- package/templates/base/pages/lib/_category-nav.tsx +30 -115
- package/templates/base/pages/lib/_category-tree-nav.tsx +38 -65
- package/templates/base/pages/lib/_compose-meta-title.ts +2 -6
- package/templates/base/pages/lib/_doc-body-end.tsx +3 -35
- package/templates/base/pages/lib/_doc-content-header.tsx +10 -111
- package/templates/base/pages/lib/_doc-history-area.tsx +19 -211
- package/templates/base/pages/lib/_doc-metainfo-area.tsx +10 -113
- package/templates/base/pages/lib/_doc-page-renderer.tsx +22 -183
- package/templates/base/pages/lib/_doc-page-shell.tsx +17 -251
- package/templates/base/pages/lib/_doc-pager.tsx +4 -74
- package/templates/base/pages/lib/_doc-route-entries.ts +43 -177
- package/templates/base/pages/lib/_doc-route-paths.ts +16 -101
- package/templates/base/pages/lib/_doc-tags-area.tsx +14 -77
- package/templates/base/pages/lib/_footer-with-defaults.tsx +37 -225
- package/templates/base/pages/lib/_frontmatter-preview-data.ts +5 -31
- package/templates/base/pages/lib/_head-with-defaults.tsx +13 -138
- package/templates/base/pages/lib/_header-with-defaults.tsx +24 -324
- package/templates/base/pages/lib/_inline-version-switcher.tsx +16 -78
- package/templates/base/pages/lib/_nav-data-prep.ts +32 -51
- package/templates/base/pages/lib/_nav-source-cache.ts +12 -57
- package/templates/base/pages/lib/_nav-source-docs.ts +33 -233
- package/templates/base/pages/lib/_search-widget-script.ts +2 -470
- package/templates/base/pages/lib/_search-widget.tsx +9 -195
- package/templates/base/pages/lib/_sidebar-prepaint.tsx +6 -47
- package/templates/base/pages/lib/_sidebar-with-defaults.tsx +16 -118
- package/templates/base/pages/lib/_site-tree-nav.tsx +29 -80
- package/templates/base/pages/lib/doc-page-props.ts +26 -44
- package/templates/base/pages/lib/locale-merge.ts +32 -145
- package/templates/base/pages/lib/route-enumerators.ts +52 -286
- package/templates/base/pages/robots.txt.tsx +2 -26
- package/templates/base/src/components/ai-chat-modal.tsx +9 -8
- package/templates/base/src/components/doc-history.tsx +9 -8
- package/templates/base/src/components/image-enlarge.tsx +11 -8
- package/templates/base/src/components/sidebar-toggle.tsx +6 -170
- package/templates/base/src/components/sidebar-tree.tsx +6 -548
- package/templates/base/src/components/site-tree-nav.tsx +6 -220
- package/templates/base/src/config/color-scheme-utils.ts +34 -158
- package/templates/base/src/config/i18n.ts +9 -0
- package/templates/base/src/config/z-index-tokens.ts +5 -4
- package/templates/base/src/styles/global.css +5 -579
- package/templates/base/src/utils/base.ts +1 -1
- package/templates/base/src/utils/docs.ts +47 -16
- package/templates/base/src/utils/github.ts +12 -9
- package/templates/base/src/utils/nav-scope.ts +13 -42
- package/templates/base/src/utils/sidebar.ts +18 -86
- package/templates/base/src/utils/slug.ts +10 -53
- package/templates/base/src/utils/smart-break.tsx +12 -120
- package/templates/base/src/utils/tags.ts +25 -68
- package/templates/features/bodyFootUtil/files/src/utils/github.ts +12 -9
- package/templates/features/designTokenPanel/files/src/lib/design-token-panel-bootstrap.ts +13 -39
- package/templates/features/docHistory/files/src/components/doc-history.tsx +8 -636
- package/templates/features/docHistory/files/src/types/doc-history.ts +7 -23
- package/templates/features/docTags/files/pages/lib/_tag-pages.tsx +35 -201
- package/templates/features/imageEnlarge/files/src/components/image-enlarge.tsx +8 -269
- package/templates/features/sidebarToggle/files/src/components/desktop-sidebar-toggle.tsx +6 -99
- package/templates/features/tagGovernance/files/scripts/tags-audit.ts +67 -515
- package/templates/features/tauri/files/src-tauri/capabilities/default.json +1 -4
- package/templates/features/tauri/files/src-tauri/tauri.conf.json +1 -1
- package/templates/features/tauriDev/files/src-tauri-dev/capabilities/default.json +1 -1
- package/templates/features/versioning/files/pages/lib/_versions-page.tsx +21 -73
- package/templates/base/plugins/connect-adapter.mjs +0 -169
- package/templates/base/plugins/search-index-plugin.mjs +0 -66
- package/templates/base/scripts/gen-z-index.mjs +0 -157
- package/templates/base/src/components/mermaid-enlarge.tsx +0 -490
- package/templates/features/claudeResources/files/plugins/claude-resources-plugin.mjs +0 -47
- package/templates/features/docHistory/files/plugins/doc-history-plugin.mjs +0 -111
- package/templates/features/llmsTxt/files/plugins/llms-txt-plugin.mjs +0 -93
|
@@ -1,220 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import type { NavNode } from "@/utils/docs";
|
|
8
|
-
import { INDENT, connectorLeft, ConnectorLines, CategoryLinkIcon } from "./tree-nav-shared";
|
|
9
|
-
import { ChevronRight } from "@takazudo/zudo-doc/icons";
|
|
10
|
-
|
|
11
|
-
// site-tree-nav uses wider padding than the narrow sidebar
|
|
12
|
-
const SITE_BASE_PAD = "clamp(0.5rem, 0.8vw, 1rem)";
|
|
13
|
-
|
|
14
|
-
function padLeft(depth: number): string {
|
|
15
|
-
if (depth === 0) return SITE_BASE_PAD;
|
|
16
|
-
return `calc(${depth} * ${INDENT} + 1.25rem + 5px)`;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function reorderTree(tree: NavNode[], order: string[]): NavNode[] {
|
|
20
|
-
const map = new Map(tree.map((node) => [node.slug, node]));
|
|
21
|
-
const ordered: NavNode[] = [];
|
|
22
|
-
for (const slug of order) {
|
|
23
|
-
const node = map.get(slug);
|
|
24
|
-
if (node) {
|
|
25
|
-
ordered.push(node);
|
|
26
|
-
map.delete(slug);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
// append unmatched nodes at end
|
|
30
|
-
for (const node of map.values()) {
|
|
31
|
-
ordered.push(node);
|
|
32
|
-
}
|
|
33
|
-
return ordered;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
interface SiteTreeNavProps {
|
|
37
|
-
tree: NavNode[];
|
|
38
|
-
ariaLabel?: string;
|
|
39
|
-
categoryOrder?: string[];
|
|
40
|
-
categoryIgnore?: string[];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export default function SiteTreeNav({
|
|
44
|
-
tree,
|
|
45
|
-
ariaLabel = "Site index",
|
|
46
|
-
categoryOrder,
|
|
47
|
-
categoryIgnore,
|
|
48
|
-
}: SiteTreeNavProps) {
|
|
49
|
-
let processedTree = tree;
|
|
50
|
-
if (categoryIgnore) {
|
|
51
|
-
const ignoreSet = new Set(categoryIgnore);
|
|
52
|
-
processedTree = processedTree.filter((node) => !ignoreSet.has(node.slug));
|
|
53
|
-
}
|
|
54
|
-
if (categoryOrder) {
|
|
55
|
-
processedTree = reorderTree(processedTree, categoryOrder);
|
|
56
|
-
}
|
|
57
|
-
return (
|
|
58
|
-
<nav
|
|
59
|
-
aria-label={ariaLabel}
|
|
60
|
-
data-site-nav
|
|
61
|
-
className="grid gap-vsp-md"
|
|
62
|
-
style={{
|
|
63
|
-
gridTemplateColumns: "repeat(auto-fill, minmax(min(18rem, 100%), 1fr))",
|
|
64
|
-
}}
|
|
65
|
-
>
|
|
66
|
-
{processedTree.map((node) => (
|
|
67
|
-
<div key={node.slug} className="min-w-0 border border-muted pl-hsp-sm py-vsp-2xs">
|
|
68
|
-
{node.children.length > 0 ? (
|
|
69
|
-
<CategoryNode node={node} depth={0} isLast={true} />
|
|
70
|
-
) : (
|
|
71
|
-
<LeafNode node={node} depth={0} isLast={true} />
|
|
72
|
-
)}
|
|
73
|
-
</div>
|
|
74
|
-
))}
|
|
75
|
-
</nav>
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function NodeList({ nodes, depth }: { nodes: NavNode[]; depth: number }) {
|
|
80
|
-
return (
|
|
81
|
-
<>
|
|
82
|
-
{nodes.map((node, index) => {
|
|
83
|
-
const isLast = index === nodes.length - 1;
|
|
84
|
-
return node.children.length > 0 ? (
|
|
85
|
-
<CategoryNode
|
|
86
|
-
key={node.slug}
|
|
87
|
-
node={node}
|
|
88
|
-
depth={depth}
|
|
89
|
-
isLast={isLast}
|
|
90
|
-
/>
|
|
91
|
-
) : (
|
|
92
|
-
<LeafNode
|
|
93
|
-
key={node.slug}
|
|
94
|
-
node={node}
|
|
95
|
-
depth={depth}
|
|
96
|
-
isLast={isLast}
|
|
97
|
-
/>
|
|
98
|
-
);
|
|
99
|
-
})}
|
|
100
|
-
</>
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function CategoryNode({
|
|
105
|
-
node,
|
|
106
|
-
depth,
|
|
107
|
-
isLast,
|
|
108
|
-
}: {
|
|
109
|
-
node: NavNode;
|
|
110
|
-
depth: number;
|
|
111
|
-
isLast: boolean;
|
|
112
|
-
}) {
|
|
113
|
-
const [open, setOpen] = useState(true);
|
|
114
|
-
const toggle = () => setOpen((prev) => !prev);
|
|
115
|
-
const paddingLeft = padLeft(depth);
|
|
116
|
-
|
|
117
|
-
return (
|
|
118
|
-
<div className={`${depth >= 1 && !isLast ? "relative" : ""}`}>
|
|
119
|
-
{depth >= 1 && !isLast && open && (
|
|
120
|
-
<div
|
|
121
|
-
className="absolute border-l border-dashed border-muted z-local-1"
|
|
122
|
-
style={{
|
|
123
|
-
left: connectorLeft(depth),
|
|
124
|
-
top: 0,
|
|
125
|
-
bottom: 0,
|
|
126
|
-
}}
|
|
127
|
-
/>
|
|
128
|
-
)}
|
|
129
|
-
<div className="relative">
|
|
130
|
-
<ConnectorLines
|
|
131
|
-
depth={depth}
|
|
132
|
-
isLast={isLast}
|
|
133
|
-
widthScale={2}
|
|
134
|
-
topPad="calc(0.15rem + var(--spacing-vsp-xs))"
|
|
135
|
-
/>
|
|
136
|
-
<div
|
|
137
|
-
className="flex w-full items-center justify-between text-small font-semibold pt-[0.15rem] text-fg"
|
|
138
|
-
style={{ paddingLeft }}
|
|
139
|
-
>
|
|
140
|
-
{node.href ? (
|
|
141
|
-
<a
|
|
142
|
-
href={node.href}
|
|
143
|
-
className="flex-1 flex items-start gap-hsp-xs py-vsp-xs text-fg hover:text-accent hover:underline focus:underline"
|
|
144
|
-
>
|
|
145
|
-
{depth === 0 && (
|
|
146
|
-
<span className="flex h-[1lh] items-center">
|
|
147
|
-
<CategoryLinkIcon className="w-[18px] 2xl:w-[24px]" />
|
|
148
|
-
</span>
|
|
149
|
-
)}
|
|
150
|
-
{node.label}
|
|
151
|
-
</a>
|
|
152
|
-
) : (
|
|
153
|
-
<button
|
|
154
|
-
type="button"
|
|
155
|
-
onClick={toggle}
|
|
156
|
-
className="flex-1 py-vsp-xs text-left hover:text-accent hover:underline focus:underline"
|
|
157
|
-
>
|
|
158
|
-
{node.label}
|
|
159
|
-
</button>
|
|
160
|
-
)}
|
|
161
|
-
<button
|
|
162
|
-
type="button"
|
|
163
|
-
onClick={toggle}
|
|
164
|
-
className="aspect-square flex items-center justify-center w-[1.75rem] border-y border-l border-muted hover:underline focus:underline"
|
|
165
|
-
aria-expanded={open}
|
|
166
|
-
aria-label={open ? `Collapse ${node.label}` : `Expand ${node.label}`}
|
|
167
|
-
>
|
|
168
|
-
<ChevronRight className={`h-icon-xs w-icon-xs transition-transform duration-150 ${open ? "rotate-90" : ""} text-muted`} />
|
|
169
|
-
</button>
|
|
170
|
-
</div>
|
|
171
|
-
</div>
|
|
172
|
-
{open && (
|
|
173
|
-
<div>
|
|
174
|
-
<NodeList nodes={node.children} depth={depth + 1} />
|
|
175
|
-
</div>
|
|
176
|
-
)}
|
|
177
|
-
</div>
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function LeafNode({
|
|
182
|
-
node,
|
|
183
|
-
depth,
|
|
184
|
-
isLast,
|
|
185
|
-
}: {
|
|
186
|
-
node: NavNode;
|
|
187
|
-
depth: number;
|
|
188
|
-
isLast: boolean;
|
|
189
|
-
}) {
|
|
190
|
-
if (!node.href) return null;
|
|
191
|
-
const isRoot = depth === 0;
|
|
192
|
-
const paddingLeft = padLeft(depth);
|
|
193
|
-
|
|
194
|
-
const topPad = isRoot
|
|
195
|
-
? "calc(var(--spacing-vsp-xs) + 0.15rem)"
|
|
196
|
-
: "var(--spacing-vsp-2xs)";
|
|
197
|
-
|
|
198
|
-
return (
|
|
199
|
-
<div>
|
|
200
|
-
<div className="relative">
|
|
201
|
-
<ConnectorLines depth={depth} isLast={isLast} widthScale={2} topPad={topPad} />
|
|
202
|
-
<a
|
|
203
|
-
href={node.href}
|
|
204
|
-
className={isRoot
|
|
205
|
-
? "flex items-start gap-hsp-xs py-[calc(var(--spacing-vsp-xs)+0.15rem)] text-small font-semibold text-fg hover:text-accent hover:underline focus:underline"
|
|
206
|
-
: `block py-vsp-2xs ${isLast ? "pb-vsp-xs" : ""} text-small text-fg hover:text-accent hover:underline focus:underline`
|
|
207
|
-
}
|
|
208
|
-
style={{ paddingLeft }}
|
|
209
|
-
>
|
|
210
|
-
{isRoot && (
|
|
211
|
-
<span className="flex h-[1lh] items-center">
|
|
212
|
-
<CategoryLinkIcon className="w-[18px] 2xl:w-[24px]" />
|
|
213
|
-
</span>
|
|
214
|
-
)}
|
|
215
|
-
{node.label}
|
|
216
|
-
</a>
|
|
217
|
-
</div>
|
|
218
|
-
</div>
|
|
219
|
-
);
|
|
220
|
-
}
|
|
1
|
+
// Thin re-export shim. SiteTreeNav moved into the package
|
|
2
|
+
// (`@takazudo/zudo-doc/site-tree-nav-island`) as part of the package-first
|
|
3
|
+
// migration (#2344, S2). Host code using `@/components/site-tree-nav`
|
|
4
|
+
// still resolves correctly; the implementation lives in the package.
|
|
5
|
+
export { SiteTreeNav } from "@takazudo/zudo-doc/site-tree-nav-island";
|
|
6
|
+
export type { SiteTreeNavProps } from "@takazudo/zudo-doc/site-tree-nav-island";
|
|
@@ -1,64 +1,39 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Project-side color-scheme helpers.
|
|
3
|
+
*
|
|
4
|
+
* The MECHANISM (palette→CSS injection logic) now lives in the package:
|
|
5
|
+
* `@takazudo/zudo-doc/color-scheme-utils`. This file re-exports those
|
|
6
|
+
* mechanism symbols and adds project-specific thin wrappers that read from
|
|
7
|
+
* this project's `colorSchemes` map and `settings`. The DATA (palette values,
|
|
8
|
+
* scheme names) stays in `./color-schemes` and `./settings`.
|
|
9
|
+
*
|
|
10
|
+
* S9a package-first migration — zudolab/zudo-doc#2333.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
type ColorRef,
|
|
15
|
+
type ColorScheme,
|
|
16
|
+
SEMANTIC_DEFAULTS,
|
|
17
|
+
SEMANTIC_CSS_NAMES,
|
|
18
|
+
resolveColor,
|
|
19
|
+
resolveSemanticColors,
|
|
20
|
+
schemeToCssPairs,
|
|
21
|
+
generateCssCustomProperties as generateCssCustomPropertiesFromScheme,
|
|
22
|
+
generateLightDarkCssProperties as generateLightDarkCssPropertiesFromSchemes,
|
|
23
|
+
} from "@takazudo/zudo-doc/color-scheme-utils";
|
|
24
|
+
import {
|
|
25
|
+
generateCssCustomProperties as _generateCssCustomProperties,
|
|
26
|
+
generateLightDarkCssProperties as _generateLightDarkCssProperties,
|
|
27
|
+
} from "@takazudo/zudo-doc/color-scheme-utils";
|
|
28
|
+
|
|
29
|
+
import { colorSchemes } from "./color-schemes";
|
|
2
30
|
import { settings } from "./settings";
|
|
3
31
|
|
|
4
|
-
/** Default mapping: semantic token name → palette index */
|
|
5
|
-
export const SEMANTIC_DEFAULTS: Record<string, number> = {
|
|
6
|
-
surface: 0,
|
|
7
|
-
muted: 8,
|
|
8
|
-
accent: 5,
|
|
9
|
-
accentHover: 14,
|
|
10
|
-
codeBg: 10,
|
|
11
|
-
codeFg: 11,
|
|
12
|
-
success: 2,
|
|
13
|
-
danger: 1,
|
|
14
|
-
warning: 3,
|
|
15
|
-
info: 4,
|
|
16
|
-
mermaidNodeBg: 9,
|
|
17
|
-
mermaidText: 11,
|
|
18
|
-
mermaidLine: 8,
|
|
19
|
-
mermaidLabelBg: 10,
|
|
20
|
-
mermaidNoteBg: 0,
|
|
21
|
-
chatUserBg: 5,
|
|
22
|
-
chatUserText: 9,
|
|
23
|
-
chatAssistantBg: 9,
|
|
24
|
-
chatAssistantText: 11,
|
|
25
|
-
imageOverlayBg: 0,
|
|
26
|
-
imageOverlayFg: 11,
|
|
27
|
-
matchedKeywordBg: 3,
|
|
28
|
-
matchedKeywordFg: 15,
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export const SEMANTIC_CSS_NAMES: Record<string, string> = {
|
|
32
|
-
surface: "--zd-surface",
|
|
33
|
-
muted: "--zd-muted",
|
|
34
|
-
accent: "--zd-accent",
|
|
35
|
-
accentHover: "--zd-accent-hover",
|
|
36
|
-
codeBg: "--zd-code-bg",
|
|
37
|
-
codeFg: "--zd-code-fg",
|
|
38
|
-
success: "--zd-success",
|
|
39
|
-
danger: "--zd-danger",
|
|
40
|
-
warning: "--zd-warning",
|
|
41
|
-
info: "--zd-info",
|
|
42
|
-
mermaidNodeBg: "--zd-mermaid-node-bg",
|
|
43
|
-
mermaidText: "--zd-mermaid-text",
|
|
44
|
-
mermaidLine: "--zd-mermaid-line",
|
|
45
|
-
mermaidLabelBg: "--zd-mermaid-label-bg",
|
|
46
|
-
mermaidNoteBg: "--zd-mermaid-note-bg",
|
|
47
|
-
chatUserBg: "--zd-chat-user-bg",
|
|
48
|
-
chatUserText: "--zd-chat-user-text",
|
|
49
|
-
chatAssistantBg: "--zd-chat-assistant-bg",
|
|
50
|
-
chatAssistantText: "--zd-chat-assistant-text",
|
|
51
|
-
imageOverlayBg: "--zd-image-overlay-bg",
|
|
52
|
-
imageOverlayFg: "--zd-image-overlay-fg",
|
|
53
|
-
matchedKeywordBg: "--zd-matched-keyword-bg",
|
|
54
|
-
matchedKeywordFg: "--zd-matched-keyword-fg",
|
|
55
|
-
};
|
|
56
|
-
|
|
57
32
|
export const lightDarkPairings = [
|
|
58
33
|
{ light: "Default Light", dark: "Default Dark", label: "Default" },
|
|
59
34
|
];
|
|
60
35
|
|
|
61
|
-
export function getActiveScheme()
|
|
36
|
+
export function getActiveScheme() {
|
|
62
37
|
const scheme = colorSchemes[settings.colorScheme];
|
|
63
38
|
if (!scheme) {
|
|
64
39
|
throw new Error(`Unknown color scheme: "${settings.colorScheme}". Available: ${Object.keys(colorSchemes).join(", ")}`);
|
|
@@ -66,93 +41,12 @@ export function getActiveScheme(): ColorScheme {
|
|
|
66
41
|
return scheme;
|
|
67
42
|
}
|
|
68
43
|
|
|
69
|
-
/**
|
|
70
|
-
* - number → palette[value]
|
|
71
|
-
* - string → used as-is
|
|
72
|
-
* - undefined → fallback */
|
|
73
|
-
export function resolveColor(
|
|
74
|
-
value: ColorRef | undefined,
|
|
75
|
-
palette: string[],
|
|
76
|
-
fallback: string,
|
|
77
|
-
): string {
|
|
78
|
-
if (value === undefined) return fallback;
|
|
79
|
-
if (typeof value === "number") return palette[value] ?? fallback;
|
|
80
|
-
return value;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/** Resolve semantic colors with fallbacks to default palette slots */
|
|
84
|
-
export function resolveSemanticColors(scheme: ColorScheme) {
|
|
85
|
-
const p = scheme.palette;
|
|
86
|
-
return {
|
|
87
|
-
surface: resolveColor(scheme.semantic?.surface, p, p[0]),
|
|
88
|
-
muted: resolveColor(scheme.semantic?.muted, p, p[8]),
|
|
89
|
-
accent: resolveColor(scheme.semantic?.accent, p, p[5]),
|
|
90
|
-
accentHover: resolveColor(scheme.semantic?.accentHover, p, p[14]),
|
|
91
|
-
codeBg: resolveColor(scheme.semantic?.codeBg, p, p[10]),
|
|
92
|
-
codeFg: resolveColor(scheme.semantic?.codeFg, p, p[11]),
|
|
93
|
-
success: resolveColor(scheme.semantic?.success, p, p[2]),
|
|
94
|
-
danger: resolveColor(scheme.semantic?.danger, p, p[1]),
|
|
95
|
-
warning: resolveColor(scheme.semantic?.warning, p, p[3]),
|
|
96
|
-
info: resolveColor(scheme.semantic?.info, p, p[4]),
|
|
97
|
-
mermaidNodeBg: resolveColor(scheme.semantic?.mermaidNodeBg, p, p[9]),
|
|
98
|
-
mermaidText: resolveColor(scheme.semantic?.mermaidText, p, p[11]),
|
|
99
|
-
mermaidLine: resolveColor(scheme.semantic?.mermaidLine, p, p[8]),
|
|
100
|
-
mermaidLabelBg: resolveColor(scheme.semantic?.mermaidLabelBg, p, p[10]),
|
|
101
|
-
mermaidNoteBg: resolveColor(scheme.semantic?.mermaidNoteBg, p, p[0]),
|
|
102
|
-
chatUserBg: resolveColor(scheme.semantic?.chatUserBg, p, p[5]),
|
|
103
|
-
chatUserText: resolveColor(scheme.semantic?.chatUserText, p, p[9]),
|
|
104
|
-
chatAssistantBg: resolveColor(scheme.semantic?.chatAssistantBg, p, p[9]),
|
|
105
|
-
chatAssistantText: resolveColor(scheme.semantic?.chatAssistantText, p, p[11]),
|
|
106
|
-
imageOverlayBg: resolveColor(scheme.semantic?.imageOverlayBg, p, p[0]),
|
|
107
|
-
imageOverlayFg: resolveColor(scheme.semantic?.imageOverlayFg, p, p[11]),
|
|
108
|
-
matchedKeywordBg: resolveColor(scheme.semantic?.matchedKeywordBg, p, p[3]),
|
|
109
|
-
matchedKeywordFg: resolveColor(scheme.semantic?.matchedKeywordFg, p, p[15]),
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export function schemeToCssPairs(scheme: ColorScheme): [string, string][] {
|
|
114
|
-
const p = scheme.palette;
|
|
115
|
-
const sem = resolveSemanticColors(scheme);
|
|
116
|
-
return [
|
|
117
|
-
["--zd-bg", resolveColor(scheme.background, p, p[0])],
|
|
118
|
-
["--zd-fg", resolveColor(scheme.foreground, p, p[15])],
|
|
119
|
-
["--zd-cursor", resolveColor(scheme.cursor, p, p[6])], // intentionally inert/vestigial: exposed in the design-token panel but no CSS rule consumes it (no caret-color wiring); mirrors shikiTheme's status
|
|
120
|
-
["--zd-sel-bg", resolveColor(scheme.selectionBg, p, resolveColor(scheme.background, p, p[0]))],
|
|
121
|
-
["--zd-sel-fg", resolveColor(scheme.selectionFg, p, resolveColor(scheme.foreground, p, p[15]))],
|
|
122
|
-
...p.map((color, i) => [`--zd-${i}`, color] as [string, string]),
|
|
123
|
-
["--zd-surface", sem.surface],
|
|
124
|
-
["--zd-muted", sem.muted],
|
|
125
|
-
["--zd-accent", sem.accent],
|
|
126
|
-
["--zd-accent-hover", sem.accentHover],
|
|
127
|
-
["--zd-code-bg", sem.codeBg],
|
|
128
|
-
["--zd-code-fg", sem.codeFg],
|
|
129
|
-
["--zd-success", sem.success],
|
|
130
|
-
["--zd-danger", sem.danger],
|
|
131
|
-
["--zd-warning", sem.warning],
|
|
132
|
-
["--zd-info", sem.info],
|
|
133
|
-
["--zd-mermaid-node-bg", sem.mermaidNodeBg],
|
|
134
|
-
["--zd-mermaid-text", sem.mermaidText],
|
|
135
|
-
["--zd-mermaid-line", sem.mermaidLine],
|
|
136
|
-
["--zd-mermaid-label-bg", sem.mermaidLabelBg],
|
|
137
|
-
["--zd-mermaid-note-bg", sem.mermaidNoteBg],
|
|
138
|
-
["--zd-chat-user-bg", sem.chatUserBg],
|
|
139
|
-
["--zd-chat-user-text", sem.chatUserText],
|
|
140
|
-
["--zd-chat-assistant-bg", sem.chatAssistantBg],
|
|
141
|
-
["--zd-chat-assistant-text", sem.chatAssistantText],
|
|
142
|
-
["--zd-image-overlay-bg", sem.imageOverlayBg],
|
|
143
|
-
["--zd-image-overlay-fg", sem.imageOverlayFg],
|
|
144
|
-
["--zd-matched-keyword-bg", sem.matchedKeywordBg],
|
|
145
|
-
["--zd-matched-keyword-fg", sem.matchedKeywordFg],
|
|
146
|
-
];
|
|
147
|
-
}
|
|
148
|
-
|
|
44
|
+
/** Generate `:root { --zd-* }` CSS for the project's active single scheme. */
|
|
149
45
|
export function generateCssCustomProperties(): string {
|
|
150
|
-
|
|
151
|
-
const pairs = schemeToCssPairs(scheme);
|
|
152
|
-
const lines = [":root {", ...pairs.map(([prop, value]) => ` ${prop}: ${value};`), "}"];
|
|
153
|
-
return lines.join("\n");
|
|
46
|
+
return _generateCssCustomProperties(getActiveScheme());
|
|
154
47
|
}
|
|
155
48
|
|
|
49
|
+
/** Generate `:root { --zd-*: light-dark(…) }` CSS for the project's configured light/dark pair. */
|
|
156
50
|
export function generateLightDarkCssProperties(): string {
|
|
157
51
|
if (!settings.colorMode) {
|
|
158
52
|
throw new Error("colorMode is not configured");
|
|
@@ -162,23 +56,5 @@ export function generateLightDarkCssProperties(): string {
|
|
|
162
56
|
const dark = colorSchemes[darkScheme];
|
|
163
57
|
if (!light) throw new Error(`Unknown light scheme: "${lightScheme}"`);
|
|
164
58
|
if (!dark) throw new Error(`Unknown dark scheme: "${darkScheme}"`);
|
|
165
|
-
|
|
166
|
-
const lightPairs = schemeToCssPairs(light);
|
|
167
|
-
const darkPairs = schemeToCssPairs(dark);
|
|
168
|
-
|
|
169
|
-
if (lightPairs.length !== darkPairs.length) {
|
|
170
|
-
throw new Error(`Light scheme has ${lightPairs.length} properties but dark scheme has ${darkPairs.length}`);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const lines = [":root {", " color-scheme: light dark;"];
|
|
174
|
-
for (let i = 0; i < lightPairs.length; i++) {
|
|
175
|
-
const lightPair = lightPairs[i];
|
|
176
|
-
const darkPair = darkPairs[i];
|
|
177
|
-
if (!lightPair || !darkPair) continue;
|
|
178
|
-
const [prop, lightVal] = lightPair;
|
|
179
|
-
const darkVal = darkPair[1];
|
|
180
|
-
lines.push(` ${prop}: light-dark(${lightVal}, ${darkVal});`);
|
|
181
|
-
}
|
|
182
|
-
lines.push("}");
|
|
183
|
-
return lines.join("\n");
|
|
59
|
+
return _generateLightDarkCssProperties(light, dark);
|
|
184
60
|
}
|
|
@@ -74,6 +74,9 @@ const translations: Record<string, Record<string, string>> = {
|
|
|
74
74
|
"search.placeholder": "Type to search...",
|
|
75
75
|
"search.shortcutHint": "to open search from anywhere",
|
|
76
76
|
"search.resultCount": "{count} results",
|
|
77
|
+
"search.unavailable": "Search unavailable",
|
|
78
|
+
"search.loadingIndex": "Loading search index…",
|
|
79
|
+
"search.noResults": "No results found.",
|
|
77
80
|
"code.copy": "Copy code",
|
|
78
81
|
"code.copied": "Copied!",
|
|
79
82
|
"code.wrapToggle": "Toggle word wrap",
|
|
@@ -134,6 +137,9 @@ const translations: Record<string, Record<string, string>> = {
|
|
|
134
137
|
"search.placeholder": "検索したい単語を入力",
|
|
135
138
|
"search.shortcutHint": "いつでも検索バーを開ける",
|
|
136
139
|
"search.resultCount": "{count} 件",
|
|
140
|
+
"search.unavailable": "検索を利用できません",
|
|
141
|
+
"search.loadingIndex": "検索インデックスを読み込み中…",
|
|
142
|
+
"search.noResults": "検索結果が見つかりませんでした。",
|
|
137
143
|
"code.copy": "コードをコピー",
|
|
138
144
|
"code.copied": "コピーしました!",
|
|
139
145
|
"code.wrapToggle": "折り返し切替",
|
|
@@ -194,6 +200,9 @@ const translations: Record<string, Record<string, string>> = {
|
|
|
194
200
|
"search.placeholder": "Suchbegriff eingeben...",
|
|
195
201
|
"search.shortcutHint": "Suche von überall öffnen",
|
|
196
202
|
"search.resultCount": "{count} Ergebnisse",
|
|
203
|
+
"search.unavailable": "Suche nicht verfügbar",
|
|
204
|
+
"search.loadingIndex": "Suchindex wird geladen…",
|
|
205
|
+
"search.noResults": "Keine Ergebnisse gefunden.",
|
|
197
206
|
"code.copy": "Code kopieren",
|
|
198
207
|
"code.copied": "Kopiert!",
|
|
199
208
|
"code.wrapToggle": "Zeilenumbruch umschalten",
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// z-index design tokens — single source of truth.
|
|
2
2
|
//
|
|
3
3
|
// This file is the ONE place z-index tiers are defined. The CSS `@theme` block
|
|
4
|
-
// in `src/styles/global.css` is GENERATED from this list by
|
|
5
|
-
// `
|
|
6
|
-
// generated block. `pnpm check:z-index` re-runs the generator
|
|
7
|
-
// fails on drift, so the committed CSS can never silently
|
|
4
|
+
// in `src/styles/global.css` is GENERATED from this list by the
|
|
5
|
+
// `gen-z-index` bin from `@takazudo/zudo-doc` (run `pnpm gen:z-index`); never
|
|
6
|
+
// hand-edit the generated block. `pnpm check:z-index` re-runs the generator
|
|
7
|
+
// into a buffer and fails on drift, so the committed CSS can never silently
|
|
8
|
+
// diverge from this list.
|
|
8
9
|
//
|
|
9
10
|
// Strategy (from zudolab/zudo-css-wisdom z-index-strategy): semantic single-
|
|
10
11
|
// namespace tokens — names describe ROLES, never magnitudes. One flat ordered
|