create-zudo-doc 0.2.21 → 0.2.22
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/features/image-enlarge.d.ts +10 -2
- package/dist/features/image-enlarge.js +10 -2
- package/dist/scaffold.js +20 -22
- package/dist/zfb-config-gen.d.ts +16 -10
- package/dist/zfb-config-gen.js +34 -239
- package/package.json +1 -1
- package/templates/base/pages/lib/_body-end-islands.tsx +6 -13
- package/templates/base/pages/lib/_category-nav.tsx +30 -115
- package/templates/base/pages/lib/_category-tree-nav.tsx +38 -65
- package/templates/base/pages/lib/_compose-meta-title.ts +2 -6
- package/templates/base/pages/lib/_doc-body-end.tsx +3 -35
- package/templates/base/pages/lib/_doc-content-header.tsx +10 -111
- package/templates/base/pages/lib/_doc-history-area.tsx +19 -211
- package/templates/base/pages/lib/_doc-metainfo-area.tsx +10 -113
- package/templates/base/pages/lib/_doc-page-renderer.tsx +22 -183
- package/templates/base/pages/lib/_doc-page-shell.tsx +17 -251
- package/templates/base/pages/lib/_doc-pager.tsx +4 -74
- package/templates/base/pages/lib/_doc-route-entries.ts +43 -177
- package/templates/base/pages/lib/_doc-route-paths.ts +16 -101
- package/templates/base/pages/lib/_doc-tags-area.tsx +14 -77
- package/templates/base/pages/lib/_footer-with-defaults.tsx +37 -225
- package/templates/base/pages/lib/_frontmatter-preview-data.ts +5 -31
- package/templates/base/pages/lib/_head-with-defaults.tsx +13 -138
- package/templates/base/pages/lib/_header-with-defaults.tsx +24 -324
- package/templates/base/pages/lib/_inline-version-switcher.tsx +16 -78
- package/templates/base/pages/lib/_nav-data-prep.ts +32 -51
- package/templates/base/pages/lib/_nav-source-cache.ts +12 -57
- package/templates/base/pages/lib/_nav-source-docs.ts +33 -233
- package/templates/base/pages/lib/_search-widget-script.ts +2 -470
- package/templates/base/pages/lib/_search-widget.tsx +9 -195
- package/templates/base/pages/lib/_sidebar-prepaint.tsx +6 -59
- package/templates/base/pages/lib/_sidebar-with-defaults.tsx +16 -118
- package/templates/base/pages/lib/_site-tree-nav.tsx +29 -80
- package/templates/base/pages/lib/doc-page-props.ts +26 -44
- package/templates/base/pages/lib/locale-merge.ts +32 -145
- package/templates/base/pages/lib/route-enumerators.ts +52 -286
- package/templates/base/pages/robots.txt.tsx +2 -26
- package/templates/base/src/components/ai-chat-modal.tsx +9 -8
- package/templates/base/src/components/doc-history.tsx +9 -8
- package/templates/base/src/components/image-enlarge.tsx +11 -8
- package/templates/base/src/components/sidebar-toggle.tsx +6 -170
- package/templates/base/src/components/sidebar-tree.tsx +6 -548
- package/templates/base/src/components/site-tree-nav.tsx +6 -220
- package/templates/base/src/config/color-scheme-utils.ts +34 -158
- package/templates/base/src/config/i18n.ts +9 -0
- package/templates/base/src/config/z-index-tokens.ts +5 -4
- package/templates/base/src/styles/global.css +5 -579
- package/templates/base/src/utils/base.ts +1 -1
- package/templates/base/src/utils/docs.ts +47 -16
- package/templates/base/src/utils/github.ts +12 -9
- package/templates/base/src/utils/nav-scope.ts +13 -42
- package/templates/base/src/utils/sidebar.ts +18 -86
- package/templates/base/src/utils/slug.ts +10 -53
- package/templates/base/src/utils/smart-break.tsx +12 -120
- package/templates/base/src/utils/tags.ts +25 -68
- package/templates/features/bodyFootUtil/files/src/utils/github.ts +12 -9
- package/templates/features/designTokenPanel/files/src/lib/design-token-panel-bootstrap.ts +13 -39
- package/templates/features/docHistory/files/src/components/doc-history.tsx +8 -636
- package/templates/features/docHistory/files/src/types/doc-history.ts +7 -23
- package/templates/features/docTags/files/pages/lib/_tag-pages.tsx +35 -201
- package/templates/features/imageEnlarge/files/src/components/image-enlarge.tsx +8 -269
- package/templates/features/sidebarToggle/files/src/components/desktop-sidebar-toggle.tsx +6 -99
- package/templates/features/tagGovernance/files/scripts/tags-audit.ts +67 -515
- package/templates/features/versioning/files/pages/lib/_versions-page.tsx +21 -73
- package/templates/base/plugins/connect-adapter.mjs +0 -169
- package/templates/base/plugins/search-index-plugin.mjs +0 -66
- package/templates/base/scripts/gen-z-index.mjs +0 -157
- package/templates/base/src/components/mermaid-enlarge.tsx +0 -490
- package/templates/features/claudeResources/files/plugins/claude-resources-plugin.mjs +0 -47
- package/templates/features/docHistory/files/plugins/doc-history-plugin.mjs +0 -111
- package/templates/features/llmsTxt/files/plugins/llms-txt-plugin.mjs +0 -93
|
@@ -1,35 +1,15 @@
|
|
|
1
1
|
/** @jsxRuntime automatic */
|
|
2
2
|
/** @jsxImportSource preact */
|
|
3
|
-
//
|
|
3
|
+
// Host thin-stub — see @takazudo/zudo-doc/doc-history-area (epic #2344, S7).
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// skips it as a page module, while the two doc-page modules
|
|
8
|
-
// (docs/[...slug].tsx and [locale]/docs/[...slug].tsx) import it directly.
|
|
9
|
-
// It gates on settings.docHistory, resolves the correct locale prop
|
|
10
|
-
// (omitted for the default locale, matching the doc-history fetch-path
|
|
11
|
-
// branch in src/components/doc-history.tsx), and passes the assembled
|
|
12
|
-
// island into BodyFootUtilArea — restoring the
|
|
13
|
-
// `<section aria-label="Document utilities">` landmark and its Revision
|
|
14
|
-
// History heading in the SSG output for all zfb doc routes.
|
|
15
|
-
//
|
|
16
|
-
// Wave 8 (Path A — super-epic #1333 / child epic #1355): the doc-history
|
|
17
|
-
// island is now built right here using zfb's native `<Island ssrFallback>`
|
|
18
|
-
// API with the real DocHistory component imported from
|
|
19
|
-
// `@/components/doc-history`. Previously this file passed
|
|
20
|
-
// DocHistoryIslandProps to BodyFootUtilArea, which fed an SSR-skip
|
|
21
|
-
// wrapper that did not import the real component — the orphan-component
|
|
22
|
-
// bug that left the marker un-bundled. The host-side import here is the
|
|
23
|
-
// page → real-component chain zfb's island scanner walks.
|
|
24
|
-
|
|
25
|
-
import type { VNode } from "preact";
|
|
26
|
-
import { Island } from "@takazudo/zfb";
|
|
5
|
+
// The DocHistory import is kept here so zfb's island scanner walks the chain:
|
|
6
|
+
// page → stub → DocHistory. The factory receives the constructor via deps.
|
|
27
7
|
import { settings } from "@/config/settings";
|
|
28
8
|
import { defaultLocale, t } from "@/config/i18n";
|
|
29
|
-
import { BodyFootUtilArea } from "@takazudo/zudo-doc/body-foot-util";
|
|
30
|
-
import { buildGitHubSourceUrl } from "@/utils/github";
|
|
31
|
-
import { DocHistory } from "@/components/doc-history";
|
|
32
9
|
import { toHistorySlug } from "@/utils/slug";
|
|
10
|
+
import { buildGitHubSourceUrl as _buildGitHubSourceUrl } from "@/utils/github";
|
|
11
|
+
import { createDocHistoryArea } from "@takazudo/zudo-doc/doc-history-area";
|
|
12
|
+
import { DocHistory } from "@takazudo/zudo-doc/doc-history";
|
|
33
13
|
// SSR author + date metadata comes from `.zfb/doc-history-meta.json`, a
|
|
34
14
|
// build-time manifest emitted by `scripts/zfb-prebuild.mjs` (step 2:
|
|
35
15
|
// doc-history-meta) before `zfb build` runs. esbuild inlines the JSON
|
|
@@ -39,188 +19,16 @@ import { toHistorySlug } from "@/utils/slug";
|
|
|
39
19
|
// because the zfb bundler builds pages from a shadow tree; relative paths
|
|
40
20
|
// across the shadow boundary would resolve to the wrong location.
|
|
41
21
|
import docHistoryMeta from "#doc-history-meta";
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
locale: string;
|
|
56
|
-
/**
|
|
57
|
-
* Raw zfb entry slug (relative path without extension), e.g.
|
|
58
|
-
* "getting-started/intro" or "getting-started/index". Appended with
|
|
59
|
-
* the source extension from the build-time manifest (".mdx" fallback)
|
|
60
|
-
* to form the file path passed to buildGitHubSourceUrl.
|
|
61
|
-
* Omit for auto-index pages (no underlying MDX file) — sourceUrl
|
|
62
|
-
* will be suppressed automatically.
|
|
63
|
-
*/
|
|
64
|
-
entrySlug?: string;
|
|
65
|
-
/**
|
|
66
|
-
* Content directory for the active locale, e.g. "src/content/docs"
|
|
67
|
-
* or "src/content/docs-ja". Combined with entrySlug to build the
|
|
68
|
-
* view-source GitHub URL. Omit to suppress the view-source link.
|
|
69
|
-
*/
|
|
70
|
-
contentDir?: string;
|
|
71
|
-
/**
|
|
72
|
-
* True when this locale page falls back to the base EN collection
|
|
73
|
-
* (i.e. the slug has no translation for the active locale). When true,
|
|
74
|
-
* the history data-path derivations use defaultLocale so the island
|
|
75
|
-
* fetches the correct bare-slug JSON and the SSR manifest lookup hits
|
|
76
|
-
* the bare key — both of which only exist for EN-origin files.
|
|
77
|
-
* Display labels (t() calls) still use the active locale so JA users
|
|
78
|
-
* see JA labels on fallback pages. Omit (or false) for translated pages
|
|
79
|
-
* and all other call sites (EN route, tag pages) — behavior unchanged.
|
|
80
|
-
*/
|
|
81
|
-
isFallback?: boolean;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Renders the `<BodyFootUtilArea>` shell with a doc-history island when
|
|
86
|
-
* `settings.docHistory` is enabled. Returns null otherwise so no empty
|
|
87
|
-
* landmark appears on pages where history is disabled.
|
|
88
|
-
*
|
|
89
|
-
* The locale prop is forwarded to the real DocHistory component only for
|
|
90
|
-
* non-default locales — the history JSON server stores default-locale
|
|
91
|
-
* files without a locale path segment (matching the fetch-path branch in
|
|
92
|
-
* doc-history.tsx).
|
|
93
|
-
*
|
|
94
|
-
* When entrySlug + contentDir are both provided and settings.bodyFootUtilArea
|
|
95
|
-
* has viewSourceLink enabled, computes sourceUrl via buildGitHubSourceUrl and
|
|
96
|
-
* resolves the i18n label for the active locale — keeping the v2 component
|
|
97
|
-
* oblivious to project settings (host-side computation, B-8-2).
|
|
98
|
-
*
|
|
99
|
-
* The SSR fallback for the doc-history island is built from git metadata
|
|
100
|
-
* (author name, created/updated dates) so that static HTML contains the
|
|
101
|
-
* author marker before JS hydration, visible to screen readers and crawlers.
|
|
102
|
-
*/
|
|
103
|
-
export function DocHistoryArea({
|
|
104
|
-
slug,
|
|
105
|
-
locale,
|
|
106
|
-
entrySlug,
|
|
107
|
-
contentDir,
|
|
108
|
-
isFallback,
|
|
109
|
-
}: DocHistoryAreaProps): VNode | null {
|
|
110
|
-
if (!settings.docHistory) return null;
|
|
111
|
-
|
|
112
|
-
// Doc-history storage sentinel ("" -> "index"): a root index page has the
|
|
113
|
-
// canonical route slug "" (→ /docs/), but doc-history JSON and the meta
|
|
114
|
-
// manifest store/serve the root entry under "index" (an empty path segment
|
|
115
|
-
// is unroutable — the server regex and the prebuild key composition both
|
|
116
|
-
// reject ""). Apply the sentinel to the slug segment BEFORE locale
|
|
117
|
-
// composition so root pages resolve to e.g. /doc-history/index.json and the
|
|
118
|
-
// meta key "ja/index". See @/utils/slug `toHistorySlug` and the
|
|
119
|
-
// collectContentFiles walk in packages/doc-history-server. (#1891)
|
|
120
|
-
const historySlug = toHistorySlug(slug);
|
|
121
|
-
|
|
122
|
-
// On EN-fallback locale pages the history data exists only at the bare
|
|
123
|
-
// (non-locale-prefixed) path — the prebuild/server writes locale-prefixed
|
|
124
|
-
// keys/paths only for files physically present in the locale collection.
|
|
125
|
-
// Use defaultLocale for data lookups when isFallback is true; keep locale
|
|
126
|
-
// for all display label calls (t()) so JA users see JA labels.
|
|
127
|
-
const effectiveHistoryLocale = isFallback ? defaultLocale : locale;
|
|
128
|
-
|
|
129
|
-
// Look up the build-time manifest entry for this page. The composedSlug
|
|
130
|
-
// matches the key written by the prebuild step: bare slug for the default
|
|
131
|
-
// locale, "<localeKey>/<slug>" for non-default locales.
|
|
132
|
-
const composedSlug =
|
|
133
|
-
effectiveHistoryLocale === defaultLocale ? historySlug : `${effectiveHistoryLocale}/${historySlug}`;
|
|
134
|
-
type MetaEntry = {
|
|
135
|
-
author: string;
|
|
136
|
-
createdDate: string;
|
|
137
|
-
updatedDate: string;
|
|
138
|
-
/** Source file extension (".mdx" | ".md") — optional in older manifests. */
|
|
139
|
-
ext?: string;
|
|
140
|
-
};
|
|
141
|
-
const meta = (docHistoryMeta as Record<string, MetaEntry>)[composedSlug];
|
|
142
|
-
|
|
143
|
-
// Locale-aware labels for the SSR fallback.
|
|
144
|
-
const createdLabel = t("doc.created", locale);
|
|
145
|
-
const updatedLabel = t("doc.updated", locale);
|
|
146
|
-
const historyLabel = t("doc.history", locale);
|
|
147
|
-
|
|
148
|
-
// Real-component props — locale omitted for the default locale.
|
|
149
|
-
// Use effectiveHistoryLocale so fallback pages fetch the bare (non-ja/) path.
|
|
150
|
-
const docHistoryLocale = effectiveHistoryLocale === defaultLocale ? undefined : effectiveHistoryLocale;
|
|
151
|
-
const docHistoryBasePath = settings.base ?? "/";
|
|
152
|
-
|
|
153
|
-
// Build the SSR fallback with only the sr-only metadata block so the
|
|
154
|
-
// author marker and Created/Updated labels are present in SSG output
|
|
155
|
-
// before JS hydration, discoverable by screen readers and crawlers.
|
|
156
|
-
// The visible "History" trigger button is NOT included here — DocHistory
|
|
157
|
-
// renders its own trigger after hydration, and including one in the
|
|
158
|
-
// ssrFallback as well caused a duplicate button in the DOM because
|
|
159
|
-
// Preact's render() does not reliably remove static ssrFallback HTML
|
|
160
|
-
// before mounting the new component output (same wrapper-self-Island
|
|
161
|
-
// pattern fixed for Toc/Sidebar in commit 4014cdc).
|
|
162
|
-
const author = meta?.author;
|
|
163
|
-
const createdDate = meta?.createdDate;
|
|
164
|
-
const updatedDate = meta?.updatedDate;
|
|
165
|
-
|
|
166
|
-
// Explicit type annotation omitted: inferred JSX return is structurally
|
|
167
|
-
// compatible with zfb's VNode (the ssrFallback prop target). Preact's
|
|
168
|
-
// VNode<{}> generic form is not directly assignable to zfb's VNode at the
|
|
169
|
-
// type level even though the runtime shapes are identical.
|
|
170
|
-
const fallback = (
|
|
171
|
-
<div class="sr-only">
|
|
172
|
-
{author && <span>{author}</span>}
|
|
173
|
-
<span>
|
|
174
|
-
{createdLabel}
|
|
175
|
-
{createdDate ? `: ${createdDate}` : ""}
|
|
176
|
-
</span>
|
|
177
|
-
<span>
|
|
178
|
-
{updatedLabel}
|
|
179
|
-
{updatedDate ? `: ${updatedDate}` : ""}
|
|
180
|
-
</span>
|
|
181
|
-
</div>
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
// Compose the SSR-skip island with zfb's native `<Island ssrFallback>` API.
|
|
185
|
-
// The page → this file → real DocHistory import chain is what the scanner
|
|
186
|
-
// walks; the marker emitted is "DocHistory" via captureComponentName.
|
|
187
|
-
const docHistoryIsland = Island({
|
|
188
|
-
when: "idle",
|
|
189
|
-
ssrFallback: fallback,
|
|
190
|
-
children: (
|
|
191
|
-
<DocHistory
|
|
192
|
-
slug={historySlug}
|
|
193
|
-
locale={docHistoryLocale}
|
|
194
|
-
basePath={docHistoryBasePath}
|
|
195
|
-
/>
|
|
196
|
-
),
|
|
197
|
-
}) as unknown as VNode;
|
|
198
|
-
|
|
199
|
-
// Compute the view-source GitHub URL host-side so the v2 BodyFootUtilArea
|
|
200
|
-
// component stays oblivious to project settings. Gate on
|
|
201
|
-
// bodyFootUtilArea.viewSourceLink, and require both entrySlug and contentDir
|
|
202
|
-
// (auto-index pages pass neither). The real source extension comes from the
|
|
203
|
-
// build-time manifest (`ext`, written by pre-build.ts) — the content walkers
|
|
204
|
-
// accept both .mdx and .md, so hardcoding ".mdx" produced broken view-source
|
|
205
|
-
// URLs for .md pages. ".mdx" remains the fallback for entries without a
|
|
206
|
-
// manifest record (untracked files, SKIP_DOC_HISTORY=1, stale manifests).
|
|
207
|
-
const utilSettings = settings.bodyFootUtilArea;
|
|
208
|
-
const sourceExt = meta?.ext ?? ".mdx";
|
|
209
|
-
const sourceUrl =
|
|
210
|
-
utilSettings && utilSettings.viewSourceLink && entrySlug && contentDir
|
|
211
|
-
? buildGitHubSourceUrl(contentDir, entrySlug + sourceExt)
|
|
212
|
-
: null;
|
|
213
|
-
|
|
214
|
-
// Resolve the i18n label host-side; pass the result so the v2 component
|
|
215
|
-
// stays framework-agnostic. Falls back to the EN default when locale has
|
|
216
|
-
// no translation (see DEFAULT_VIEW_SOURCE_LABEL in the v2 package).
|
|
217
|
-
const viewSourceLabel = t("doc.viewSource", locale);
|
|
218
|
-
|
|
219
|
-
return (
|
|
220
|
-
<BodyFootUtilArea
|
|
221
|
-
docHistoryIsland={docHistoryIsland}
|
|
222
|
-
sourceUrl={sourceUrl}
|
|
223
|
-
viewSourceLabel={viewSourceLabel}
|
|
224
|
-
/>
|
|
225
|
-
);
|
|
226
|
-
}
|
|
22
|
+
import type { DocHistoryAreaProps } from "@takazudo/zudo-doc/doc-history-area";
|
|
23
|
+
|
|
24
|
+
export type { DocHistoryAreaProps };
|
|
25
|
+
|
|
26
|
+
export const DocHistoryArea = createDocHistoryArea({
|
|
27
|
+
settings,
|
|
28
|
+
defaultLocale,
|
|
29
|
+
docHistoryMeta: docHistoryMeta as Record<string, { author: string; createdDate: string; updatedDate: string; ext?: string }>,
|
|
30
|
+
t,
|
|
31
|
+
toHistorySlug,
|
|
32
|
+
buildGitHubSourceUrl: (contentDir: string, entryId: string) => _buildGitHubSourceUrl(contentDir, entryId),
|
|
33
|
+
DocHistory,
|
|
34
|
+
});
|
|
@@ -1,31 +1,10 @@
|
|
|
1
1
|
/** @jsxRuntime automatic */
|
|
2
2
|
/** @jsxImportSource preact */
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// Renders the visible date block (created / updated dates + author)
|
|
6
|
-
// between the article <h1> and the description paragraph (doc-metainfo
|
|
7
|
-
// placement — between <h1> and description).
|
|
8
|
-
//
|
|
9
|
-
// Data source: `.zfb/doc-history-meta.json`, a build-time manifest
|
|
10
|
-
// emitted by `scripts/zfb-prebuild.mjs` before `zfb build` runs.
|
|
11
|
-
// esbuild inlines the JSON statically so no Node.js `fs` code reaches
|
|
12
|
-
// the client bundle — the same approach used by `_doc-history-area.tsx`
|
|
13
|
-
// (b11-2 pattern).
|
|
14
|
-
//
|
|
15
|
-
// Date formatting uses Intl.DateTimeFormat (browser-safe). We do NOT
|
|
16
|
-
// import the old `formatDate` from `src/utils/git-info.ts` — that module
|
|
17
|
-
// carried top-level Node.js imports (`execFileSync`, `existsSync`) that
|
|
18
|
-
// would be dragged into the client bundle (the B-11 lesson). That file
|
|
19
|
-
// was removed in S1 cleanup (#1928); the mirror below is the canonical copy.
|
|
20
|
-
//
|
|
21
|
-
// Labels are resolved from the project's i18n table so non-default
|
|
22
|
-
// locales (e.g. /ja/) get translated "作成" / "更新" strings.
|
|
23
|
-
|
|
24
|
-
import type { VNode } from "preact";
|
|
3
|
+
// Host thin-stub — see @takazudo/zudo-doc/doc-metainfo-area (epic #2344, S7).
|
|
25
4
|
import { settings } from "@/config/settings";
|
|
26
5
|
import { defaultLocale, t } from "@/config/i18n";
|
|
27
|
-
import { DocMetainfo } from "@takazudo/zudo-doc/metainfo";
|
|
28
6
|
import { toHistorySlug } from "@/utils/slug";
|
|
7
|
+
import { createDocMetainfoArea } from "@takazudo/zudo-doc/doc-metainfo-area";
|
|
29
8
|
// SSR author + date metadata comes from `.zfb/doc-history-meta.json`, a
|
|
30
9
|
// build-time manifest emitted by `scripts/zfb-prebuild.mjs` (step 2:
|
|
31
10
|
// doc-history-meta) before `zfb build` runs. esbuild inlines the JSON
|
|
@@ -36,94 +15,12 @@ import { toHistorySlug } from "@/utils/slug";
|
|
|
36
15
|
// across the shadow boundary would resolve to the wrong location.
|
|
37
16
|
import docHistoryMeta from "#doc-history-meta";
|
|
38
17
|
|
|
39
|
-
|
|
40
|
-
// Originally mirrored from `src/utils/git-info.ts` (removed in S1 #1928).
|
|
41
|
-
// The formatDate function below is the stable copy; kept in sync manually.
|
|
42
|
-
const LOCALE_TO_BCP47: Record<string, string> = {
|
|
43
|
-
en: "en-US",
|
|
44
|
-
ja: "ja-JP",
|
|
45
|
-
de: "de-DE",
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
/** Format an ISO date string for display, respecting the active locale. */
|
|
49
|
-
function formatDate(isoDate: string, locale: string): string {
|
|
50
|
-
const d = new Date(isoDate);
|
|
51
|
-
if (isNaN(d.getTime())) return isoDate;
|
|
52
|
-
return d.toLocaleDateString(LOCALE_TO_BCP47[locale] ?? "en-US", {
|
|
53
|
-
year: "numeric",
|
|
54
|
-
month: "short",
|
|
55
|
-
day: "numeric",
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
interface DocMetainfoAreaProps {
|
|
60
|
-
/** Page slug, e.g. "getting-started/intro". */
|
|
61
|
-
slug: string;
|
|
62
|
-
/** Active locale string, e.g. "en", "ja". */
|
|
63
|
-
locale: string;
|
|
64
|
-
/**
|
|
65
|
-
* True when this locale page falls back to the base EN collection
|
|
66
|
-
* (i.e. the slug has no translation for the active locale). When true,
|
|
67
|
-
* the manifest lookup uses defaultLocale so the visible block resolves
|
|
68
|
-
* the bare-slug key — the only key that exists for EN-origin files —
|
|
69
|
-
* matching the dropdown's `effectiveHistoryLocale` derivation in
|
|
70
|
-
* _doc-history-area.tsx. Display formatting (dates + labels) still uses
|
|
71
|
-
* the active locale so JA users see JA formatting on fallback pages.
|
|
72
|
-
*/
|
|
73
|
-
isFallback?: boolean;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Renders the visible date block (Created / Updated / Author) when
|
|
78
|
-
* `settings.docMetainfo` is enabled and the build-time manifest has an
|
|
79
|
-
* entry for the active page.
|
|
80
|
-
*
|
|
81
|
-
* Returns null when `docMetainfo` is disabled, the page is untracked
|
|
82
|
-
* (no manifest entry), or the manifest was generated in a shallow clone
|
|
83
|
-
* (`SKIP_DOC_HISTORY=1` → empty JSON).
|
|
84
|
-
*
|
|
85
|
-
* The component is intentionally server-render-only: it emits static
|
|
86
|
-
* HTML from build-time data and has no client JS footprint. It sits
|
|
87
|
-
* between `<h1>` and the description `<p>` (doc-metainfo placement).
|
|
88
|
-
*/
|
|
89
|
-
export function DocMetainfoArea({ slug, locale, isFallback }: DocMetainfoAreaProps): VNode | null {
|
|
90
|
-
if (!settings.docMetainfo) return null;
|
|
91
|
-
|
|
92
|
-
// Doc-history storage sentinel ("" -> "index"): a root index page has the
|
|
93
|
-
// canonical route slug "" (→ /docs/), but the prebuild keys the root entry
|
|
94
|
-
// under "index" (collectContentFiles keeps the bare root; an empty path
|
|
95
|
-
// segment is unroutable). Apply the sentinel BEFORE locale composition so
|
|
96
|
-
// the visible Created/Updated/Author block resolves for a root page — see
|
|
97
|
-
// @/utils/slug `toHistorySlug` and _doc-history-area.tsx. (#1891)
|
|
98
|
-
const historySlug = toHistorySlug(slug);
|
|
99
|
-
|
|
100
|
-
// On EN-fallback locale pages the manifest only has the bare
|
|
101
|
-
// (non-locale-prefixed) key — the prebuild writes locale-prefixed keys
|
|
102
|
-
// only for files physically present in the locale collection. Use
|
|
103
|
-
// defaultLocale for the data lookup when isFallback is true, mirroring
|
|
104
|
-
// `effectiveHistoryLocale` in _doc-history-area.tsx so the visible block
|
|
105
|
-
// and the dropdown agree. Display formatting keeps the active locale.
|
|
106
|
-
const effectiveHistoryLocale = isFallback ? defaultLocale : locale;
|
|
107
|
-
|
|
108
|
-
// Key format: bare slug for default locale, "<locale>/<slug>" for others.
|
|
109
|
-
// Matches the prebuild step's composedSlug logic (pre-build.ts).
|
|
110
|
-
const composedSlug =
|
|
111
|
-
effectiveHistoryLocale === defaultLocale
|
|
112
|
-
? historySlug
|
|
113
|
-
: `${effectiveHistoryLocale}/${historySlug}`;
|
|
114
|
-
|
|
115
|
-
type MetaEntry = { author: string; createdDate: string; updatedDate: string };
|
|
116
|
-
const meta = (docHistoryMeta as Record<string, MetaEntry>)[composedSlug];
|
|
117
|
-
|
|
118
|
-
if (!meta) return null;
|
|
18
|
+
export type { DocMetainfoAreaProps } from "@takazudo/zudo-doc/doc-metainfo-area";
|
|
119
19
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
/>
|
|
128
|
-
);
|
|
129
|
-
}
|
|
20
|
+
export const DocMetainfoArea = createDocMetainfoArea({
|
|
21
|
+
settings,
|
|
22
|
+
defaultLocale,
|
|
23
|
+
docHistoryMeta: docHistoryMeta as Record<string, { author: string; createdDate: string; updatedDate: string }>,
|
|
24
|
+
t,
|
|
25
|
+
toHistorySlug,
|
|
26
|
+
});
|
|
@@ -1,192 +1,31 @@
|
|
|
1
1
|
/** @jsxRuntime automatic */
|
|
2
2
|
/** @jsxImportSource preact */
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
// Extracted (#2010) from the near-identical default components of:
|
|
6
|
-
// pages/docs/[[...slug]].tsx
|
|
7
|
-
// pages/[locale]/docs/[[...slug]].tsx
|
|
8
|
-
// pages/v/[version]/docs/[[...slug]].tsx
|
|
9
|
-
// pages/v/[version]/[locale]/docs/[[...slug]].tsx
|
|
10
|
-
//
|
|
11
|
-
// Each route's default export stays a thin adapter that reads its params /
|
|
12
|
-
// route-specific props (locale, version, contentDir, isFallback) and
|
|
13
|
-
// delegates here. Route-specific behavior is parameterized:
|
|
14
|
-
// - `version` present → versioned chrome: versioned canonical URL, version
|
|
15
|
-
// banner, version-aware switcher, auto-index child hrefs kept as the
|
|
16
|
-
// pre-remapped versioned hrefs from paths() (#1916 #2), and doc history
|
|
17
|
-
// hidden until versioned history is supported (#1916 #5).
|
|
18
|
-
// - `version` absent → latest chrome: docsUrl canonical, child hrefs fall
|
|
19
|
-
// back to the nav node's own docsUrl, doc history rendered for listed
|
|
20
|
-
// entries via `docHistoryContentDir`.
|
|
21
|
-
|
|
22
|
-
import { settings } from "@/config/settings";
|
|
23
|
-
import type { VersionConfig } from "@/config/settings";
|
|
24
|
-
import { t, type Locale } from "@/config/i18n";
|
|
3
|
+
// Host thin-stub — see @takazudo/zudo-doc/doc-page-renderer (epic #2344, S7).
|
|
4
|
+
import { t } from "@/config/i18n";
|
|
25
5
|
import { docsUrl, versionedDocsUrl, absoluteUrl } from "@/utils/base";
|
|
26
|
-
import type { NavNode } from "@/utils/docs";
|
|
27
6
|
import { getNavSectionForSlug } from "@/utils/nav-scope";
|
|
28
7
|
import { toRouteSlug } from "@/utils/slug";
|
|
29
|
-
import type { JSX } from "preact";
|
|
30
|
-
// Shared MDX-tag → Preact-component bag. Includes htmlOverrides
|
|
31
|
-
// (native typography), HtmlPreviewWrapper (Island), and stub bindings
|
|
32
|
-
// for every other custom tag the MDX corpus references — see
|
|
33
|
-
// `pages/_mdx-components.ts` for the full list and rationale.
|
|
34
8
|
import { createMdxComponents } from "../_mdx-components";
|
|
35
|
-
import
|
|
36
|
-
import { DocHistoryArea } from "./_doc-history-area";
|
|
37
|
-
import { DocMetainfoArea } from "./_doc-metainfo-area";
|
|
9
|
+
import { createRenderDocPage } from "@takazudo/zudo-doc/doc-page-renderer";
|
|
38
10
|
import { buildInlineVersionSwitcher } from "./_inline-version-switcher";
|
|
39
|
-
import { DocContentHeader } from "./_doc-content-header";
|
|
40
11
|
import { DocPageShell } from "./_doc-page-shell";
|
|
12
|
+
import { DocContentHeader } from "./_doc-content-header";
|
|
13
|
+
import { DocMetainfoArea } from "./_doc-metainfo-area";
|
|
14
|
+
import { DocHistoryArea } from "./_doc-history-area";
|
|
41
15
|
|
|
42
|
-
export
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function renderDocPage(
|
|
60
|
-
props: DocPageBaseProps,
|
|
61
|
-
opts: RenderDocPageOptions,
|
|
62
|
-
): JSX.Element {
|
|
63
|
-
const { breadcrumbs, prev, next, headings } = props;
|
|
64
|
-
const { locale, version, isFallback } = opts;
|
|
65
|
-
|
|
66
|
-
const slug = props.kind === "autoIndex"
|
|
67
|
-
? props.autoIndex.slug
|
|
68
|
-
: (props.entry.data.slug ?? toRouteSlug(props.entry.slug));
|
|
69
|
-
|
|
70
|
-
const title = props.kind === "autoIndex" ? props.autoIndex.label : props.entry.data.title;
|
|
71
|
-
const description = props.kind === "autoIndex" ? props.autoIndex.description : props.entry.data.description;
|
|
72
|
-
|
|
73
|
-
// Locale-aware components bag — creates nav wrappers bound to the active
|
|
74
|
-
// locale so CategoryNav/CategoryTreeNav/SiteTreeNav query the right collection.
|
|
75
|
-
const components = createMdxComponents(locale);
|
|
76
|
-
|
|
77
|
-
// Resolve child hrefs for auto-index pages. Versioned routes: child cards
|
|
78
|
-
// already carry versioned hrefs from paths() (#1916 #2) — just filter to
|
|
79
|
-
// renderable nodes. Latest routes: keep the nav node's own docsUrl href
|
|
80
|
-
// (fallback for a noPage parent without an href).
|
|
81
|
-
const autoIndexChildren = props.kind === "autoIndex"
|
|
82
|
-
? version
|
|
83
|
-
? props.autoIndex.children.filter((c: NavNode) => c.hasPage || c.children.length > 0)
|
|
84
|
-
: props.autoIndex.children
|
|
85
|
-
.filter((c: NavNode) => c.hasPage || c.children.length > 0)
|
|
86
|
-
.map((c: NavNode) => ({
|
|
87
|
-
...c,
|
|
88
|
-
href: c.href ?? docsUrl(c.slug, locale),
|
|
89
|
-
}))
|
|
90
|
-
: [];
|
|
91
|
-
|
|
92
|
-
// Version banner: drives the `<VersionBanner>` element inside
|
|
93
|
-
// DocLayoutWithDefaults when `version.banner` is "unmaintained" or
|
|
94
|
-
// "unreleased". The banner links out to the latest version of the
|
|
95
|
-
// current page (slug-preserving — strips the /v/{version}/ prefix,
|
|
96
|
-
// keeps the /{locale}/ locale prefix).
|
|
97
|
-
const versionBannerType = version?.banner ? version.banner : undefined;
|
|
98
|
-
const versionBannerLatestUrl = versionBannerType
|
|
99
|
-
? docsUrl(slug, locale)
|
|
100
|
-
: undefined;
|
|
101
|
-
const versionBannerLabels = versionBannerType
|
|
102
|
-
? {
|
|
103
|
-
message:
|
|
104
|
-
versionBannerType === "unmaintained"
|
|
105
|
-
? t("version.banner.unmaintained", locale)
|
|
106
|
-
: t("version.banner.unreleased", locale),
|
|
107
|
-
latestLink: t("version.banner.latestLink", locale),
|
|
108
|
-
}
|
|
109
|
-
: undefined;
|
|
110
|
-
|
|
111
|
-
// Canonical URL — base-prefixed page path, absolutized against siteUrl.
|
|
112
|
-
// Versioned pages use the versioned URL as canonical.
|
|
113
|
-
const currentPath = version
|
|
114
|
-
? versionedDocsUrl(slug, version.slug, locale)
|
|
115
|
-
: docsUrl(slug, locale);
|
|
116
|
-
const canonical = absoluteUrl(currentPath);
|
|
117
|
-
|
|
118
|
-
// Persist key: locale + nav-section so the sidebar DOM node is reused
|
|
119
|
-
// across same-locale + same-section navigations only. No sanitizer needed —
|
|
120
|
-
// both lang (BCP-47 locale string) and navSection (filesystem-derived
|
|
121
|
-
// kebab-case slug) come from controlled, trusted sources.
|
|
122
|
-
const navSection = getNavSectionForSlug(slug);
|
|
123
|
-
const hideSidebar = props.kind === "entry" ? props.entry.data.hide_sidebar : undefined;
|
|
124
|
-
const sidebarPersistKey = hideSidebar
|
|
125
|
-
? undefined
|
|
126
|
-
: `sidebar-${locale}-${navSection ?? "default"}`;
|
|
127
|
-
|
|
128
|
-
return (
|
|
129
|
-
<DocPageShell
|
|
130
|
-
kind={props.kind}
|
|
131
|
-
locale={locale}
|
|
132
|
-
slug={slug}
|
|
133
|
-
title={title}
|
|
134
|
-
description={description}
|
|
135
|
-
canonical={canonical}
|
|
136
|
-
breadcrumbs={breadcrumbs}
|
|
137
|
-
prev={prev}
|
|
138
|
-
next={next}
|
|
139
|
-
headings={headings}
|
|
140
|
-
navSection={navSection}
|
|
141
|
-
sidebarPersistKey={sidebarPersistKey}
|
|
142
|
-
hideSidebar={hideSidebar}
|
|
143
|
-
hideToc={props.kind === "entry" ? props.entry.data.hide_toc : undefined}
|
|
144
|
-
currentPath={currentPath}
|
|
145
|
-
currentVersion={version?.slug}
|
|
146
|
-
versionSwitcher={buildInlineVersionSwitcher(slug, locale, version?.slug)}
|
|
147
|
-
versionBanner={versionBannerType}
|
|
148
|
-
versionBannerLatestUrl={versionBannerLatestUrl}
|
|
149
|
-
versionBannerLabels={versionBannerLabels}
|
|
150
|
-
autoIndexLabel={props.kind === "autoIndex" ? props.autoIndex.label : undefined}
|
|
151
|
-
autoIndexChildren={autoIndexChildren}
|
|
152
|
-
metainfoSlot={
|
|
153
|
-
// Versioned gate mirrors DocContentHeader: the doc-history-meta
|
|
154
|
-
// manifest is built from latest dirs only, so a bare versioned slug
|
|
155
|
-
// would surface the LATEST page's Created/Updated/Author.
|
|
156
|
-
!version && props.kind === "autoIndex" ? (
|
|
157
|
-
<DocMetainfoArea slug={slug} locale={locale} isFallback={isFallback} />
|
|
158
|
-
) : null
|
|
159
|
-
}
|
|
160
|
-
contentHeaderSlot={
|
|
161
|
-
props.kind === "entry" ? (
|
|
162
|
-
<DocContentHeader
|
|
163
|
-
entry={props.entry}
|
|
164
|
-
slug={slug}
|
|
165
|
-
locale={locale}
|
|
166
|
-
isFallback={isFallback}
|
|
167
|
-
version={version?.slug}
|
|
168
|
-
/>
|
|
169
|
-
) : undefined
|
|
170
|
-
}
|
|
171
|
-
contentSlot={
|
|
172
|
-
props.kind === "entry" ? <props.entry.Content components={components} /> : undefined
|
|
173
|
-
}
|
|
174
|
-
docHistorySlot={
|
|
175
|
-
// #1916 #5: doc-history hidden on versioned pages until versioned
|
|
176
|
-
// history is supported.
|
|
177
|
-
!version &&
|
|
178
|
-
opts.docHistoryContentDir !== undefined &&
|
|
179
|
-
props.kind === "entry" &&
|
|
180
|
-
!props.entry.data.unlisted ? (
|
|
181
|
-
<DocHistoryArea
|
|
182
|
-
slug={slug}
|
|
183
|
-
locale={locale}
|
|
184
|
-
entrySlug={props.entry.slug}
|
|
185
|
-
contentDir={opts.docHistoryContentDir}
|
|
186
|
-
isFallback={isFallback}
|
|
187
|
-
/>
|
|
188
|
-
) : null
|
|
189
|
-
}
|
|
190
|
-
/>
|
|
191
|
-
);
|
|
192
|
-
}
|
|
16
|
+
export type { RenderDocPageOptions } from "@takazudo/zudo-doc/doc-page-renderer";
|
|
17
|
+
|
|
18
|
+
export const renderDocPage = createRenderDocPage({
|
|
19
|
+
docsUrl,
|
|
20
|
+
versionedDocsUrl,
|
|
21
|
+
absoluteUrl,
|
|
22
|
+
getNavSectionForSlug,
|
|
23
|
+
toRouteSlug,
|
|
24
|
+
createMdxComponents,
|
|
25
|
+
t,
|
|
26
|
+
buildInlineVersionSwitcher,
|
|
27
|
+
DocPageShell,
|
|
28
|
+
DocContentHeader,
|
|
29
|
+
DocMetainfoArea,
|
|
30
|
+
DocHistoryArea,
|
|
31
|
+
});
|