@takazudo/zudo-doc 1.2.0 → 2.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/chrome/derive.d.ts +68 -0
- package/dist/chrome/derive.js +231 -0
- package/dist/chrome/index.d.ts +37 -0
- package/dist/chrome/index.js +43 -0
- package/dist/content.css +25 -9
- package/dist/doc-body-end/index.d.ts +9 -11
- package/dist/doc-body-end/index.js +4 -2
- package/dist/doc-content-header/index.d.ts +10 -2
- package/dist/doc-content-header/index.js +8 -8
- package/dist/doc-history-area/index.d.ts +10 -25
- package/dist/doc-history-area/index.js +14 -10
- package/dist/doc-metainfo-area/index.d.ts +9 -15
- package/dist/doc-metainfo-area/index.js +6 -2
- package/dist/doc-page-renderer/index.d.ts +11 -2
- package/dist/doc-page-renderer/index.js +22 -15
- package/dist/doc-page-shell/index.d.ts +11 -3
- package/dist/doc-page-shell/index.js +21 -14
- package/dist/doc-pager/index.d.ts +6 -7
- package/dist/doc-pager/index.js +2 -2
- package/dist/doc-route-entries/index.d.ts +22 -46
- package/dist/doc-route-entries/index.js +15 -10
- package/dist/doc-tags-area/index.d.ts +9 -19
- package/dist/doc-tags-area/index.js +12 -2
- package/dist/factory-context/index.d.ts +163 -1
- package/dist/footer-with-defaults/index.d.ts +12 -13
- package/dist/footer-with-defaults/index.js +8 -10
- package/dist/head-with-defaults/index.d.ts +12 -16
- package/dist/head-with-defaults/index.js +7 -9
- package/dist/header-with-defaults/index.d.ts +10 -31
- package/dist/header-with-defaults/index.js +15 -18
- package/dist/integrations/claude-resources/generate.js +48 -11
- package/dist/nav-source-docs/index.d.ts +20 -54
- package/dist/nav-source-docs/index.js +9 -10
- package/dist/route-context/index.d.ts +24 -0
- package/dist/route-context/index.js +147 -0
- package/dist/route-enumerators/index.d.ts +25 -74
- package/dist/route-enumerators/index.js +17 -18
- package/dist/routes/_chrome.d.ts +6 -25
- package/dist/routes/_chrome.js +14 -387
- package/dist/routes/_context.d.ts +10 -43
- package/dist/routes/_context.js +29 -157
- package/dist/safelist.css +1 -1
- package/dist/sidebar-with-defaults/index.d.ts +8 -15
- package/dist/sidebar-with-defaults/index.js +6 -10
- package/dist/tag-pages/index.d.ts +12 -3
- package/dist/tag-pages/index.js +24 -19
- package/dist/versions-page/index.d.ts +10 -3
- package/dist/versions-page/index.js +18 -14
- package/eject/doc-pager/index.tsx +8 -10
- package/package.json +14 -6
- package/routes-src/_chrome.tsx +31 -552
- package/routes-src/_context.ts +37 -269
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@takazudo/zudo-doc",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "zudo-doc framework primitives layer that sits on top of zfb's engine — sidebar, theme, TOC, breadcrumb, layouts, head injection, View Transitions, SSR-skip wrappers (per ADR-003).",
|
|
6
6
|
"license": "MIT",
|
|
@@ -207,6 +207,14 @@
|
|
|
207
207
|
"types": "./dist/mdx-components/index.d.ts",
|
|
208
208
|
"default": "./dist/mdx-components/index.js"
|
|
209
209
|
},
|
|
210
|
+
"./route-context": {
|
|
211
|
+
"types": "./dist/route-context/index.d.ts",
|
|
212
|
+
"default": "./dist/route-context/index.js"
|
|
213
|
+
},
|
|
214
|
+
"./chrome": {
|
|
215
|
+
"types": "./dist/chrome/index.d.ts",
|
|
216
|
+
"default": "./dist/chrome/index.js"
|
|
217
|
+
},
|
|
210
218
|
"./safelist.css": "./dist/safelist.css",
|
|
211
219
|
"./safelist": "./dist/safelist.css",
|
|
212
220
|
"./content.css": "./dist/content.css",
|
|
@@ -515,9 +523,9 @@
|
|
|
515
523
|
],
|
|
516
524
|
"peerDependencies": {
|
|
517
525
|
"preact": "^10.29.1",
|
|
518
|
-
"@takazudo/zfb": "^0.1.0-next.
|
|
519
|
-
"@takazudo/zfb-runtime": "^0.1.0-next.
|
|
520
|
-
"@takazudo/zudo-doc-history-server": "^1.
|
|
526
|
+
"@takazudo/zfb": "^0.1.0-next.70",
|
|
527
|
+
"@takazudo/zfb-runtime": "^0.1.0-next.70",
|
|
528
|
+
"@takazudo/zudo-doc-history-server": "^1.2.0",
|
|
521
529
|
"@takazudo/zdtp": "^0.3.3",
|
|
522
530
|
"shiki": "^4.0.2",
|
|
523
531
|
"zod": "^4.3.6",
|
|
@@ -559,8 +567,8 @@
|
|
|
559
567
|
"typescript": "^5.0.0",
|
|
560
568
|
"vitest": "^4.1.0",
|
|
561
569
|
"zod": "^4.3.6",
|
|
562
|
-
"@takazudo/zfb": "0.1.0-next.
|
|
563
|
-
"@takazudo/zfb-runtime": "0.1.0-next.
|
|
570
|
+
"@takazudo/zfb": "0.1.0-next.70",
|
|
571
|
+
"@takazudo/zfb-runtime": "0.1.0-next.70"
|
|
564
572
|
},
|
|
565
573
|
"scripts": {
|
|
566
574
|
"build": "tsup && tsc -p tsconfig.build.json",
|
package/routes-src/_chrome.tsx
CHANGED
|
@@ -1,558 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// routes/_chrome — package-default chrome wiring for the package-owned page
|
|
4
|
-
// route entrypoints (epic Package-First Finale #2356, A1 #2361).
|
|
1
|
+
// routes/_chrome — thin chrome shim for the package-owned route entrypoints
|
|
2
|
+
// (epic Package-First Finale #2356, A1 #2361).
|
|
5
3
|
//
|
|
6
|
-
// The
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// them: an empty default color scheme, an auto-generated (empty) sidebars
|
|
23
|
-
// config, an empty doc-history manifest, empty frontmatter renderers, and a
|
|
24
|
-
// package no-op `BodyEndIslands` stub. The seam (data-context + paths()
|
|
25
|
-
// enumeration) is fully reconstructed in `_context`; the END-TO-END render
|
|
26
|
-
// proof of a stub-less injected route — including re-homing these host-only
|
|
27
|
-
// bindings — is A2's job (#2363). With `packageOwnedRoutes` off this module is
|
|
28
|
-
// never evaluated; it only needs to typecheck and import.
|
|
29
|
-
|
|
30
|
-
import type { JSX, VNode, ComponentChildren } from "preact";
|
|
31
|
-
import {
|
|
32
|
-
settings,
|
|
33
|
-
defaultLocale,
|
|
34
|
-
locales,
|
|
35
|
-
t,
|
|
36
|
-
withBase,
|
|
37
|
-
stripBase,
|
|
38
|
-
docsUrl,
|
|
39
|
-
versionedDocsUrl,
|
|
40
|
-
absoluteUrl,
|
|
41
|
-
navHref,
|
|
42
|
-
buildLocaleLinks,
|
|
43
|
-
getNavSectionForSlug,
|
|
44
|
-
getCategoryOrder,
|
|
45
|
-
toRouteSlug,
|
|
46
|
-
resolveNavSource,
|
|
47
|
-
loadNavSourceDocs,
|
|
48
|
-
buildNavTree,
|
|
49
|
-
groupSatelliteNodes,
|
|
50
|
-
collectAutoIndexNodes,
|
|
51
|
-
findNode,
|
|
52
|
-
firstRoutedHref,
|
|
53
|
-
collectTags,
|
|
54
|
-
stableDocs,
|
|
55
|
-
colorSchemes,
|
|
56
|
-
} from "./_context.js";
|
|
57
|
-
import type { CategoryMeta, DocNavNode } from "./_docs-helpers.js";
|
|
58
|
-
|
|
59
|
-
import { createComposeMetaTitle } from "@takazudo/zudo-doc/compose-meta-title";
|
|
60
|
-
import {
|
|
61
|
-
generateCssCustomProperties,
|
|
62
|
-
generateLightDarkCssProperties,
|
|
63
|
-
type ColorScheme,
|
|
64
|
-
} from "@takazudo/zudo-doc/color-scheme-utils";
|
|
65
|
-
import { createHeadWithDefaults } from "@takazudo/zudo-doc/head-with-defaults";
|
|
66
|
-
import { createHeaderWithDefaults } from "@takazudo/zudo-doc/header-with-defaults";
|
|
67
|
-
import { createFooterWithDefaults } from "@takazudo/zudo-doc/footer-with-defaults";
|
|
68
|
-
import { createSidebarWithDefaults } from "@takazudo/zudo-doc/sidebar-with-defaults";
|
|
69
|
-
import { createSidebarPrepaint } from "@takazudo/zudo-doc/sidebar-prepaint";
|
|
70
|
-
import { createDocBodyEnd } from "@takazudo/zudo-doc/doc-body-end";
|
|
71
|
-
import { createBodyEndIslands } from "@takazudo/zudo-doc/doc-body-end-islands";
|
|
72
|
-
import { createDocPager } from "@takazudo/zudo-doc/doc-pager";
|
|
73
|
-
import { createDocPageShell } from "@takazudo/zudo-doc/doc-page-shell";
|
|
74
|
-
import { createDocContentHeader } from "@takazudo/zudo-doc/doc-content-header";
|
|
75
|
-
import { createDocMetainfoArea } from "@takazudo/zudo-doc/doc-metainfo-area";
|
|
76
|
-
import { createDocTagsArea } from "@takazudo/zudo-doc/doc-tags-area";
|
|
77
|
-
import { createDocHistoryArea } from "@takazudo/zudo-doc/doc-history-area";
|
|
78
|
-
import { createInlineVersionSwitcher } from "@takazudo/zudo-doc/inline-version-switcher";
|
|
79
|
-
import { createRenderDocPage } from "@takazudo/zudo-doc/doc-page-renderer";
|
|
80
|
-
import { createVersionsPageView } from "@takazudo/zudo-doc/versions-page";
|
|
81
|
-
import { createTagPages } from "@takazudo/zudo-doc/tag-pages";
|
|
82
|
-
import { createMdxComponents } from "@takazudo/zudo-doc/mdx-components";
|
|
83
|
-
import { createCategoryNavWrapper } from "@takazudo/zudo-doc/category-nav";
|
|
84
|
-
import { createCategoryTreeNavWrapper } from "@takazudo/zudo-doc/category-tree-nav";
|
|
85
|
-
import { createSiteTreeNavWrapper } from "@takazudo/zudo-doc/site-tree-nav";
|
|
86
|
-
import { getTocTitle } from "@takazudo/zudo-doc/toc";
|
|
87
|
-
import { SearchWidget } from "@takazudo/zudo-doc/search-widget";
|
|
88
|
-
import { buildGitHubRepoUrl, buildGitHubSourceUrl } from "@takazudo/zudo-doc/github-helpers";
|
|
89
|
-
import { toHistorySlug } from "@takazudo/zudo-doc/slug";
|
|
90
|
-
import {
|
|
91
|
-
buildRootMenuItems as buildRootMenuItemsBase,
|
|
92
|
-
buildLocaleLinksForNav as buildLocaleLinksForNavBase,
|
|
93
|
-
remapVersionedHrefs,
|
|
94
|
-
getThemeDefaultMode as getThemeDefaultModeBase,
|
|
95
|
-
} from "@takazudo/zudo-doc/nav-data-prep";
|
|
96
|
-
import { buildSidebarForSection } from "@takazudo/zudo-doc/sidebar-utils";
|
|
97
|
-
import { Details } from "@takazudo/zudo-doc/details";
|
|
98
|
-
import {
|
|
99
|
-
HtmlPreviewWrapper,
|
|
100
|
-
type HtmlPreviewWrapperProps,
|
|
101
|
-
} from "@takazudo/zudo-doc/html-preview-wrapper";
|
|
102
|
-
|
|
103
|
-
// ---------------------------------------------------------------------------
|
|
104
|
-
// Package-default host-only bindings (see module header).
|
|
105
|
-
// ---------------------------------------------------------------------------
|
|
106
|
-
|
|
107
|
-
/** Package-default color scheme — a neutral 16-step grey ramp. The project's
|
|
108
|
-
* real `colorSchemes` palette map is project DATA (not in `settings`), so it
|
|
109
|
-
* is not in the serializable virtual module; A2 re-homes it for the render
|
|
110
|
-
* proof. Semantic roles fall back to `SEMANTIC_DEFAULTS`. */
|
|
111
|
-
const GREY_RAMP: ColorScheme["palette"] = [
|
|
112
|
-
"#000000", "#1a1a1a", "#333333", "#4d4d4d", "#666666", "#808080",
|
|
113
|
-
"#999999", "#b3b3b3", "#cccccc", "#d9d9d9", "#e6e6e6", "#f2f2f2",
|
|
114
|
-
"#ff5555", "#50fa7b", "#f1fa8c", "#8be9fd",
|
|
115
|
-
];
|
|
116
|
-
const DEFAULT_SCHEME: ColorScheme = {
|
|
117
|
-
background: "#000000",
|
|
118
|
-
foreground: "#ffffff",
|
|
119
|
-
cursor: "#ffffff",
|
|
120
|
-
selectionBg: "#444444",
|
|
121
|
-
selectionFg: "#ffffff",
|
|
122
|
-
palette: GREY_RAMP,
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
/** Empty doc-history manifest — the real `#doc-history-meta` virtual JSON is
|
|
126
|
-
* host-bound. With the flag off this is never read. */
|
|
127
|
-
const docHistoryMeta: Record<string, never> = {};
|
|
128
|
-
|
|
129
|
-
/** Empty sidebars config — sidebar sections fall back to the auto-generated
|
|
130
|
-
* tree. The project `sidebars` config is host-bound (A2). */
|
|
131
|
-
const sidebarsConfig: Record<string, never> = {};
|
|
132
|
-
|
|
133
|
-
/** Package-default body-end islands — the package-island subset of the host's
|
|
134
|
-
* `BodyEndIslands` (AiChatModal / ImageEnlarge / MermaidEnlarge), reconstructed
|
|
135
|
-
* from the serializable virtual-module `settings` flags (#2406 / #2401(c)).
|
|
136
|
-
* The host-owned bootstraps (client-router / design-token-panel) cannot live
|
|
137
|
-
* in the package, so they are NOT included here — A2/S4 re-homes those. */
|
|
138
|
-
const BodyEndIslands = createBodyEndIslands({ settings });
|
|
139
|
-
|
|
140
|
-
/** Package no-op DocHistory island stub — renders an empty fragment (the
|
|
141
|
-
* `DocHistoryComponent` contract requires a VNode, not null). */
|
|
142
|
-
function DocHistoryStub(_props: { slug: string; locale?: string; basePath?: string }): VNode {
|
|
143
|
-
return (<></>) as VNode;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/** SearchWidget adapter: the package `SearchWidget` requires a `base` prop, but
|
|
147
|
-
* the `HeaderWithDefaults` dep signature omits it (the host stub injects it).
|
|
148
|
-
* Inject the base-prefixed search index root here. */
|
|
149
|
-
function SearchWidgetBound(props: {
|
|
150
|
-
placeholderText: string;
|
|
151
|
-
shortcutHint: string;
|
|
152
|
-
resultCountTemplate: string;
|
|
153
|
-
searchLabel: string;
|
|
154
|
-
searchUnavailableText: string;
|
|
155
|
-
loadingIndexText: string;
|
|
156
|
-
noResultsText: string;
|
|
157
|
-
}): JSX.Element {
|
|
158
|
-
return SearchWidget({ ...props, base: withBase("/") });
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// ---------------------------------------------------------------------------
|
|
162
|
-
// composeMetaTitle + Head.
|
|
163
|
-
// ---------------------------------------------------------------------------
|
|
164
|
-
|
|
165
|
-
export const composeMetaTitle = createComposeMetaTitle(settings.siteName);
|
|
166
|
-
|
|
167
|
-
// Scheme-selection: resolve the active color scheme(s) from the host
|
|
168
|
-
// `colorSchemes` map supplied via the virtual module. Falls back to
|
|
169
|
-
// `DEFAULT_SCHEME` for any missing key or when `colorSchemes` is absent.
|
|
170
|
-
// `generateCssCustomProperties` is called in single-scheme mode
|
|
171
|
-
// (`settings.colorMode` is false); `generateLightDarkCssProperties` in
|
|
172
|
-
// light/dark mode. Both delegate to DEFAULT_SCHEME when `colorSchemes` is null.
|
|
173
|
-
function resolveHostScheme(key: string): ColorScheme {
|
|
174
|
-
if (!colorSchemes) return DEFAULT_SCHEME;
|
|
175
|
-
return colorSchemes[key] ?? DEFAULT_SCHEME;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
export const HeadWithDefaults = createHeadWithDefaults({
|
|
179
|
-
settings,
|
|
180
|
-
composeMetaTitle,
|
|
181
|
-
withBase,
|
|
182
|
-
absoluteUrl,
|
|
183
|
-
// Called only in single-scheme mode (colorMode false): resolve via settings.colorScheme.
|
|
184
|
-
generateCssCustomProperties: () =>
|
|
185
|
-
generateCssCustomProperties(resolveHostScheme(settings.colorScheme)),
|
|
186
|
-
// Called only in light/dark mode (colorMode truthy): resolve the pair.
|
|
187
|
-
generateLightDarkCssProperties: () => {
|
|
188
|
-
const cm = settings.colorMode;
|
|
189
|
-
if (cm) {
|
|
190
|
-
return generateLightDarkCssProperties(
|
|
191
|
-
resolveHostScheme(cm.lightScheme),
|
|
192
|
-
resolveHostScheme(cm.darkScheme),
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
// Should not be reached (head-with-defaults only calls this when colorMode
|
|
196
|
-
// is truthy), but guard the contract by falling back to DEFAULT_SCHEME.
|
|
197
|
-
return generateLightDarkCssProperties(DEFAULT_SCHEME, DEFAULT_SCHEME);
|
|
198
|
-
},
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
// ---------------------------------------------------------------------------
|
|
202
|
-
// nav data-prep (bound to settings via _context helpers).
|
|
203
|
-
// ---------------------------------------------------------------------------
|
|
204
|
-
|
|
205
|
-
function buildRootMenuItems(lang: string, currentVersion: string | undefined) {
|
|
206
|
-
return buildRootMenuItemsBase(
|
|
207
|
-
lang,
|
|
208
|
-
currentVersion,
|
|
209
|
-
settings.headerNav,
|
|
210
|
-
(key, l) => t(key, l),
|
|
211
|
-
(path, l, v) => navHref(path, l, v),
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
function buildLocaleLinksForNav(currentPath: string, lang: string, localeCount: number) {
|
|
216
|
-
return buildLocaleLinksForNavBase(currentPath, lang, localeCount, (path, l) =>
|
|
217
|
-
buildLocaleLinks(path, l),
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
function buildSidebarNodes(
|
|
222
|
-
lang: string,
|
|
223
|
-
navSection: string | undefined,
|
|
224
|
-
currentVersion: string | undefined,
|
|
225
|
-
emptyWhenUnsectioned = true,
|
|
226
|
-
) {
|
|
227
|
-
if (navSection === undefined && emptyWhenUnsectioned) return [];
|
|
228
|
-
const { navDocs, categoryMeta } = loadNavSourceDocs(lang, currentVersion);
|
|
229
|
-
const explicitPrefixes = getCategoryOrder().filter((cm) => cm !== "!");
|
|
230
|
-
const rawNodes = buildSidebarForSection(
|
|
231
|
-
navDocs,
|
|
232
|
-
lang,
|
|
233
|
-
navSection,
|
|
234
|
-
categoryMeta as unknown as Map<string, CategoryMeta>,
|
|
235
|
-
sidebarsConfig,
|
|
236
|
-
(d, l, meta) =>
|
|
237
|
-
buildNavTree(
|
|
238
|
-
d as never[],
|
|
239
|
-
l,
|
|
240
|
-
meta as Map<string, CategoryMeta> | undefined,
|
|
241
|
-
(slug, loc) => docsUrl(slug, loc),
|
|
242
|
-
) as never[],
|
|
243
|
-
explicitPrefixes,
|
|
244
|
-
);
|
|
245
|
-
return currentVersion
|
|
246
|
-
? remapVersionedHrefs(rawNodes, currentVersion, lang, (slug, v, l) =>
|
|
247
|
-
versionedDocsUrl(slug, v, l),
|
|
248
|
-
)
|
|
249
|
-
: rawNodes;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
function getThemeDefaultMode() {
|
|
253
|
-
return getThemeDefaultModeBase(settings.colorMode);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// ---------------------------------------------------------------------------
|
|
257
|
-
// Header / Footer / Sidebar.
|
|
258
|
-
// ---------------------------------------------------------------------------
|
|
259
|
-
|
|
260
|
-
export const HeaderWithDefaults = createHeaderWithDefaults({
|
|
261
|
-
settings,
|
|
262
|
-
defaultLocale,
|
|
263
|
-
locales,
|
|
264
|
-
t,
|
|
265
|
-
withBase,
|
|
266
|
-
stripBase,
|
|
267
|
-
docsUrl,
|
|
268
|
-
navHref,
|
|
269
|
-
versionedDocsUrl,
|
|
270
|
-
buildLocaleLinksForNav,
|
|
271
|
-
buildRootMenuItems,
|
|
272
|
-
buildSidebarNodes,
|
|
273
|
-
getThemeDefaultMode,
|
|
274
|
-
buildGitHubRepoUrl: () => buildGitHubRepoUrl(settings.githubUrl),
|
|
275
|
-
SearchWidget: SearchWidgetBound,
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
export const FooterWithDefaults = createFooterWithDefaults({
|
|
279
|
-
settings,
|
|
280
|
-
defaultLocale,
|
|
281
|
-
tagVocabulary: [],
|
|
282
|
-
isExternal: (href: string) => /^https?:\/\//.test(href),
|
|
283
|
-
resolveHref: (href: string) => (/^https?:\/\//.test(href) ? href : withBase(href)),
|
|
284
|
-
withBase,
|
|
285
|
-
// The footer taglist is host-bound (project tag aggregation); package default
|
|
286
|
-
// renders no tag columns.
|
|
287
|
-
loadTagsForLocale: () => [],
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
export const SidebarWithDefaults = createSidebarWithDefaults({
|
|
291
|
-
defaultLocale,
|
|
292
|
-
localeCount: locales.length,
|
|
293
|
-
buildRootMenuItems,
|
|
294
|
-
buildLocaleLinksForNav,
|
|
295
|
-
buildSidebarNodes,
|
|
296
|
-
getThemeDefaultMode,
|
|
297
|
-
t,
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
const SidebarPrepaint = createSidebarPrepaint({ sidebarToggle: settings.sidebarToggle });
|
|
301
|
-
const DocBodyEnd = createDocBodyEnd({ settings, BodyEndIslands });
|
|
302
|
-
const DocPager = createDocPager({ t });
|
|
303
|
-
|
|
304
|
-
// ---------------------------------------------------------------------------
|
|
305
|
-
// Doc content header / metainfo / tags / history.
|
|
306
|
-
// ---------------------------------------------------------------------------
|
|
307
|
-
|
|
308
|
-
const DocMetainfoArea = createDocMetainfoArea({
|
|
309
|
-
settings,
|
|
310
|
-
defaultLocale,
|
|
311
|
-
docHistoryMeta,
|
|
312
|
-
t,
|
|
313
|
-
toHistorySlug,
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
const DocTagsArea = createDocTagsArea({
|
|
317
|
-
settings,
|
|
318
|
-
defaultLocale,
|
|
319
|
-
tagVocabularyEntries: [],
|
|
320
|
-
tagHref: (tag: string, locale: string) => {
|
|
321
|
-
const encoded = encodeURIComponent(tag);
|
|
322
|
-
return withBase(
|
|
323
|
-
locale === defaultLocale
|
|
324
|
-
? `/docs/tags/${encoded}`
|
|
325
|
-
: `/${locale}/docs/tags/${encoded}`,
|
|
326
|
-
);
|
|
327
|
-
},
|
|
328
|
-
t,
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
const DocContentHeader = createDocContentHeader({
|
|
332
|
-
t,
|
|
333
|
-
buildFrontmatterPreviewEntries: () => [],
|
|
334
|
-
frontmatterRenderers: {},
|
|
335
|
-
DocMetainfoArea,
|
|
336
|
-
DocTagsArea,
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
const DocHistoryArea = createDocHistoryArea({
|
|
340
|
-
settings,
|
|
341
|
-
defaultLocale,
|
|
342
|
-
docHistoryMeta,
|
|
343
|
-
t,
|
|
344
|
-
toHistorySlug,
|
|
345
|
-
buildGitHubSourceUrl: (contentDir: string, entryId: string) =>
|
|
346
|
-
buildGitHubSourceUrl(settings.githubUrl, contentDir, entryId),
|
|
347
|
-
DocHistory: DocHistoryStub,
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
const buildInlineVersionSwitcher = createInlineVersionSwitcher({
|
|
351
|
-
settings,
|
|
352
|
-
defaultLocale,
|
|
353
|
-
t,
|
|
354
|
-
docsUrl,
|
|
355
|
-
versionedDocsUrl,
|
|
356
|
-
withBase,
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
// ---------------------------------------------------------------------------
|
|
360
|
-
// MDX components (locale-bound nav wrappers + package defaults).
|
|
361
|
-
// ---------------------------------------------------------------------------
|
|
362
|
-
|
|
363
|
-
const CategoryNavWrapper = createCategoryNavWrapper({
|
|
364
|
-
defaultLocale,
|
|
365
|
-
resolveNavSource: resolveNavSource as never,
|
|
366
|
-
buildNavTree: ((docs: unknown[], locale: string, categoryMeta: Map<string, unknown>) =>
|
|
367
|
-
buildNavTree(
|
|
368
|
-
docs as never[],
|
|
369
|
-
locale,
|
|
370
|
-
categoryMeta as Map<string, CategoryMeta>,
|
|
371
|
-
(slug, loc) => docsUrl(slug, loc),
|
|
372
|
-
)) as never,
|
|
373
|
-
findNode: findNode as never,
|
|
374
|
-
firstRoutedHref: firstRoutedHref as never,
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
const CategoryTreeNavWrapper = createCategoryTreeNavWrapper({
|
|
378
|
-
defaultLocale,
|
|
379
|
-
resolveNavSource: resolveNavSource as never,
|
|
380
|
-
buildNavTree: ((docs: unknown[], locale: string, categoryMeta: Map<string, unknown>) =>
|
|
381
|
-
buildNavTree(
|
|
382
|
-
docs as never[],
|
|
383
|
-
locale,
|
|
384
|
-
categoryMeta as Map<string, CategoryMeta>,
|
|
385
|
-
(slug, loc) => docsUrl(slug, loc),
|
|
386
|
-
)) as never,
|
|
387
|
-
groupSatelliteNodes: groupSatelliteNodes as never,
|
|
388
|
-
findNode: findNode as never,
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
const SiteTreeNavWrapper = createSiteTreeNavWrapper({
|
|
392
|
-
defaultLocale,
|
|
393
|
-
resolveNavSource: resolveNavSource as never,
|
|
394
|
-
buildNavTree: ((docs: unknown[], locale: string, categoryMeta: Map<string, unknown>) =>
|
|
395
|
-
buildNavTree(
|
|
396
|
-
docs as never[],
|
|
397
|
-
locale,
|
|
398
|
-
categoryMeta as Map<string, CategoryMeta>,
|
|
399
|
-
(slug, loc) => docsUrl(slug, loc),
|
|
400
|
-
)) as never,
|
|
401
|
-
groupSatelliteNodes: groupSatelliteNodes as never,
|
|
402
|
-
getCategoryOrder,
|
|
403
|
-
});
|
|
404
|
-
|
|
405
|
-
/** HtmlPreview MDX binding (package default).
|
|
406
|
-
*
|
|
407
|
-
* Mirrors the host stub (`pages/_mdx-components.ts`): the global preview
|
|
408
|
-
* config is `settings.htmlPreview`, a SERIALIZABLE setting that DOES ride in
|
|
409
|
-
* the route-context virtual module, so the package can read it directly (no
|
|
410
|
-
* host config needed). `HtmlPreviewWrapper` wraps the bare preview in
|
|
411
|
-
* `<Island when="visible">`, which SSR-renders the preview tree — so an
|
|
412
|
-
* injected docs page using `<HtmlPreview html="…" />` renders correct HTML.
|
|
413
|
-
*
|
|
414
|
-
* Hydration caveat: the interactive code-toggle hydrates only if zfb's islands
|
|
415
|
-
* scanner reaches the `@takazudo/zfb` <Island> import inside
|
|
416
|
-
* `HtmlPreviewWrapper`. The esbuild islands bundler does NOT walk imports of
|
|
417
|
-
* modules whose realpath is under `node_modules` (the same gap the routes
|
|
418
|
-
* plugin stages around — see `plugins/routes.ts`; upstream report:
|
|
419
|
-
* Takazudo/zudo-front-builder, "islands bundler skips addVirtualModule /
|
|
420
|
-
* import-walk for node_modules route realpaths"). SSR output is unaffected. */
|
|
421
|
-
function HtmlPreviewBound(props: HtmlPreviewWrapperProps): JSX.Element {
|
|
422
|
-
return HtmlPreviewWrapper({
|
|
423
|
-
globalConfig: settings.htmlPreview ?? null,
|
|
424
|
-
...props,
|
|
425
|
-
}) as JSX.Element;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
/** Island MDX binding (package default) — an SSR pass-through that renders its
|
|
429
|
-
* children, deliberately NOT the real `@takazudo/zfb` <Island>.
|
|
430
|
-
*
|
|
431
|
-
* Why a pass-through and not `Island → @takazudo/zfb` (the sub-issue's literal
|
|
432
|
-
* ask): the MDX corpus never uses `<Island>` as a real render tag (only inside
|
|
433
|
-
* changelog prose), and the host stub itself uses this same pass-through. The
|
|
434
|
-
* real zfb <Island> emits `data-zfb-island="<firstChildTagName>"` for generic
|
|
435
|
-
* MDX children, i.e. a hydration marker pointing at a non-existent manifest
|
|
436
|
-
* entry — and the islands scanner can't register it anyway from a package
|
|
437
|
-
* (node_modules) import (upstream report above). A pass-through renders the
|
|
438
|
-
* server-renderable children correctly with no bogus marker, which is the
|
|
439
|
-
* complete and correct behaviour for the corpus. `when` is ignored at SSR
|
|
440
|
-
* time (it only matters to the client hydration runtime). */
|
|
441
|
-
function IslandPassthrough(props: {
|
|
442
|
-
when?: "load" | "idle" | "visible" | "media";
|
|
443
|
-
children?: ComponentChildren;
|
|
444
|
-
}): ComponentChildren {
|
|
445
|
-
return props.children ?? null;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
export function createMdxComponentsBound(lang: string = defaultLocale) {
|
|
449
|
-
return createMdxComponents({
|
|
450
|
-
settings,
|
|
451
|
-
locale: lang,
|
|
452
|
-
navData: {
|
|
453
|
-
CategoryNav: CategoryNavWrapper as never,
|
|
454
|
-
CategoryTreeNav: CategoryTreeNavWrapper as never,
|
|
455
|
-
SiteTreeNav: SiteTreeNavWrapper as never,
|
|
456
|
-
},
|
|
457
|
-
// Package-owned content components wired here so an INJECTED docs route
|
|
458
|
-
// (packageOwnedRoutes, no host `pages/` stub) renders MDX using these tags
|
|
459
|
-
// without the "MDX requires '<X>' to be passed via the 'components' prop"
|
|
460
|
-
// error (sub-issue #2390 / supersedes #2377).
|
|
461
|
-
// - Details → fully functional (pure <details>, no client JS).
|
|
462
|
-
// - HtmlPreview → SSR-renders; see HtmlPreviewBound for the hydration
|
|
463
|
-
// caveat tied to the node_modules islands-scanner gap.
|
|
464
|
-
// - Island → SSR pass-through; see IslandPassthrough.
|
|
465
|
-
// PresetGenerator stays a package stub (render nothing): it is the
|
|
466
|
-
// showcase's project-bound interactive island and downstream projects stub
|
|
467
|
-
// it. The showcase keeps its host-owned docs catch-all routes (allowlisted)
|
|
468
|
-
// so its real PresetGenerator still renders.
|
|
469
|
-
extras: {
|
|
470
|
-
Details: Details as never,
|
|
471
|
-
HtmlPreview: HtmlPreviewBound as never,
|
|
472
|
-
Island: IslandPassthrough as never,
|
|
473
|
-
PresetGenerator: (_props: unknown) => null,
|
|
474
|
-
},
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
// ---------------------------------------------------------------------------
|
|
479
|
-
// DocPageShell + renderDocPage.
|
|
480
|
-
// ---------------------------------------------------------------------------
|
|
481
|
-
|
|
482
|
-
const DocPageShell = createDocPageShell({
|
|
483
|
-
settings,
|
|
4
|
+
// The chrome wiring was PROMOTED to the public, shared
|
|
5
|
+
// `createChrome(context, hostBindings)` builder
|
|
6
|
+
// (`@takazudo/zudo-doc/chrome`, CTX #2423). This module is now just the seam
|
|
7
|
+
// that calls it ONCE with the reconstructed route context and NO host bindings
|
|
8
|
+
// — so every host-bound slot resolves to its package-default stub and the
|
|
9
|
+
// injected package-routes render is byte-identical to before. The host
|
|
10
|
+
// (HOSTCOLLAPSE wave) will call `createChrome` directly with real bindings.
|
|
11
|
+
|
|
12
|
+
import { routeCtx } from "./_context.js";
|
|
13
|
+
import { createChrome } from "@takazudo/zudo-doc/chrome";
|
|
14
|
+
import type { DocNavNode } from "./_docs-helpers.js";
|
|
15
|
+
|
|
16
|
+
// Empty host bindings → package-default stubs (byte-identical injected path).
|
|
17
|
+
const chrome = createChrome(routeCtx);
|
|
18
|
+
|
|
19
|
+
export const {
|
|
484
20
|
composeMetaTitle,
|
|
485
|
-
getTocTitle,
|
|
486
21
|
HeadWithDefaults,
|
|
487
|
-
SidebarWithDefaults,
|
|
488
22
|
HeaderWithDefaults,
|
|
489
23
|
FooterWithDefaults,
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
buildInlineVersionSwitcher,
|
|
504
|
-
DocPageShell,
|
|
505
|
-
DocContentHeader,
|
|
506
|
-
DocMetainfoArea,
|
|
507
|
-
DocHistoryArea,
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
// ---------------------------------------------------------------------------
|
|
511
|
-
// VersionsPageView + TagPages.
|
|
512
|
-
// ---------------------------------------------------------------------------
|
|
513
|
-
|
|
514
|
-
export const VersionsPageView = createVersionsPageView({
|
|
515
|
-
settings,
|
|
516
|
-
defaultLocale,
|
|
517
|
-
t,
|
|
518
|
-
withBase,
|
|
519
|
-
composeMetaTitle,
|
|
520
|
-
components: {
|
|
521
|
-
HeadWithDefaults,
|
|
522
|
-
HeaderWithDefaults,
|
|
523
|
-
FooterWithDefaults,
|
|
524
|
-
BodyEndIslands,
|
|
525
|
-
},
|
|
526
|
-
});
|
|
527
|
-
|
|
528
|
-
const tagPages = createTagPages({
|
|
529
|
-
settings,
|
|
530
|
-
defaultLocale,
|
|
531
|
-
t,
|
|
532
|
-
withBase,
|
|
533
|
-
docsUrl,
|
|
534
|
-
composeMetaTitle,
|
|
535
|
-
collectTags: collectTags as never,
|
|
536
|
-
stableDocs: stableDocs as never,
|
|
537
|
-
isDefaultLocaleOnlyPath: undefined,
|
|
538
|
-
components: {
|
|
539
|
-
HeadWithDefaults,
|
|
540
|
-
HeaderWithDefaults,
|
|
541
|
-
FooterWithDefaults,
|
|
542
|
-
BodyEndIslands,
|
|
543
|
-
DocHistoryArea: DocHistoryArea as never,
|
|
544
|
-
},
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
export const { collectTagMapForLocale, TagDetailPageView, TagsIndexPageView } = tagPages;
|
|
548
|
-
|
|
549
|
-
// Re-export the locale-aware site-tree wrapper + the package-default body-end
|
|
550
|
-
// islands for the index entrypoints.
|
|
551
|
-
export { SiteTreeNavWrapper, BodyEndIslands };
|
|
552
|
-
|
|
553
|
-
// Bring the doc-route-entries builder + types into the chrome surface so the
|
|
554
|
-
// doc entrypoints import a single module.
|
|
555
|
-
export {
|
|
556
|
-
buildDocRouteEntries,
|
|
557
|
-
} from "./_context.js";
|
|
24
|
+
SidebarWithDefaults,
|
|
25
|
+
renderDocPage,
|
|
26
|
+
VersionsPageView,
|
|
27
|
+
collectTagMapForLocale,
|
|
28
|
+
TagDetailPageView,
|
|
29
|
+
TagsIndexPageView,
|
|
30
|
+
SiteTreeNavWrapper,
|
|
31
|
+
BodyEndIslands,
|
|
32
|
+
} = chrome;
|
|
33
|
+
|
|
34
|
+
// The doc-route-entries builder lives on the route context; the doc entrypoints
|
|
35
|
+
// import it from this chrome module so they reach a single barrel.
|
|
36
|
+
export { buildDocRouteEntries } from "./_context.js";
|
|
558
37
|
export type { DocNavNode };
|