@takazudo/zudo-doc 0.2.22 → 1.0.1
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/bin/zudo-doc.mjs +83 -0
- package/dist/eject/index.d.ts +33 -0
- package/dist/eject/index.js +229 -0
- package/dist/plugins/routes.d.ts +2 -0
- package/dist/plugins/routes.js +100 -0
- package/dist/preset.d.ts +47 -1
- package/dist/preset.js +29 -13
- package/dist/routes/404.d.ts +7 -0
- package/dist/routes/404.js +47 -0
- package/dist/routes/_chrome.d.ts +32 -0
- package/dist/routes/_chrome.js +365 -0
- package/dist/routes/_context.d.ts +56 -0
- package/dist/routes/_context.js +222 -0
- package/dist/routes/_docs-helpers.d.ts +43 -0
- package/dist/routes/_docs-helpers.js +173 -0
- package/dist/routes/_virtual.d.js +0 -0
- package/dist/routes/api-ai-chat.d.ts +5 -0
- package/dist/routes/api-ai-chat.js +24 -0
- package/dist/routes/docs-slug.d.ts +21 -0
- package/dist/routes/docs-slug.js +26 -0
- package/dist/routes/docs-tags-index.d.ts +7 -0
- package/dist/routes/docs-tags-index.js +11 -0
- package/dist/routes/docs-tags-tag.d.ts +23 -0
- package/dist/routes/docs-tags-tag.js +19 -0
- package/dist/routes/docs-versions.d.ts +7 -0
- package/dist/routes/docs-versions.js +11 -0
- package/dist/routes/index.d.ts +7 -0
- package/dist/routes/index.js +117 -0
- package/dist/routes/locale-docs-slug.d.ts +27 -0
- package/dist/routes/locale-docs-slug.js +40 -0
- package/dist/routes/locale-docs-tags-index.d.ts +18 -0
- package/dist/routes/locale-docs-tags-index.js +15 -0
- package/dist/routes/locale-docs-tags-tag.d.ts +25 -0
- package/dist/routes/locale-docs-tags-tag.js +22 -0
- package/dist/routes/locale-docs-versions.d.ts +18 -0
- package/dist/routes/locale-docs-versions.js +15 -0
- package/dist/routes/locale-index.d.ts +24 -0
- package/dist/routes/locale-index.js +132 -0
- package/dist/routes/robots.txt.d.ts +3 -0
- package/dist/routes/robots.txt.js +8 -0
- package/dist/routes/sitemap.xml.d.ts +5 -0
- package/dist/routes/sitemap.xml.js +31 -0
- package/dist/routes/v-docs-slug.d.ts +27 -0
- package/dist/routes/v-docs-slug.js +34 -0
- package/dist/routes/v-locale-docs-slug.d.ts +31 -0
- package/dist/routes/v-locale-docs-slug.js +50 -0
- package/dist/safelist.css +1 -1
- package/dist/settings.d.ts +15 -0
- package/eject/breadcrumb/breadcrumb.tsx +194 -0
- package/eject/breadcrumb/find-path.ts +26 -0
- package/eject/breadcrumb/index.ts +4 -0
- package/eject/breadcrumb/types.ts +32 -0
- package/eject/code-group/index.tsx +78 -0
- package/eject/content-admonition/index.tsx +50 -0
- package/eject/details/details.tsx +34 -0
- package/eject/details/index.ts +4 -0
- package/eject/doc-pager/index.tsx +91 -0
- package/eject/footer/footer.tsx +167 -0
- package/eject/footer/index.ts +19 -0
- package/eject/footer/types.ts +60 -0
- package/eject/header/header.tsx +725 -0
- package/eject/header/index.ts +36 -0
- package/eject/header/nav-active.ts +122 -0
- package/eject/header/nav-overflow-script.ts +302 -0
- package/eject/header/right-items.ts +78 -0
- package/eject/header/types.ts +69 -0
- package/eject/page-loading/index.ts +10 -0
- package/eject/page-loading/page-loading-overlay.tsx +103 -0
- package/eject/sidebar/index.ts +27 -0
- package/eject/sidebar/sidebar.tsx +137 -0
- package/eject/sidebar/types.ts +73 -0
- package/eject/tab-item/index.ts +7 -0
- package/eject/tab-item/tab-item.tsx +70 -0
- package/eject/theme-toggle/color-scheme-sync.ts +73 -0
- package/eject/theme-toggle/index.tsx +120 -0
- package/eject/toc/cx.ts +38 -0
- package/eject/toc/index.ts +11 -0
- package/eject/toc/mobile-toc.tsx +133 -0
- package/eject/toc/toc-title.ts +33 -0
- package/eject/toc/toc.tsx +119 -0
- package/eject/toc/types.ts +14 -0
- package/eject/toc/use-active-heading.ts +162 -0
- package/package.json +87 -7
- package/routes-src/404.tsx +49 -0
- package/routes-src/_chrome.tsx +470 -0
- package/routes-src/_context.ts +314 -0
- package/routes-src/_docs-helpers.ts +284 -0
- package/routes-src/_virtual.d.ts +15 -0
- package/routes-src/api-ai-chat.tsx +46 -0
- package/routes-src/docs-slug.tsx +43 -0
- package/routes-src/docs-tags-index.tsx +14 -0
- package/routes-src/docs-tags-tag.tsx +29 -0
- package/routes-src/docs-versions.tsx +15 -0
- package/routes-src/index.tsx +134 -0
- package/routes-src/locale-docs-slug.tsx +69 -0
- package/routes-src/locale-docs-tags-index.tsx +23 -0
- package/routes-src/locale-docs-tags-tag.tsx +39 -0
- package/routes-src/locale-docs-versions.tsx +23 -0
- package/routes-src/locale-index.tsx +150 -0
- package/routes-src/robots.txt.tsx +13 -0
- package/routes-src/sitemap.xml.tsx +48 -0
- package/routes-src/v-docs-slug.tsx +64 -0
- package/routes-src/v-locale-docs-slug.tsx +85 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
// Package route entrypoint: /docs/[[...slug]] — package-owned equivalent of
|
|
4
|
+
// pages/docs/[[...slug]].tsx (epic Package-First Finale #2356, A1 #2361).
|
|
5
|
+
//
|
|
6
|
+
// Default-locale (EN) catch-all docs route. `paths()` enumerates every page in
|
|
7
|
+
// the "docs" collection plus auto-generated category index pages — the
|
|
8
|
+
// load-bearing route-injection seam, reconstructed entirely from the package
|
|
9
|
+
// factories via `_context` (no `@/` imports). Rendering is via the package
|
|
10
|
+
// `renderDocPage` chrome (`_chrome`). Dormant unless `settings.packageOwnedRoutes`
|
|
11
|
+
// is on; even then dropped if the user keeps a `pages/docs/[[...slug]].tsx`
|
|
12
|
+
// stub (Decision 6).
|
|
13
|
+
|
|
14
|
+
import type { JSX } from "preact";
|
|
15
|
+
import type { DocPageEntryProps, DocPageAutoIndexProps } from "@takazudo/zudo-doc/doc-page-props";
|
|
16
|
+
import { settings, defaultLocale, resolveNavSource, buildDocRouteEntries } from "./_context.js";
|
|
17
|
+
import { renderDocPage } from "./_chrome.js";
|
|
18
|
+
|
|
19
|
+
export const frontmatter = { title: "Docs" };
|
|
20
|
+
|
|
21
|
+
type DocPageProps = DocPageEntryProps | DocPageAutoIndexProps;
|
|
22
|
+
|
|
23
|
+
export function paths(): Array<{ params: { slug: string[] }; props: DocPageProps }> {
|
|
24
|
+
const locale = defaultLocale;
|
|
25
|
+
const source = resolveNavSource(locale, undefined);
|
|
26
|
+
return buildDocRouteEntries({
|
|
27
|
+
source,
|
|
28
|
+
locale,
|
|
29
|
+
routeSig: `docs;${locale}`,
|
|
30
|
+
}).map((item) => ({
|
|
31
|
+
params: { slug: item.slugParams },
|
|
32
|
+
props: item.props as DocPageProps,
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type PageArgs = DocPageProps & { params: { slug: string[] } };
|
|
37
|
+
|
|
38
|
+
export default function DocsPage(props: PageArgs): JSX.Element {
|
|
39
|
+
return renderDocPage(props, {
|
|
40
|
+
locale: defaultLocale,
|
|
41
|
+
docHistoryContentDir: settings.docsDir,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
// Package route entrypoint: /docs/tags — package-owned equivalent of
|
|
4
|
+
// pages/docs/tags/index.tsx (A1 #2361). Default-locale "All Tags" index.
|
|
5
|
+
|
|
6
|
+
import type { JSX } from "preact";
|
|
7
|
+
import { defaultLocale } from "./_context.js";
|
|
8
|
+
import { TagsIndexPageView } from "./_chrome.js";
|
|
9
|
+
|
|
10
|
+
export const frontmatter = { title: "All Tags" };
|
|
11
|
+
|
|
12
|
+
export default function DocsTagsIndexPage(): JSX.Element {
|
|
13
|
+
return <TagsIndexPageView locale={defaultLocale} />;
|
|
14
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
// Package route entrypoint: /docs/tags/[tag] — package-owned equivalent of
|
|
4
|
+
// pages/docs/tags/[tag].tsx (A1 #2361). One route per unique tag in the
|
|
5
|
+
// default-locale collection.
|
|
6
|
+
|
|
7
|
+
import type { JSX } from "preact";
|
|
8
|
+
import type { TagInfo } from "@takazudo/zudo-doc/tag-pages";
|
|
9
|
+
import { defaultLocale } from "./_context.js";
|
|
10
|
+
import { collectTagMapForLocale, TagDetailPageView } from "./_chrome.js";
|
|
11
|
+
|
|
12
|
+
export const frontmatter = { title: "Tag" };
|
|
13
|
+
|
|
14
|
+
export function paths(): Array<{ params: { tag: string }; props: { tagInfo: TagInfo } }> {
|
|
15
|
+
const tagMap = collectTagMapForLocale(defaultLocale);
|
|
16
|
+
return [...tagMap.entries()].map(([tag, tagInfo]) => ({
|
|
17
|
+
params: { tag },
|
|
18
|
+
props: { tagInfo },
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface PageProps {
|
|
23
|
+
params: { tag: string };
|
|
24
|
+
tagInfo: TagInfo;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default function DocTagPage({ params, tagInfo }: PageProps): JSX.Element {
|
|
28
|
+
return <TagDetailPageView locale={defaultLocale} tag={params.tag} tagInfo={tagInfo} />;
|
|
29
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
// Package route entrypoint: /docs/versions — package-owned equivalent of
|
|
4
|
+
// pages/docs/versions.tsx (A1 #2361). Default-locale versions index; rendered
|
|
5
|
+
// by the package `VersionsPageView` (`_chrome`).
|
|
6
|
+
|
|
7
|
+
import type { JSX } from "preact";
|
|
8
|
+
import { defaultLocale } from "./_context.js";
|
|
9
|
+
import { VersionsPageView } from "./_chrome.js";
|
|
10
|
+
|
|
11
|
+
export const frontmatter = { title: "Versions" };
|
|
12
|
+
|
|
13
|
+
export default function VersionsPage(): JSX.Element {
|
|
14
|
+
return <VersionsPageView locale={defaultLocale} />;
|
|
15
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
// Package route entrypoint: / — package-owned equivalent of pages/index.tsx
|
|
4
|
+
// (A1 #2361). Default-locale (EN) site index: site-map grid + optional tag
|
|
5
|
+
// count, rendered through the package chrome (`_chrome`). Static route — no
|
|
6
|
+
// paths() export.
|
|
7
|
+
|
|
8
|
+
import type { JSX, VNode } from "preact";
|
|
9
|
+
import { Island } from "@takazudo/zfb";
|
|
10
|
+
import { DocLayoutWithDefaults } from "@takazudo/zudo-doc/doclayout";
|
|
11
|
+
import { SiteTreeNav } from "@takazudo/zudo-doc/site-tree-nav-island";
|
|
12
|
+
import type { SidebarNavNode } from "@takazudo/zudo-doc/sidebar";
|
|
13
|
+
import {
|
|
14
|
+
settings,
|
|
15
|
+
defaultLocale,
|
|
16
|
+
t,
|
|
17
|
+
withBase,
|
|
18
|
+
resolveNavSource,
|
|
19
|
+
buildNavTree,
|
|
20
|
+
groupSatelliteNodes,
|
|
21
|
+
getCategoryOrder,
|
|
22
|
+
collectTags,
|
|
23
|
+
docsUrl,
|
|
24
|
+
toRouteSlug,
|
|
25
|
+
} from "./_context.js";
|
|
26
|
+
import type { CategoryMeta } from "./_docs-helpers.js";
|
|
27
|
+
import {
|
|
28
|
+
HeadWithDefaults,
|
|
29
|
+
HeaderWithDefaults,
|
|
30
|
+
FooterWithDefaults,
|
|
31
|
+
BodyEndIslandsStub,
|
|
32
|
+
composeMetaTitle,
|
|
33
|
+
} from "./_chrome.js";
|
|
34
|
+
|
|
35
|
+
export const frontmatter = { title: "Home" };
|
|
36
|
+
|
|
37
|
+
export default function IndexPage(): JSX.Element {
|
|
38
|
+
const locale = defaultLocale;
|
|
39
|
+
|
|
40
|
+
const { navDocs, categoryMeta } = resolveNavSource(locale, undefined);
|
|
41
|
+
const tree = buildNavTree(
|
|
42
|
+
navDocs,
|
|
43
|
+
locale,
|
|
44
|
+
categoryMeta as Map<string, CategoryMeta>,
|
|
45
|
+
(slug, loc) => docsUrl(slug, loc),
|
|
46
|
+
);
|
|
47
|
+
const categoryOrder = getCategoryOrder();
|
|
48
|
+
const groupedTree = groupSatelliteNodes(tree, categoryOrder);
|
|
49
|
+
|
|
50
|
+
const tagCount = collectTags(
|
|
51
|
+
navDocs.filter((d) => !d.data.category_no_page),
|
|
52
|
+
(id, data) => data.slug ?? toRouteSlug(id),
|
|
53
|
+
).size;
|
|
54
|
+
|
|
55
|
+
const ctaNav = settings.headerNav[0] ?? null;
|
|
56
|
+
const overview = ctaNav ? withBase(ctaNav.path) : null;
|
|
57
|
+
const logoUrl = withBase("/img/logo.svg");
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<DocLayoutWithDefaults
|
|
61
|
+
title={composeMetaTitle(settings.siteName)}
|
|
62
|
+
head={<HeadWithDefaults title={settings.siteName} />}
|
|
63
|
+
lang={locale}
|
|
64
|
+
noindex={settings.noindex}
|
|
65
|
+
hideSidebar={true}
|
|
66
|
+
hideToc={true}
|
|
67
|
+
sidebarOverride={<></>}
|
|
68
|
+
headerOverride={<HeaderWithDefaults lang={locale} currentPath={withBase("/")} />}
|
|
69
|
+
footerOverride={<FooterWithDefaults lang={locale} />}
|
|
70
|
+
bodyEndComponents={<BodyEndIslandsStub basePath={settings.base ?? "/"} />}
|
|
71
|
+
enableClientRouter={settings.dynamicPageTransition}
|
|
72
|
+
>
|
|
73
|
+
<div class="flex justify-center mb-vsp-xl">
|
|
74
|
+
<div class="flex flex-col items-center text-center gap-hsp-md lg:flex-row lg:text-left lg:gap-hsp-xl">
|
|
75
|
+
<div
|
|
76
|
+
class="w-[320px] max-w-full aspect-[1200/630] bg-fg shrink-0"
|
|
77
|
+
style={{
|
|
78
|
+
WebkitMask: `url(${logoUrl}) center/contain no-repeat`,
|
|
79
|
+
mask: `url(${logoUrl}) center/contain no-repeat`,
|
|
80
|
+
}}
|
|
81
|
+
aria-hidden="true"
|
|
82
|
+
/>
|
|
83
|
+
<div>
|
|
84
|
+
<h1 class="text-heading font-bold mb-vsp-2xs">{settings.siteName}</h1>
|
|
85
|
+
<p class="text-muted text-small mb-vsp-sm">{settings.siteDescription}</p>
|
|
86
|
+
<div class="flex items-center justify-center lg:justify-start gap-hsp-md text-small">
|
|
87
|
+
{overview && (
|
|
88
|
+
<>
|
|
89
|
+
<a href={overview} class="text-fg underline hover:text-accent">
|
|
90
|
+
{t("nav.overview", locale)}
|
|
91
|
+
</a>
|
|
92
|
+
<span class="text-muted">/</span>
|
|
93
|
+
</>
|
|
94
|
+
)}
|
|
95
|
+
{settings.githubUrl && (
|
|
96
|
+
<>
|
|
97
|
+
<a
|
|
98
|
+
href={settings.githubUrl as string}
|
|
99
|
+
class="inline-flex items-center gap-[0.3em] text-fg underline hover:text-accent"
|
|
100
|
+
target="_blank"
|
|
101
|
+
rel="noopener noreferrer"
|
|
102
|
+
>
|
|
103
|
+
GitHub
|
|
104
|
+
</a>
|
|
105
|
+
<span class="text-muted">/</span>
|
|
106
|
+
</>
|
|
107
|
+
)}
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
{Island({
|
|
114
|
+
when: "idle",
|
|
115
|
+
children: (
|
|
116
|
+
<SiteTreeNav
|
|
117
|
+
tree={groupedTree as unknown as SidebarNavNode[]}
|
|
118
|
+
categoryOrder={categoryOrder}
|
|
119
|
+
categoryIgnore={["inbox", "develop"]}
|
|
120
|
+
/>
|
|
121
|
+
),
|
|
122
|
+
}) as unknown as VNode}
|
|
123
|
+
|
|
124
|
+
{settings.docTags && tagCount > 0 && (
|
|
125
|
+
<section class="mt-vsp-xl">
|
|
126
|
+
<h2 class="text-title font-bold mb-vsp-md">{t("doc.allTags", locale)}</h2>
|
|
127
|
+
<a href={withBase("/docs/tags")} class="text-accent underline hover:text-accent-hover">
|
|
128
|
+
{t("doc.allTags", locale)}
|
|
129
|
+
</a>
|
|
130
|
+
</section>
|
|
131
|
+
)}
|
|
132
|
+
</DocLayoutWithDefaults>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
// Package route entrypoint: /[locale]/docs/[[...slug]] — package-owned
|
|
4
|
+
// equivalent of pages/[locale]/docs/[[...slug]].tsx (A1 #2361).
|
|
5
|
+
//
|
|
6
|
+
// Non-default-locale catch-all docs route. The dynamic `[locale]` pattern is
|
|
7
|
+
// injected ONCE; `paths()` enumerates one route per (non-default locale, slug)
|
|
8
|
+
// with the locale-first + base-EN-fallback merge — reconstructed via `_context`.
|
|
9
|
+
|
|
10
|
+
import type { JSX } from "preact";
|
|
11
|
+
import type { DocPageEntryProps, DocPageAutoIndexProps } from "@takazudo/zudo-doc/doc-page-props";
|
|
12
|
+
import { settings, getLocaleConfig, resolveNavSource, buildDocRouteEntries } from "./_context.js";
|
|
13
|
+
import { renderDocPage } from "./_chrome.js";
|
|
14
|
+
|
|
15
|
+
export const frontmatter = { title: "Docs" };
|
|
16
|
+
|
|
17
|
+
interface LocaleDocPageExtra {
|
|
18
|
+
contentDir: string;
|
|
19
|
+
isFallback: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type DocPageProps =
|
|
23
|
+
| (DocPageEntryProps & LocaleDocPageExtra)
|
|
24
|
+
| (DocPageAutoIndexProps & LocaleDocPageExtra);
|
|
25
|
+
|
|
26
|
+
export function paths(): Array<{
|
|
27
|
+
params: { locale: string; slug: string[] };
|
|
28
|
+
props: DocPageProps;
|
|
29
|
+
}> {
|
|
30
|
+
const result: Array<{
|
|
31
|
+
params: { locale: string; slug: string[] };
|
|
32
|
+
props: DocPageProps;
|
|
33
|
+
}> = [];
|
|
34
|
+
|
|
35
|
+
for (const locale of Object.keys(settings.locales)) {
|
|
36
|
+
const contentDir = getLocaleConfig(locale)?.dir ?? settings.docsDir;
|
|
37
|
+
const source = resolveNavSource(locale, undefined, {
|
|
38
|
+
applyDefaultLocaleOnlyFilter: true,
|
|
39
|
+
keepUnlisted: true,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
for (const item of buildDocRouteEntries({
|
|
43
|
+
source,
|
|
44
|
+
locale,
|
|
45
|
+
routeSig: `locale-docs;${locale}`,
|
|
46
|
+
})) {
|
|
47
|
+
const extra: LocaleDocPageExtra = {
|
|
48
|
+
contentDir: item.isFallback ? settings.docsDir : contentDir,
|
|
49
|
+
isFallback: item.isFallback,
|
|
50
|
+
};
|
|
51
|
+
result.push({
|
|
52
|
+
params: { locale, slug: item.slugParams },
|
|
53
|
+
props: { ...(item.props as DocPageProps), ...extra },
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
type PageArgs = DocPageProps & { params: { locale: string; slug: string[] } };
|
|
62
|
+
|
|
63
|
+
export default function LocaleDocsPage(props: PageArgs): JSX.Element {
|
|
64
|
+
return renderDocPage(props, {
|
|
65
|
+
locale: props.params.locale,
|
|
66
|
+
isFallback: props.isFallback,
|
|
67
|
+
docHistoryContentDir: props.contentDir,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
// Package route entrypoint: /[locale]/docs/tags — package-owned equivalent of
|
|
4
|
+
// pages/[locale]/docs/tags/index.tsx (A1 #2361). One route per non-default
|
|
5
|
+
// locale; the tag map is computed at render time (locale-first + base merge).
|
|
6
|
+
|
|
7
|
+
import type { JSX } from "preact";
|
|
8
|
+
import { settings } from "./_context.js";
|
|
9
|
+
import { TagsIndexPageView } from "./_chrome.js";
|
|
10
|
+
|
|
11
|
+
export const frontmatter = { title: "All Tags" };
|
|
12
|
+
|
|
13
|
+
export function paths(): Array<{ params: { locale: string } }> {
|
|
14
|
+
return Object.keys(settings.locales).map((locale) => ({ params: { locale } }));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface PageProps {
|
|
18
|
+
params: { locale: string };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default function LocaleTagsIndexPage({ params }: PageProps): JSX.Element {
|
|
22
|
+
return <TagsIndexPageView locale={params.locale} />;
|
|
23
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
// Package route entrypoint: /[locale]/docs/tags/[tag] — package-owned
|
|
4
|
+
// equivalent of pages/[locale]/docs/tags/[tag].tsx (A1 #2361). One route per
|
|
5
|
+
// (non-default locale, tag) pair.
|
|
6
|
+
|
|
7
|
+
import type { JSX } from "preact";
|
|
8
|
+
import type { TagInfo } from "@takazudo/zudo-doc/tag-pages";
|
|
9
|
+
import { settings } from "./_context.js";
|
|
10
|
+
import { collectTagMapForLocale, TagDetailPageView } from "./_chrome.js";
|
|
11
|
+
|
|
12
|
+
export const frontmatter = { title: "Tag" };
|
|
13
|
+
|
|
14
|
+
export function paths(): Array<{
|
|
15
|
+
params: { locale: string; tag: string };
|
|
16
|
+
props: { tagInfo: TagInfo };
|
|
17
|
+
}> {
|
|
18
|
+
const result: Array<{
|
|
19
|
+
params: { locale: string; tag: string };
|
|
20
|
+
props: { tagInfo: TagInfo };
|
|
21
|
+
}> = [];
|
|
22
|
+
|
|
23
|
+
for (const locale of Object.keys(settings.locales)) {
|
|
24
|
+
const tagMap = collectTagMapForLocale(locale);
|
|
25
|
+
for (const [tag, tagInfo] of tagMap.entries()) {
|
|
26
|
+
result.push({ params: { locale, tag }, props: { tagInfo } });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface PageProps {
|
|
33
|
+
params: { locale: string; tag: string };
|
|
34
|
+
tagInfo: TagInfo;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default function LocaleDocTagPage({ params, tagInfo }: PageProps): JSX.Element {
|
|
38
|
+
return <TagDetailPageView locale={params.locale} tag={params.tag} tagInfo={tagInfo} />;
|
|
39
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
// Package route entrypoint: /[locale]/docs/versions — package-owned equivalent
|
|
4
|
+
// of pages/[locale]/docs/versions.tsx (A1 #2361). One route per non-default
|
|
5
|
+
// locale; rendered by the shared package `VersionsPageView`.
|
|
6
|
+
|
|
7
|
+
import type { JSX } from "preact";
|
|
8
|
+
import { settings } from "./_context.js";
|
|
9
|
+
import { VersionsPageView } from "./_chrome.js";
|
|
10
|
+
|
|
11
|
+
export const frontmatter = { title: "Versions" };
|
|
12
|
+
|
|
13
|
+
export function paths(): Array<{ params: { locale: string } }> {
|
|
14
|
+
return Object.keys(settings.locales).map((locale) => ({ params: { locale } }));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface PageProps {
|
|
18
|
+
params: { locale: string };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default function LocaleVersionsPage({ params }: PageProps): JSX.Element {
|
|
22
|
+
return <VersionsPageView locale={params.locale} />;
|
|
23
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
// Package route entrypoint: /[locale] — package-owned equivalent of
|
|
4
|
+
// pages/[locale]/index.tsx (A1 #2361). One route per non-default locale; the
|
|
5
|
+
// locale-prefixed site index (site-map grid + optional tag count).
|
|
6
|
+
|
|
7
|
+
import type { JSX, VNode } from "preact";
|
|
8
|
+
import { Island } from "@takazudo/zfb";
|
|
9
|
+
import { DocLayoutWithDefaults } from "@takazudo/zudo-doc/doclayout";
|
|
10
|
+
import { SiteTreeNav } from "@takazudo/zudo-doc/site-tree-nav-island";
|
|
11
|
+
import type { SidebarNavNode } from "@takazudo/zudo-doc/sidebar";
|
|
12
|
+
import { loadCategoryMeta } from "@takazudo/zudo-doc/sidebar-tree";
|
|
13
|
+
import {
|
|
14
|
+
settings,
|
|
15
|
+
getLocaleConfig,
|
|
16
|
+
t,
|
|
17
|
+
withBase,
|
|
18
|
+
resolveNavSource,
|
|
19
|
+
buildNavTree,
|
|
20
|
+
groupSatelliteNodes,
|
|
21
|
+
getCategoryOrder,
|
|
22
|
+
collectTags,
|
|
23
|
+
docsUrl,
|
|
24
|
+
toRouteSlug,
|
|
25
|
+
} from "./_context.js";
|
|
26
|
+
import type { CategoryMeta } from "./_docs-helpers.js";
|
|
27
|
+
import {
|
|
28
|
+
HeadWithDefaults,
|
|
29
|
+
HeaderWithDefaults,
|
|
30
|
+
FooterWithDefaults,
|
|
31
|
+
BodyEndIslandsStub,
|
|
32
|
+
composeMetaTitle,
|
|
33
|
+
} from "./_chrome.js";
|
|
34
|
+
|
|
35
|
+
export const frontmatter = { title: "Home" };
|
|
36
|
+
|
|
37
|
+
export function paths(): Array<{ params: { locale: string }; props: { locale: string } }> {
|
|
38
|
+
return Object.keys(settings.locales).map((locale) => ({
|
|
39
|
+
params: { locale },
|
|
40
|
+
props: { locale },
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface PageArgs {
|
|
45
|
+
params: { locale: string };
|
|
46
|
+
props: { locale: string };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export default function LocaleIndexPage({ params }: PageArgs): JSX.Element {
|
|
50
|
+
const locale = params.locale;
|
|
51
|
+
const cfg = getLocaleConfig(locale);
|
|
52
|
+
if (!cfg) {
|
|
53
|
+
throw new Error(`LocaleIndexPage: locale "${locale}" is not configured in settings.locales`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const { navDocs } = resolveNavSource(locale, undefined, {
|
|
57
|
+
applyDefaultLocaleOnlyFilter: true,
|
|
58
|
+
keepUnlisted: true,
|
|
59
|
+
});
|
|
60
|
+
const categoryMeta = loadCategoryMeta(cfg.dir) as Map<string, CategoryMeta>;
|
|
61
|
+
|
|
62
|
+
const tree = buildNavTree(navDocs, locale, categoryMeta, (slug, loc) => docsUrl(slug, loc));
|
|
63
|
+
const categoryOrder = getCategoryOrder();
|
|
64
|
+
const groupedTree = groupSatelliteNodes(tree, categoryOrder);
|
|
65
|
+
|
|
66
|
+
const tagCount = collectTags(
|
|
67
|
+
navDocs.filter((d) => !d.data.category_no_page),
|
|
68
|
+
(id, data) => data.slug ?? toRouteSlug(id),
|
|
69
|
+
).size;
|
|
70
|
+
|
|
71
|
+
const ctaNav = settings.headerNav[0] ?? null;
|
|
72
|
+
const overview = ctaNav ? withBase(`/${locale}${ctaNav.path}`) : null;
|
|
73
|
+
const logoUrl = withBase("/img/logo.svg");
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<DocLayoutWithDefaults
|
|
77
|
+
title={composeMetaTitle(settings.siteName)}
|
|
78
|
+
head={<HeadWithDefaults title={settings.siteName} />}
|
|
79
|
+
lang={locale}
|
|
80
|
+
noindex={settings.noindex}
|
|
81
|
+
hideSidebar={true}
|
|
82
|
+
hideToc={true}
|
|
83
|
+
sidebarOverride={<></>}
|
|
84
|
+
headerOverride={<HeaderWithDefaults lang={locale} currentPath={withBase(`/${locale}/`)} />}
|
|
85
|
+
footerOverride={<FooterWithDefaults lang={locale} />}
|
|
86
|
+
bodyEndComponents={<BodyEndIslandsStub basePath={settings.base ?? "/"} />}
|
|
87
|
+
enableClientRouter={settings.dynamicPageTransition}
|
|
88
|
+
>
|
|
89
|
+
<div class="flex justify-center mb-vsp-xl">
|
|
90
|
+
<div class="flex flex-col items-center text-center gap-hsp-md lg:flex-row lg:text-left lg:gap-hsp-xl">
|
|
91
|
+
<div
|
|
92
|
+
class="w-[320px] max-w-full aspect-[1200/630] bg-fg shrink-0"
|
|
93
|
+
style={{
|
|
94
|
+
WebkitMask: `url(${logoUrl}) center/contain no-repeat`,
|
|
95
|
+
mask: `url(${logoUrl}) center/contain no-repeat`,
|
|
96
|
+
}}
|
|
97
|
+
aria-hidden="true"
|
|
98
|
+
/>
|
|
99
|
+
<div>
|
|
100
|
+
<h1 class="text-heading font-bold mb-vsp-2xs">{settings.siteName}</h1>
|
|
101
|
+
<p class="text-muted text-small mb-vsp-sm">{settings.siteDescription}</p>
|
|
102
|
+
<div class="flex items-center justify-center lg:justify-start gap-hsp-md text-small">
|
|
103
|
+
{overview && (
|
|
104
|
+
<>
|
|
105
|
+
<a href={overview} class="text-fg underline hover:text-accent">
|
|
106
|
+
{t("nav.overview", locale)}
|
|
107
|
+
</a>
|
|
108
|
+
<span class="text-muted">/</span>
|
|
109
|
+
</>
|
|
110
|
+
)}
|
|
111
|
+
{settings.githubUrl && (
|
|
112
|
+
<a
|
|
113
|
+
href={settings.githubUrl as string}
|
|
114
|
+
class="inline-flex items-center gap-[0.3em] text-fg underline hover:text-accent"
|
|
115
|
+
target="_blank"
|
|
116
|
+
rel="noopener noreferrer"
|
|
117
|
+
>
|
|
118
|
+
GitHub
|
|
119
|
+
</a>
|
|
120
|
+
)}
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
{Island({
|
|
127
|
+
when: "idle",
|
|
128
|
+
children: (
|
|
129
|
+
<SiteTreeNav
|
|
130
|
+
tree={groupedTree as unknown as SidebarNavNode[]}
|
|
131
|
+
categoryOrder={categoryOrder}
|
|
132
|
+
categoryIgnore={["inbox", "develop"]}
|
|
133
|
+
/>
|
|
134
|
+
),
|
|
135
|
+
}) as unknown as VNode}
|
|
136
|
+
|
|
137
|
+
{settings.docTags && tagCount > 0 && (
|
|
138
|
+
<section class="mt-vsp-xl">
|
|
139
|
+
<h2 class="text-title font-bold mb-vsp-md">{t("doc.allTags", locale)}</h2>
|
|
140
|
+
<a
|
|
141
|
+
href={withBase(`/${locale}/docs/tags`)}
|
|
142
|
+
class="text-accent underline hover:text-accent-hover"
|
|
143
|
+
>
|
|
144
|
+
{t("doc.allTags", locale)}
|
|
145
|
+
</a>
|
|
146
|
+
</section>
|
|
147
|
+
)}
|
|
148
|
+
</DocLayoutWithDefaults>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Package route entrypoint: /robots.txt — package-owned equivalent of
|
|
2
|
+
// pages/robots.txt.tsx (epic Package-First Finale #2356, A1 #2361).
|
|
3
|
+
//
|
|
4
|
+
// Reads `settings` from the route-context virtual module via `_context` and
|
|
5
|
+
// renders through the package `renderRobots` (`@takazudo/zudo-doc/robots`).
|
|
6
|
+
// Dormant unless `settings.packageOwnedRoutes` is on (and even then dropped if
|
|
7
|
+
// the user's `pages/robots.txt.tsx` stub is present — Decision 6).
|
|
8
|
+
|
|
9
|
+
import { renderRobots } from "@takazudo/zudo-doc/robots";
|
|
10
|
+
import { settings } from "./_context.js";
|
|
11
|
+
|
|
12
|
+
export const contentType = "text/plain";
|
|
13
|
+
export default () => renderRobots(settings);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Package route entrypoint: /sitemap.xml — package-owned equivalent of
|
|
2
|
+
// pages/sitemap.xml.tsx (epic Package-First Finale #2356, A1 #2361).
|
|
3
|
+
//
|
|
4
|
+
// URL enumeration is delegated to `enumerateAllRoutes` (reconstructed in
|
|
5
|
+
// `_context` from `@takazudo/zudo-doc/route-enumerators`) so the sitemap cannot
|
|
6
|
+
// drift from the actual routes the page entrypoints build. Dormant unless
|
|
7
|
+
// `settings.packageOwnedRoutes` is on (Decision 6 precedence still applies).
|
|
8
|
+
|
|
9
|
+
import { settings, enumerateAllRoutes } from "./_context.js";
|
|
10
|
+
|
|
11
|
+
export const frontmatter = { title: "Sitemap" };
|
|
12
|
+
export const contentType = "application/xml";
|
|
13
|
+
|
|
14
|
+
function escapeXml(str: string): string {
|
|
15
|
+
return str
|
|
16
|
+
.replace(/&/g, "&")
|
|
17
|
+
.replace(/</g, "<")
|
|
18
|
+
.replace(/>/g, ">")
|
|
19
|
+
.replace(/"/g, """)
|
|
20
|
+
.replace(/'/g, "'");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default function Sitemap(): string {
|
|
24
|
+
if (!settings.sitemap) {
|
|
25
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
26
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
27
|
+
</urlset>`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const routeMap = enumerateAllRoutes();
|
|
31
|
+
const siteUrlBase = (settings.siteUrl ?? "").replace(/\/$/, "");
|
|
32
|
+
|
|
33
|
+
const urlEntries = [...routeMap.entries()]
|
|
34
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
35
|
+
.map(
|
|
36
|
+
([url, lastmod]) => ` <url>
|
|
37
|
+
<loc>${escapeXml(siteUrlBase + url)}</loc>
|
|
38
|
+
<lastmod>${lastmod}</lastmod>
|
|
39
|
+
</url>`,
|
|
40
|
+
)
|
|
41
|
+
.join("\n");
|
|
42
|
+
|
|
43
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
44
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
45
|
+
${urlEntries}
|
|
46
|
+
</urlset>
|
|
47
|
+
`;
|
|
48
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
// Package route entrypoint: /v/[version]/docs/[[...slug]] — package-owned
|
|
4
|
+
// equivalent of pages/v/[version]/docs/[[...slug]].tsx (A1 #2361).
|
|
5
|
+
//
|
|
6
|
+
// Versioned EN docs route. The dynamic `[version]` pattern is injected ONCE;
|
|
7
|
+
// `paths()` enumerates one route per (version, slug) over the
|
|
8
|
+
// `docs-v-${version.slug}` collection, with versioned URL closures.
|
|
9
|
+
|
|
10
|
+
import type { JSX } from "preact";
|
|
11
|
+
import type { VersionConfig } from "@takazudo/zudo-doc/settings";
|
|
12
|
+
import type { DocPageEntryProps, DocPageAutoIndexProps } from "@takazudo/zudo-doc/doc-page-props";
|
|
13
|
+
import { settings, resolveNavSource, versionedDocsUrl, buildDocRouteEntries } from "./_context.js";
|
|
14
|
+
import { renderDocPage } from "./_chrome.js";
|
|
15
|
+
|
|
16
|
+
export const frontmatter = { title: "Docs" };
|
|
17
|
+
|
|
18
|
+
interface VersionedDocPageExtra {
|
|
19
|
+
version: VersionConfig;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type DocPageProps =
|
|
23
|
+
| (DocPageEntryProps & VersionedDocPageExtra)
|
|
24
|
+
| (DocPageAutoIndexProps & VersionedDocPageExtra);
|
|
25
|
+
|
|
26
|
+
export function paths(): Array<{
|
|
27
|
+
params: { version: string; slug: string[] };
|
|
28
|
+
props: DocPageProps;
|
|
29
|
+
}> {
|
|
30
|
+
if (!settings.versions) return [];
|
|
31
|
+
|
|
32
|
+
const result: Array<{
|
|
33
|
+
params: { version: string; slug: string[] };
|
|
34
|
+
props: DocPageProps;
|
|
35
|
+
}> = [];
|
|
36
|
+
|
|
37
|
+
for (const version of settings.versions) {
|
|
38
|
+
const source = resolveNavSource(settings.defaultLocale, version.slug);
|
|
39
|
+
const urlFor = (s: string): string => versionedDocsUrl(s, version.slug);
|
|
40
|
+
|
|
41
|
+
for (const item of buildDocRouteEntries({
|
|
42
|
+
source,
|
|
43
|
+
locale: settings.defaultLocale,
|
|
44
|
+
routeSig: `v-docs;${version.slug}`,
|
|
45
|
+
urlFor,
|
|
46
|
+
})) {
|
|
47
|
+
result.push({
|
|
48
|
+
params: { version: version.slug, slug: item.slugParams },
|
|
49
|
+
props: { ...(item.props as DocPageProps), version },
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
type PageArgs = DocPageProps & { params: { version: string; slug: string[] } };
|
|
58
|
+
|
|
59
|
+
export default function VersionedDocsPage(props: PageArgs): JSX.Element {
|
|
60
|
+
return renderDocPage(props, {
|
|
61
|
+
locale: settings.defaultLocale,
|
|
62
|
+
version: props.version,
|
|
63
|
+
});
|
|
64
|
+
}
|