create-zudo-doc 0.2.1 → 0.2.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/compose.d.ts +2 -3
- package/dist/compose.js +7 -4
- package/dist/features/tauri.d.ts +10 -5
- package/dist/features/tauri.js +49 -6
- package/dist/scaffold.js +13 -5
- package/dist/settings-gen.js +4 -1
- package/package.json +1 -1
- package/templates/base/pages/404.tsx +5 -0
- package/templates/base/pages/index.tsx +5 -0
- package/templates/base/pages/lib/_body-end-islands.tsx +61 -31
- package/templates/base/pages/lib/_doc-page-shell.tsx +30 -0
- package/templates/base/pages/lib/_header-with-defaults.tsx +5 -4
- package/templates/base/pages/lib/_search-widget-script.ts +17 -0
- package/templates/base/pages/lib/_toc-title.ts +22 -0
- package/templates/base/src/components/ai-chat-modal.tsx +2 -0
- package/templates/base/src/components/doc-history.tsx +2 -0
- package/templates/base/src/components/image-enlarge.tsx +2 -0
- package/templates/base/src/components/sidebar-toggle.tsx +8 -1
- package/templates/base/src/components/sidebar-tree.tsx +1 -1
- package/templates/base/zfb-shim.d.ts +167 -0
- package/templates/features/docHistory/files/src/components/doc-history.tsx +2 -0
- package/templates/features/docTags/files/pages/lib/_tag-pages.tsx +10 -0
- package/templates/features/i18n/files/pages/[locale]/index.tsx +5 -0
- package/templates/features/imageEnlarge/files/src/components/image-enlarge.tsx +2 -0
- package/templates/features/tauri/files/src/components/find-in-page-init.tsx +9 -3
- package/templates/features/versioning/files/pages/lib/_versions-page.tsx +5 -0
package/dist/compose.d.ts
CHANGED
|
@@ -78,9 +78,8 @@ export declare function validateDependencies(features: FeatureDefinition[], allS
|
|
|
78
78
|
* - `pages/_mdx-components.ts` — image-enlarge.ts injects the
|
|
79
79
|
* EnlargeableParagraph p-override (ENLARGE_SVG, EnlargeableParagraph def,
|
|
80
80
|
* `p:` map entry) when imageEnlarge is enabled.
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* compatibility.
|
|
81
|
+
* - `pages/lib/_body-end-islands.tsx` — tauri.ts injects the FindInPageInit
|
|
82
|
+
* island (import, displayName, Island mount) when tauri is enabled.
|
|
84
83
|
*/
|
|
85
84
|
export declare const ANCHOR_FILES: string[];
|
|
86
85
|
/**
|
package/dist/compose.js
CHANGED
|
@@ -164,11 +164,14 @@ export function validateDependencies(features, allSelectedNames) {
|
|
|
164
164
|
* - `pages/_mdx-components.ts` — image-enlarge.ts injects the
|
|
165
165
|
* EnlargeableParagraph p-override (ENLARGE_SVG, EnlargeableParagraph def,
|
|
166
166
|
* `p:` map entry) when imageEnlarge is enabled.
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
* compatibility.
|
|
167
|
+
* - `pages/lib/_body-end-islands.tsx` — tauri.ts injects the FindInPageInit
|
|
168
|
+
* island (import, displayName, Island mount) when tauri is enabled.
|
|
170
169
|
*/
|
|
171
|
-
export const ANCHOR_FILES = [
|
|
170
|
+
export const ANCHOR_FILES = [
|
|
171
|
+
"src/styles/global.css",
|
|
172
|
+
"pages/_mdx-components.ts",
|
|
173
|
+
"pages/lib/_body-end-islands.tsx",
|
|
174
|
+
];
|
|
172
175
|
/**
|
|
173
176
|
* Main composition entry point. Orchestrates the full feature composition
|
|
174
177
|
* pipeline for a generated project.
|
package/dist/features/tauri.d.ts
CHANGED
|
@@ -2,10 +2,15 @@ import type { FeatureModule } from "../compose.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Tauri feature.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* #2052: the FindInPageInit island (Cmd/Ctrl+F find bar for the Tauri
|
|
6
|
+
* WebView, where the browser-native find UI is unavailable) is wired into
|
|
7
|
+
* `pages/lib/_body-end-islands.tsx` via the three injections below — import,
|
|
8
|
+
* displayName, and Island mount. zfb's island scanner only registers
|
|
9
|
+
* components reachable through static import chains (page → wrapper →
|
|
10
|
+
* component), so without this injection the feature-copied component files
|
|
11
|
+
* are orphaned dead code that never hydrates. The find-match highlight CSS
|
|
12
|
+
* is unconditional in `templates/base/src/styles/global.css` (matches host);
|
|
13
|
+
* the component runtime-gates itself (renders null unless
|
|
14
|
+
* `window.__TAURI_INTERNALS__` exists), so no settings field is needed.
|
|
10
15
|
*/
|
|
11
16
|
export declare const tauriFeature: FeatureModule;
|
package/dist/features/tauri.js
CHANGED
|
@@ -3,15 +3,58 @@ import path from "path";
|
|
|
3
3
|
/**
|
|
4
4
|
* Tauri feature.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* #2052: the FindInPageInit island (Cmd/Ctrl+F find bar for the Tauri
|
|
7
|
+
* WebView, where the browser-native find UI is unavailable) is wired into
|
|
8
|
+
* `pages/lib/_body-end-islands.tsx` via the three injections below — import,
|
|
9
|
+
* displayName, and Island mount. zfb's island scanner only registers
|
|
10
|
+
* components reachable through static import chains (page → wrapper →
|
|
11
|
+
* component), so without this injection the feature-copied component files
|
|
12
|
+
* are orphaned dead code that never hydrates. The find-match highlight CSS
|
|
13
|
+
* is unconditional in `templates/base/src/styles/global.css` (matches host);
|
|
14
|
+
* the component runtime-gates itself (renders null unless
|
|
15
|
+
* `window.__TAURI_INTERNALS__` exists), so no settings field is needed.
|
|
11
16
|
*/
|
|
12
17
|
export const tauriFeature = (choices) => ({
|
|
13
18
|
name: "tauri",
|
|
14
|
-
injections: [
|
|
19
|
+
injections: [
|
|
20
|
+
// 1. Import the island entry. Inserted AFTER the
|
|
21
|
+
// `// @slot:body-end-islands:imports` anchor.
|
|
22
|
+
{
|
|
23
|
+
file: "pages/lib/_body-end-islands.tsx",
|
|
24
|
+
anchor: "// @slot:body-end-islands:imports",
|
|
25
|
+
position: "after",
|
|
26
|
+
content: `import FindInPageInit from "@/components/find-in-page-init";`,
|
|
27
|
+
},
|
|
28
|
+
// 2. Stable island marker name (same belt-and-braces guard as the
|
|
29
|
+
// sibling islands in the file). Inserted AFTER the
|
|
30
|
+
// `// @slot:body-end-islands:display-names` anchor.
|
|
31
|
+
{
|
|
32
|
+
file: "pages/lib/_body-end-islands.tsx",
|
|
33
|
+
anchor: "// @slot:body-end-islands:display-names",
|
|
34
|
+
position: "after",
|
|
35
|
+
content: `(FindInPageInit as { displayName?: string }).displayName = "FindInPageInit";`,
|
|
36
|
+
},
|
|
37
|
+
// 3. Island mount. Inserted AFTER the
|
|
38
|
+
// `{/* @slot:body-end-islands:extra-islands */}` anchor.
|
|
39
|
+
// when="load" (not "idle"): the island's job is to intercept
|
|
40
|
+
// Cmd/Ctrl+F via a keydown listener, so it must hydrate as soon as
|
|
41
|
+
// the islands runtime mounts — same rationale as the
|
|
42
|
+
// clientRouterBootstrap click intercept above it. Deferring to idle
|
|
43
|
+
// would leave a post-load window where Cmd+F does nothing, which is
|
|
44
|
+
// the very bug this injection fixes.
|
|
45
|
+
{
|
|
46
|
+
file: "pages/lib/_body-end-islands.tsx",
|
|
47
|
+
anchor: "{/* @slot:body-end-islands:extra-islands */}",
|
|
48
|
+
position: "after",
|
|
49
|
+
content: ` {/* Tauri-only find-in-page (Cmd/Ctrl+F) bar. Renders null outside
|
|
50
|
+
a Tauri WebView, so the island is inert in plain browser builds
|
|
51
|
+
of the same scaffold. */}
|
|
52
|
+
{Island({
|
|
53
|
+
when: "load",
|
|
54
|
+
children: <FindInPageInit />,
|
|
55
|
+
}) as unknown as VNode}`,
|
|
56
|
+
},
|
|
57
|
+
],
|
|
15
58
|
postProcess: async (targetDir) => {
|
|
16
59
|
// Patch Cargo.toml package name
|
|
17
60
|
const cargoPath = path.join(targetDir, "src-tauri/Cargo.toml");
|
package/dist/scaffold.js
CHANGED
|
@@ -269,16 +269,24 @@ function generatePackageJson(choices) {
|
|
|
269
269
|
// cross-file anchor validation. BREAKING upstream: the no-op
|
|
270
270
|
// `linkValidation.allowExternal` knob was removed — neither the host nor
|
|
271
271
|
// the generated config ever emitted it, so no migration is needed here.
|
|
272
|
-
|
|
273
|
-
|
|
272
|
+
// next.39 is features + fixes, no breaking changes:
|
|
273
|
+
// npm-dist `"use client"` island scanning, link-resolution fixes for
|
|
274
|
+
// directory-style hrefs, and island-registry hardening (warns on island
|
|
275
|
+
// marker-name collisions).
|
|
276
|
+
// next.40 (current pin) flips `zfb dev` to lazy rendering by default —
|
|
277
|
+
// pages render on first request instead of on every file-change tick
|
|
278
|
+
// (Takazudo/zudo-front-builder#1029); `ZFB_DEV_EAGER=1` restores eager
|
|
279
|
+
// mode. Dev-server-only change, no build/config migration needed.
|
|
280
|
+
"@takazudo/zfb": "0.1.0-next.40",
|
|
281
|
+
"@takazudo/zfb-runtime": "0.1.0-next.40",
|
|
274
282
|
// zfb-adapter-cloudflare — required for any route with `prerender = false`.
|
|
275
283
|
// Pinned in lockstep with @takazudo/zfb.
|
|
276
|
-
"@takazudo/zfb-adapter-cloudflare": "0.1.0-next.
|
|
284
|
+
"@takazudo/zfb-adapter-cloudflare": "0.1.0-next.40",
|
|
277
285
|
// @takazudo/zudo-doc — published from this monorepo via
|
|
278
286
|
// .github/workflows/publish-zudo-doc.yml. The pin here is bumped in
|
|
279
287
|
// lockstep by scripts/release-create-zudo-doc.sh whenever zudo-doc's
|
|
280
288
|
// version moves, so a fresh scaffold pulls the version we just published.
|
|
281
|
-
"@takazudo/zudo-doc": "^0.2.
|
|
289
|
+
"@takazudo/zudo-doc": "^0.2.3",
|
|
282
290
|
// zod — used by the generated zfb.config.ts. zfb-config-gen emits
|
|
283
291
|
// `import { z } from "zod"` for the content-collection schema +
|
|
284
292
|
// `z.toJSONSchema(...)` conversion. Without this dep, the consumer
|
|
@@ -332,7 +340,7 @@ function generatePackageJson(choices) {
|
|
|
332
340
|
// @takazudo/zudo-doc/integrations/doc-history which in turn imports
|
|
333
341
|
// @takazudo/zudo-doc-history-server/git-history. Without this dep the
|
|
334
342
|
// plugin host fails at init with ERR_MODULE_NOT_FOUND — W8A (#1739).
|
|
335
|
-
deps["@takazudo/zudo-doc-history-server"] = "^0.2.
|
|
343
|
+
deps["@takazudo/zudo-doc-history-server"] = "^0.2.3";
|
|
336
344
|
// W7A (#1736): doc-history-plugin.mjs spawns `tsx -e <inline-script>` to
|
|
337
345
|
// run the v2 runtime in a TS-aware Node subprocess; without tsx the
|
|
338
346
|
// plugin's preBuild step exits with ENOENT before zfb finishes config
|
package/dist/settings-gen.js
CHANGED
|
@@ -69,7 +69,10 @@ export function generateSettingsFile(choices) {
|
|
|
69
69
|
lines.push(` } satisfies Record<string, LocaleConfig>,`);
|
|
70
70
|
}
|
|
71
71
|
else {
|
|
72
|
-
|
|
72
|
+
// `as`, not `satisfies`: satisfies keeps the inferred type at literal {},
|
|
73
|
+
// so Object.entries(settings.locales) in the generated zfb.config.ts
|
|
74
|
+
// yields unknown values and `zfb check` fails with TS18046 (#2053).
|
|
75
|
+
lines.push(` locales: {} as Record<string, LocaleConfig>,`);
|
|
73
76
|
}
|
|
74
77
|
// mermaid is controlled by the markdown.features block in zfb.config.ts
|
|
75
78
|
// (zfb next.12+). This field is retained for compatibility with framework
|
package/package.json
CHANGED
|
@@ -36,6 +36,11 @@ export default function NotFoundPage(): JSX.Element {
|
|
|
36
36
|
noindex={true}
|
|
37
37
|
hideSidebar={true}
|
|
38
38
|
hideToc={true}
|
|
39
|
+
// Empty fragment suppresses DocLayoutWithDefaults' empty-data default
|
|
40
|
+
// Sidebar island — its marker never hydrates for published-package
|
|
41
|
+
// consumers (zfb#999) and zfb >= next.38 warns about it; the sidebar is
|
|
42
|
+
// hidden on this page anyway (zudolab/zudo-doc#2057).
|
|
43
|
+
sidebarOverride={<></>}
|
|
39
44
|
headerOverride={<HeaderWithDefaults lang={locale} />}
|
|
40
45
|
footerOverride={<FooterWithDefaults lang={locale} />}
|
|
41
46
|
bodyEndComponents={<BodyEndIslands basePath={settings.base ?? "/"} />}
|
|
@@ -65,6 +65,11 @@ export default function IndexPage(): JSX.Element {
|
|
|
65
65
|
noindex={settings.noindex}
|
|
66
66
|
hideSidebar={true}
|
|
67
67
|
hideToc={true}
|
|
68
|
+
// Empty fragment suppresses DocLayoutWithDefaults' empty-data default
|
|
69
|
+
// Sidebar island — its marker never hydrates for published-package
|
|
70
|
+
// consumers (zfb#999) and zfb >= next.38 warns about it; the sidebar is
|
|
71
|
+
// hidden on this page anyway (zudolab/zudo-doc#2057).
|
|
72
|
+
sidebarOverride={<></>}
|
|
68
73
|
headerOverride={<HeaderWithDefaults lang={locale} currentPath={withBase("/")} />}
|
|
69
74
|
footerOverride={<FooterWithDefaults lang={locale} />}
|
|
70
75
|
bodyEndComponents={<BodyEndIslands basePath={settings.base ?? "/"} />}
|
|
@@ -37,6 +37,7 @@ import ClientRouterBootstrap from "@/components/client-router-bootstrap";
|
|
|
37
37
|
import DesignTokenPanelBootstrap from "@/components/design-token-panel-bootstrap";
|
|
38
38
|
import ImageEnlarge, { ImageEnlargeSsrFallback } from "@/components/image-enlarge";
|
|
39
39
|
import { PageLoadingOverlay } from "@takazudo/zudo-doc/page-loading";
|
|
40
|
+
// @slot:body-end-islands:imports
|
|
40
41
|
|
|
41
42
|
// Set explicit `displayName` on each default-exported island so zfb's
|
|
42
43
|
// `captureComponentName` produces a stable marker even after the SSR
|
|
@@ -51,6 +52,7 @@ import { PageLoadingOverlay } from "@takazudo/zudo-doc/page-loading";
|
|
|
51
52
|
(DesignTokenPanelBootstrap as { displayName?: string }).displayName =
|
|
52
53
|
"DesignTokenPanelBootstrap";
|
|
53
54
|
(ImageEnlarge as { displayName?: string }).displayName = "ImageEnlarge";
|
|
55
|
+
// @slot:body-end-islands:display-names
|
|
54
56
|
|
|
55
57
|
/**
|
|
56
58
|
* Default sr-only label rendered as the AiChatModal SSR fallback. This
|
|
@@ -107,10 +109,14 @@ export interface BodyEndIslandsProps {
|
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
/**
|
|
110
|
-
* The
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
112
|
+
* The default body-end islands a doc page may mount: the design-token
|
|
113
|
+
* tweak panel (overlay, fixed-position), the AI chat modal (`<dialog>`
|
|
114
|
+
* overlay), and the image-enlarge dialog (mounted lazily based on
|
|
115
|
+
* viewport scan). Each is feature-gated — the design-token panel on
|
|
116
|
+
* `settings.designTokenPanel`, the AI chat modal (and its sr-only
|
|
117
|
+
* landmark heading) on `settings.aiAssistant`, and image-enlarge on
|
|
118
|
+
* `settings.imageEnlarge` — so a feature-off consumer ships neither the
|
|
119
|
+
* island marker nor a misleading landmark (zudolab/zudo-doc#2058).
|
|
114
120
|
*
|
|
115
121
|
* Each island is wrapped in `<Island ssrFallback>` so the heavy
|
|
116
122
|
* component is NOT evaluated server-side — they depend on
|
|
@@ -118,9 +124,10 @@ export interface BodyEndIslandsProps {
|
|
|
118
124
|
* fetch, etc. The hydration runtime swaps each placeholder on the
|
|
119
125
|
* client.
|
|
120
126
|
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
127
|
+
* When `settings.aiAssistant` is enabled, the
|
|
128
|
+
* `<h2 class="sr-only">AI Assistant</h2>` heading is emitted in the SSG
|
|
129
|
+
* output so screen readers and crawlers can discover the chat section
|
|
130
|
+
* landmark before JS hydration.
|
|
124
131
|
*/
|
|
125
132
|
export function BodyEndIslands({
|
|
126
133
|
basePath,
|
|
@@ -161,26 +168,52 @@ export function BodyEndIslands({
|
|
|
161
168
|
)
|
|
162
169
|
: null;
|
|
163
170
|
|
|
164
|
-
//
|
|
165
|
-
//
|
|
166
|
-
//
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
+
// Gated on `settings.aiAssistant` (zudolab/zudo-doc#2058): when the AI
|
|
172
|
+
// assistant feature is off, neither the AiChatModal island marker nor the
|
|
173
|
+
// sr-only "AI Assistant" landmark heading should reach the SSG output —
|
|
174
|
+
// otherwise feature-off consumers ship a dead island marker plus a
|
|
175
|
+
// misleading screen-reader landmark for a section that never hydrates.
|
|
176
|
+
// Mirrors the `designTokenPanel` gating above.
|
|
177
|
+
//
|
|
178
|
+
// KNOWN CAVEAT: zfb's island scanner walks the static `"use client"`
|
|
179
|
+
// import chain, so gating this JSX removes the SSR marker and heading but
|
|
180
|
+
// may NOT strip the AiChatModal bundle from the build output. Marker
|
|
181
|
+
// removal is the agreed first fix (#2058); bundle stripping is out of scope.
|
|
182
|
+
//
|
|
183
|
+
// The sr-only <p> fallback keeps the body label in static HTML for screen
|
|
184
|
+
// readers before JS hydration; sr-only keeps it invisible to sighted users.
|
|
185
|
+
const aiAssistant = settings.aiAssistant ? (
|
|
186
|
+
<>
|
|
187
|
+
{/* Emits the "AI Assistant" heading in the SSG output so screen
|
|
188
|
+
readers can discover the chat section landmark before JS
|
|
189
|
+
hydration. */}
|
|
190
|
+
<h2 class="sr-only">AI Assistant</h2>
|
|
191
|
+
{
|
|
192
|
+
Island({
|
|
193
|
+
ssrFallback: <p class="sr-only">{aiChatBodyLabel}</p>,
|
|
194
|
+
children: <AiChatModal basePath={basePath} />,
|
|
195
|
+
}) as unknown as VNode
|
|
196
|
+
}
|
|
197
|
+
</>
|
|
198
|
+
) : null;
|
|
171
199
|
|
|
172
|
-
//
|
|
173
|
-
//
|
|
174
|
-
//
|
|
175
|
-
//
|
|
176
|
-
// (
|
|
177
|
-
// dialog
|
|
178
|
-
//
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
200
|
+
// Gated on `settings.imageEnlarge` (zudolab/zudo-doc#2058). Same caveat as
|
|
201
|
+
// the AI assistant gating: removing this JSX drops the SSR dialog shell and
|
|
202
|
+
// island marker, but the bundle may persist via the static import scan.
|
|
203
|
+
//
|
|
204
|
+
// Wave 11 (zudolab/zudo-doc#1355): the SSR fallback is the empty, closed
|
|
205
|
+
// `<dialog class="zd-enlarge-dialog ...">` shell so the dist HTML carries
|
|
206
|
+
// one dialog from the start. Without this the smoke "exactly one
|
|
207
|
+
// zd-enlarge-dialog element" assertion sees zero (skip-ssr placeholders are
|
|
208
|
+
// empty divs) and the no-JS path has no dialog at all. Hydration replaces
|
|
209
|
+
// this shell with the real ImageEnlarge component when the page goes idle.
|
|
210
|
+
const imageEnlarge = settings.imageEnlarge
|
|
211
|
+
? (Island({
|
|
212
|
+
when: "idle",
|
|
213
|
+
ssrFallback: <ImageEnlargeSsrFallback />,
|
|
214
|
+
children: <ImageEnlarge />,
|
|
215
|
+
}) as unknown as VNode)
|
|
216
|
+
: null;
|
|
184
217
|
|
|
185
218
|
return (
|
|
186
219
|
<>
|
|
@@ -190,12 +223,9 @@ export function BodyEndIslands({
|
|
|
190
223
|
<PageLoadingOverlay />
|
|
191
224
|
{clientRouterBootstrap}
|
|
192
225
|
{designTokenPanelBootstrap}
|
|
193
|
-
{
|
|
194
|
-
readers can discover the chat section landmark before JS
|
|
195
|
-
hydration. */}
|
|
196
|
-
<h2 class="sr-only">AI Assistant</h2>
|
|
197
|
-
{aiChat}
|
|
226
|
+
{aiAssistant}
|
|
198
227
|
{imageEnlarge}
|
|
228
|
+
{/* @slot:body-end-islands:extra-islands */}
|
|
199
229
|
</>
|
|
200
230
|
);
|
|
201
231
|
}
|
|
@@ -17,9 +17,12 @@
|
|
|
17
17
|
// keeping the create-zudo-doc template copies byte-identical to the host.
|
|
18
18
|
|
|
19
19
|
import type { ComponentChildren, JSX, VNode } from "preact";
|
|
20
|
+
import { Island } from "@takazudo/zfb";
|
|
20
21
|
import { settings } from "@/config/settings";
|
|
21
22
|
import type { NavNode } from "@/utils/docs";
|
|
22
23
|
import { DocLayoutWithDefaults } from "@takazudo/zudo-doc/doclayout";
|
|
24
|
+
import { Toc, MobileToc } from "@takazudo/zudo-doc/toc";
|
|
25
|
+
import { getTocTitle } from "./_toc-title";
|
|
23
26
|
import { Breadcrumb } from "@takazudo/zudo-doc/breadcrumb";
|
|
24
27
|
import { NavCardGrid } from "@takazudo/zudo-doc/nav-indexing";
|
|
25
28
|
import { HeadWithDefaults } from "./_head-with-defaults";
|
|
@@ -145,6 +148,31 @@ export function DocPageShell(props: DocPageShellProps): JSX.Element {
|
|
|
145
148
|
docHistorySlot,
|
|
146
149
|
} = props;
|
|
147
150
|
|
|
151
|
+
// TOC overrides: mount the package Toc/MobileToc with the host-resolved
|
|
152
|
+
// locale-aware `tocTitle`. The gating mirrors the package's
|
|
153
|
+
// `shouldRenderDefaultToc` exactly (`!hideToc && headings.length > 0`) so an
|
|
154
|
+
// undefined override never silently falls back to the package default with a
|
|
155
|
+
// different title. Each is wrapped in `<Island when="load">` here (the call
|
|
156
|
+
// site), matching how the package wraps its own default. Hydrating these
|
|
157
|
+
// npm-dist "use client" components requires zfb >= 0.1.0-next.39, whose
|
|
158
|
+
// scanner registers node_modules islands (zfb#999/#1001) — the former
|
|
159
|
+
// scanner-visible local shims (#2057) are gone; re-adding them would
|
|
160
|
+
// recreate island marker-name collisions.
|
|
161
|
+
const tocTitle = getTocTitle(locale);
|
|
162
|
+
const shouldRenderToc = !hideToc && headings.length > 0;
|
|
163
|
+
const tocOverride = shouldRenderToc
|
|
164
|
+
? (Island({
|
|
165
|
+
when: "load",
|
|
166
|
+
children: <Toc headings={headings} title={tocTitle} />,
|
|
167
|
+
}) as unknown as VNode)
|
|
168
|
+
: undefined;
|
|
169
|
+
const mobileTocOverride = shouldRenderToc
|
|
170
|
+
? (Island({
|
|
171
|
+
when: "load",
|
|
172
|
+
children: <MobileToc headings={headings} title={tocTitle} />,
|
|
173
|
+
}) as unknown as VNode)
|
|
174
|
+
: undefined;
|
|
175
|
+
|
|
148
176
|
return (
|
|
149
177
|
<DocLayoutWithDefaults
|
|
150
178
|
title={composeMetaTitle(title)}
|
|
@@ -183,6 +211,8 @@ export function DocPageShell(props: DocPageShellProps): JSX.Element {
|
|
|
183
211
|
currentPath={currentPath}
|
|
184
212
|
/>
|
|
185
213
|
}
|
|
214
|
+
tocOverride={tocOverride}
|
|
215
|
+
mobileTocOverride={mobileTocOverride}
|
|
186
216
|
afterSidebar={<SidebarPrepaint />}
|
|
187
217
|
footerOverride={<FooterWithDefaults lang={locale} />}
|
|
188
218
|
bodyEndComponents={<DocBodyEnd />}
|
|
@@ -45,10 +45,11 @@ import {
|
|
|
45
45
|
VersionSwitcher,
|
|
46
46
|
type VersionSwitcherLabels,
|
|
47
47
|
} from "@takazudo/zudo-doc/i18n-version";
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
//
|
|
48
|
+
// The bare (non-island-wrapped) package ThemeToggle, imported straight from
|
|
49
|
+
// the npm subpath: zfb >= 0.1.0-next.39 scans "use client" modules under
|
|
50
|
+
// node_modules (zfb#999/#1001), so the marker registers without the former
|
|
51
|
+
// project-source shim (#2048/#2057). This header composes its own Island
|
|
52
|
+
// below, avoiding nesting an island inside an island.
|
|
52
53
|
import { ThemeToggle } from "@takazudo/zudo-doc/theme-toggle";
|
|
53
54
|
import SidebarToggle from "@/components/sidebar-toggle";
|
|
54
55
|
import { settings } from "@/config/settings";
|
|
@@ -249,6 +249,9 @@ export const SEARCH_WIDGET_SCRIPT = /* javascript */ `(function () {
|
|
|
249
249
|
self._entries = Array.isArray(data) ? data : (data.entries || []);
|
|
250
250
|
prepareLc(self._entries);
|
|
251
251
|
self._loading = false;
|
|
252
|
+
// Clear the unavailable flag BEFORE re-running search so a successful
|
|
253
|
+
// retry (e.g. via the openDialog() reload path) fully recovers (#2062).
|
|
254
|
+
self._indexUnavailable = false;
|
|
252
255
|
// If user already typed, search now
|
|
253
256
|
if (self._input && self._input.value.trim()) {
|
|
254
257
|
self.search();
|
|
@@ -277,6 +280,20 @@ export const SEARCH_WIDGET_SCRIPT = /* javascript */ `(function () {
|
|
|
277
280
|
}
|
|
278
281
|
|
|
279
282
|
if (!this._entries) {
|
|
283
|
+
// Index failed to load: show the terminal "Search unavailable" state and
|
|
284
|
+
// stop — do NOT show "Loading search index…" or refetch on every
|
|
285
|
+
// keystroke (#2062). The openDialog() reload path is the intended retry
|
|
286
|
+
// trigger. Clear any stale result state/count/sentinel first.
|
|
287
|
+
if (this._indexUnavailable) {
|
|
288
|
+
this.teardownSentinel();
|
|
289
|
+
this._allResults = [];
|
|
290
|
+
this._shownCount = 0;
|
|
291
|
+
if (this._results) {
|
|
292
|
+
this._results.innerHTML = "<p class=\\"text-small text-muted\\">Search unavailable</p>";
|
|
293
|
+
}
|
|
294
|
+
this.updateCount();
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
280
297
|
if (this._results) {
|
|
281
298
|
this._results.innerHTML = "<p class=\\"text-small text-muted\\">Loading search index\\u2026</p>";
|
|
282
299
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// TOC section-label resolver for the Toc/MobileToc overrides mounted by
|
|
2
|
+
// `_doc-page-shell.tsx`. Hand-mirrors `getTocTitle`, which the zudo-doc
|
|
3
|
+
// package exports from "@takazudo/zudo-doc/toc" in versions > 0.2.2. The
|
|
4
|
+
// published version this scaffold installs (<= 0.2.2) does not yet export it,
|
|
5
|
+
// so the tiny lang→title map is duplicated here. After bumping the
|
|
6
|
+
// @takazudo/zudo-doc dependency past 0.2.2 you can replace this whole file
|
|
7
|
+
// with: export { getTocTitle } from "@takazudo/zudo-doc/toc";
|
|
8
|
+
const TOC_TITLES: Record<string, string> = {
|
|
9
|
+
en: "On this page",
|
|
10
|
+
ja: "目次",
|
|
11
|
+
de: "Auf dieser Seite",
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const DEFAULT_TOC_TITLE = "On this page";
|
|
15
|
+
|
|
16
|
+
/** Return the TOC section label for the given BCP-47 language tag. */
|
|
17
|
+
export function getTocTitle(lang?: string): string {
|
|
18
|
+
if (!lang) return DEFAULT_TOC_TITLE;
|
|
19
|
+
// "en-US" → try "en" first, then "en-US", then the English default.
|
|
20
|
+
const primary = lang.split("-")[0]!;
|
|
21
|
+
return TOC_TITLES[primary] ?? TOC_TITLES[lang] ?? DEFAULT_TOC_TITLE;
|
|
22
|
+
}
|
|
@@ -131,8 +131,15 @@ export default function SidebarToggle({
|
|
|
131
131
|
onClick={() => setOpen(false)}
|
|
132
132
|
/>
|
|
133
133
|
|
|
134
|
-
{/* Sidebar panel - mobile only (desktop sidebar is in doc-layout)
|
|
134
|
+
{/* Sidebar panel - mobile only (desktop sidebar is in doc-layout).
|
|
135
|
+
`inert` when closed: the panel is only visually hidden via
|
|
136
|
+
`-translate-x-full`, so without `inert` its links/filter/buttons
|
|
137
|
+
stay in the tab order and accessibility tree while off-screen
|
|
138
|
+
(zudolab/zudo-doc#2059). `inert={false}` serialises to no attribute,
|
|
139
|
+
so the SSR (open=false → `inert`) and initial client render stay
|
|
140
|
+
byte-stable for hydration. */}
|
|
135
141
|
<aside
|
|
142
|
+
inert={!open}
|
|
136
143
|
className={`
|
|
137
144
|
fixed top-[3.5rem] left-0 z-40 h-[calc(100vh-3.5rem)] w-[16rem] flex flex-col
|
|
138
145
|
border-r border-muted bg-bg transition-transform duration-200
|
|
@@ -288,7 +288,7 @@ export default function SidebarTree({ nodes, currentSlug, rootMenuItems, backToM
|
|
|
288
288
|
type="text"
|
|
289
289
|
placeholder={filterPlaceholder}
|
|
290
290
|
value={query}
|
|
291
|
-
onChange={(e) => setQuery(e.
|
|
291
|
+
onChange={(e) => setQuery(e.currentTarget.value)}
|
|
292
292
|
className="bg-transparent text-small outline-none w-full text-fg placeholder:text-muted"
|
|
293
293
|
/>
|
|
294
294
|
</div>
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// Local type shim for the bare `zfb/config` specifier.
|
|
2
|
+
//
|
|
3
|
+
// `@takazudo/zfb` is consumed as a published npm package (version pinned
|
|
4
|
+
// in the root `package.json`). The package exposes its real config types
|
|
5
|
+
// under the *scoped* subpath `@takazudo/zfb/config` → `dist/config.d.ts`.
|
|
6
|
+
// But `zfb.config.ts` imports from the *bare* specifier `zfb/config`,
|
|
7
|
+
// which zfb's build tool aliases to a runtime-only stub at parse time
|
|
8
|
+
// (`zfb-config-stub.mjs` — `defineConfig` is identity, carrying no types).
|
|
9
|
+
// No real file backs `zfb/config` in `node_modules`, so this ambient
|
|
10
|
+
// declaration is what supplies the `ZfbConfig` type to `zfb.config.ts`.
|
|
11
|
+
//
|
|
12
|
+
// IMPORTANT — this block is the source of truth for the type `zfb check`
|
|
13
|
+
// (plain `tsc --noEmit`) binds against the config. An ambient `declare
|
|
14
|
+
// module` wins over node resolution AND over tsconfig `paths`, so it must
|
|
15
|
+
// be kept in sync BY HAND with the published `@takazudo/zfb/config`
|
|
16
|
+
// (`dist/config.d.ts`). When it lags the engine, valid config fields fail
|
|
17
|
+
// `pnpm check` with TS2353 (see Takazudo/zudo-front-builder#678 +
|
|
18
|
+
// zudolab/zudo-doc#1834 — `bundle` was missing here, blocking next.22's
|
|
19
|
+
// `bundle.exclude`).
|
|
20
|
+
|
|
21
|
+
declare module "zfb/config" {
|
|
22
|
+
/** JSX framework runtime. */
|
|
23
|
+
export type Framework = "preact" | "react";
|
|
24
|
+
|
|
25
|
+
/** A content collection registered with the zfb engine. */
|
|
26
|
+
export interface CollectionDef {
|
|
27
|
+
/** Identifier used at the call site (e.g. `"docs"`). */
|
|
28
|
+
name: string;
|
|
29
|
+
/** Directory (relative to the project root) holding the entries. */
|
|
30
|
+
path: string;
|
|
31
|
+
/**
|
|
32
|
+
* Optional schema. Reserved for v1.1 — accepted but not enforced
|
|
33
|
+
* today. Authored as zod and converted to JSON Schema via
|
|
34
|
+
* `z.toJSONSchema()` at the boundary.
|
|
35
|
+
*/
|
|
36
|
+
schema?: Record<string, unknown>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Tailwind options; absent = defaults. */
|
|
40
|
+
export interface TailwindConfig {
|
|
41
|
+
enabled?: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** User-supplied plugin configuration entry. */
|
|
45
|
+
export interface PluginConfig {
|
|
46
|
+
name: string;
|
|
47
|
+
options?: Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Bundler options. Mirrors `BundleConfig` in crates/zfb/src/config.rs
|
|
52
|
+
* and the published `@takazudo/zfb/config` (`dist/config.d.ts`). Added
|
|
53
|
+
* in next.22 (`bundle.exclude`, #664) and extended in next.23
|
|
54
|
+
* (`mainFields` / `external`, #676).
|
|
55
|
+
*/
|
|
56
|
+
export interface BundleConfig {
|
|
57
|
+
/**
|
|
58
|
+
* Project-relative, gitignore-style globs for source files the bundler
|
|
59
|
+
* must NOT pull into the esbuild graph (e.g. test fixtures or
|
|
60
|
+
* `*.stories.tsx`). Matched files are skipped from the shadow-tree walk
|
|
61
|
+
* and dropped from any eager `import.meta.glob(...)` expansion.
|
|
62
|
+
*/
|
|
63
|
+
exclude?: string[];
|
|
64
|
+
/**
|
|
65
|
+
* Explicit esbuild `main-fields` for the `--platform=neutral` page/SSR
|
|
66
|
+
* pass (empty by default under `neutral`), letting CJS-`main`-only deps
|
|
67
|
+
* resolve. Mirrors `BundleConfig::main_fields`.
|
|
68
|
+
*/
|
|
69
|
+
mainFields?: string[];
|
|
70
|
+
/**
|
|
71
|
+
* Bare specifiers to mark external in the `--platform=neutral` pass so
|
|
72
|
+
* esbuild leaves them unbundled. Mirrors `BundleConfig::external`.
|
|
73
|
+
*/
|
|
74
|
+
external?: string[];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Mirrors the Rust `Config` struct one-for-one. */
|
|
78
|
+
export interface ZfbConfig {
|
|
79
|
+
outDir?: string;
|
|
80
|
+
publicDir?: string;
|
|
81
|
+
host?: string;
|
|
82
|
+
port?: number;
|
|
83
|
+
framework?: Framework;
|
|
84
|
+
collections?: CollectionDef[];
|
|
85
|
+
tailwind?: TailwindConfig;
|
|
86
|
+
/**
|
|
87
|
+
* Bundler options. `bundle.exclude` keeps project-relative globs out of
|
|
88
|
+
* the esbuild graph — used here to skip `packages/md-plugins/__fixtures__/**`
|
|
89
|
+
* so the MDX link resolver no longer walks the test fixtures (silences
|
|
90
|
+
* ~15 pre-existing broken-link warnings). Mirrors `Config::bundle`.
|
|
91
|
+
*/
|
|
92
|
+
bundle?: BundleConfig;
|
|
93
|
+
plugins?: PluginConfig[];
|
|
94
|
+
adapter?: string;
|
|
95
|
+
/**
|
|
96
|
+
* Strip `.md` / `.mdx` from in-page `<a href>` paths and append a
|
|
97
|
+
* trailing `/` so author-written `[label](other.mdx)` references
|
|
98
|
+
* resolve to the rendered route URL. Mirrors Config::strip_md_ext
|
|
99
|
+
* in crates/zfb/src/config.rs (zudolab/zfb#131).
|
|
100
|
+
*/
|
|
101
|
+
stripMdExt?: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Site base path. Prefixed onto stable HTML asset URLs (CSS / JS
|
|
104
|
+
* `<link>` and `<script>` tags). Normalised to start AND end with
|
|
105
|
+
* `/`; `undefined` / `""` / `"/"` all behave identically (no
|
|
106
|
+
* prefix). Mirrors Config::base in crates/zfb/src/config.rs
|
|
107
|
+
* (Takazudo/zudo-front-builder#154).
|
|
108
|
+
*/
|
|
109
|
+
base?: string;
|
|
110
|
+
/**
|
|
111
|
+
* Configures the syntect-based syntax highlighter shipped with zfb.
|
|
112
|
+
* Mirrors `code_highlight` in crates/zfb/src/config.rs (Takazudo/zudo-front-builder#188 / sub #194; landed in commit 339e30f).
|
|
113
|
+
* When omitted, the engine falls back to the hardcoded default theme `base16-ocean.dark`.
|
|
114
|
+
*/
|
|
115
|
+
codeHighlight?: {
|
|
116
|
+
theme?: string;
|
|
117
|
+
themesDir?: string;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Markdown link resolver (port of `remarkResolveMarkdownLinks`).
|
|
121
|
+
* Mirrors `Config::resolve_markdown_links` in crates/zfb/src/config.rs
|
|
122
|
+
* (Takazudo/zudo-front-builder PR #234 / zudolab/zudo-doc#1577).
|
|
123
|
+
* When `enabled: true`, the build appends `ResolveLinksPlugin` to the
|
|
124
|
+
* mdast pipeline so author-written `[label](./other.mdx)` links are
|
|
125
|
+
* rewritten to the corresponding rendered route URL — bypassing the
|
|
126
|
+
* file→directory transformation that breaks relative paths in dist
|
|
127
|
+
* HTML when `foo.mdx` becomes `foo/index.html`.
|
|
128
|
+
*/
|
|
129
|
+
resolveMarkdownLinks?: {
|
|
130
|
+
enabled?: boolean;
|
|
131
|
+
docsDir?: string;
|
|
132
|
+
dirs?: Array<{ dir: string; routePrefix: string }>;
|
|
133
|
+
onBrokenLinks?: "warn" | "error" | "ignore";
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Whether the basePath rewriter should append a trailing `/` to
|
|
137
|
+
* extensionless absolute hrefs. Mirrors `Config::trailing_slash` in
|
|
138
|
+
* crates/zfb/src/config.rs (Takazudo/zudo-front-builder PR #234 /
|
|
139
|
+
* zudolab/zudo-doc#1579). Off by default — preserves byte-for-byte
|
|
140
|
+
* parity with the pre-`trailingSlash` build for projects that
|
|
141
|
+
* haven't opted in.
|
|
142
|
+
*/
|
|
143
|
+
trailingSlash?: boolean;
|
|
144
|
+
/**
|
|
145
|
+
* Markdown / MDX pipeline options. Mirrors `Config::markdown` →
|
|
146
|
+
* `MarkdownConfig` in crates/zfb/src/config.rs. zfb next.12 moved the
|
|
147
|
+
* former-Core features under `markdown.features` and next.13 ships the
|
|
148
|
+
* rest as opt-in; zudo-doc uses `markdown.features` to opt back into the
|
|
149
|
+
* former-Core four plus the additional opt-in features (#1804). Each
|
|
150
|
+
* `features` value is per-feature: `true` for boolean-shorthand features,
|
|
151
|
+
* or an options object for object-typed features.
|
|
152
|
+
*/
|
|
153
|
+
markdown?: {
|
|
154
|
+
gfm?: boolean | Record<string, boolean>;
|
|
155
|
+
toc?: Record<string, unknown>;
|
|
156
|
+
externalLinks?: Record<string, unknown>;
|
|
157
|
+
cjkFriendly?: boolean;
|
|
158
|
+
features?: Record<string, boolean | Record<string, unknown>>;
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Identity helper: returns the supplied config as-is, but typed
|
|
164
|
+
* against `ZfbConfig`. Use as the default export of `zfb.config.ts`.
|
|
165
|
+
*/
|
|
166
|
+
export function defineConfig(config: ZfbConfig): ZfbConfig;
|
|
167
|
+
}
|
|
@@ -131,6 +131,11 @@ export function TagDetailPageView({
|
|
|
131
131
|
noindex={settings.noindex}
|
|
132
132
|
hideSidebar={true}
|
|
133
133
|
hideToc={true}
|
|
134
|
+
// Empty fragment suppresses DocLayoutWithDefaults' empty-data default
|
|
135
|
+
// Sidebar island — its marker never hydrates for published-package
|
|
136
|
+
// consumers (zfb#999) and zfb >= next.38 warns about it; the sidebar is
|
|
137
|
+
// hidden on this page anyway (zudolab/zudo-doc#2057).
|
|
138
|
+
sidebarOverride={<></>}
|
|
134
139
|
// Tag segment URL-encoded — emitted href/path sites only; route params
|
|
135
140
|
// stay raw (e.g. "type:guide" → "type%3Aguide").
|
|
136
141
|
headerOverride={<HeaderWithDefaults lang={locale} currentPath={withBase(`${prefix}/docs/tags/${encodeURIComponent(tag)}`)} />}
|
|
@@ -184,6 +189,11 @@ export function TagsIndexPageView({ locale }: { locale: string }): JSX.Element {
|
|
|
184
189
|
noindex={settings.noindex}
|
|
185
190
|
hideSidebar={true}
|
|
186
191
|
hideToc={true}
|
|
192
|
+
// Empty fragment suppresses DocLayoutWithDefaults' empty-data default
|
|
193
|
+
// Sidebar island — its marker never hydrates for published-package
|
|
194
|
+
// consumers (zfb#999) and zfb >= next.38 warns about it; the sidebar is
|
|
195
|
+
// hidden on this page anyway (zudolab/zudo-doc#2057).
|
|
196
|
+
sidebarOverride={<></>}
|
|
187
197
|
headerOverride={<HeaderWithDefaults lang={locale} currentPath={withBase(`${prefix}/docs/tags`)} />}
|
|
188
198
|
breadcrumbOverride={<Breadcrumb items={breadcrumbItems} />}
|
|
189
199
|
footerOverride={<FooterWithDefaults lang={locale} />}
|
|
@@ -103,6 +103,11 @@ export default function LocaleIndexPage({ params }: PageArgs): JSX.Element {
|
|
|
103
103
|
noindex={settings.noindex}
|
|
104
104
|
hideSidebar={true}
|
|
105
105
|
hideToc={true}
|
|
106
|
+
// Empty fragment suppresses DocLayoutWithDefaults' empty-data default
|
|
107
|
+
// Sidebar island — its marker never hydrates for published-package
|
|
108
|
+
// consumers (zfb#999) and zfb >= next.38 warns about it; the sidebar is
|
|
109
|
+
// hidden on this page anyway (zudolab/zudo-doc#2057).
|
|
110
|
+
sidebarOverride={<></>}
|
|
106
111
|
headerOverride={<HeaderWithDefaults lang={locale as Locale} currentPath={withBase(`/${locale}/`)} />}
|
|
107
112
|
footerOverride={<FooterWithDefaults lang={locale} />}
|
|
108
113
|
bodyEndComponents={<BodyEndIslands basePath={settings.base ?? "/"} />}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import { useState, useEffect, useRef } from "preact/compat";
|
|
2
4
|
import { FindBar } from "./find-bar";
|
|
3
5
|
import { createFindInPage } from "@/utils/find-in-page";
|
|
@@ -30,14 +32,18 @@ export default function FindInPageInit() {
|
|
|
30
32
|
return () => document.removeEventListener("keydown", handler);
|
|
31
33
|
}, [isTauri]);
|
|
32
34
|
|
|
33
|
-
// Clear search on zfb page navigation
|
|
35
|
+
// Clear search on zfb page navigation. zfb navigates via SPA body swap and
|
|
36
|
+
// fires "zfb:before-preparation" on document before nav — it never fires the
|
|
37
|
+
// native "pagehide" (full-unload) event. The literal is inlined because
|
|
38
|
+
// downstream scaffolds do not depend on @takazudo/zudo-doc as a runtime dep
|
|
39
|
+
// (same reason as the designTokenPanel bootstrap).
|
|
34
40
|
useEffect(() => {
|
|
35
41
|
const handler = () => {
|
|
36
42
|
findInPageRef.current.stop();
|
|
37
43
|
setVisible(false);
|
|
38
44
|
};
|
|
39
|
-
document.addEventListener("
|
|
40
|
-
return () => document.removeEventListener("
|
|
45
|
+
document.addEventListener("zfb:before-preparation", handler);
|
|
46
|
+
return () => document.removeEventListener("zfb:before-preparation", handler);
|
|
41
47
|
}, []);
|
|
42
48
|
|
|
43
49
|
if (!isTauri) return null;
|
|
@@ -65,6 +65,11 @@ export function VersionsPageView({ locale }: { locale: string }): JSX.Element {
|
|
|
65
65
|
noindex={settings.noindex}
|
|
66
66
|
hideSidebar={true}
|
|
67
67
|
hideToc={true}
|
|
68
|
+
// Empty fragment suppresses DocLayoutWithDefaults' empty-data default
|
|
69
|
+
// Sidebar island — its marker never hydrates for published-package
|
|
70
|
+
// consumers (zfb#999) and zfb >= next.38 warns about it; the sidebar is
|
|
71
|
+
// hidden on this page anyway (zudolab/zudo-doc#2057).
|
|
72
|
+
sidebarOverride={<></>}
|
|
68
73
|
headerOverride={<HeaderWithDefaults lang={locale as Locale} currentPath={withBase(`${prefix}/docs/versions`)} />}
|
|
69
74
|
footerOverride={<FooterWithDefaults lang={locale} />}
|
|
70
75
|
bodyEndComponents={<BodyEndIslands basePath={settings.base ?? "/"} />}
|