create-zudo-doc 1.3.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.
Files changed (39) hide show
  1. package/dist/scaffold.d.ts +1 -1
  2. package/dist/scaffold.js +2 -2
  3. package/package.json +1 -1
  4. package/templates/base/pages/index.tsx +6 -4
  5. package/templates/base/pages/lib/_chrome.ts +166 -0
  6. package/templates/base/pages/lib/_doc-route-entries.ts +7 -51
  7. package/templates/base/pages/lib/_nav-source-docs.ts +9 -29
  8. package/templates/base/pages/lib/_route-context.ts +32 -0
  9. package/templates/base/src/config/tag-vocabulary-types.ts +4 -39
  10. package/templates/features/i18n/files/pages/[locale]/index.tsx +6 -4
  11. package/templates/base/pages/_mdx-components.ts +0 -106
  12. package/templates/base/pages/lib/_category-nav.tsx +0 -34
  13. package/templates/base/pages/lib/_category-tree-nav.tsx +0 -45
  14. package/templates/base/pages/lib/_compose-meta-title.ts +0 -25
  15. package/templates/base/pages/lib/_doc-body-end.tsx +0 -8
  16. package/templates/base/pages/lib/_doc-content-header.tsx +0 -17
  17. package/templates/base/pages/lib/_doc-history-area.tsx +0 -34
  18. package/templates/base/pages/lib/_doc-metainfo-area.tsx +0 -26
  19. package/templates/base/pages/lib/_doc-page-renderer.tsx +0 -31
  20. package/templates/base/pages/lib/_doc-page-shell.tsx +0 -29
  21. package/templates/base/pages/lib/_doc-pager.tsx +0 -9
  22. package/templates/base/pages/lib/_doc-route-paths.ts +0 -16
  23. package/templates/base/pages/lib/_doc-tags-area.tsx +0 -30
  24. package/templates/base/pages/lib/_footer-with-defaults.tsx +0 -58
  25. package/templates/base/pages/lib/_head-with-defaults.tsx +0 -22
  26. package/templates/base/pages/lib/_header-with-defaults.tsx +0 -45
  27. package/templates/base/pages/lib/_inline-version-switcher.tsx +0 -23
  28. package/templates/base/pages/lib/_math-block.tsx +0 -4
  29. package/templates/base/pages/lib/_nav-data-prep.ts +0 -118
  30. package/templates/base/pages/lib/_search-widget-script.ts +0 -2
  31. package/templates/base/pages/lib/_sidebar-prepaint.tsx +0 -11
  32. package/templates/base/pages/lib/_sidebar-with-defaults.tsx +0 -26
  33. package/templates/base/pages/lib/_site-tree-nav.tsx +0 -37
  34. package/templates/base/pages/lib/_toc-title.ts +0 -3
  35. package/templates/base/pages/lib/route-enumerators.ts +0 -58
  36. package/templates/base/src/components/tree-nav-shared.tsx +0 -71
  37. package/templates/base/src/utils/content-files.ts +0 -110
  38. package/templates/features/docTags/files/pages/lib/_tag-pages.tsx +0 -47
  39. package/templates/features/versioning/files/pages/lib/_versions-page.tsx +0 -33
@@ -11,5 +11,5 @@ export { getSecondaryLang };
11
11
  *
12
12
  * Bumped in lockstep by scripts/release-create-zudo-doc.sh.
13
13
  */
14
- export declare const ZUDO_DOC_PIN = "^1.3.0";
14
+ export declare const ZUDO_DOC_PIN = "^2.0.0";
15
15
  export declare function scaffold(choices: UserChoices): Promise<void>;
package/dist/scaffold.js CHANGED
@@ -18,7 +18,7 @@ export { getSecondaryLang };
18
18
  *
19
19
  * Bumped in lockstep by scripts/release-create-zudo-doc.sh.
20
20
  */
21
- export const ZUDO_DOC_PIN = "^1.3.0";
21
+ export const ZUDO_DOC_PIN = "^2.0.0";
22
22
  /**
23
23
  * Files in `templates/base/**` that must never be copied into a generated
24
24
  * project. Each entry is matched against the path relative to `templates/base/`
@@ -570,7 +570,7 @@ function generatePackageJson(choices) {
570
570
  // @takazudo/zudo-doc/integrations/doc-history which in turn imports
571
571
  // @takazudo/zudo-doc-history-server/git-history. Without this dep the
572
572
  // plugin host fails at init with ERR_MODULE_NOT_FOUND — W8A (#1739).
573
- deps["@takazudo/zudo-doc-history-server"] = "^1.3.0";
573
+ deps["@takazudo/zudo-doc-history-server"] = "^2.0.0";
574
574
  // tsx is no longer needed here: the relocated package plugin imports the
575
575
  // runner directly (no `tsx -e` spawn) since the package ships compiled
576
576
  // dist/ — package-first migration #2321 (#2337).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-zudo-doc",
3
- "version": "1.3.0",
3
+ "version": "2.0.0",
4
4
  "description": "Create a new zudo-doc documentation site",
5
5
  "license": "MIT",
6
6
  "author": "Takeshi Takatsudo",
@@ -28,10 +28,12 @@ import type { JSX } from "preact";
28
28
  import type { VNode } from "preact";
29
29
  import { Island } from "@takazudo/zfb";
30
30
  import { SiteTreeNav } from "@takazudo/zudo-doc/site-tree-nav-island";
31
- import { FooterWithDefaults } from "./lib/_footer-with-defaults";
32
- import { HeaderWithDefaults } from "./lib/_header-with-defaults";
33
- import { HeadWithDefaults } from "./lib/_head-with-defaults";
34
- import { composeMetaTitle } from "./lib/_compose-meta-title";
31
+ import {
32
+ FooterWithDefaults,
33
+ HeaderWithDefaults,
34
+ HeadWithDefaults,
35
+ composeMetaTitle,
36
+ } from "./lib/_chrome";
35
37
  import { BodyEndIslands } from "./lib/_body-end-islands";
36
38
 
37
39
  export const frontmatter = { title: "Home" };
@@ -0,0 +1,166 @@
1
+ /** @jsxRuntime automatic */
2
+ /** @jsxImportSource preact */
3
+ // Host chrome adapter — THE single host adapter for the page-chrome surface
4
+ // (epic Collapse Wiring Shells #2420; HOSTCOLLAPSE #2427 collapsed the former
5
+ // per-component `pages/lib/_*` chrome shells into this one module).
6
+ //
7
+ // It builds the host's REAL bindings ONCE and threads them through the public
8
+ // `createChrome(routeContext, hostBindings)` builder, then re-exports the wired
9
+ // page-chrome barrel (renderDocPage, HeaderWithDefaults, FooterWithDefaults,
10
+ // HeadWithDefaults, composeMetaTitle, …). Every doc route + homepage chrome
11
+ // import resolves here.
12
+ //
13
+ // - the reconstructed route context comes from the retained, vitest-safe
14
+ // `./_route-context` seam (settings + i18n + URL/nav/slug helpers +
15
+ // nav-source resolvers + route enumerators), fed the host content bridge
16
+ // (`stableDocs`) so the content read + nav enumeration stay byte-identical;
17
+ // - the genuinely host-bound slots (`hostBindings`): the real SearchWidget,
18
+ // git-history manifest, sidebars config, frontmatter renderers/builder,
19
+ // footer tag loader + vocabulary, body-end islands, DocHistory island, and
20
+ // the showcase MDX content overrides (`mdxExtras`).
21
+ //
22
+ // Island-scanner contract (load-bearing): this module MUST keep the STATIC
23
+ // imports of DocHistory (`@takazudo/zudo-doc/doc-history`), BodyEndIslands
24
+ // (`./_body-end-islands`) and PresetGeneratorFallback (`./_preset-generator`).
25
+ // After the collapse the only page→island import chain is
26
+ // `pages/docs/*.tsx → _chrome.ts → {DocHistory, BodyEndIslands, PresetGenerator}`;
27
+ // if any of these became a type-only or dynamic import the zfb island scanner
28
+ // would stop walking it and the marker/bundle would silently drop.
29
+
30
+ import type { ComponentChildren } from "preact";
31
+ import type { ChromeHostBindings } from "@takazudo/zudo-doc/factory-context";
32
+
33
+ import { createChrome } from "@takazudo/zudo-doc/chrome";
34
+
35
+ import { settings } from "@/config/settings";
36
+ import { defaultLocale } from "@/config/i18n";
37
+ import { tagVocabulary } from "@/config/tag-vocabulary";
38
+ import sidebars from "@/config/sidebars";
39
+ import { frontmatterRenderers } from "@/config/frontmatter-preview-renderers";
40
+ import { collectTags } from "@/utils/tags";
41
+ import { toRouteSlug } from "@/utils/slug";
42
+ import type { DocsEntry } from "@/types/docs-entry";
43
+
44
+ import { routeContext } from "./_route-context";
45
+ import { stableDocs, memoizeDerived } from "./_nav-source-cache";
46
+ import { mergeLocaleDocs } from "./locale-merge";
47
+ import { SearchWidget } from "./_search-widget";
48
+ import { BodyEndIslands as BodyEndIslandsSeam } from "./_body-end-islands";
49
+ import { buildFrontmatterPreviewEntries } from "./_frontmatter-preview-data";
50
+ import { DetailsWrapper } from "./_details";
51
+ import { PresetGeneratorFallback } from "./_preset-generator";
52
+ import { DocHistory } from "@takazudo/zudo-doc/doc-history";
53
+ import { HtmlPreviewWrapper, type HtmlPreviewWrapperProps } from "@takazudo/zudo-doc/html-preview-wrapper";
54
+ // SSR author + date metadata — `#doc-history-meta` is the build-time manifest
55
+ // alias (esbuild-inlined, no fs). Static import is load-bearing for the island
56
+ // scanner chain noted above.
57
+ import docHistoryMeta from "#doc-history-meta";
58
+
59
+ // ---------------------------------------------------------------------------
60
+ // Footer tag loader (host-side; moved verbatim from the former
61
+ // _chrome-context.ts / _footer-with-defaults.tsx). Reads collections via
62
+ // stableDocs / memoizeDerived and aggregates tags per locale. Threaded as
63
+ // hostBindings.loadTagsForLocale.
64
+ // ---------------------------------------------------------------------------
65
+
66
+ function loadTagsForLocale(lang: string) {
67
+ if (lang === defaultLocale) {
68
+ const baseDocs = stableDocs("docs");
69
+ return memoizeDerived([baseDocs], "footerTaglist;default", () => {
70
+ const docs: DocsEntry[] = baseDocs.filter(
71
+ (d) => !d.data.draft && !d.data.unlisted && !d.data.category_no_page,
72
+ );
73
+ const tagMap = collectTags(docs, (id, data) => data.slug ?? toRouteSlug(id));
74
+ return [...tagMap.values()].sort((a, b) => a.tag.localeCompare(b.tag, lang));
75
+ });
76
+ }
77
+ const baseDocs = stableDocs("docs");
78
+ const localeDocs = stableDocs(`docs-${lang}`);
79
+ return memoizeDerived([baseDocs, localeDocs], `footerTaglist;${lang}`, () => {
80
+ const result = mergeLocaleDocs({
81
+ baseDocs: baseDocs.filter((d) => !d.data.draft),
82
+ localeDocs: localeDocs.filter((d) => !d.data.draft),
83
+ applyDefaultLocaleOnlyFilter: true,
84
+ });
85
+ const docs: DocsEntry[] = result.docs.filter((d) => !d.data.category_no_page);
86
+ const tagMap = collectTags(docs, (id, data) => data.slug ?? toRouteSlug(id));
87
+ return [...tagMap.values()].sort((a, b) => a.tag.localeCompare(b.tag, lang));
88
+ });
89
+ }
90
+
91
+ // ---------------------------------------------------------------------------
92
+ // Showcase MDX content overrides (host-bound; identical to the former
93
+ // pages/_mdx-components.ts `extras` block — kept in lockstep). Threaded via
94
+ // hostBindings.mdxExtras; the package factory merges them over its defaults.
95
+ // ---------------------------------------------------------------------------
96
+
97
+ /** MDX-tag stub: renders nothing (Preact null-vnode path). */
98
+ const MdxStub = (_props: unknown) => null;
99
+
100
+ /** SSR pass-through for `<Island when=…>` — renders children, ignores `when`. */
101
+ function IslandWrapper(props: {
102
+ when?: "load" | "idle" | "visible" | "media";
103
+ children?: ComponentChildren;
104
+ }): ComponentChildren {
105
+ return props.children ?? null;
106
+ }
107
+
108
+ const HtmlPreviewWithGlobalConfig = (props: HtmlPreviewWrapperProps) =>
109
+ HtmlPreviewWrapper({ globalConfig: settings.htmlPreview ?? null, ...props });
110
+
111
+ const mdxExtras = {
112
+ HtmlPreview: HtmlPreviewWithGlobalConfig,
113
+ Details: DetailsWrapper,
114
+ SmartBreak: MdxStub,
115
+ Island: IslandWrapper,
116
+ PresetGenerator: PresetGeneratorFallback,
117
+ Avatar: MdxStub,
118
+ Button: MdxStub,
119
+ Card: MdxStub,
120
+ MyComponent: MdxStub,
121
+ PageLayout: MdxStub,
122
+ } as unknown as Record<string, (props: Record<string, unknown>) => unknown>;
123
+
124
+ // ---------------------------------------------------------------------------
125
+ // The host's real bindings (the 10 ChromeHostBindings slots).
126
+ // ---------------------------------------------------------------------------
127
+
128
+ const hostBindings: ChromeHostBindings = {
129
+ SearchWidget: SearchWidget as ChromeHostBindings["SearchWidget"],
130
+ docHistoryMeta: docHistoryMeta as Record<string, unknown>,
131
+ sidebarsConfig: sidebars as unknown as Record<string, unknown>,
132
+ frontmatterRenderers: frontmatterRenderers as unknown as ChromeHostBindings["frontmatterRenderers"],
133
+ buildFrontmatterPreviewEntries:
134
+ buildFrontmatterPreviewEntries as unknown as ChromeHostBindings["buildFrontmatterPreviewEntries"],
135
+ loadTagsForLocale: loadTagsForLocale as unknown as ChromeHostBindings["loadTagsForLocale"],
136
+ tagVocabulary,
137
+ BodyEndIslands: BodyEndIslandsSeam as unknown as ChromeHostBindings["BodyEndIslands"],
138
+ DocHistory: DocHistory as unknown as ChromeHostBindings["DocHistory"],
139
+ mdxExtras: mdxExtras as ChromeHostBindings["mdxExtras"],
140
+ };
141
+
142
+ // ---------------------------------------------------------------------------
143
+ // Build the wired page-chrome surface ONCE from the route context + real host
144
+ // bindings, and re-export the barrel. Every omitted slot falls back to the
145
+ // package stub (byte-identical to the injected package-routes path); each REAL
146
+ // slot above overrides it.
147
+ // ---------------------------------------------------------------------------
148
+
149
+ const chrome = createChrome(routeContext, hostBindings);
150
+
151
+ export type { RenderDocPageOptions } from "@takazudo/zudo-doc/doc-page-renderer";
152
+
153
+ export const {
154
+ composeMetaTitle,
155
+ HeadWithDefaults,
156
+ HeaderWithDefaults,
157
+ FooterWithDefaults,
158
+ SidebarWithDefaults,
159
+ renderDocPage,
160
+ VersionsPageView,
161
+ collectTagMapForLocale,
162
+ TagDetailPageView,
163
+ TagsIndexPageView,
164
+ SiteTreeNavWrapper,
165
+ BodyEndIslands,
166
+ } = chrome;
@@ -1,54 +1,10 @@
1
- // Thin stub — doc-route-entries moved to the package (epic #2344, S6).
2
- // Calls `createDocRouteEntries(ctx)` from @takazudo/zudo-doc/doc-route-entries
3
- // with the host utilities injected, then re-exports the resulting builder
4
- // function so all existing call sites continue to work unchanged.
1
+ // Thin shimthe memoized doc-route-entry builder rides on the unified
2
+ // ChromeContext now (epic Collapse Wiring Shells #2420, FACTORIES #2424).
3
+ // `createRouteContext` (in _chrome-context.ts) assembles `buildDocRouteEntries`
4
+ // as part of the route context; this module just re-exports it so the doc-route
5
+ // page files keep importing it from here unchanged.
5
6
 
6
- import { createDocRouteEntries } from "@takazudo/zudo-doc/doc-route-entries";
7
- import type {
8
- DocPageEntry,
9
- DocNavNode,
10
- BreadcrumbItem,
11
- } from "@takazudo/zudo-doc/doc-route-entries";
12
7
  export type { DocRouteEntry, BuildDocRouteEntriesArgs } from "@takazudo/zudo-doc/doc-route-entries";
13
- import {
14
- buildNavTree,
15
- buildBreadcrumbs,
16
- collectAutoIndexNodes,
17
- type NavNode,
18
- type CategoryMeta,
19
- } from "@/utils/docs";
20
- import { getNavSectionForSlug, getNavSubtree } from "@/utils/nav-scope";
21
- import { toRouteSlug, toSlugParams } from "@/utils/slug";
22
- import type { DocsEntry } from "@/types/docs-entry";
23
- import type { Locale } from "@/config/i18n";
24
- import { extractHeadings } from "./_extract-headings";
8
+ import { routeContext } from "./_route-context";
25
9
 
26
- export const { buildDocRouteEntries } = createDocRouteEntries({
27
- // The factory describes its injected nav builders with the package's own
28
- // structural counterparts (DocPageEntry / DocNavNode / Map<string, unknown>)
29
- // and a plain `locale: string`. The host's buildNavTree / buildBreadcrumbs
30
- // are typed against the concrete project types (DocsEntry / NavNode / the
31
- // Locale union / Map<string, CategoryMeta>). They are runtime-identical, so
32
- // the stub adapts them with thin wrappers that cast at the injection boundary
33
- // where the host owns the type knowledge.
34
- buildNavTree: (docs: DocPageEntry[], locale: string, categoryMeta: Map<string, unknown>) =>
35
- buildNavTree(
36
- docs as unknown as DocsEntry[],
37
- locale as Locale,
38
- categoryMeta as Map<string, CategoryMeta>,
39
- ) as DocNavNode[],
40
- buildBreadcrumbs: (
41
- tree: DocNavNode[],
42
- slug: string,
43
- locale: string,
44
- urlFor?: (slug: string) => string,
45
- ): BreadcrumbItem[] =>
46
- buildBreadcrumbs(tree as NavNode[], slug, locale as Locale, urlFor),
47
- collectAutoIndexNodes: (tree: DocNavNode[]) =>
48
- collectAutoIndexNodes(tree as NavNode[]) as DocNavNode[],
49
- getNavSectionForSlug,
50
- getNavSubtree,
51
- toRouteSlug,
52
- toSlugParams,
53
- extractHeadings,
54
- });
10
+ export const { buildDocRouteEntries } = routeContext;
@@ -1,37 +1,17 @@
1
- // Thin stub — nav-source-docs moved to the package (epic #2344, S6).
2
- // Calls `createNavSourceDocs(ctx)` from @takazudo/zudo-doc/nav-source-docs
3
- // with the host singletons injected, then re-exports the resulting resolver
4
- // functions so all existing call sites continue to work unchanged.
1
+ // Thin shim — nav-source resolvers ride on the unified ChromeContext now
2
+ // (epic Collapse Wiring Shells #2420, FACTORIES #2424). The reconstructed
3
+ // `createRouteContext` (in _chrome-context.ts) builds the identity-stable
4
+ // nav-source API as part of the route context; this module just re-exports the
5
+ // bindings so the existing call sites (route files, nav wrappers, _nav-data-prep,
6
+ // route-enumerators) keep importing them from here unchanged.
5
7
 
6
- import { createNavSourceDocs } from "@takazudo/zudo-doc/nav-source-docs";
7
8
  export type { NavSourceDocs, NavSourceOptions } from "@takazudo/zudo-doc/nav-source-docs";
8
- import { defaultLocale, getLocaleConfig } from "@/config/i18n";
9
- import { settings } from "@/config/settings";
10
- import { loadCategoryMeta, isNavVisible } from "@/utils/docs";
11
- import { isDefaultLocaleOnlyPath } from "@/utils/base";
12
- import { stableDocs } from "./_nav-source-cache";
9
+ import { routeContext } from "./_route-context";
13
10
 
14
- const {
11
+ export const {
15
12
  resolveNavSource,
16
13
  resolveVersionedLocaleSource,
17
14
  loadNavSourceDocs,
18
15
  stableMergeCategoryMeta,
19
16
  stableNavDocs,
20
- } = createNavSourceDocs({
21
- defaultLocale,
22
- docsDir: settings.docsDir,
23
- getVersions: () => settings.versions,
24
- getLocaleConfig,
25
- loadCategoryMeta,
26
- isNavVisible,
27
- isDefaultLocaleOnlyPath,
28
- stableDocs,
29
- });
30
-
31
- export {
32
- resolveNavSource,
33
- resolveVersionedLocaleSource,
34
- loadNavSourceDocs,
35
- stableMergeCategoryMeta,
36
- stableNavDocs,
37
- };
17
+ } = routeContext;
@@ -0,0 +1,32 @@
1
+ // Host route context — the reconstructed RouteContext (settings + i18n + URL
2
+ // helpers + nav/slug helpers + identity-stable nav-source resolvers + doc-route
3
+ // + route enumerators), built ONCE via the public `createRouteContext`
4
+ // (epic Collapse Wiring Shells #2420, FACTORIES #2424).
5
+ //
6
+ // Kept SEPARATE from `_chrome-context.ts` so the data shells (`_nav-source-docs`
7
+ // / `_doc-route-entries` / `route-enumerators`) — and the unit tests that import
8
+ // them — depend ONLY on this lightweight module, NOT on the chrome host bindings
9
+ // (which pull the build-time `#doc-history-meta` alias + island components that
10
+ // don't resolve under vitest).
11
+ //
12
+ // The host content bridge (`stableDocs`) is injected so the docs read + nav
13
+ // enumeration match the project's existing `pages/*` paths() exactly (host
14
+ // `bridgeDocsEntries` over the `zfb/content` snapshot), not the package default.
15
+
16
+ import { createRouteContext } from "@takazudo/zudo-doc/route-context";
17
+ import type { ColorScheme } from "@takazudo/zudo-doc/color-scheme-utils";
18
+ import { settings } from "@/config/settings";
19
+ import { translations } from "@/config/i18n";
20
+ import { tagVocabulary } from "@/config/tag-vocabulary";
21
+ import { colorSchemes } from "@/config/color-schemes";
22
+ import { stableDocs } from "./_nav-source-cache";
23
+
24
+ export const routeContext = createRouteContext(
25
+ {
26
+ settings,
27
+ translations,
28
+ tagVocabulary,
29
+ colorSchemes: colorSchemes as unknown as Record<string, ColorScheme>,
30
+ },
31
+ { stableDocs },
32
+ );
@@ -1,39 +1,4 @@
1
- /**
2
- * Tag governance enforcement level.
3
- *
4
- * - `"off"` — no vocabulary-aware enforcement. The `tags` schema stays a
5
- * free-form `string[]`. Identical to pre-vocabulary behaviour.
6
- * - `"warn"` — `tags` schema stays free-form so builds pass, but the tag
7
- * audit script (see Sub 2) reports unknown tags as warnings and
8
- * exits non-zero under `--ci`.
9
- * - `"strict"` — `tags` schema is tightened to `z.enum([...allowedIds])`, so
10
- * unknown tags fail `pnpm check` / `pnpm build`.
11
- *
12
- * Orthogonal to `tagVocabulary` (the on/off switch for consulting the
13
- * vocabulary file at runtime). See `settings-types.ts` for details.
14
- */
15
- export type TagGovernanceMode = "off" | "warn" | "strict";
16
-
17
- /**
18
- * A single entry in the tag vocabulary.
19
- *
20
- * - `id` — canonical tag id. What content files should ideally use.
21
- * - `label` — optional human-readable label (falls back to `id`).
22
- * - `description`— optional short description for tooling / tag index pages.
23
- * - `group` — optional grouping key used by the grouped tag footer
24
- * (e.g. `"type"`, `"level"`, `"topic"`).
25
- * - `aliases` — alternate strings that content files may use. Alias
26
- * resolution rewrites these to `id` before aggregation.
27
- * - `deprecated` — `true` marks the tag as deprecated with no redirect: the
28
- * canonical id is dropped from aggregation. Pass
29
- * `{ redirect: "<other-id>" }` to rewrite this tag to another
30
- * canonical id when it appears in content.
31
- */
32
- export interface TagVocabularyEntry {
33
- id: string;
34
- label?: string;
35
- description?: string;
36
- group?: string;
37
- aliases?: readonly string[];
38
- deprecated?: boolean | { redirect?: string };
39
- }
1
+ // Re-export from the shared package — canonical definitions live in
2
+ // @takazudo/zudo-doc/settings (epic #2321). Consumers that import from
3
+ // this local path continue to work unchanged.
4
+ export type { TagGovernanceMode, TagVocabularyEntry } from "@takazudo/zudo-doc/settings";
@@ -32,10 +32,12 @@ import type { VNode } from "preact";
32
32
  import { Island } from "@takazudo/zfb";
33
33
  import { SiteTreeNav } from "@takazudo/zudo-doc/site-tree-nav-island";
34
34
  import { resolveNavSource } from "../lib/_nav-source-docs";
35
- import { FooterWithDefaults } from "../lib/_footer-with-defaults";
36
- import { HeaderWithDefaults } from "../lib/_header-with-defaults";
37
- import { HeadWithDefaults } from "../lib/_head-with-defaults";
38
- import { composeMetaTitle } from "../lib/_compose-meta-title";
35
+ import {
36
+ FooterWithDefaults,
37
+ HeaderWithDefaults,
38
+ HeadWithDefaults,
39
+ composeMetaTitle,
40
+ } from "../lib/_chrome";
39
41
  import { BodyEndIslands } from "../lib/_body-end-islands";
40
42
 
41
43
  export const frontmatter = { title: "Home" };
@@ -1,106 +0,0 @@
1
- // Project MDX-components assembly — thin wrapper over the package factory.
2
- //
3
- // The bulk of the components bag (htmlOverrides, admonitions, CodeGroup,
4
- // Tabs/TabItem, MathBlock, the img base-rewrite, the enlargeable-`p` override)
5
- // now ships from `@takazudo/zudo-doc/mdx-components` (package-first migration,
6
- // epic #2321, S8 #2332). This file keeps ONLY what is genuinely project-bound:
7
- //
8
- // - the 4 locale-bound nav wrappers (CategoryNav / CategoryTreeNav /
9
- // SiteTreeNav / SiteTreeNavDemo) — they depend on the project's content
10
- // collections + nav-tree utilities, so they cannot live in the package.
11
- // They are passed into the factory as `navData`; the factory injects the
12
- // active `locale` so `/ja` resolves the JA collection (the load-bearing
13
- // locale thread — a static global mdx-components slot would render the EN
14
- // tree on every `/ja` page, which is why this stays a per-call factory).
15
- // - project `extras` spread last: HtmlPreview (with the host's global
16
- // config), Details, the Island SSR pass-through, the PresetGenerator SSR
17
- // shell, and the pure-showcase stubs (Avatar/Button/Card/MyComponent/
18
- // PageLayout) that appear only as illustrative MDX prose.
19
-
20
- import type { ComponentChildren } from "preact";
21
- import { createMdxComponents as createMdxComponentsBase } from "@takazudo/zudo-doc/mdx-components";
22
- import { HtmlPreviewWrapper, type HtmlPreviewWrapperProps } from "@takazudo/zudo-doc/html-preview-wrapper";
23
- import { defaultLocale, type Locale } from "@/config/i18n";
24
- import { settings } from "@/config/settings";
25
- import { CategoryNavWrapper } from "./lib/_category-nav";
26
- import { CategoryTreeNavWrapper } from "./lib/_category-tree-nav";
27
- import { SiteTreeNavWrapper } from "./lib/_site-tree-nav";
28
- import { DetailsWrapper } from "./lib/_details";
29
- import { PresetGeneratorFallback } from "./lib/_preset-generator";
30
-
31
- const HtmlPreviewWithGlobalConfig = (props: HtmlPreviewWrapperProps) =>
32
- HtmlPreviewWrapper({ globalConfig: settings.htmlPreview ?? null, ...props });
33
-
34
- /**
35
- * MDX-tag stub: renders nothing. Returning `null` keeps the rendered tree
36
- * intact (Preact's null-vnode path) without leaking placeholder markup into
37
- * the SSR output.
38
- */
39
- const MdxStub = (_props: unknown) => null;
40
-
41
- /**
42
- * SSR-pass-through wrapper for `<Island when="load|idle|visible">`.
43
- *
44
- * In the zfb build the zfb `<Island>` component is unavailable here, so the
45
- * MDX corpus tag resolves to this binding instead. Rendering the children
46
- * directly ensures server-renderable content nested inside `<Island>`
47
- * (headings, paragraphs, etc.) appears in the SSR HTML. The `when` prop is
48
- * ignored at render time — it is only meaningful to the zfb hydration runtime
49
- * on the client, which reads `data-when` on the inner SSR-skip placeholder.
50
- */
51
- function IslandWrapper(props: {
52
- when?: "load" | "idle" | "visible" | "media";
53
- children?: ComponentChildren;
54
- }): ComponentChildren {
55
- return props.children ?? null;
56
- }
57
-
58
- /**
59
- * Build a locale-aware MDX components map for the given locale.
60
- *
61
- * Delegates the package-resident components to the `@takazudo/zudo-doc`
62
- * factory and supplies the project-bound pieces:
63
- * - `navData`: the 4 locale-aware nav wrappers (the factory injects `lang`).
64
- * - `extras`: HtmlPreview (host-configured), Details, Island pass-through,
65
- * PresetGenerator SSR shell, and the showcase stubs.
66
- *
67
- * Page modules should call createMdxComponents(locale) — not the static
68
- * mdxComponents export — so each render gets the locale-correct map.
69
- */
70
- export function createMdxComponents(lang: Locale | string = defaultLocale) {
71
- return createMdxComponentsBase({
72
- settings,
73
- locale: lang,
74
- navData: {
75
- CategoryNav: CategoryNavWrapper as unknown as (props: Record<string, unknown>) => unknown,
76
- CategoryTreeNav: CategoryTreeNavWrapper as unknown as (props: Record<string, unknown>) => unknown,
77
- SiteTreeNav: SiteTreeNavWrapper as unknown as (props: Record<string, unknown>) => unknown,
78
- },
79
- extras: {
80
- HtmlPreview: HtmlPreviewWithGlobalConfig,
81
- Details: DetailsWrapper,
82
- // SmartBreak: corpus tag with no visual rendering — render nothing.
83
- SmartBreak: MdxStub,
84
- // Island: pass children through so server-renderable content nested
85
- // inside <Island> appears in SSR HTML. See IslandWrapper comment above.
86
- Island: IslandWrapper,
87
- // PresetGenerator: SSR fallback shell that renders the 8 section headings;
88
- // the interactive form hydrates client-side via the SSR-skip placeholder
89
- // inside PresetGeneratorFallback (see pages/lib/_preset-generator.tsx).
90
- PresetGenerator: PresetGeneratorFallback,
91
- // Pure showcase placeholders — appear only inside MDX prose as
92
- // illustrative examples, never implemented as real components.
93
- Avatar: MdxStub,
94
- Button: MdxStub,
95
- Card: MdxStub,
96
- MyComponent: MdxStub,
97
- PageLayout: MdxStub,
98
- },
99
- });
100
- }
101
-
102
- /**
103
- * Static default-locale components map for backward compatibility.
104
- * New page modules should call createMdxComponents(locale) instead.
105
- */
106
- export const mdxComponents = createMdxComponents(defaultLocale);
@@ -1,34 +0,0 @@
1
- /** @jsxRuntime automatic */
2
- /** @jsxImportSource preact */
3
- // Thin stub — category-nav moved to the package (epic #2344, S8).
4
- // Calls `createCategoryNavWrapper(deps)` from @takazudo/zudo-doc/category-nav
5
- // with host singletons injected, then re-exports the resulting component so
6
- // all existing call sites continue to work unchanged.
7
-
8
- import { createCategoryNavWrapper } from "@takazudo/zudo-doc/category-nav";
9
- import { buildNavTree, findNode, firstRoutedHref } from "@/utils/docs";
10
- import { defaultLocale } from "@/config/i18n";
11
- import { resolveNavSource } from "./_nav-source-docs";
12
-
13
- export type { CategoryNavWrapperProps } from "@takazudo/zudo-doc/category-nav";
14
-
15
- export const CategoryNavWrapper = createCategoryNavWrapper({
16
- defaultLocale,
17
- resolveNavSource: resolveNavSource as (
18
- lang: string,
19
- currentVersion: string | undefined,
20
- options?: { applyDefaultLocaleOnlyFilter?: boolean; keepUnlisted?: boolean },
21
- ) => import("@takazudo/zudo-doc/category-nav").CategoryNavSource,
22
- buildNavTree: buildNavTree as (
23
- docs: unknown[],
24
- locale: string,
25
- categoryMeta: Map<string, unknown>,
26
- ) => import("@takazudo/zudo-doc/category-nav").CategoryNavNode[],
27
- findNode: findNode as (
28
- tree: import("@takazudo/zudo-doc/category-nav").CategoryNavNode[],
29
- slug: string,
30
- ) => import("@takazudo/zudo-doc/category-nav").CategoryNavNode | undefined,
31
- firstRoutedHref: firstRoutedHref as (
32
- node: import("@takazudo/zudo-doc/category-nav").CategoryNavNode,
33
- ) => string | undefined,
34
- });
@@ -1,45 +0,0 @@
1
- /** @jsxRuntime automatic */
2
- /** @jsxImportSource preact */
3
- // Thin stub — category-tree-nav moved to the package (epic #2344, S8).
4
- // Calls `createCategoryTreeNavWrapper(deps)` from
5
- // @takazudo/zudo-doc/category-tree-nav with host singletons injected,
6
- // then re-exports the resulting component so all existing call sites continue
7
- // to work unchanged.
8
-
9
- import { createCategoryTreeNavWrapper } from "@takazudo/zudo-doc/category-tree-nav";
10
- import type {
11
- CategoryTreeNavNode,
12
- CategoryTreeNavSource,
13
- } from "@takazudo/zudo-doc/category-tree-nav";
14
- import { buildNavTree, groupSatelliteNodes, findNode, type NavNode } from "@/utils/docs";
15
- import { defaultLocale, type Locale } from "@/config/i18n";
16
- import type { DocsEntry } from "@/types/docs-entry";
17
- import type { CategoryMeta } from "@/utils/docs";
18
- import { resolveNavSource } from "./_nav-source-docs";
19
-
20
- export type { CategoryTreeNavWrapperProps } from "@takazudo/zudo-doc/category-tree-nav";
21
-
22
- // The factory describes its injected nav helpers with the minimal
23
- // CategoryTreeNavNode view (no `slug` / `position`), while the host helpers are
24
- // typed against the full NavNode. At runtime the nodes are real NavNodes; the
25
- // wrappers re-view them as the minimal type at the injection boundary (cast via
26
- // `unknown` because NavNode is a structural supertype of CategoryTreeNavNode,
27
- // so a direct cast is rejected as non-overlapping).
28
- export const CategoryTreeNavWrapper = createCategoryTreeNavWrapper({
29
- defaultLocale,
30
- resolveNavSource: resolveNavSource as (
31
- lang: string,
32
- currentVersion: string | undefined,
33
- options?: { applyDefaultLocaleOnlyFilter?: boolean; keepUnlisted?: boolean },
34
- ) => CategoryTreeNavSource,
35
- buildNavTree: (docs: unknown[], locale: string, categoryMeta: Map<string, unknown>) =>
36
- buildNavTree(
37
- docs as DocsEntry[],
38
- locale as Locale,
39
- categoryMeta as Map<string, CategoryMeta>,
40
- ) as unknown as CategoryTreeNavNode[],
41
- groupSatelliteNodes: (tree: CategoryTreeNavNode[], prefixes: string[]) =>
42
- groupSatelliteNodes(tree as unknown as NavNode[], prefixes) as unknown as CategoryTreeNavNode[],
43
- findNode: (tree: CategoryTreeNavNode[], slug: string) =>
44
- findNode(tree as unknown as NavNode[], slug) as unknown as CategoryTreeNavNode | undefined,
45
- });
@@ -1,25 +0,0 @@
1
- /**
2
- * Compose the canonical "<title> | <siteName>" page-title shape used by
3
- * both <title> (emitted by DocLayout) and og:title (emitted by
4
- * HeadWithDefaults).
5
- *
6
- * Why this exists: the legacy Astro layout synthesised this suffix
7
- * inline. The zfb DocLayout shell intentionally renders only what the
8
- * host passes as `title`, so the host has to compose the suffix itself.
9
- * Centralising the composition in one helper keeps every host call
10
- * site in sync and matches the SEO/UX-recognised shape the original
11
- * site shipped (also asserted by smoke-seo.spec.ts).
12
- *
13
- * Edge cases:
14
- * - When `title` is identical to `settings.siteName` (e.g. the home
15
- * page already passes `settings.siteName` as the title), do NOT
16
- * duplicate — return just the bare site name. Mirrors the legacy
17
- * Astro behaviour.
18
- * - When `siteName` is missing/empty (defensive — settings.ts always
19
- * has it in practice), fall back to the bare title.
20
- *
21
- */
22
- import { createComposeMetaTitle } from "@takazudo/zudo-doc/compose-meta-title";
23
- import { settings } from "@/config/settings";
24
-
25
- export const composeMetaTitle = createComposeMetaTitle(settings.siteName);
@@ -1,8 +0,0 @@
1
- /** @jsxRuntime automatic */
2
- /** @jsxImportSource preact */
3
- // Host thin-stub — see @takazudo/zudo-doc/doc-body-end (epic #2344, S7).
4
- import { settings } from "@/config/settings";
5
- import { createDocBodyEnd } from "@takazudo/zudo-doc/doc-body-end";
6
- import { BodyEndIslands } from "./_body-end-islands";
7
-
8
- export const DocBodyEnd = createDocBodyEnd({ settings, BodyEndIslands });