@takazudo/zudo-doc 3.2.0 → 3.3.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/chrome/derive.d.ts +7 -1
  3. package/dist/chrome/derive.js +13 -2
  4. package/dist/chrome-bindings.d.ts +159 -0
  5. package/dist/chrome-bindings.js +6 -0
  6. package/dist/color-scheme-utils.d.ts +1 -1
  7. package/dist/color-schemes-defaults/index.d.ts +23 -0
  8. package/dist/color-schemes-defaults/index.js +121 -0
  9. package/dist/config.d.ts +443 -0
  10. package/dist/config.js +116 -0
  11. package/dist/design-token-panel-bootstrap.d.ts +57 -7
  12. package/dist/design-token-panel-bootstrap.js +12 -0
  13. package/dist/design-token-panel-config/index.d.ts +49 -0
  14. package/dist/design-token-panel-config/index.js +214 -0
  15. package/dist/design-token-panel-config/manifest.d.ts +46 -0
  16. package/dist/design-token-panel-config/manifest.js +105 -0
  17. package/dist/directive-vocabulary-defaults/index.d.ts +16 -0
  18. package/dist/directive-vocabulary-defaults/index.js +12 -0
  19. package/dist/doc-body-end-islands/index.d.ts +30 -7
  20. package/dist/doc-body-end-islands/index.js +27 -0
  21. package/dist/docs-schema/index.d.ts +67 -0
  22. package/dist/docs-schema/index.js +47 -0
  23. package/dist/factory-context/index.d.ts +14 -0
  24. package/dist/features.css +10 -0
  25. package/dist/find-in-page/find-bar.d.ts +9 -0
  26. package/dist/find-in-page/find-bar.js +114 -0
  27. package/dist/find-in-page/find-in-page.d.ts +17 -0
  28. package/dist/find-in-page/find-in-page.js +131 -0
  29. package/dist/find-in-page/index.d.ts +11 -0
  30. package/dist/find-in-page/index.js +49 -0
  31. package/dist/frontmatter-preview-defaults/index.d.ts +16 -0
  32. package/dist/frontmatter-preview-defaults/index.js +25 -0
  33. package/dist/i18n-defaults/index.d.ts +22 -0
  34. package/dist/i18n-defaults/index.js +167 -0
  35. package/dist/plugins/routes.js +44 -20
  36. package/dist/preset.d.ts +9 -0
  37. package/dist/routes/_chrome.js +2 -1
  38. package/dist/safelist.css +1 -1
  39. package/dist/settings.d.ts +37 -0
  40. package/dist/theme.css +319 -0
  41. package/dist/z-index-defaults/index.d.ts +45 -0
  42. package/dist/z-index-defaults/index.js +34 -0
  43. package/package.json +50 -3
  44. package/routes-src/_chrome.tsx +30 -8
  45. package/routes-src/_virtual.d.ts +34 -2
  46. package/tsconfig.base.json +29 -0
  47. package/virtual-modules.d.ts +79 -0
  48. package/zfb-config-shim.d.ts +188 -0
@@ -0,0 +1,443 @@
1
+ /**
2
+ * `@takazudo/zudo-doc/config` — the single-entry config API (epic
3
+ * zudolab/zudo-doc#2651, Wave 4 #2657).
4
+ *
5
+ * A generated project's ENTIRE configuration is:
6
+ *
7
+ * ```ts
8
+ * // zfb.config.ts — the one config file
9
+ * import { defineConfig } from "zfb/config";
10
+ * import { zudoDoc } from "@takazudo/zudo-doc/config";
11
+ *
12
+ * export default defineConfig(zudoDoc({
13
+ * siteName: "My Docs",
14
+ * // …only the fields you chose; everything has a documented @default.
15
+ * }));
16
+ * ```
17
+ *
18
+ * `zudoDoc()` SHALLOW-merges the user's fields over {@link DEFAULT_SETTINGS} —
19
+ * top-level fields only (`{ ...DEFAULT_SETTINGS, ...user }`). A supplied nested
20
+ * object (e.g. `colorMode`, `metaTags`) REPLACES the default wholesale; it is
21
+ * NOT deep-merged key-by-key. This is safe because every nested config type is
22
+ * all-required-fields, so a caller supplying one supplies all of its fields.
23
+ * `zudoDoc()` also supplies the Wave-3 package defaults
24
+ * (`buildDocsSchema`/`directiveVocabulary`/`translations`/`colorSchemes`/tag
25
+ * vocabulary) unless overridden, and returns a **complete `ZfbConfig`** — the
26
+ * host spreads nothing.
27
+ *
28
+ * ──────────────────────────────────────────────────────────────────────────
29
+ * COMPOSITION MECHANISM (locked, #2653): JS object composition — NOT zfb-native
30
+ * `presets:`. `zudoDoc()` builds the full `ZfbConfig` in JS and returns it
31
+ * complete; the returned object carries **no `presets` field**. `zudoDocPreset()`
32
+ * stays the internal fragment builder this calls (still exported at
33
+ * `@takazudo/zudo-doc/preset` as an advanced escape hatch); its
34
+ * collections/plugins/markdown logic is NOT reimplemented here.
35
+ *
36
+ * ──────────────────────────────────────────────────────────────────────────
37
+ * NODE-BUILTIN-FREE EVAL GRAPH (non-negotiable — guarded by a unit test)
38
+ * ──────────────────────────────────────────────────────────────────────────
39
+ * zfb evaluates the config module through esbuild with `--platform=neutral`
40
+ * (mirrors zfb's `loader.rs:277`); a transitive `node:*` import fails the load.
41
+ * `zudoDoc()` is the new central node in that eval graph — it transitively pulls
42
+ * in `preset.ts` plus every #2654 default module — so this module and all of
43
+ * them MUST stay free of `node:*` builtins. `zod` is the only allowed runtime
44
+ * dependency on this path (a required peer). The `ZfbConfig`/`BundleConfig`
45
+ * imports from `@takazudo/zfb/config` are **type-only** (erased before esbuild
46
+ * resolution), so they add nothing to the eval graph. The guard lives in
47
+ * `src/__tests__/foundation-eval-graph.test.ts` (`config.ts` is in
48
+ * `NODE_FREE_MODULES`).
49
+ *
50
+ * ──────────────────────────────────────────────────────────────────────────
51
+ * SERIALIZABILITY SPLIT
52
+ * ──────────────────────────────────────────────────────────────────────────
53
+ * The non-serializable / data overrides (`buildDocsSchema` fn, `colorSchemes`,
54
+ * `translations`, `directives`, `tagVocabularyEntries`) and the shell fields
55
+ * (`port`/`adapter`/`bundle`) are peeled off `user` up front so they never leak
56
+ * into the merged `settings` object — only clean, JSON-serializable settings
57
+ * ride into the routes plugin's virtual-module payload (exactly as
58
+ * `zudoDocPreset()` does today). The function-valued/data overrides travel the
59
+ * import-graph side (passed as `zudoDocPreset()` arguments, not serialized).
60
+ */
61
+ import type { ZfbConfig, BundleConfig } from "@takazudo/zfb/config";
62
+ import type { ZodType } from "zod";
63
+ import type { DirectiveVocabulary, PresetTranslations, PresetTagVocabularyEntry } from "./preset.js";
64
+ import type { ColorScheme } from "./color-scheme-utils.js";
65
+ import type { Settings, ColorModeConfig, LocaleConfig, MetaTagsConfig, SiteHeadConfig, TagPlacement, TagGovernanceMode, VersionConfig, FooterConfig, HeaderNavItem, HeaderRightItem, FrontmatterPreviewConfig, BodyFootUtilAreaConfig, HtmlPreviewConfig } from "./settings.js";
66
+ /** The `settings.claudeResources` block (or `false` when disabled). */
67
+ type ClaudeResourcesConfig = {
68
+ claudeDir: string;
69
+ projectRoot?: string;
70
+ scanRoot?: string;
71
+ } | false;
72
+ export declare const DEFAULT_SETTINGS: Settings;
73
+ export interface ZudoDocConfig {
74
+ /**
75
+ * Active color scheme name (must exist in `colorSchemes`).
76
+ * @default "Default Dark"
77
+ */
78
+ colorScheme?: string;
79
+ /**
80
+ * Light/dark mode wiring, or `false` for a single fixed scheme.
81
+ * @default { defaultMode: "dark", lightScheme: "Default Light", darkScheme: "Default Dark", respectPrefersColorScheme: true }
82
+ */
83
+ colorMode?: ColorModeConfig | false;
84
+ /**
85
+ * Site name shown in the header and metadata. The one field you almost
86
+ * always set.
87
+ * @default "Docs"
88
+ */
89
+ siteName?: string;
90
+ /**
91
+ * Site description used in metadata (`<meta name="description">`, llms.txt).
92
+ * @default ""
93
+ */
94
+ siteDescription?: string;
95
+ /**
96
+ * Public URL sub-path prefix mounted in front of every absolute asset URL
97
+ * (e.g. `"/pj/my-site/"`). `"/"` = root-mounted.
98
+ * @default "/"
99
+ */
100
+ base?: string;
101
+ /**
102
+ * Append a trailing `/` to extensionless internal hrefs.
103
+ * @default false
104
+ */
105
+ trailingSlash?: boolean;
106
+ /**
107
+ * Minify production HTML output from `zfb build`.
108
+ * @default true
109
+ */
110
+ minifyHtml?: boolean;
111
+ /**
112
+ * Directory (project-root-relative) holding the default-locale docs.
113
+ * @default "src/content/docs"
114
+ */
115
+ docsDir?: string;
116
+ /**
117
+ * Default locale code (unprefixed routes).
118
+ * @default "en"
119
+ */
120
+ defaultLocale?: string;
121
+ /**
122
+ * Additional locales: code → `{ label, dir }`. Each becomes a
123
+ * `/<code>/docs/…` route tree + `docs-<code>` collection.
124
+ * @default {}
125
+ */
126
+ locales?: Record<string, LocaleConfig>;
127
+ /**
128
+ * Enable mermaid diagram rendering in markdown.
129
+ * @default true
130
+ */
131
+ mermaid?: boolean;
132
+ /**
133
+ * Add `noindex,nofollow` to every page (for internal docs).
134
+ * @default false
135
+ */
136
+ noindex?: boolean;
137
+ /**
138
+ * "Edit this page" link base, or `false` to omit.
139
+ * @default false
140
+ */
141
+ editUrl?: string | false;
142
+ /**
143
+ * GitHub repository URL shown in the header, or `false` to omit.
144
+ * @default false
145
+ */
146
+ githubUrl?: string | false;
147
+ /**
148
+ * "owner/repo" — enables `#123` / SHA autolinks in markdown. Omit to disable.
149
+ * @default undefined
150
+ */
151
+ githubAutolinksRepo?: string;
152
+ /**
153
+ * Canonical site origin (e.g. `"https://example.com"`) for sitemap /
154
+ * canonical / og:url. Empty = not set.
155
+ * @default ""
156
+ */
157
+ siteUrl?: string;
158
+ /**
159
+ * `<meta>` / OpenGraph / Twitter-card emission toggles.
160
+ * @default { description: true, keywords: false, ogImage: false, ogSiteName: true, twitterCard: false }
161
+ */
162
+ metaTags?: MetaTagsConfig;
163
+ /**
164
+ * Site-wide custom `<head>` extras (preconnect / preload / stylesheets /
165
+ * meta / alternateLinks). Omit to emit nothing extra.
166
+ * @default undefined
167
+ */
168
+ head?: SiteHeadConfig;
169
+ /**
170
+ * Emit a sitemap route.
171
+ * @default false
172
+ */
173
+ sitemap?: boolean;
174
+ /**
175
+ * Show the Created/Updated/Author meta block on doc pages.
176
+ * @default false
177
+ */
178
+ docMetainfo?: boolean;
179
+ /**
180
+ * Enable the `/docs/tags` + `/docs/tags/[tag]` tag index routes.
181
+ * @default false
182
+ */
183
+ docTags?: boolean;
184
+ /**
185
+ * Where per-page tags render relative to the content.
186
+ * @default "after-title"
187
+ */
188
+ tagPlacement?: TagPlacement;
189
+ /**
190
+ * Tag-governance enforcement level when the vocabulary is consulted.
191
+ * @default "off"
192
+ */
193
+ tagGovernance?: TagGovernanceMode;
194
+ /**
195
+ * Whether the tag vocabulary is consulted at runtime (alias resolution,
196
+ * deprecation filtering, grouped footer). Orthogonal to `tagGovernance`.
197
+ * The vocabulary ENTRIES are supplied separately via `tagVocabularyEntries`.
198
+ * @default false
199
+ */
200
+ tagVocabulary?: boolean;
201
+ /**
202
+ * Emit an `llms.txt` route summarising the docs.
203
+ * @default false
204
+ */
205
+ llmsTxt?: boolean;
206
+ /**
207
+ * Changelog generation config(s), or `false` to disable.
208
+ * @default false
209
+ */
210
+ changelogs?: Settings["changelogs"];
211
+ /**
212
+ * Enable KaTeX math rendering in markdown.
213
+ * @default false
214
+ */
215
+ math?: boolean;
216
+ /**
217
+ * Enable zfb's CJK-friendly line-break / emphasis handling.
218
+ * @default false
219
+ */
220
+ cjkFriendly?: boolean;
221
+ /**
222
+ * What to do when a `.md`/`.mdx` link cannot be resolved.
223
+ * @default "warn"
224
+ */
225
+ onBrokenMarkdownLinks?: "warn" | "error" | "ignore";
226
+ /**
227
+ * Enable the AI-chat assistant route (`/api/ai-chat`, SSR).
228
+ * @default false
229
+ */
230
+ aiAssistant?: boolean;
231
+ /**
232
+ * Short-circuit `/api/ai-chat` with a fixed "disabled" reply (no API key /
233
+ * KV / rate limiter touched).
234
+ * @default false
235
+ */
236
+ aiChatDemoMode?: boolean;
237
+ /**
238
+ * Allowed CORS origins for `/api/ai-chat` when not in demo mode. Empty =
239
+ * block all cross-origin browser requests.
240
+ * @default []
241
+ */
242
+ aiChatAllowedOrigins?: string[];
243
+ /**
244
+ * Global daily request ceiling across all IPs for `/api/ai-chat`, or `false`
245
+ * to disable the ceiling.
246
+ * @default false
247
+ */
248
+ aiChatGlobalDailyLimit?: number | false;
249
+ /**
250
+ * Enable the interactive Design Token Panel (zdtp).
251
+ * @default false
252
+ */
253
+ designTokenPanel?: boolean;
254
+ /**
255
+ * Minimum heading depth included in the TOC (2–4).
256
+ * @default 2
257
+ */
258
+ tocMinDepth?: number;
259
+ /**
260
+ * Maximum heading depth included in the TOC (2–4).
261
+ * @default 4
262
+ */
263
+ tocMaxDepth?: number;
264
+ /**
265
+ * Heading-ID (anchor) strategy. `"hierarchical"` prefixes each anchor with
266
+ * its ancestor chain; `"flat"` is zfb's legacy github-slugger scheme.
267
+ * @default "hierarchical"
268
+ */
269
+ headingIdStrategy?: "flat" | "hierarchical";
270
+ /**
271
+ * Enable the draggable sidebar resizer.
272
+ * @default false
273
+ */
274
+ sidebarResizer?: boolean;
275
+ /**
276
+ * Enable the desktop sidebar collapse toggle.
277
+ * @default false
278
+ */
279
+ sidebarToggle?: boolean;
280
+ /**
281
+ * Enable click-to-enlarge for content images.
282
+ * @default false
283
+ */
284
+ imageEnlarge?: boolean;
285
+ /**
286
+ * Mount the `FindInPageInit` island (Cmd/Ctrl+F find bar). Self-gates on
287
+ * `window.__TAURI_INTERNALS__`, so it is a safe no-op outside a Tauri
288
+ * shell even when `true`.
289
+ * @default false
290
+ */
291
+ findInPage?: boolean;
292
+ /**
293
+ * Enable the dynamic (view-transition) page-loading overlay.
294
+ * @default false
295
+ */
296
+ dynamicPageTransition?: boolean;
297
+ /**
298
+ * Frontmatter-preview config (ignore-key overrides), or `false` to disable
299
+ * the preview panel.
300
+ * @default false
301
+ */
302
+ frontmatterPreview?: FrontmatterPreviewConfig | false;
303
+ /**
304
+ * Enable per-page git history (Created/Updated + dropdown).
305
+ * @default false
306
+ */
307
+ docHistory?: boolean;
308
+ /**
309
+ * Body-foot utility area (doc-history / view-source), or `false` to disable.
310
+ * @default false
311
+ */
312
+ bodyFootUtilArea?: BodyFootUtilAreaConfig | false;
313
+ /**
314
+ * Global HTML-preview sandbox config, or `undefined` to disable.
315
+ * @default undefined
316
+ */
317
+ htmlPreview?: HtmlPreviewConfig | undefined;
318
+ /**
319
+ * Docs versions, or `false` for a single (unversioned) doc set.
320
+ * @default false
321
+ */
322
+ versions?: VersionConfig[] | false;
323
+ /**
324
+ * Claude-resources ingestion config, or `false` to disable.
325
+ * @default false
326
+ */
327
+ claudeResources?: ClaudeResourcesConfig;
328
+ /**
329
+ * Route prefixes served only in the default locale (never locale-prefixed).
330
+ * @default []
331
+ */
332
+ defaultLocaleOnlyPrefixes?: string[];
333
+ /**
334
+ * Footer config (link columns / copyright / taglist), or `false` for no
335
+ * footer.
336
+ * @default false
337
+ */
338
+ footer?: FooterConfig | false;
339
+ /**
340
+ * Primary header navigation items.
341
+ * @default []
342
+ */
343
+ headerNav?: HeaderNavItem[];
344
+ /**
345
+ * Header right-hand-side items (toggles, switchers, links).
346
+ * @default [{ type: "component", component: "theme-toggle" }]
347
+ */
348
+ headerRightItems?: HeaderRightItem[];
349
+ /**
350
+ * Build-time package-owned route injection. When `true`, doc routes are
351
+ * injected from the package (no project-shipped `pages/*.tsx` stubs needed).
352
+ * Set `false` only if your project ships its own doc-route stubs.
353
+ * @default true
354
+ */
355
+ packageOwnedRoutes?: boolean;
356
+ /**
357
+ * Project-root-relative path to a host module exporting
358
+ * `chromeBindings: ChromeHostBindings` (only consumed when
359
+ * `packageOwnedRoutes` is on). Omit to keep the injected chrome shim at its
360
+ * package-default stubs.
361
+ * @default undefined
362
+ */
363
+ chromeBindingsModule?: string;
364
+ /**
365
+ * Project-root-relative path to a host module exporting a named
366
+ * `buildDesignTokenPanelConfig(mode: "light" | "dark")` zdtp `PanelConfig`
367
+ * builder (only consumed when `packageOwnedRoutes` is on, and only relevant
368
+ * when `designTokenPanel` is `true`). When omitted, the panel uses the
369
+ * package-default builder (`@takazudo/zudo-doc/design-token-panel-config`)
370
+ * — derived from the shipped token manifest and the bundled color schemes —
371
+ * so `designTokenPanel: true` works with no host config file. Point this at
372
+ * your own module only when you need a fully custom panel (your own token
373
+ * manifest, your own color schemes).
374
+ * @default undefined (package-default builder is used)
375
+ */
376
+ designTokenPanelConfigModule?: string;
377
+ /**
378
+ * Replace the default docs-frontmatter zod schema builder entirely. When
379
+ * omitted, `zudoDoc()` builds the default schema
380
+ * (`@takazudo/zudo-doc/docs-schema`), governance-aware from `tagGovernance`
381
+ * + `tagVocabularyEntries`.
382
+ * @default undefined (package default `buildDocsSchema` is used)
383
+ */
384
+ buildDocsSchema?: () => ZodType;
385
+ /**
386
+ * Override the color-scheme palette map. When omitted, the two shipped
387
+ * schemes (`@takazudo/zudo-doc/color-schemes-defaults` — Default Light /
388
+ * Default Dark) are used.
389
+ * @default undefined (`defaultColorSchemes` is used)
390
+ */
391
+ colorSchemes?: Record<string, ColorScheme>;
392
+ /**
393
+ * Override the UI-string translation table. When omitted, the shipped
394
+ * en/ja/de defaults (`@takazudo/zudo-doc/i18n-defaults`) are used.
395
+ * @default undefined (`defaultTranslations` is used)
396
+ */
397
+ translations?: PresetTranslations;
398
+ /**
399
+ * Override the directive → JSX-component-name map (`markdown.features.directives`).
400
+ * When omitted, the canonical seven
401
+ * (`@takazudo/zudo-doc/directive-vocabulary-defaults`) are used.
402
+ * @default undefined (`defaultDirectiveVocabulary` is used)
403
+ */
404
+ directives?: DirectiveVocabulary;
405
+ /**
406
+ * The tag-vocabulary ENTRIES array (distinct from the boolean `tagVocabulary`
407
+ * gate). Threaded into the route-context virtual module and consulted by the
408
+ * governance-aware default schema builder.
409
+ * @default []
410
+ */
411
+ tagVocabularyEntries?: readonly PresetTagVocabularyEntry[];
412
+ /**
413
+ * Dev/preview server port.
414
+ * @default 4321
415
+ */
416
+ port?: number;
417
+ /**
418
+ * Deploy-target adapter package name (e.g.
419
+ * `"@takazudo/zfb-adapter-cloudflare"`). Omit for a pure static build.
420
+ * @default undefined (pure static build)
421
+ */
422
+ adapter?: string;
423
+ /**
424
+ * zfb bundler options (`exclude` / `mainFields` / `external`) — passed
425
+ * through verbatim when set.
426
+ * @default undefined
427
+ */
428
+ bundle?: BundleConfig;
429
+ }
430
+ /**
431
+ * Build a complete `ZfbConfig` from user config, defaulting every field.
432
+ *
433
+ * ```ts
434
+ * export default defineConfig(zudoDoc({ siteName: "My Docs" }));
435
+ * ```
436
+ *
437
+ * @param user Partial config; every field has a documented default. See
438
+ * {@link ZudoDocConfig}.
439
+ * @returns A complete `ZfbConfig` — spread nothing; pass it straight to
440
+ * `defineConfig`.
441
+ */
442
+ export declare function zudoDoc(user?: ZudoDocConfig): ZfbConfig;
443
+ export {};
package/dist/config.js ADDED
@@ -0,0 +1,116 @@
1
+ import { zudoDocPreset } from "./preset.js";
2
+ import { buildDocsSchema as defaultBuildDocsSchema } from "./docs-schema/index.js";
3
+ import { defaultDirectiveVocabulary } from "./directive-vocabulary-defaults/index.js";
4
+ import { defaultTranslations } from "./i18n-defaults/index.js";
5
+ import { defaultColorSchemes } from "./color-schemes-defaults/index.js";
6
+ const DEFAULT_SETTINGS = {
7
+ colorScheme: "Default Dark",
8
+ colorMode: {
9
+ defaultMode: "dark",
10
+ lightScheme: "Default Light",
11
+ darkScheme: "Default Dark",
12
+ respectPrefersColorScheme: true
13
+ },
14
+ siteName: "Docs",
15
+ siteDescription: "",
16
+ base: "/",
17
+ trailingSlash: false,
18
+ minifyHtml: true,
19
+ docsDir: "src/content/docs",
20
+ defaultLocale: "en",
21
+ locales: {},
22
+ mermaid: true,
23
+ noindex: false,
24
+ editUrl: false,
25
+ githubUrl: false,
26
+ siteUrl: "",
27
+ metaTags: {
28
+ description: true,
29
+ keywords: false,
30
+ ogImage: false,
31
+ ogSiteName: true,
32
+ twitterCard: false
33
+ },
34
+ sitemap: false,
35
+ docMetainfo: false,
36
+ docTags: false,
37
+ tagPlacement: "after-title",
38
+ tagGovernance: "off",
39
+ tagVocabulary: false,
40
+ llmsTxt: false,
41
+ changelogs: false,
42
+ math: false,
43
+ cjkFriendly: false,
44
+ onBrokenMarkdownLinks: "warn",
45
+ aiAssistant: false,
46
+ aiChatDemoMode: false,
47
+ aiChatAllowedOrigins: [],
48
+ aiChatGlobalDailyLimit: false,
49
+ designTokenPanel: false,
50
+ tocMinDepth: 2,
51
+ tocMaxDepth: 4,
52
+ headingIdStrategy: "hierarchical",
53
+ sidebarResizer: false,
54
+ sidebarToggle: false,
55
+ imageEnlarge: false,
56
+ findInPage: false,
57
+ dynamicPageTransition: false,
58
+ frontmatterPreview: false,
59
+ docHistory: false,
60
+ bodyFootUtilArea: false,
61
+ htmlPreview: void 0,
62
+ versions: false,
63
+ claudeResources: false,
64
+ defaultLocaleOnlyPrefixes: [],
65
+ footer: false,
66
+ headerNav: [],
67
+ headerRightItems: [{ type: "component", component: "theme-toggle" }],
68
+ packageOwnedRoutes: true
69
+ };
70
+ function zudoDoc(user = {}) {
71
+ const {
72
+ port,
73
+ adapter,
74
+ bundle,
75
+ buildDocsSchema: userBuildDocsSchema,
76
+ colorSchemes: userColorSchemes,
77
+ translations: userTranslations,
78
+ directives: userDirectives,
79
+ tagVocabularyEntries: userTagVocabularyEntries,
80
+ ...settingsOverrides
81
+ } = user;
82
+ const settings = { ...DEFAULT_SETTINGS, ...settingsOverrides };
83
+ const fragment = zudoDocPreset({
84
+ settings,
85
+ buildDocsSchema: userBuildDocsSchema ?? (() => defaultBuildDocsSchema({
86
+ tagGovernance: settings.tagGovernance,
87
+ tagVocabulary: userTagVocabularyEntries
88
+ })),
89
+ directiveVocabulary: userDirectives ?? defaultDirectiveVocabulary,
90
+ translations: userTranslations ?? defaultTranslations,
91
+ colorSchemes: userColorSchemes ?? defaultColorSchemes,
92
+ tagVocabulary: userTagVocabularyEntries ?? []
93
+ });
94
+ return {
95
+ // ── Host-owned shell fields ──────────────────────────────────────────
96
+ framework: "preact",
97
+ port: port ?? 4321,
98
+ tailwind: { enabled: true },
99
+ base: settings.base,
100
+ ...adapter ? { adapter } : {},
101
+ ...bundle ? { bundle } : {},
102
+ // ── Preset-owned fields (collections, plugins, markdown, …) ──────────
103
+ ...fragment,
104
+ // The preset's `markdown.features` intentionally uses the loose Record
105
+ // shape (the exact shape zfb's config shim binds against); the engine's
106
+ // strict `MarkdownFeaturesConfig` is a structural subset of it. Every
107
+ // other preset field type-checks against `ZfbConfig` directly, so only
108
+ // `markdown` needs this single documented bridge — `satisfies ZfbConfig`
109
+ // below keeps full strict checking on all the rest.
110
+ markdown: fragment.markdown
111
+ };
112
+ }
113
+ export {
114
+ DEFAULT_SETTINGS,
115
+ zudoDoc
116
+ };
@@ -1,14 +1,19 @@
1
+ /** @jsxRuntime automatic */
2
+ /** @jsxImportSource preact */
1
3
  /**
2
- * Design-token panel (zdtp) WIRING MECHANISM.
4
+ * Design-token panel (zdtp) WIRING MECHANISM + PACKAGE-DEFAULT ISLAND (#2658,
5
+ * epic Minimal Scaffold #2651).
3
6
  *
4
- * A side-effect module that configures zdtp's panel and wires its lifecycle
5
- * hooks to zfb's navigation events via `setLifecycleAdapter()`. Projects import
6
- * this with their own PanelConfig DATA — which stays project-side.
7
+ * `bootstrapDesignTokenPanel` is a callable that configures zdtp's panel and
8
+ * wires its lifecycle hooks to zfb's navigation events via
9
+ * `setLifecycleAdapter()`. Projects import it with their own PanelConfig
10
+ * DATA — which stays project-side (or, since #2658, the PACKAGE-DEFAULT data
11
+ * from `@takazudo/zudo-doc/design-token-panel-config`).
7
12
  *
8
13
  * Two calling shapes (both supported):
9
14
  *
10
- * // Mode-scoped builder (showcase host) — rebuilds the panel per light/dark
11
- * // mode on every `color-scheme-changed` toggle:
15
+ * // Mode-scoped builder — rebuilds the panel per light/dark mode on every
16
+ * // `color-scheme-changed` toggle:
12
17
  * import { bootstrapDesignTokenPanel } from "@takazudo/zudo-doc/design-token-panel-bootstrap";
13
18
  * import { buildDesignTokenPanelConfig } from "@/config/design-token-panel-config";
14
19
  * bootstrapDesignTokenPanel(buildDesignTokenPanelConfig);
@@ -20,9 +25,34 @@
20
25
  * A plain-config caller gets NO toggle listener (a static config has nothing to
21
26
  * rebuild), so existing generated projects keep working with zero changes.
22
27
  *
28
+ * `DesignTokenPanelBootstrap` (below) is the PACKAGE-OWNED island component
29
+ * that wires the mode-scoped builder for package-owned routes with no host
30
+ * config file — the #2658 "Approach (a)" package default. It resolves its
31
+ * builder from the `virtual:zudo-doc-design-token-panel-config` virtual
32
+ * module the routes plugin registers (`../plugins/routes.ts`): absent a host
33
+ * `designTokenPanelConfigModule` override, that resolves to
34
+ * `@takazudo/zudo-doc/design-token-panel-config`'s `buildDesignTokenPanelConfig`.
35
+ * `packages/zudo-doc/src/routes/_chrome.tsx` statically imports it so zfb's
36
+ * island scanner walks route → `_chrome` → here (mirrors the DocHistory
37
+ * #2480 static-import chain). A host that ejects entirely (its own
38
+ * `src/lib/*` + `src/components/*`, like the pre-#2658 showcase) never
39
+ * reaches this component — it only calls `bootstrapDesignTokenPanel` itself,
40
+ * same as always.
41
+ *
42
+ * KNOWN COUPLING: `DesignTokenPanelBootstrap`'s top-level import of
43
+ * `virtual:zudo-doc-design-token-panel-config` requires the routes plugin
44
+ * (`settings.packageOwnedRoutes`, default `true`) to be active in the
45
+ * consuming project, since that plugin is what registers the virtual module.
46
+ * A project that explicitly sets `packageOwnedRoutes: false` AND wants to
47
+ * reuse the bare `bootstrapDesignTokenPanel` export for its own hand-wired
48
+ * component (as every current consumer's `src/lib/design-token-panel-bootstrap.ts`
49
+ * does) is unaffected — that import graph never reaches `DesignTokenPanelBootstrap`
50
+ * — but a `packageOwnedRoutes: false` project must not import
51
+ * `DesignTokenPanelBootstrap` itself.
52
+ *
23
53
  * Moved from the host's `src/lib/design-token-panel-bootstrap.ts` as part of
24
54
  * the package-first migration (S9a zudolab/zudo-doc#2333); mode-scoped rebuild
25
- * wiring added in zudolab/zudo-doc#2610.
55
+ * wiring added in zudolab/zudo-doc#2610; package-default island added in #2658.
26
56
  *
27
57
  * CSS is pulled via `@import "@takazudo/zdtp/styles.css"` in the project's
28
58
  * `src/styles/global.css` so the panel chrome lands in the main page CSS
@@ -30,6 +60,7 @@
30
60
  * import from the emitted JS, so the explicit CSS-side import is the
31
61
  * required pull point. See @takazudo/zdtp PORTABLE-CONTRACT.md §7.
32
62
  */
63
+ import type { JSX } from "preact";
33
64
  import { type PanelConfig } from "@takazudo/zdtp";
34
65
  /** Active color-scheme mode, read from `<html data-theme>`. */
35
66
  type ColorSchemeMode = "light" | "dark";
@@ -56,4 +87,23 @@ export type PanelConfigBuilder = (mode: ColorSchemeMode) => PanelConfig;
56
87
  * `src/config/design-token-panel-config.ts`.
57
88
  */
58
89
  export declare function bootstrapDesignTokenPanel(configOrBuilder: PanelConfig | PanelConfigBuilder): void;
90
+ /**
91
+ * The package-default `<DesignTokenPanelBootstrap/>` island: mounted (via
92
+ * `Island({ when: "load" })`, no `ssrFallback` — it renders nothing on either
93
+ * side) by `../doc-body-end-islands/index.tsx` when `settings.designTokenPanel`
94
+ * is on, gated the same way `AiChatModal`/`ImageEnlarge`/`MermaidEnlarge` are.
95
+ * On first render, calls `bootstrapDesignTokenPanel` with the mode-scoped
96
+ * `buildDesignTokenPanelConfig` builder resolved from
97
+ * `virtual:zudo-doc-design-token-panel-config` (package default, or the
98
+ * host's `designTokenPanelConfigModule` override).
99
+ *
100
+ * `displayName` pinned explicitly (belt-and-braces, matching
101
+ * `AiChatModal`/`ImageEnlarge`/`MermaidEnlarge`/`DocHistory`) so zfb's
102
+ * `captureComponentName` emits a stable `data-zfb-island="DesignTokenPanelBootstrap"`
103
+ * marker independent of minification.
104
+ */
105
+ export declare function DesignTokenPanelBootstrap(): JSX.Element | null;
106
+ export declare namespace DesignTokenPanelBootstrap {
107
+ var displayName: string;
108
+ }
59
109
  export {};
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import {
2
3
  configurePanel,
3
4
  setLifecycleAdapter,
@@ -7,6 +8,7 @@ import {
7
8
  BEFORE_NAVIGATE_EVENT,
8
9
  AFTER_NAVIGATE_EVENT
9
10
  } from "./transitions/page-events.js";
11
+ import { buildDesignTokenPanelConfig } from "virtual:zudo-doc-design-token-panel-config";
10
12
  const COLOR_SCHEME_CHANGED_EVENT = "color-scheme-changed";
11
13
  function openStateKey(instancePrefix) {
12
14
  return `${instancePrefix}-open`;
@@ -52,6 +54,16 @@ function bootstrapDesignTokenPanel(configOrBuilder) {
52
54
  };
53
55
  setLifecycleAdapter(adapter);
54
56
  }
57
+ let bootstrapped = false;
58
+ function DesignTokenPanelBootstrap() {
59
+ if (!bootstrapped) {
60
+ bootstrapped = true;
61
+ bootstrapDesignTokenPanel(buildDesignTokenPanelConfig);
62
+ }
63
+ return null;
64
+ }
65
+ DesignTokenPanelBootstrap.displayName = "DesignTokenPanelBootstrap";
55
66
  export {
67
+ DesignTokenPanelBootstrap,
56
68
  bootstrapDesignTokenPanel
57
69
  };