@takazudo/zudo-doc 1.0.2 → 1.2.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.
- package/dist/doc-body-end-islands/index.d.ts +32 -0
- package/dist/doc-body-end-islands/index.js +40 -0
- package/dist/doc-page-renderer/index.js +5 -2
- package/dist/eject/index.js +24 -0
- package/dist/nav-indexing/doc-card-grid.js +1 -1
- package/dist/nav-indexing/nav-card-grid.js +1 -1
- package/dist/plugins/routes.js +3 -1
- package/dist/preset.d.ts +28 -8
- package/dist/preset.js +37 -9
- package/dist/routes/404.js +2 -2
- package/dist/routes/_chrome.d.ts +9 -9
- package/dist/routes/_chrome.js +53 -12
- package/dist/routes/_context.d.ts +5 -0
- package/dist/routes/_context.js +2 -0
- package/dist/routes/index.js +2 -2
- package/dist/routes/locale-index.js +2 -2
- package/dist/safelist.css +1 -1
- package/dist/settings.d.ts +12 -10
- package/eject/desktop-sidebar-toggle-island/index.tsx +105 -0
- package/eject/doc-history/index.tsx +649 -0
- package/eject/image-enlarge/index.tsx +219 -0
- package/eject/sidebar-toggle-island/index.tsx +165 -0
- package/eject/sidebar-tree-island/index.tsx +589 -0
- package/eject/site-tree-nav-island/index.tsx +222 -0
- package/package.json +10 -6
- package/routes-src/404.tsx +2 -2
- package/routes-src/_chrome.tsx +105 -17
- package/routes-src/_context.ts +5 -0
- package/routes-src/_virtual.d.ts +6 -2
- package/routes-src/index.tsx +2 -2
- package/routes-src/locale-index.tsx +2 -2
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
import type { JSX } from "preact";
|
|
4
|
+
/** The `settings` subset this factory reads — the three package-island flags.
|
|
5
|
+
* A structural subset so the host can pass its full `Settings` object. */
|
|
6
|
+
export interface BodyEndIslandsSettings {
|
|
7
|
+
aiAssistant: boolean;
|
|
8
|
+
imageEnlarge: boolean;
|
|
9
|
+
mermaid: boolean;
|
|
10
|
+
}
|
|
11
|
+
/** Dependencies injected by `_chrome.tsx` (carries the virtual-module settings). */
|
|
12
|
+
export interface BodyEndIslandsDeps {
|
|
13
|
+
settings: BodyEndIslandsSettings;
|
|
14
|
+
}
|
|
15
|
+
/** Props for the produced `BodyEndIslands` component. */
|
|
16
|
+
export interface BodyEndIslandsProps {
|
|
17
|
+
/** Base path the AI chat modal uses to construct API URLs. */
|
|
18
|
+
basePath: string;
|
|
19
|
+
/**
|
|
20
|
+
* Sr-only label rendered as the AiChatModal SSR fallback. Defaults to the
|
|
21
|
+
* English string; pass a locale-translated string for non-default locales so
|
|
22
|
+
* screen readers announce the chat entrypoint correctly before hydration.
|
|
23
|
+
*/
|
|
24
|
+
aiChatBodyLabel?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build the package-default `BodyEndIslands` component bound to the host's
|
|
28
|
+
* serializable `settings` flags. The produced component matches the
|
|
29
|
+
* `createDocBodyEnd` `BodyEndIslands` slot contract
|
|
30
|
+
* (`(props: { basePath: string }) => JSX.Element`).
|
|
31
|
+
*/
|
|
32
|
+
export declare function createBodyEndIslands(deps: BodyEndIslandsDeps): (props: BodyEndIslandsProps) => JSX.Element;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
2
|
+
import { Island } from "@takazudo/zfb";
|
|
3
|
+
import { AiChatModal } from "../ai-chat-modal/index.js";
|
|
4
|
+
import { ImageEnlarge, ImageEnlargeSsrFallback } from "../image-enlarge/index.js";
|
|
5
|
+
import { MermaidEnlarge, MermaidEnlargeSsrFallback } from "../mermaid-enlarge/index.js";
|
|
6
|
+
const DEFAULT_AI_CHAT_BODY_LABEL = "Ask a question about the documentation.";
|
|
7
|
+
function createBodyEndIslands(deps) {
|
|
8
|
+
const { settings } = deps;
|
|
9
|
+
function BodyEndIslands({
|
|
10
|
+
basePath,
|
|
11
|
+
aiChatBodyLabel = DEFAULT_AI_CHAT_BODY_LABEL
|
|
12
|
+
}) {
|
|
13
|
+
const aiAssistant = settings.aiAssistant ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14
|
+
/* @__PURE__ */ jsx("h2", { class: "sr-only", children: "AI Assistant" }),
|
|
15
|
+
Island({
|
|
16
|
+
ssrFallback: /* @__PURE__ */ jsx("p", { class: "sr-only", children: aiChatBodyLabel }),
|
|
17
|
+
children: /* @__PURE__ */ jsx(AiChatModal, { basePath })
|
|
18
|
+
})
|
|
19
|
+
] }) : null;
|
|
20
|
+
const imageEnlarge = settings.imageEnlarge ? Island({
|
|
21
|
+
when: "idle",
|
|
22
|
+
ssrFallback: /* @__PURE__ */ jsx(ImageEnlargeSsrFallback, {}),
|
|
23
|
+
children: /* @__PURE__ */ jsx(ImageEnlarge, {})
|
|
24
|
+
}) : null;
|
|
25
|
+
const mermaidEnlarge = settings.mermaid ? Island({
|
|
26
|
+
when: "idle",
|
|
27
|
+
ssrFallback: /* @__PURE__ */ jsx(MermaidEnlargeSsrFallback, {}),
|
|
28
|
+
children: /* @__PURE__ */ jsx(MermaidEnlarge, {})
|
|
29
|
+
}) : null;
|
|
30
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31
|
+
aiAssistant,
|
|
32
|
+
imageEnlarge,
|
|
33
|
+
mermaidEnlarge
|
|
34
|
+
] });
|
|
35
|
+
}
|
|
36
|
+
return BodyEndIslands;
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
createBodyEndIslands
|
|
40
|
+
};
|
|
@@ -34,7 +34,10 @@ function createRenderDocPage(deps) {
|
|
|
34
34
|
const currentPath = version ? versionedDocsUrl(slug, version.slug, locale) : docsUrl(slug, locale);
|
|
35
35
|
const canonical = absoluteUrl(currentPath);
|
|
36
36
|
const navSection = getNavSectionForSlug(slug);
|
|
37
|
-
const
|
|
37
|
+
const entryData = props.kind === "entry" ? props.entry.data : void 0;
|
|
38
|
+
const standalone = entryData?.standalone;
|
|
39
|
+
const hideSidebar = entryData ? entryData.hide_sidebar || standalone : void 0;
|
|
40
|
+
const hideToc = entryData ? entryData.hide_toc || standalone : void 0;
|
|
38
41
|
const sidebarPersistKey = hideSidebar ? void 0 : `sidebar-${locale}-${navSection ?? "default"}`;
|
|
39
42
|
const ContentComponent = props.kind === "entry" ? props.entry.Content : null;
|
|
40
43
|
return /* @__PURE__ */ jsx(
|
|
@@ -53,7 +56,7 @@ function createRenderDocPage(deps) {
|
|
|
53
56
|
navSection,
|
|
54
57
|
sidebarPersistKey,
|
|
55
58
|
hideSidebar,
|
|
56
|
-
hideToc
|
|
59
|
+
hideToc,
|
|
57
60
|
currentPath,
|
|
58
61
|
currentVersion: version?.slug,
|
|
59
62
|
versionSwitcher: buildInlineVersionSwitcher(slug, locale, version?.slug),
|
package/dist/eject/index.js
CHANGED
|
@@ -49,6 +49,30 @@ const EJECTABLE = {
|
|
|
49
49
|
details: {
|
|
50
50
|
packageSubpath: "@takazudo/zudo-doc/details",
|
|
51
51
|
localDir: "src/components/zudo-doc/details"
|
|
52
|
+
},
|
|
53
|
+
"sidebar-tree-island": {
|
|
54
|
+
packageSubpath: "@takazudo/zudo-doc/sidebar-tree-island",
|
|
55
|
+
localDir: "src/components/zudo-doc/sidebar-tree-island"
|
|
56
|
+
},
|
|
57
|
+
"sidebar-toggle-island": {
|
|
58
|
+
packageSubpath: "@takazudo/zudo-doc/sidebar-toggle-island",
|
|
59
|
+
localDir: "src/components/zudo-doc/sidebar-toggle-island"
|
|
60
|
+
},
|
|
61
|
+
"desktop-sidebar-toggle-island": {
|
|
62
|
+
packageSubpath: "@takazudo/zudo-doc/desktop-sidebar-toggle-island",
|
|
63
|
+
localDir: "src/components/zudo-doc/desktop-sidebar-toggle-island"
|
|
64
|
+
},
|
|
65
|
+
"image-enlarge": {
|
|
66
|
+
packageSubpath: "@takazudo/zudo-doc/image-enlarge",
|
|
67
|
+
localDir: "src/components/zudo-doc/image-enlarge"
|
|
68
|
+
},
|
|
69
|
+
"doc-history": {
|
|
70
|
+
packageSubpath: "@takazudo/zudo-doc/doc-history",
|
|
71
|
+
localDir: "src/components/zudo-doc/doc-history"
|
|
72
|
+
},
|
|
73
|
+
"site-tree-nav-island": {
|
|
74
|
+
packageSubpath: "@takazudo/zudo-doc/site-tree-nav-island",
|
|
75
|
+
localDir: "src/components/zudo-doc/site-tree-nav-island"
|
|
52
76
|
}
|
|
53
77
|
};
|
|
54
78
|
async function rewireImports(dir) {
|
|
@@ -29,7 +29,7 @@ function DocCardGrid(props) {
|
|
|
29
29
|
/* @__PURE__ */ jsx(ArrowIcon, {}),
|
|
30
30
|
/* @__PURE__ */ jsx("span", { class: "font-medium text-accent group-hover:underline", children: item.title })
|
|
31
31
|
] }),
|
|
32
|
-
item.description && /* @__PURE__ */ jsx("span", { class: "mt-vsp-2xs block text-small text-muted", children: item.description })
|
|
32
|
+
item.description && /* @__PURE__ */ jsx("span", { class: "mt-vsp-2xs block text-small text-muted group-hover:text-accent group-focus-visible:text-accent", children: item.description })
|
|
33
33
|
]
|
|
34
34
|
},
|
|
35
35
|
`doc-card-${i}`
|
|
@@ -32,7 +32,7 @@ function NavCardGrid(props) {
|
|
|
32
32
|
/* @__PURE__ */ jsx(ArrowIcon, {}),
|
|
33
33
|
/* @__PURE__ */ jsx("span", { class: "font-medium text-accent group-hover:underline", children: child.label })
|
|
34
34
|
] }),
|
|
35
|
-
child.description && /* @__PURE__ */ jsx("span", { class: "mt-vsp-2xs block text-small text-muted group-hover:underline decoration-muted", children: child.description })
|
|
35
|
+
child.description && /* @__PURE__ */ jsx("span", { class: "mt-vsp-2xs block text-small text-muted group-hover:text-accent group-hover:underline group-focus-visible:text-accent decoration-muted", children: child.description })
|
|
36
36
|
]
|
|
37
37
|
},
|
|
38
38
|
`nav-card-${i}`
|
package/dist/plugins/routes.js
CHANGED
|
@@ -48,12 +48,14 @@ const plugin = definePlugin({
|
|
|
48
48
|
const settings = options.settings ?? {};
|
|
49
49
|
const translations = options.translations ?? {};
|
|
50
50
|
const tagVocabulary = options.tagVocabulary ?? [];
|
|
51
|
+
const colorSchemes = options.colorSchemes ?? null;
|
|
51
52
|
ctx.addVirtualModule(
|
|
52
53
|
"virtual:zudo-doc-route-context",
|
|
53
54
|
() => `export const routeContext = ${JSON.stringify({
|
|
54
55
|
settings,
|
|
55
56
|
translations,
|
|
56
|
-
tagVocabulary
|
|
57
|
+
tagVocabulary,
|
|
58
|
+
colorSchemes
|
|
57
59
|
})};
|
|
58
60
|
`
|
|
59
61
|
);
|
package/dist/preset.d.ts
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
* bundles cleanly under `--platform=neutral` (verified: zero `node:*`).
|
|
34
34
|
*/
|
|
35
35
|
import { z } from "zod";
|
|
36
|
+
import type { ColorScheme } from "./color-scheme-utils.js";
|
|
36
37
|
/** A single locale's content directory (`settings.locales[code]`). */
|
|
37
38
|
export interface PresetLocaleConfig {
|
|
38
39
|
dir: string;
|
|
@@ -72,18 +73,23 @@ export interface PresetSettings {
|
|
|
72
73
|
claudeResources?: PresetClaudeResourcesConfig | false;
|
|
73
74
|
/** "owner/repo" — when set, enables `#123` / SHA autolinks in markdown. Omit to disable entirely. */
|
|
74
75
|
githubAutolinksRepo?: string;
|
|
75
|
-
/**
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
76
|
+
/**
|
|
77
|
+
* When `true` (the **default** when omitted — #2404), the preset adds the
|
|
78
|
+
* package-owned route-injection plugin (`@takazudo/zudo-doc/plugins/routes`).
|
|
79
|
+
* Set explicitly to `false` to opt out — only needed for projects shipping
|
|
80
|
+
* their own `pages/*.tsx` stubs for every doc route. When `false` AND doc
|
|
81
|
+
* content is configured (`docsDir` non-empty and/or locales/versions set),
|
|
82
|
+
* a single `console.warn` is emitted per build as a heads-up (the build
|
|
83
|
+
* succeeds). See `docs/adr/route-injection-seam.md`. (#2404)
|
|
84
|
+
*/
|
|
82
85
|
packageOwnedRoutes?: boolean;
|
|
83
86
|
/** Gate for the `/docs/tags` + `/docs/tags/[tag]` injected routes. */
|
|
84
87
|
docTags?: boolean;
|
|
85
88
|
/** Gate for the SSR `/api/ai-chat` injected route (`prerender: false`). */
|
|
86
89
|
aiAssistant?: boolean;
|
|
90
|
+
/** When `false`, disables zfb's CJK-friendly line-break behaviour.
|
|
91
|
+
* Absent means "use the engine default" (currently `true`). */
|
|
92
|
+
cjkFriendly?: boolean;
|
|
87
93
|
}
|
|
88
94
|
/**
|
|
89
95
|
* The directives recipe map (`markdown.features.directives`): directive name →
|
|
@@ -143,6 +149,19 @@ export interface ZudoDocPresetArgs {
|
|
|
143
149
|
* `settings.packageOwnedRoutes` is true. Optional — defaults to `[]`.
|
|
144
150
|
*/
|
|
145
151
|
tagVocabulary?: readonly PresetTagVocabularyEntry[];
|
|
152
|
+
/**
|
|
153
|
+
* The host's color-scheme palette map (`src/config/color-schemes.ts`
|
|
154
|
+
* `colorSchemes`). Only consumed when `settings.packageOwnedRoutes` is true
|
|
155
|
+
* — rides into the route-context virtual module so the package-owned routes
|
|
156
|
+
* (incl. `/404`) can emit the correct `--zd-*` CSS custom properties.
|
|
157
|
+
*
|
|
158
|
+
* Serializable JSON (ColorScheme has no function-valued fields), so it
|
|
159
|
+
* round-trips through `JSON.stringify` losslessly.
|
|
160
|
+
*
|
|
161
|
+
* Optional — when absent, package-owned routes fall back to `DEFAULT_SCHEME`
|
|
162
|
+
* (a neutral grey ramp). See `routes/_chrome.tsx`.
|
|
163
|
+
*/
|
|
164
|
+
colorSchemes?: Record<string, ColorScheme>;
|
|
146
165
|
}
|
|
147
166
|
export interface PresetCollection {
|
|
148
167
|
name: string;
|
|
@@ -163,6 +182,7 @@ export interface PresetResolveMarkdownLinks {
|
|
|
163
182
|
}
|
|
164
183
|
export interface PresetMarkdown {
|
|
165
184
|
features: Record<string, boolean | Record<string, unknown>>;
|
|
185
|
+
cjkFriendly?: boolean;
|
|
166
186
|
}
|
|
167
187
|
export interface PresetCodeHighlight {
|
|
168
188
|
themeLight: string;
|
|
@@ -195,4 +215,4 @@ export interface ZudoDocPresetResult {
|
|
|
195
215
|
* });
|
|
196
216
|
* ```
|
|
197
217
|
*/
|
|
198
|
-
export declare function zudoDocPreset({ settings, buildDocsSchema, directiveVocabulary, translations, tagVocabulary, }: ZudoDocPresetArgs): ZudoDocPresetResult;
|
|
218
|
+
export declare function zudoDocPreset({ settings, buildDocsSchema, directiveVocabulary, translations, tagVocabulary, colorSchemes, }: ZudoDocPresetArgs): ZudoDocPresetResult;
|
package/dist/preset.js
CHANGED
|
@@ -4,13 +4,17 @@ function zudoDocPreset({
|
|
|
4
4
|
buildDocsSchema,
|
|
5
5
|
directiveVocabulary,
|
|
6
6
|
translations,
|
|
7
|
-
tagVocabulary
|
|
7
|
+
tagVocabulary,
|
|
8
|
+
colorSchemes
|
|
8
9
|
}) {
|
|
9
10
|
const docsSchemaJson = z.toJSONSchema(buildDocsSchema());
|
|
10
11
|
return {
|
|
11
12
|
collections: buildCollections(settings, docsSchemaJson),
|
|
12
|
-
plugins: buildPlugins(settings, { translations, tagVocabulary }),
|
|
13
|
-
markdown: {
|
|
13
|
+
plugins: buildPlugins(settings, { translations, tagVocabulary, colorSchemes }),
|
|
14
|
+
markdown: {
|
|
15
|
+
features: buildMarkdownFeatures(settings, directiveVocabulary),
|
|
16
|
+
...settings.cjkFriendly !== void 0 ? { cjkFriendly: settings.cjkFriendly } : {}
|
|
17
|
+
},
|
|
14
18
|
// Dual-theme syntect (zfb >= 0.1.0-next.45). Theme names are SYNTECT
|
|
15
19
|
// built-ins, NOT Shiki names. Tokens emit `--shiki-light`/`--shiki-dark`
|
|
16
20
|
// CSS custom properties resolved by the host CSS via `light-dark()`, so
|
|
@@ -113,18 +117,41 @@ function buildPlugins(settings, routeContext) {
|
|
|
113
117
|
const localeRecord = Object.fromEntries(
|
|
114
118
|
Object.entries(settings.locales).map(([code, locale]) => [code, { dir: locale.dir }])
|
|
115
119
|
);
|
|
120
|
+
const effectivePackageOwnedRoutes = settings.packageOwnedRoutes ?? true;
|
|
121
|
+
if (effectivePackageOwnedRoutes) {
|
|
122
|
+
const contentConfiguredForWarn = typeof settings.docsDir === "string" && settings.docsDir.length > 0 || Object.keys(settings.locales).length > 0 || Array.isArray(settings.versions) && settings.versions.length > 0;
|
|
123
|
+
const translationsMissing = !routeContext.translations || Object.keys(routeContext.translations).length === 0;
|
|
124
|
+
const colorSchemesMissing = !routeContext.colorSchemes;
|
|
125
|
+
if (contentConfiguredForWarn && (translationsMissing || colorSchemesMissing)) {
|
|
126
|
+
const missing = [
|
|
127
|
+
...translationsMissing ? ["translations"] : [],
|
|
128
|
+
...colorSchemesMissing ? ["colorSchemes"] : []
|
|
129
|
+
].join(" and/or ");
|
|
130
|
+
console.warn(
|
|
131
|
+
`zudo-doc: packageOwnedRoutes is on but ${missing} were not passed to zudoDocPreset \u2014 package-owned routes (incl. /404) will render with fallback i18n/theme. Pass them to inherit host bindings.`
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (!effectivePackageOwnedRoutes) {
|
|
136
|
+
const contentConfigured = typeof settings.docsDir === "string" && settings.docsDir.length > 0 || Object.keys(settings.locales).length > 0 || Array.isArray(settings.versions) && settings.versions.length > 0;
|
|
137
|
+
if (contentConfigured) {
|
|
138
|
+
console.warn(
|
|
139
|
+
"zudo-doc: packageOwnedRoutes is off but doc content is configured \u2014 no doc routes will be injected; the build will produce only host pages/. Set packageOwnedRoutes: true in settings."
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
116
143
|
return [
|
|
117
|
-
// Package-owned route injection —
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
//
|
|
144
|
+
// Package-owned route injection — default-on (#2404). The descriptor is a
|
|
145
|
+
// BARE SPECIFIER, never an imported plugin function: the preset's node-free
|
|
146
|
+
// eval-graph guard (preset.test.ts) bundles this module under
|
|
147
|
+
// --platform=neutral, and importing the plugin would drag its
|
|
121
148
|
// `injectRoute`/`node:*` graph into the config eval. The plugin's `setup`
|
|
122
149
|
// hook reads `options` to (a) emit the route-context virtual module
|
|
123
150
|
// (serializable settings/translations/tagVocabulary only) and (b) derive
|
|
124
151
|
// the route catalog from `settings.locales` / `settings.versions`. Listed
|
|
125
152
|
// FIRST so an injected route is registered before the other plugins'
|
|
126
153
|
// preBuild work runs (ordering is cosmetic — injection happens in `setup`).
|
|
127
|
-
...
|
|
154
|
+
...effectivePackageOwnedRoutes ? [
|
|
128
155
|
{
|
|
129
156
|
name: "@takazudo/zudo-doc/plugins/routes",
|
|
130
157
|
options: {
|
|
@@ -133,7 +160,8 @@ function buildPlugins(settings, routeContext) {
|
|
|
133
160
|
// src/config/settings.ts), so it round-trips losslessly.
|
|
134
161
|
settings,
|
|
135
162
|
translations: routeContext.translations ?? {},
|
|
136
|
-
tagVocabulary: routeContext.tagVocabulary ?? []
|
|
163
|
+
tagVocabulary: routeContext.tagVocabulary ?? [],
|
|
164
|
+
colorSchemes: routeContext.colorSchemes ?? null
|
|
137
165
|
}
|
|
138
166
|
}
|
|
139
167
|
] : [],
|
package/dist/routes/404.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
HeadWithDefaults,
|
|
6
6
|
HeaderWithDefaults,
|
|
7
7
|
FooterWithDefaults,
|
|
8
|
-
|
|
8
|
+
BodyEndIslands,
|
|
9
9
|
composeMetaTitle
|
|
10
10
|
} from "./_chrome.js";
|
|
11
11
|
const frontmatter = { title: "404" };
|
|
@@ -24,7 +24,7 @@ function NotFoundPage() {
|
|
|
24
24
|
sidebarOverride: /* @__PURE__ */ jsx(Fragment, {}),
|
|
25
25
|
headerOverride: /* @__PURE__ */ jsx(HeaderWithDefaults, { lang: locale }),
|
|
26
26
|
footerOverride: /* @__PURE__ */ jsx(FooterWithDefaults, { lang: locale }),
|
|
27
|
-
bodyEndComponents: /* @__PURE__ */ jsx(
|
|
27
|
+
bodyEndComponents: /* @__PURE__ */ jsx(BodyEndIslands, { basePath: settings.base ?? "/" }),
|
|
28
28
|
enableClientRouter: settings.dynamicPageTransition,
|
|
29
29
|
children: /* @__PURE__ */ jsxs("div", { class: "min-h-[60vh] flex flex-col items-center justify-center px-hsp-2xl py-vsp-xl", children: [
|
|
30
30
|
/* @__PURE__ */ jsx("h1", { class: "text-display font-bold mb-vsp-md", children: "404" }),
|
package/dist/routes/_chrome.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/** @jsxRuntime automatic */
|
|
2
2
|
/** @jsxImportSource preact */
|
|
3
|
-
import type { JSX, VNode } from "preact";
|
|
3
|
+
import type { JSX, VNode, ComponentChildren } from "preact";
|
|
4
4
|
import type { DocNavNode } from "./_docs-helpers.js";
|
|
5
|
-
/** Package
|
|
6
|
-
*
|
|
7
|
-
* the
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
/** Package-default body-end islands — the package-island subset of the host's
|
|
6
|
+
* `BodyEndIslands` (AiChatModal / ImageEnlarge / MermaidEnlarge), reconstructed
|
|
7
|
+
* from the serializable virtual-module `settings` flags (#2406 / #2401(c)).
|
|
8
|
+
* The host-owned bootstraps (client-router / design-token-panel) cannot live
|
|
9
|
+
* in the package, so they are NOT included here — A2/S4 re-homes those. */
|
|
10
|
+
declare const BodyEndIslands: (props: import("../doc-body-end-islands/index.js").BodyEndIslandsProps) => JSX.Element;
|
|
11
11
|
export declare const composeMetaTitle: (title: string) => string;
|
|
12
12
|
export declare const HeadWithDefaults: (props: import("../head-with-defaults/index.js").HeadWithDefaultsProps) => JSX.Element;
|
|
13
13
|
export declare const HeaderWithDefaults: (props: import("../header-with-defaults/index.js").HeaderWithDefaultsProps) => JSX.Element;
|
|
@@ -25,8 +25,8 @@ export declare const collectTagMapForLocale: (locale: string) => Map<string, imp
|
|
|
25
25
|
tagInfo: import("../tag-pages/index.js").TagInfo;
|
|
26
26
|
}) => JSX.Element, TagsIndexPageView: (props: {
|
|
27
27
|
locale: string;
|
|
28
|
-
children?:
|
|
28
|
+
children?: ComponentChildren;
|
|
29
29
|
}) => JSX.Element;
|
|
30
|
-
export { SiteTreeNavWrapper,
|
|
30
|
+
export { SiteTreeNavWrapper, BodyEndIslands };
|
|
31
31
|
export { buildDocRouteEntries, } from "./_context.js";
|
|
32
32
|
export type { DocNavNode };
|
package/dist/routes/_chrome.js
CHANGED
|
@@ -22,7 +22,8 @@ import {
|
|
|
22
22
|
findNode,
|
|
23
23
|
firstRoutedHref,
|
|
24
24
|
collectTags,
|
|
25
|
-
stableDocs
|
|
25
|
+
stableDocs,
|
|
26
|
+
colorSchemes
|
|
26
27
|
} from "./_context.js";
|
|
27
28
|
import { createComposeMetaTitle } from "../compose-meta-title/index.js";
|
|
28
29
|
import {
|
|
@@ -35,6 +36,7 @@ import { createFooterWithDefaults } from "../footer-with-defaults/index.js";
|
|
|
35
36
|
import { createSidebarWithDefaults } from "../sidebar-with-defaults/index.js";
|
|
36
37
|
import { createSidebarPrepaint } from "../sidebar-prepaint/index.js";
|
|
37
38
|
import { createDocBodyEnd } from "../doc-body-end/index.js";
|
|
39
|
+
import { createBodyEndIslands } from "../doc-body-end-islands/index.js";
|
|
38
40
|
import { createDocPager } from "../doc-pager/index.js";
|
|
39
41
|
import { createDocPageShell } from "../doc-page-shell/index.js";
|
|
40
42
|
import { createDocContentHeader } from "../doc-content-header/index.js";
|
|
@@ -60,6 +62,10 @@ import {
|
|
|
60
62
|
getThemeDefaultMode as getThemeDefaultModeBase
|
|
61
63
|
} from "../nav-data-prep/index.js";
|
|
62
64
|
import { buildSidebarForSection } from "../sidebar-utils/index.js";
|
|
65
|
+
import { Details } from "../details/index.js";
|
|
66
|
+
import {
|
|
67
|
+
HtmlPreviewWrapper
|
|
68
|
+
} from "../html-preview-wrapper/index.js";
|
|
63
69
|
const GREY_RAMP = [
|
|
64
70
|
"#000000",
|
|
65
71
|
"#1a1a1a",
|
|
@@ -88,9 +94,7 @@ const DEFAULT_SCHEME = {
|
|
|
88
94
|
};
|
|
89
95
|
const docHistoryMeta = {};
|
|
90
96
|
const sidebarsConfig = {};
|
|
91
|
-
|
|
92
|
-
return /* @__PURE__ */ jsx(Fragment, {});
|
|
93
|
-
}
|
|
97
|
+
const BodyEndIslands = createBodyEndIslands({ settings });
|
|
94
98
|
function DocHistoryStub(_props) {
|
|
95
99
|
return /* @__PURE__ */ jsx(Fragment, {});
|
|
96
100
|
}
|
|
@@ -98,13 +102,28 @@ function SearchWidgetBound(props) {
|
|
|
98
102
|
return SearchWidget({ ...props, base: withBase("/") });
|
|
99
103
|
}
|
|
100
104
|
const composeMetaTitle = createComposeMetaTitle(settings.siteName);
|
|
105
|
+
function resolveHostScheme(key) {
|
|
106
|
+
if (!colorSchemes) return DEFAULT_SCHEME;
|
|
107
|
+
return colorSchemes[key] ?? DEFAULT_SCHEME;
|
|
108
|
+
}
|
|
101
109
|
const HeadWithDefaults = createHeadWithDefaults({
|
|
102
110
|
settings,
|
|
103
111
|
composeMetaTitle,
|
|
104
112
|
withBase,
|
|
105
113
|
absoluteUrl,
|
|
106
|
-
|
|
107
|
-
|
|
114
|
+
// Called only in single-scheme mode (colorMode false): resolve via settings.colorScheme.
|
|
115
|
+
generateCssCustomProperties: () => generateCssCustomProperties(resolveHostScheme(settings.colorScheme)),
|
|
116
|
+
// Called only in light/dark mode (colorMode truthy): resolve the pair.
|
|
117
|
+
generateLightDarkCssProperties: () => {
|
|
118
|
+
const cm = settings.colorMode;
|
|
119
|
+
if (cm) {
|
|
120
|
+
return generateLightDarkCssProperties(
|
|
121
|
+
resolveHostScheme(cm.lightScheme),
|
|
122
|
+
resolveHostScheme(cm.darkScheme)
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
return generateLightDarkCssProperties(DEFAULT_SCHEME, DEFAULT_SCHEME);
|
|
126
|
+
}
|
|
108
127
|
});
|
|
109
128
|
function buildRootMenuItems(lang, currentVersion) {
|
|
110
129
|
return buildRootMenuItemsBase(
|
|
@@ -189,7 +208,7 @@ const SidebarWithDefaults = createSidebarWithDefaults({
|
|
|
189
208
|
t
|
|
190
209
|
});
|
|
191
210
|
const SidebarPrepaint = createSidebarPrepaint({ sidebarToggle: settings.sidebarToggle });
|
|
192
|
-
const DocBodyEnd = createDocBodyEnd({ settings, BodyEndIslands
|
|
211
|
+
const DocBodyEnd = createDocBodyEnd({ settings, BodyEndIslands });
|
|
193
212
|
const DocPager = createDocPager({ t });
|
|
194
213
|
const DocMetainfoArea = createDocMetainfoArea({
|
|
195
214
|
settings,
|
|
@@ -270,6 +289,15 @@ const SiteTreeNavWrapper = createSiteTreeNavWrapper({
|
|
|
270
289
|
groupSatelliteNodes,
|
|
271
290
|
getCategoryOrder
|
|
272
291
|
});
|
|
292
|
+
function HtmlPreviewBound(props) {
|
|
293
|
+
return HtmlPreviewWrapper({
|
|
294
|
+
globalConfig: settings.htmlPreview ?? null,
|
|
295
|
+
...props
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
function IslandPassthrough(props) {
|
|
299
|
+
return props.children ?? null;
|
|
300
|
+
}
|
|
273
301
|
function createMdxComponentsBound(lang = defaultLocale) {
|
|
274
302
|
return createMdxComponents({
|
|
275
303
|
settings,
|
|
@@ -279,9 +307,22 @@ function createMdxComponentsBound(lang = defaultLocale) {
|
|
|
279
307
|
CategoryTreeNav: CategoryTreeNavWrapper,
|
|
280
308
|
SiteTreeNav: SiteTreeNavWrapper
|
|
281
309
|
},
|
|
282
|
-
//
|
|
283
|
-
// (
|
|
310
|
+
// Package-owned content components wired here so an INJECTED docs route
|
|
311
|
+
// (packageOwnedRoutes, no host `pages/` stub) renders MDX using these tags
|
|
312
|
+
// without the "MDX requires '<X>' to be passed via the 'components' prop"
|
|
313
|
+
// error (sub-issue #2390 / supersedes #2377).
|
|
314
|
+
// - Details → fully functional (pure <details>, no client JS).
|
|
315
|
+
// - HtmlPreview → SSR-renders; see HtmlPreviewBound for the hydration
|
|
316
|
+
// caveat tied to the node_modules islands-scanner gap.
|
|
317
|
+
// - Island → SSR pass-through; see IslandPassthrough.
|
|
318
|
+
// PresetGenerator stays a package stub (render nothing): it is the
|
|
319
|
+
// showcase's project-bound interactive island and downstream projects stub
|
|
320
|
+
// it. The showcase keeps its host-owned docs catch-all routes (allowlisted)
|
|
321
|
+
// so its real PresetGenerator still renders.
|
|
284
322
|
extras: {
|
|
323
|
+
Details,
|
|
324
|
+
HtmlPreview: HtmlPreviewBound,
|
|
325
|
+
Island: IslandPassthrough,
|
|
285
326
|
PresetGenerator: (_props) => null
|
|
286
327
|
}
|
|
287
328
|
});
|
|
@@ -322,7 +363,7 @@ const VersionsPageView = createVersionsPageView({
|
|
|
322
363
|
HeadWithDefaults,
|
|
323
364
|
HeaderWithDefaults,
|
|
324
365
|
FooterWithDefaults,
|
|
325
|
-
BodyEndIslands
|
|
366
|
+
BodyEndIslands
|
|
326
367
|
}
|
|
327
368
|
});
|
|
328
369
|
const tagPages = createTagPages({
|
|
@@ -339,7 +380,7 @@ const tagPages = createTagPages({
|
|
|
339
380
|
HeadWithDefaults,
|
|
340
381
|
HeaderWithDefaults,
|
|
341
382
|
FooterWithDefaults,
|
|
342
|
-
BodyEndIslands
|
|
383
|
+
BodyEndIslands,
|
|
343
384
|
DocHistoryArea
|
|
344
385
|
}
|
|
345
386
|
});
|
|
@@ -348,7 +389,7 @@ import {
|
|
|
348
389
|
buildDocRouteEntries
|
|
349
390
|
} from "./_context.js";
|
|
350
391
|
export {
|
|
351
|
-
|
|
392
|
+
BodyEndIslands,
|
|
352
393
|
FooterWithDefaults,
|
|
353
394
|
HeadWithDefaults,
|
|
354
395
|
HeaderWithDefaults,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Settings } from "../settings.js";
|
|
2
|
+
import type { ColorScheme } from "../color-scheme-utils.js";
|
|
2
3
|
import type { FactoryI18n } from "../factory-context/index.js";
|
|
3
4
|
import { type UrlHelpers } from "../url-helpers/index.js";
|
|
4
5
|
import { toRouteSlug, toSlugParams } from "../slug/index.js";
|
|
@@ -10,10 +11,14 @@ export interface RouteContextPayload {
|
|
|
10
11
|
settings: Settings;
|
|
11
12
|
translations: Record<string, Record<string, string>>;
|
|
12
13
|
tagVocabulary: readonly TagVocabularyEntry[];
|
|
14
|
+
colorSchemes: Record<string, ColorScheme> | null;
|
|
13
15
|
}
|
|
14
16
|
/** The serializable route-context (from the virtual module). */
|
|
15
17
|
export declare const ctx: RouteContextPayload;
|
|
16
18
|
export declare const settings: Settings;
|
|
19
|
+
/** Host color-scheme palette map. `null` when not supplied — `_chrome.tsx`
|
|
20
|
+
* falls back to `DEFAULT_SCHEME` in that case. */
|
|
21
|
+
export declare const colorSchemes: Record<string, ColorScheme> | null;
|
|
17
22
|
export declare const defaultLocale: string;
|
|
18
23
|
export declare const locales: readonly string[];
|
|
19
24
|
export declare function getLocaleConfig(locale: string): {
|
package/dist/routes/_context.js
CHANGED
|
@@ -35,6 +35,7 @@ const ctx = routeContext;
|
|
|
35
35
|
const settings = ctx.settings;
|
|
36
36
|
const translations = ctx.translations;
|
|
37
37
|
const tagVocabulary = ctx.tagVocabulary;
|
|
38
|
+
const colorSchemes = ctx.colorSchemes;
|
|
38
39
|
const defaultLocale = settings.defaultLocale;
|
|
39
40
|
const locales = [
|
|
40
41
|
defaultLocale,
|
|
@@ -183,6 +184,7 @@ export {
|
|
|
183
184
|
buildNavTree,
|
|
184
185
|
collectAutoIndexNodes,
|
|
185
186
|
collectTags,
|
|
187
|
+
colorSchemes,
|
|
186
188
|
ctx,
|
|
187
189
|
defaultLocale,
|
|
188
190
|
docsUrl,
|
package/dist/routes/index.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
HeadWithDefaults,
|
|
20
20
|
HeaderWithDefaults,
|
|
21
21
|
FooterWithDefaults,
|
|
22
|
-
|
|
22
|
+
BodyEndIslands,
|
|
23
23
|
composeMetaTitle
|
|
24
24
|
} from "./_chrome.js";
|
|
25
25
|
const frontmatter = { title: "Home" };
|
|
@@ -53,7 +53,7 @@ function IndexPage() {
|
|
|
53
53
|
sidebarOverride: /* @__PURE__ */ jsx(Fragment, {}),
|
|
54
54
|
headerOverride: /* @__PURE__ */ jsx(HeaderWithDefaults, { lang: locale, currentPath: withBase("/") }),
|
|
55
55
|
footerOverride: /* @__PURE__ */ jsx(FooterWithDefaults, { lang: locale }),
|
|
56
|
-
bodyEndComponents: /* @__PURE__ */ jsx(
|
|
56
|
+
bodyEndComponents: /* @__PURE__ */ jsx(BodyEndIslands, { basePath: settings.base ?? "/" }),
|
|
57
57
|
enableClientRouter: settings.dynamicPageTransition,
|
|
58
58
|
children: [
|
|
59
59
|
/* @__PURE__ */ jsx("div", { class: "flex justify-center mb-vsp-xl", children: /* @__PURE__ */ jsxs("div", { class: "flex flex-col items-center text-center gap-hsp-md lg:flex-row lg:text-left lg:gap-hsp-xl", children: [
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
HeadWithDefaults,
|
|
21
21
|
HeaderWithDefaults,
|
|
22
22
|
FooterWithDefaults,
|
|
23
|
-
|
|
23
|
+
BodyEndIslands,
|
|
24
24
|
composeMetaTitle
|
|
25
25
|
} from "./_chrome.js";
|
|
26
26
|
const frontmatter = { title: "Home" };
|
|
@@ -63,7 +63,7 @@ function LocaleIndexPage({ params }) {
|
|
|
63
63
|
sidebarOverride: /* @__PURE__ */ jsx(Fragment, {}),
|
|
64
64
|
headerOverride: /* @__PURE__ */ jsx(HeaderWithDefaults, { lang: locale, currentPath: withBase(`/${locale}/`) }),
|
|
65
65
|
footerOverride: /* @__PURE__ */ jsx(FooterWithDefaults, { lang: locale }),
|
|
66
|
-
bodyEndComponents: /* @__PURE__ */ jsx(
|
|
66
|
+
bodyEndComponents: /* @__PURE__ */ jsx(BodyEndIslands, { basePath: settings.base ?? "/" }),
|
|
67
67
|
enableClientRouter: settings.dynamicPageTransition,
|
|
68
68
|
children: [
|
|
69
69
|
/* @__PURE__ */ jsx("div", { class: "flex justify-center mb-vsp-xl", children: /* @__PURE__ */ jsxs("div", { class: "flex flex-col items-center text-center gap-hsp-md lg:flex-row lg:text-left lg:gap-hsp-xl", children: [
|