create-zudo-doc 0.2.21 → 1.0.0
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/compose.d.ts +6 -3
- package/dist/compose.js +6 -4
- package/dist/features/image-enlarge.d.ts +22 -12
- package/dist/features/image-enlarge.js +23 -191
- package/dist/scaffold.d.ts +11 -0
- package/dist/scaffold.js +51 -24
- package/dist/settings-gen.js +4 -0
- 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/_mdx-components.ts +64 -185
- package/templates/base/pages/index.tsx +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/_extract-headings.ts +21 -295
- 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/_math-block.tsx +4 -63
- 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 -59
- 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/src/components/ai-chat-modal.tsx +9 -8
- package/templates/base/src/components/content/code-group.tsx +3 -76
- package/templates/base/src/components/content/content-admonition.tsx +4 -56
- 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/config/color-scheme-utils.ts +34 -158
- package/templates/base/src/config/i18n.ts +9 -0
- package/templates/base/src/config/settings-types.ts +34 -172
- package/templates/base/src/config/z-index-tokens.ts +5 -4
- package/templates/base/src/styles/global.css +40 -587
- 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/i18n/files/pages/[locale]/index.tsx +1 -1
- 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/versioning/files/pages/lib/_versions-page.tsx +21 -73
- package/templates/base/pages/404.tsx +0 -61
- package/templates/base/pages/robots.txt.tsx +0 -29
- package/templates/base/pages/sitemap.xml.tsx +0 -59
- package/templates/base/plugins/connect-adapter.mjs +0 -169
- package/templates/base/plugins/copy-public-plugin.mjs +0 -58
- 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/base/src/components/site-tree-nav.tsx +0 -220
- 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/docTags/files/pages/[locale]/docs/tags/[tag].tsx +0 -59
- package/templates/features/docTags/files/pages/[locale]/docs/tags/index.tsx +0 -39
- package/templates/features/docTags/files/pages/docs/tags/[tag].tsx +0 -43
- package/templates/features/docTags/files/pages/docs/tags/index.tsx +0 -20
- package/templates/features/llmsTxt/files/plugins/llms-txt-plugin.mjs +0 -93
- package/templates/features/versioning/files/pages/[locale]/docs/versions.tsx +0 -48
- package/templates/features/versioning/files/pages/docs/versions.tsx +0 -20
|
@@ -1,292 +1,58 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// with the
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// appear in the sitemap even though they're hidden from nav.
|
|
14
|
-
// - toRouteSlug() is applied to all entry ids so category index pages
|
|
15
|
-
// (e.g. "getting-started/index" → "getting-started") get correct URLs.
|
|
16
|
-
// - Auto-generated category index pages (categories without index.mdx) are
|
|
17
|
-
// emitted by building the nav tree and calling collectAutoIndexNodes.
|
|
18
|
-
|
|
19
|
-
import { loadDocs } from "../_data";
|
|
20
|
-
import { mergeLocaleDocs } from "./locale-merge";
|
|
21
|
-
import { resolveNavSource, resolveVersionedLocaleSource } from "./_nav-source-docs";
|
|
1
|
+
// Thin stub — route-enumerators moved to the package (epic #2344, S6).
|
|
2
|
+
// Calls `createRouteEnumerators(ctx)` from @takazudo/zudo-doc/route-enumerators
|
|
3
|
+
// with the host singletons injected, then re-exports the resulting enumeration
|
|
4
|
+
// functions so all existing call sites continue to work unchanged.
|
|
5
|
+
|
|
6
|
+
import { createRouteEnumerators } from "@takazudo/zudo-doc/route-enumerators";
|
|
7
|
+
import type {
|
|
8
|
+
DocsEntryForTags,
|
|
9
|
+
TagInfoForEnum,
|
|
10
|
+
DocPageEntry,
|
|
11
|
+
DocNavNode,
|
|
12
|
+
} from "@takazudo/zudo-doc/route-enumerators";
|
|
22
13
|
import { settings } from "@/config/settings";
|
|
23
14
|
import { defaultLocale, type Locale } from "@/config/i18n";
|
|
24
|
-
import
|
|
25
|
-
import type
|
|
26
|
-
import { docsUrl, versionedDocsUrl, withBase } from "@/utils/base";
|
|
15
|
+
import { docsUrl, versionedDocsUrl, withBase, isDefaultLocaleOnlyPath } from "@/utils/base";
|
|
16
|
+
import { buildNavTree, collectAutoIndexNodes, type CategoryMeta } from "@/utils/docs";
|
|
27
17
|
import { collectTags } from "@/utils/tags";
|
|
28
18
|
import { toRouteSlug } from "@/utils/slug";
|
|
29
|
-
import {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
} from "
|
|
33
|
-
|
|
34
|
-
// ---------------------------------------------------------------------------
|
|
35
|
-
// enumerateDocsRoutes
|
|
36
|
-
// ---------------------------------------------------------------------------
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Enumerate all doc page URLs for a locale.
|
|
40
|
-
*
|
|
41
|
-
* For the default locale: loads the "docs" collection directly.
|
|
42
|
-
* For non-default locales: inlines a locale-first merge — locale docs take
|
|
43
|
-
* priority; base EN docs fill in slugs not covered by the locale collection,
|
|
44
|
-
* with default-locale-only paths excluded. A nav-tree pass then adds
|
|
45
|
-
* auto-generated category index pages.
|
|
46
|
-
*
|
|
47
|
-
* Applies toRouteSlug so "category/index" entries become "category/" URLs.
|
|
48
|
-
* Returns deduplicated URL strings with base prefix and trailing slash.
|
|
49
|
-
*/
|
|
50
|
-
export function enumerateDocsRoutes(locale: string): string[] {
|
|
51
|
-
const urls: string[] = [];
|
|
52
|
-
|
|
53
|
-
// Identity-stable nav source — same instances the doc routes use, so the
|
|
54
|
-
// nav-tree fast-path applies here too (#1902).
|
|
55
|
-
const { docs: allDocs, navDocs, categoryMeta } = resolveNavSource(
|
|
56
|
-
locale as Locale,
|
|
57
|
-
undefined,
|
|
58
|
-
{ applyDefaultLocaleOnlyFilter: true, keepUnlisted: true },
|
|
59
|
-
);
|
|
60
|
-
const tree = buildNavTree(navDocs, locale as Locale, categoryMeta);
|
|
61
|
-
|
|
62
|
-
for (const doc of allDocs) {
|
|
63
|
-
// A `category_no_page` index.mdx is metadata-only — no route, so no sitemap
|
|
64
|
-
// URL. Same exclusion the doc-route paths() apply (zfb retains every .mdx
|
|
65
|
-
// as a collection entry, so the skip must be explicit).
|
|
66
|
-
if (doc.data.category_no_page === true) continue;
|
|
67
|
-
// Canonical route slug via the one shared rule (@/utils/slug). `doc.id` is
|
|
68
|
-
// already `toRouteSlug(doc.slug)` (bridged through stripIndexSuffix in
|
|
69
|
-
// pages/_data.ts), so a bare root index.mdx is "" here → `/docs/` — the
|
|
70
|
-
// canonical root URL (#1891). The `toRouteSlug` fallback is a redundant
|
|
71
|
-
// safety re-application of the same rule (idempotent on the already-
|
|
72
|
-
// stripped id); kept so this enumerator's slug derivation reads as a
|
|
73
|
-
// single explicit call to the canonical helper.
|
|
74
|
-
urls.push(docsUrl(doc.data.slug ?? toRouteSlug(doc.id), locale as Locale));
|
|
75
|
-
}
|
|
76
|
-
for (const node of collectAutoIndexNodes(tree)) {
|
|
77
|
-
urls.push(docsUrl(node.slug, locale as Locale));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return [...new Set(urls)];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// ---------------------------------------------------------------------------
|
|
84
|
-
// enumerateTagsRoutes
|
|
85
|
-
// ---------------------------------------------------------------------------
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Enumerate tag-index and per-tag URLs for a locale.
|
|
89
|
-
*
|
|
90
|
-
* Uses the same tag map as the tag pages (unlisted + draft excluded) so the
|
|
91
|
-
* sitemap lists exactly the same tag pages that get built.
|
|
92
|
-
*
|
|
93
|
-
* Returns:
|
|
94
|
-
* - /docs/tags/ (or /{locale}/docs/tags/)
|
|
95
|
-
* - /docs/tags/{tag}/ (or /{locale}/docs/tags/{tag}/) for each unique tag
|
|
96
|
-
*/
|
|
97
|
-
export function enumerateTagsRoutes(locale: string): string[] {
|
|
98
|
-
if (!settings.docTags) return [];
|
|
99
|
-
|
|
100
|
-
const urls: string[] = [];
|
|
101
|
-
|
|
102
|
-
const tagsBase =
|
|
103
|
-
locale === defaultLocale ? "/docs/tags" : `/${locale}/docs/tags`;
|
|
104
|
-
urls.push(withBase(tagsBase));
|
|
105
|
-
|
|
106
|
-
// Collect tags from the same merged doc set the tag pages use.
|
|
107
|
-
// Filter unlisted + draft + category_no_page — mirrors the tag [tag].tsx
|
|
108
|
-
// pages so the sitemap lists exactly the tag pages that get built (a
|
|
109
|
-
// category_no_page index has no route, so a tag it carries must not coin a
|
|
110
|
-
// tag page that links back to it). The category_no_page drop happens AFTER
|
|
111
|
-
// the locale merge so a locale override carrying the flag first wins the
|
|
112
|
-
// merge — pre-merge filtering would let the unflagged base doc resurface.
|
|
113
|
-
let docs: DocsEntry[];
|
|
114
|
-
if (locale === defaultLocale) {
|
|
115
|
-
docs = loadDocs("docs").filter(
|
|
116
|
-
(d) => !d.data.unlisted && !d.data.draft && !d.data.category_no_page,
|
|
117
|
-
);
|
|
118
|
-
} else {
|
|
119
|
-
const result = mergeLocaleDocs({
|
|
120
|
-
baseDocs: loadDocs("docs").filter((d) => !d.data.draft),
|
|
121
|
-
localeDocs: loadDocs(`docs-${locale}`).filter((d) => !d.data.draft),
|
|
122
|
-
applyDefaultLocaleOnlyFilter: true,
|
|
123
|
-
});
|
|
124
|
-
docs = result.docs.filter((d) => !d.data.category_no_page);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const tagMap = collectTags(docs, (id, data) => data.slug ?? toRouteSlug(id));
|
|
128
|
-
|
|
129
|
-
for (const tag of tagMap.keys()) {
|
|
130
|
-
// Tag segment URL-encoded — these URLs feed the sitemap, which must
|
|
131
|
-
// carry well-formed encoded URLs (e.g. "type:guide" → "type%3Aguide").
|
|
132
|
-
// Route params (the page paths() functions) stay raw.
|
|
133
|
-
const encoded = encodeURIComponent(tag);
|
|
134
|
-
const tagPath =
|
|
135
|
-
locale === defaultLocale
|
|
136
|
-
? `/docs/tags/${encoded}`
|
|
137
|
-
: `/${locale}/docs/tags/${encoded}`;
|
|
138
|
-
urls.push(withBase(tagPath));
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return urls;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// ---------------------------------------------------------------------------
|
|
145
|
-
// enumerateVersionedRoutes
|
|
146
|
-
// ---------------------------------------------------------------------------
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Enumerate doc URLs for a single (version, locale) combination.
|
|
150
|
-
*
|
|
151
|
-
* For the default locale: loads `docs-v-${version.slug}`.
|
|
152
|
-
* For non-default locales: locale-first merge — locale-specific collection
|
|
153
|
-
* takes priority; base EN collection fills in pages not yet translated.
|
|
154
|
-
* If the locale collection doesn't exist for this version, all pages fall
|
|
155
|
-
* back to the EN base (matching the page module's behaviour).
|
|
156
|
-
*
|
|
157
|
-
* Returns versioned URLs like /v/{version}/docs/{slug}/ or
|
|
158
|
-
* /v/{version}/{locale}/docs/{slug}/.
|
|
159
|
-
*/
|
|
160
|
-
export function enumerateVersionedRoutes(
|
|
161
|
-
version: VersionConfig,
|
|
162
|
-
locale: string,
|
|
163
|
-
): string[] {
|
|
164
|
-
const urls: string[] = [];
|
|
165
|
-
|
|
166
|
-
if (locale === defaultLocale) {
|
|
167
|
-
// Versioned EN base — identity-stable source (#1902).
|
|
168
|
-
const { docs: allDocs, navDocs, categoryMeta } = resolveNavSource(
|
|
169
|
-
"en",
|
|
170
|
-
version.slug,
|
|
171
|
-
);
|
|
172
|
-
const tree = buildNavTree(navDocs, "en", categoryMeta);
|
|
173
|
-
|
|
174
|
-
for (const doc of allDocs) {
|
|
175
|
-
// category_no_page index.mdx → no route, no sitemap URL (see paths()).
|
|
176
|
-
if (doc.data.category_no_page === true) continue;
|
|
177
|
-
const slug = doc.data.slug ?? toRouteSlug(doc.id);
|
|
178
|
-
urls.push(versionedDocsUrl(slug, version.slug));
|
|
179
|
-
}
|
|
180
|
-
for (const node of collectAutoIndexNodes(tree)) {
|
|
181
|
-
urls.push(versionedDocsUrl(node.slug, version.slug));
|
|
182
|
-
}
|
|
183
|
-
} else {
|
|
184
|
-
const localeDir = version.locales?.[locale]?.dir;
|
|
19
|
+
import type { DocsEntry } from "@/types/docs-entry";
|
|
20
|
+
import { loadDocs } from "../_data";
|
|
21
|
+
import { resolveNavSource, resolveVersionedLocaleSource } from "./_nav-source-docs";
|
|
22
|
+
import { mergeLocaleDocs } from "./locale-merge";
|
|
185
23
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
24
|
+
export const {
|
|
25
|
+
enumerateDocsRoutes,
|
|
26
|
+
enumerateTagsRoutes,
|
|
27
|
+
enumerateVersionedRoutes,
|
|
28
|
+
enumerateAllRoutes,
|
|
29
|
+
} = createRouteEnumerators({
|
|
30
|
+
defaultLocale,
|
|
31
|
+
getLocaleKeys: () => Object.keys(settings.locales),
|
|
32
|
+
getVersions: () => settings.versions,
|
|
33
|
+
getDocTags: () => settings.docTags,
|
|
34
|
+
docsUrl,
|
|
35
|
+
versionedDocsUrl,
|
|
36
|
+
withBase,
|
|
37
|
+
loadDocs,
|
|
38
|
+
isDefaultLocaleOnlyPath,
|
|
39
|
+
// The factory describes collectTags / buildNavTree with the package's minimal
|
|
40
|
+
// structural slots (DocsEntryForTags / DocPageEntry / Map<string, unknown> /
|
|
41
|
+
// TagInfoForEnum). The host helpers are typed against the concrete project
|
|
42
|
+
// types (DocsEntry / NavNode / the Locale union / TagInfo) but are runtime-
|
|
43
|
+
// identical, so the stub adapts them with thin casting wrappers at the
|
|
44
|
+
// injection boundary where the host owns the type knowledge.
|
|
45
|
+
collectTags: (docs: DocsEntryForTags[], slugFn): Map<string, TagInfoForEnum> =>
|
|
46
|
+
collectTags(docs as unknown as DocsEntry[], slugFn),
|
|
47
|
+
toRouteSlug,
|
|
48
|
+
buildNavTree: (docs: DocPageEntry[], locale: string, categoryMeta: Map<string, unknown>) =>
|
|
49
|
+
buildNavTree(
|
|
50
|
+
docs as unknown as DocsEntry[],
|
|
191
51
|
locale as Locale,
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if (doc.data.category_no_page === true) continue;
|
|
200
|
-
const slug = doc.data.slug ?? toRouteSlug(doc.id);
|
|
201
|
-
urls.push(versionedDocsUrl(slug, version.slug, locale as Locale));
|
|
202
|
-
}
|
|
203
|
-
for (const node of collectAutoIndexNodes(tree)) {
|
|
204
|
-
urls.push(versionedDocsUrl(node.slug, version.slug, locale as Locale));
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
return [...new Set(urls)];
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// ---------------------------------------------------------------------------
|
|
212
|
-
// enumerateAllRoutes
|
|
213
|
-
// ---------------------------------------------------------------------------
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Compose all route enumerators into a deduped Map<url, lastmod>.
|
|
217
|
-
*
|
|
218
|
-
* Covers:
|
|
219
|
-
* - Site root
|
|
220
|
-
* - Default-locale docs + tags
|
|
221
|
-
* - Per-locale homepages, docs, and tags
|
|
222
|
-
* - Versioned EN docs (for each version in settings.versions)
|
|
223
|
-
* - Versioned locale docs (for each locale in settings.locales)
|
|
224
|
-
*
|
|
225
|
-
* The map keys are absolute paths (with settings.base prefix + trailing
|
|
226
|
-
* slash). The sitemap renderer prefixes each with settings.siteUrl.
|
|
227
|
-
*/
|
|
228
|
-
export function enumerateAllRoutes(): Map<string, string> {
|
|
229
|
-
const today = new Date().toISOString().split("T")[0] ?? "";
|
|
230
|
-
const routes = new Map<string, string>();
|
|
231
|
-
|
|
232
|
-
function add(url: string): void {
|
|
233
|
-
if (!routes.has(url)) {
|
|
234
|
-
routes.set(url, today);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// Site root
|
|
239
|
-
add(withBase("/"));
|
|
240
|
-
|
|
241
|
-
// Default locale docs
|
|
242
|
-
for (const url of enumerateDocsRoutes(defaultLocale)) {
|
|
243
|
-
add(url);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// Default locale tags
|
|
247
|
-
for (const url of enumerateTagsRoutes(defaultLocale)) {
|
|
248
|
-
add(url);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// Non-default locales
|
|
252
|
-
for (const locale of Object.keys(settings.locales)) {
|
|
253
|
-
add(withBase(`/${locale}`));
|
|
254
|
-
|
|
255
|
-
for (const url of enumerateDocsRoutes(locale)) {
|
|
256
|
-
add(url);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
for (const url of enumerateTagsRoutes(locale)) {
|
|
260
|
-
add(url);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Versions listing pages — /docs/versions/ and /{locale}/docs/versions/.
|
|
265
|
-
// These static utility pages are built by pages/docs/versions.tsx and
|
|
266
|
-
// pages/[locale]/docs/versions.tsx whenever versioning is configured.
|
|
267
|
-
// They are not part of any content collection so they are added explicitly.
|
|
268
|
-
if (settings.versions) {
|
|
269
|
-
add(withBase("/docs/versions"));
|
|
270
|
-
for (const locale of Object.keys(settings.locales)) {
|
|
271
|
-
add(withBase(`/${locale}/docs/versions`));
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// Versioned docs
|
|
276
|
-
if (settings.versions) {
|
|
277
|
-
for (const version of settings.versions as VersionConfig[]) {
|
|
278
|
-
for (const url of enumerateVersionedRoutes(version, defaultLocale)) {
|
|
279
|
-
add(url);
|
|
280
|
-
}
|
|
281
|
-
// Non-default locales always have versioned pages (they fall back to EN
|
|
282
|
-
// when a locale-specific collection is not configured).
|
|
283
|
-
for (const locale of Object.keys(settings.locales)) {
|
|
284
|
-
for (const url of enumerateVersionedRoutes(version, locale)) {
|
|
285
|
-
add(url);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
return routes;
|
|
292
|
-
}
|
|
52
|
+
categoryMeta as Map<string, CategoryMeta>,
|
|
53
|
+
) as DocNavNode[],
|
|
54
|
+
collectAutoIndexNodes,
|
|
55
|
+
resolveNavSource,
|
|
56
|
+
resolveVersionedLocaleSource,
|
|
57
|
+
mergeLocaleDocs,
|
|
58
|
+
});
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// W6A stub — no-op default export.
|
|
1
|
+
// W6A stub — no-op default + AiChatModal named exports.
|
|
4
2
|
//
|
|
5
|
-
// The
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
3
|
+
// The AiChatModal island now ships from the package
|
|
4
|
+
// (`@takazudo/zudo-doc/ai-chat-modal`); the unconditional
|
|
5
|
+
// `pages/lib/_body-end-islands.tsx` imports it directly from there. This
|
|
6
|
+
// stub exists only so any project-local code that references the
|
|
7
|
+
// `@/components/ai-chat-modal` path still resolves — it renders nothing.
|
|
8
|
+
// Replace this file to wire a project-specific modal.
|
|
10
9
|
import type { JSX } from "preact";
|
|
11
10
|
|
|
12
11
|
function AiChatModal(): JSX.Element | null {
|
|
@@ -15,3 +14,5 @@ function AiChatModal(): JSX.Element | null {
|
|
|
15
14
|
AiChatModal.displayName = "AiChatModal";
|
|
16
15
|
|
|
17
16
|
export default AiChatModal;
|
|
17
|
+
|
|
18
|
+
export { AiChatModal };
|
|
@@ -1,76 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Adapter for zfb's `:::code-group` directive (codeTabs Option A).
|
|
6
|
-
*
|
|
7
|
-
* zfb emits:
|
|
8
|
-
* <CodeGroup tabs={["label1", "label2", ...]}>
|
|
9
|
-
* <pre data-lang="ts">{RAW code text}</pre>
|
|
10
|
-
* <pre data-lang="js">{RAW code text}</pre>
|
|
11
|
-
* </CodeGroup>
|
|
12
|
-
*
|
|
13
|
-
* The existing <Tabs>/<TabItem> UI uses a children-based API, so this
|
|
14
|
-
* component zips the `tabs` label array with the `<pre data-lang>` children
|
|
15
|
-
* by index, wrapping each in a <TabItem> with the matching label.
|
|
16
|
-
*
|
|
17
|
-
* Code inside each <pre> is raw text (NOT syntect-highlighted — the Rust
|
|
18
|
-
* pipeline does not run highlight inside code-group fences). We render
|
|
19
|
-
* the <pre> inside a <TabItem> with explicit styling via Tailwind tokens
|
|
20
|
-
* so it looks like a code block visually.
|
|
21
|
-
*
|
|
22
|
-
* TabsInit (the companion init script) is present in the layout
|
|
23
|
-
* (packages/zudo-doc/src/doclayout/doc-layout-with-defaults.tsx line 433)
|
|
24
|
-
* — we rely on it being there; no duplicate needed here.
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
type Props = {
|
|
28
|
-
tabs?: string[];
|
|
29
|
-
children?: React.ReactNode;
|
|
30
|
-
[key: string]: unknown;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
function toArray(children: React.ReactNode): React.ReactNode[] {
|
|
34
|
-
if (!children) return [];
|
|
35
|
-
if (Array.isArray(children)) return children;
|
|
36
|
-
return [children];
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function CodeGroup({ tabs = [], children, name }: Props) {
|
|
40
|
-
const childArray = toArray(children);
|
|
41
|
-
|
|
42
|
-
// Zip tabs labels with pre children by index. Extra children beyond the
|
|
43
|
-
// tabs array (shouldn't happen in normal zfb output) are ignored.
|
|
44
|
-
const items = tabs.map((label, i) => {
|
|
45
|
-
const child = childArray[i];
|
|
46
|
-
return { label, child };
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
if (items.length === 0) {
|
|
50
|
-
// Degenerate: no tabs — render children as-is.
|
|
51
|
-
return <>{children}</>;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// zfb forwards `:::code-group{name="x"}` as the `name` prop; Tabs persists
|
|
55
|
-
// the active tab per group via `groupId`.
|
|
56
|
-
const groupId = typeof name === "string" ? name : undefined;
|
|
57
|
-
|
|
58
|
-
return (
|
|
59
|
-
<Tabs groupId={groupId}>
|
|
60
|
-
{items.map(({ label, child }, i) => (
|
|
61
|
-
// value is suffixed with the index so two fences sharing a label
|
|
62
|
-
// (e.g. both titled "ts") get distinct stable tab identities; the
|
|
63
|
-
// label stays the visible text.
|
|
64
|
-
<TabItem
|
|
65
|
-
key={`${label}-${i}`}
|
|
66
|
-
label={label}
|
|
67
|
-
value={`${label}-${i}`}
|
|
68
|
-
default={i === 0 ? true : undefined}
|
|
69
|
-
>
|
|
70
|
-
{/* Raw-code <pre> from zfb: apply code-block visual treatment via tokens */}
|
|
71
|
-
<div class="code-group-panel">{child}</div>
|
|
72
|
-
</TabItem>
|
|
73
|
-
))}
|
|
74
|
-
</Tabs>
|
|
75
|
-
);
|
|
76
|
-
}
|
|
1
|
+
// Re-export from the shared package — moved to @takazudo/zudo-doc/code-group
|
|
2
|
+
// as part of the package-first migration (epic #2321, S4 #2327).
|
|
3
|
+
export { CodeGroup } from "@takazudo/zudo-doc/code-group";
|
|
@@ -1,56 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// `makeAdmonitionStub` in pages/_mdx-components.ts with a proper typed
|
|
6
|
-
// component — restoring the first-class admonition components the Astro-era
|
|
7
|
-
// theme shipped (zudolab/zudo-doc#1456), now on the zfb pipeline.
|
|
8
|
-
//
|
|
9
|
-
// These tags arrive from two zfb features: the `directives` map emits them from
|
|
10
|
-
// `:::note` directives, and `githubAlerts` emits Important/Caution from
|
|
11
|
-
// `[!IMPORTANT]`/`[!CAUTION]` blockquotes. The JSX form `<Note title="…">` is
|
|
12
|
-
// also authored directly in MDX. All three paths render through here.
|
|
13
|
-
//
|
|
14
|
-
// Markup contract — KEEP STABLE. The structure below
|
|
15
|
-
// <div data-admonition="<variant>" class="admonition admonition-<variant>">
|
|
16
|
-
// <p class="admonition-title">…</p>
|
|
17
|
-
// <div class="admonition-body">…</div>
|
|
18
|
-
// </div>
|
|
19
|
-
// is the hook both the design-system CSS (`.admonition-<variant>` rules in
|
|
20
|
-
// src/styles/global.css) and the e2e smoke spec (e2e/smoke-admonitions.spec.ts)
|
|
21
|
-
// target. The per-variant color + icon live in CSS keyed off `data-admonition`,
|
|
22
|
-
// so this component stays presentation-agnostic.
|
|
23
|
-
import type { ComponentChildren, VNode } from "preact";
|
|
24
|
-
|
|
25
|
-
export type AdmonitionVariant =
|
|
26
|
-
| "note"
|
|
27
|
-
| "tip"
|
|
28
|
-
| "info"
|
|
29
|
-
| "warning"
|
|
30
|
-
| "danger"
|
|
31
|
-
| "caution"
|
|
32
|
-
| "important";
|
|
33
|
-
|
|
34
|
-
export interface AdmonitionProps {
|
|
35
|
-
/** Custom title; falls back to the capitalized variant name (e.g. "Note"). */
|
|
36
|
-
title?: string;
|
|
37
|
-
children?: ComponentChildren;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Build the admonition component for a single variant. The title row is always
|
|
42
|
-
* rendered — defaulting to the capitalized variant name when the author gives
|
|
43
|
-
* no `title` — matching the Astro reference where every callout shows a title.
|
|
44
|
-
*/
|
|
45
|
-
export function makeAdmonition(variant: AdmonitionVariant) {
|
|
46
|
-
const defaultTitle = variant.charAt(0).toUpperCase() + variant.slice(1);
|
|
47
|
-
return function Admonition({ title, children }: AdmonitionProps): VNode {
|
|
48
|
-
const heading = title && title.length > 0 ? title : defaultTitle;
|
|
49
|
-
return (
|
|
50
|
-
<div data-admonition={variant} class={`admonition admonition-${variant}`}>
|
|
51
|
-
<p class="admonition-title">{heading}</p>
|
|
52
|
-
<div class="admonition-body">{children}</div>
|
|
53
|
-
</div>
|
|
54
|
-
);
|
|
55
|
-
};
|
|
56
|
-
}
|
|
1
|
+
// Re-export from the shared package — moved to @takazudo/zudo-doc/content-admonition
|
|
2
|
+
// as part of the package-first migration (epic #2321, S4 #2327).
|
|
3
|
+
export type { AdmonitionVariant, AdmonitionProps } from "@takazudo/zudo-doc/content-admonition";
|
|
4
|
+
export { makeAdmonition } from "@takazudo/zudo-doc/content-admonition";
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
1
|
// W6A stub — no-op default + DocHistory named exports.
|
|
4
2
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
3
|
+
// The real DocHistory island now ships from the package
|
|
4
|
+
// (`@takazudo/zudo-doc/doc-history`); the unconditional
|
|
5
|
+
// `pages/lib/_doc-history-area.tsx` imports it directly from there. When
|
|
6
|
+
// the docHistory feature is enabled the feature template overwrites this
|
|
7
|
+
// file with a re-export shim pointing at the package island. Generated
|
|
8
|
+
// projects without the feature ship this no-op so any project-local code
|
|
9
|
+
// that references the `@/components/doc-history` path still resolves. The
|
|
10
|
+
// host module exposes `DocHistory` as a named export, so the stub mirrors
|
|
11
|
+
// both the default and named shapes to keep the import surface stable.
|
|
11
12
|
import type { JSX } from "preact";
|
|
12
13
|
|
|
13
14
|
function DocHistoryComponent(): JSX.Element | null {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// W6A stub — no-op default + ImageEnlargeSsrFallback named exports.
|
|
1
|
+
// W6A stub — no-op default + ImageEnlarge / ImageEnlargeSsrFallback exports.
|
|
4
2
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
3
|
+
// The real ImageEnlarge island and its SSR fallback now ship from the
|
|
4
|
+
// package (`@takazudo/zudo-doc/image-enlarge`); the unconditional
|
|
5
|
+
// `pages/lib/_body-end-islands.tsx` imports them directly from there. When
|
|
6
|
+
// the imageEnlarge feature is enabled the feature template overwrites this
|
|
7
|
+
// file with a re-export shim pointing at the package island. Generated
|
|
8
|
+
// projects without the feature ship this no-op so any project-local code
|
|
9
|
+
// that references the `@/components/image-enlarge` path still resolves (the
|
|
10
|
+
// body-end renderer references both the default and the SSR fallback).
|
|
10
11
|
import type { JSX } from "preact";
|
|
11
12
|
|
|
12
13
|
function ImageEnlarge(): JSX.Element | null {
|
|
@@ -16,6 +17,8 @@ ImageEnlarge.displayName = "ImageEnlarge";
|
|
|
16
17
|
|
|
17
18
|
export default ImageEnlarge;
|
|
18
19
|
|
|
20
|
+
export { ImageEnlarge };
|
|
21
|
+
|
|
19
22
|
export function ImageEnlargeSsrFallback(): JSX.Element | null {
|
|
20
23
|
return null;
|
|
21
24
|
}
|