@takazudo/zudo-doc 5.14.0 → 5.16.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/CHANGELOG.md +40 -0
- package/dist/asset-components/asset-card.js +3 -1
- package/dist/asset-components/asset-code.js +2 -0
- package/dist/asset-components/shared.d.ts +5 -0
- package/dist/asset-components/shared.js +7 -0
- package/dist/asset-index-page/index.d.ts +1 -0
- package/dist/asset-index-page/index.js +10 -9
- package/dist/asset-page/index.d.ts +20 -2
- package/dist/asset-page/index.js +43 -24
- package/dist/asset-path/index.d.ts +2 -0
- package/dist/asset-path/index.js +11 -1
- package/dist/chrome/derive.js +31 -6
- package/dist/compiled.css +12 -0
- package/dist/config.d.ts +15 -6
- package/dist/config.js +2 -0
- package/dist/content/content-link.d.ts +5 -1
- package/dist/content/content-link.js +4 -1
- package/dist/doc-content-header/index.js +1 -1
- package/dist/doc-page-shell/index.js +1 -1
- package/dist/factory-context/index.d.ts +7 -3
- package/dist/header-with-defaults/index.js +2 -0
- package/dist/home-page/index.js +1 -1
- package/dist/html-preview-wrapper/html-preview-wrapper.d.ts +41 -7
- package/dist/html-preview-wrapper/html-preview-wrapper.js +86 -2
- package/dist/html-preview-wrapper/html-preview.d.ts +29 -4
- package/dist/html-preview-wrapper/html-preview.js +64 -6
- package/dist/html-preview-wrapper/index.d.ts +1 -1
- package/dist/html-preview-wrapper/preview-auto-height.d.ts +24 -0
- package/dist/html-preview-wrapper/preview-auto-height.js +120 -0
- package/dist/html-preview-wrapper/preview-base.d.ts +21 -1
- package/dist/html-preview-wrapper/preview-base.js +99 -50
- package/dist/i18n-defaults/index.d.ts +5 -3
- package/dist/i18n-defaults/index.js +89 -0
- package/dist/i18n-version/language-switcher.d.ts +10 -5
- package/dist/i18n-version/language-switcher.js +115 -22
- package/dist/i18n-version/types.d.ts +1 -1
- package/dist/mdx-components/index.d.ts +4 -0
- package/dist/mdx-components/index.js +11 -2
- package/dist/nav-indexing/versions-page-content.js +1 -1
- package/dist/plugins/claude-resources.js +15 -1
- package/dist/plugins/codex-resources.js +15 -1
- package/dist/plugins/internal/asset-viewer/asset-pages.d.ts +53 -0
- package/dist/plugins/internal/asset-viewer/asset-pages.js +98 -0
- package/dist/plugins/internal/asset-viewer/scan.d.ts +18 -1
- package/dist/plugins/internal/asset-viewer/scan.js +34 -27
- package/dist/plugins/internal/claude-resources/generate.d.ts +9 -0
- package/dist/plugins/internal/claude-resources/generate.js +188 -18
- package/dist/plugins/internal/claude-resources/index.d.ts +9 -0
- package/dist/plugins/internal/claude-resources/index.js +13 -1
- package/dist/plugins/internal/codex-resources/agents-md.js +15 -2
- package/dist/plugins/internal/codex-resources/agents.js +15 -2
- package/dist/plugins/internal/codex-resources/config.js +15 -2
- package/dist/plugins/internal/codex-resources/generate.d.ts +9 -0
- package/dist/plugins/internal/codex-resources/generate.js +19 -7
- package/dist/plugins/internal/codex-resources/hooks.js +15 -2
- package/dist/plugins/internal/codex-resources/index.d.ts +9 -0
- package/dist/plugins/internal/codex-resources/index.js +13 -1
- package/dist/plugins/internal/codex-resources/overview.js +136 -7
- package/dist/plugins/internal/codex-resources/rules.js +15 -2
- package/dist/plugins/internal/codex-resources/skills.js +16 -3
- package/dist/plugins/internal/llms-txt/assets.d.ts +24 -0
- package/dist/plugins/internal/llms-txt/assets.js +65 -0
- package/dist/plugins/internal/llms-txt/dev-middleware.d.ts +5 -0
- package/dist/plugins/internal/llms-txt/dev-middleware.js +9 -1
- package/dist/plugins/internal/llms-txt/emit.js +21 -5
- package/dist/plugins/internal/llms-txt/generate.d.ts +3 -3
- package/dist/plugins/internal/llms-txt/generate.js +55 -2
- package/dist/plugins/internal/llms-txt/index.d.ts +4 -1
- package/dist/plugins/internal/llms-txt/index.js +4 -0
- package/dist/plugins/internal/llms-txt/types.d.ts +24 -0
- package/dist/plugins/internal/llms-txt/types.js +4 -0
- package/dist/plugins/internal/resource-docs-shared/fs.d.ts +33 -0
- package/dist/plugins/internal/resource-docs-shared/fs.js +82 -1
- package/dist/plugins/internal/resource-docs-shared/index.d.ts +4 -2
- package/dist/plugins/internal/resource-docs-shared/index.js +21 -1
- package/dist/plugins/internal/resource-docs-shared/labels.d.ts +24 -0
- package/dist/plugins/internal/resource-docs-shared/labels.js +14 -0
- package/dist/plugins/internal/resource-docs-shared/locale-routes.d.ts +16 -0
- package/dist/plugins/internal/resource-docs-shared/locale-routes.js +14 -0
- package/dist/plugins/internal/resource-docs-shared/mdx.d.ts +7 -1
- package/dist/plugins/internal/resource-docs-shared/mdx.js +2 -2
- package/dist/plugins/internal/search-index/collect.js +46 -1
- package/dist/plugins/internal/search-index/types.d.ts +6 -1
- package/dist/plugins/llms-txt.js +9 -1
- package/dist/plugins/routes.js +14 -0
- package/dist/plugins/search-index.js +10 -1
- package/dist/preset.d.ts +9 -1
- package/dist/preset.js +25 -4
- package/dist/route-context/index.js +5 -17
- package/dist/route-enumerators/index.d.ts +14 -1
- package/dist/route-enumerators/index.js +38 -0
- package/dist/routes/locale-files-path.d.ts +29 -0
- package/dist/routes/locale-files-path.js +52 -0
- package/dist/safelist.css +1 -1
- package/dist/settings.d.ts +15 -0
- package/dist/tag-pages/index.js +2 -2
- package/eject/asset-components/asset-card.tsx +2 -0
- package/eject/asset-components/asset-code.tsx +2 -0
- package/eject/asset-components/shared.tsx +16 -0
- package/package.json +13 -9
- package/routes-src/locale-files-path.tsx +73 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,44 @@ All notable changes to `@takazudo/zudo-doc` are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on Keep a Changelog, and release notes are generated from the changelog MDX pages.
|
|
6
6
|
|
|
7
|
+
## [5.16.0] - 2026-09-02
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
- Added opt-in Markdown/MDX transclusion through `transclude`, plus independent `assetViewerIndexing` controls for search, llms.txt, and sitemap output. (`8145aae41`)
|
|
12
|
+
- Generated asset-viewer pages can now be enumerated in sitemaps and indexed in search and llms outputs, with locale, base-path, exclusion, and bounded content-extraction handling. (`5da03612e`, `b48009d7e`, `3de313585`, `76b90bc48`)
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
- Long unbroken titles now wrap across documentation, home, asset, version, and tag pages. (`f21c6b73d`)
|
|
17
|
+
- Asset search excerpts now use bounded reads for large files. (`6c81a13b3`)
|
|
18
|
+
- Asset links in llms outputs now honor the configured `siteUrl`. (`67482a1d5`)
|
|
19
|
+
|
|
20
|
+
### Other Changes
|
|
21
|
+
|
|
22
|
+
- Raised the optional `@takazudo/zudo-doc-history-server` peer floor to the already-published 5.15.0 release. (`01bd83bc7`)
|
|
23
|
+
|
|
24
|
+
## [5.15.0] - 2026-09-01
|
|
25
|
+
|
|
26
|
+
### Features
|
|
27
|
+
|
|
28
|
+
- Added an accessible language dropdown that scales to every configured locale instead of assuming a two-language site. (`607121e9`)
|
|
29
|
+
- Generated locale-owned Claude/Codex resource indexes and Asset Viewer routes for every configured locale, with translated page chrome, locale-preserving links, and safe handling of generated versus authored indexes. (`781fb820`, `8ceca53e`, `44ae7812`, `1e558854`, `5d682bc1`)
|
|
30
|
+
- Localized all seven `HtmlPreview` control labels and added per-preview `labels`, `showSource`, and `showViewportControls` overrides while preserving host-provided MDX bindings. (`ffee673f`, `6538184a`)
|
|
31
|
+
- Added `loading="visible"` for route-bound `HtmlPreview` instances, deferring iframe markup, scripts, and external resources until the reserved preview area enters the viewport. (`df63d981`)
|
|
32
|
+
- Kept auto-height previews synchronized after delayed content changes and viewport reflows, including both growth and shrink. (`df3d4b56`)
|
|
33
|
+
- Added escaped, nonblank language and title metadata to generated preview documents, with explicit author `<title>` content retaining precedence. (`2b8b0ee3`, `55e66300`)
|
|
34
|
+
|
|
35
|
+
### Bug Fixes
|
|
36
|
+
|
|
37
|
+
- Retained package English strings when a configured locale supplies only partial translations. (`0a3619cb`)
|
|
38
|
+
- Preserved an explicit empty `sandbox` attribute in generated HTML so strict opaque previews remain sandboxed as authored. (`c8b1cac7`)
|
|
39
|
+
- Increased interactive `HtmlPreview` controls to accessible minimum hit-target dimensions. (`a35f1573`)
|
|
40
|
+
|
|
41
|
+
### Other Changes
|
|
42
|
+
|
|
43
|
+
- Updated the zfb peer family to 2.14.2. (`5c5bfd2f`)
|
|
44
|
+
|
|
7
45
|
## [5.14.0] - 2026-08-31
|
|
8
46
|
|
|
9
47
|
### Features
|
|
@@ -23,6 +61,8 @@ The format is based on Keep a Changelog, and release notes are generated from th
|
|
|
23
61
|
|
|
24
62
|
### Other Changes
|
|
25
63
|
|
|
64
|
+
- Enabled Asset Viewer routes now localize automatically for existing multi-locale consumers after a package bump, unless `/${assetViewerRoutePrefix}/` is explicitly present in `defaultLocaleOnlyPrefixes`. Existing apps that already carry the legacy Claude/Codex resource prefixes remain default-locale-only after upgrading; remove the prefixes for resource sections you want generated in every configured locale. (#3820)
|
|
65
|
+
- Migration: before building with 5.14.0, remove or rename any authored locale resource overview/category `index.mdx` at a generator target and move custom titles, descriptions, and labels to `ZudoDocConfig.translations`. The generator refuses to overwrite an existing file unless its frontmatter contains `generated: true`. (#3820)
|
|
26
66
|
- Updated the zfb peer family to 2.14.0, `@takazudo/zdtp` to 0.4.14, and the doc-history-server peer floor to 5.13.1. (`dbe8553c7`, `038870c94`, `95a82f15f`)
|
|
27
67
|
|
|
28
68
|
## [5.13.1] - 2026-08-28
|
|
@@ -2,6 +2,7 @@ import { jsx, jsxs } from "preact/jsx-runtime";
|
|
|
2
2
|
import { assetRawHref, assetViewerHref } from "../asset-path/index.js";
|
|
3
3
|
import {
|
|
4
4
|
AssetFileIcon,
|
|
5
|
+
assetComponentViewerLocale,
|
|
5
6
|
assetComponentText,
|
|
6
7
|
formatAssetBytes,
|
|
7
8
|
formatAssetLanguage,
|
|
@@ -23,7 +24,8 @@ function createAssetCard(context) {
|
|
|
23
24
|
const viewerHref = assetViewerHref({
|
|
24
25
|
base: context.base,
|
|
25
26
|
routePrefix: context.routePrefix,
|
|
26
|
-
path
|
|
27
|
+
path,
|
|
28
|
+
locale: assetComponentViewerLocale(context, path)
|
|
27
29
|
});
|
|
28
30
|
const rawHref = assetRawHref({ base: context.base, dir: context.dir, path });
|
|
29
31
|
const details = [
|
|
@@ -2,6 +2,7 @@ import { jsx, jsxs } from "preact/jsx-runtime";
|
|
|
2
2
|
import { assetViewerHref } from "../asset-path/index.js";
|
|
3
3
|
import {
|
|
4
4
|
AssetFileIcon,
|
|
5
|
+
assetComponentViewerLocale,
|
|
5
6
|
assetComponentText,
|
|
6
7
|
MissingAssetWarning,
|
|
7
8
|
resolveAssetEntry
|
|
@@ -43,6 +44,7 @@ function createAssetCode(context) {
|
|
|
43
44
|
base: context.base,
|
|
44
45
|
routePrefix: context.routePrefix,
|
|
45
46
|
path: resolved.path,
|
|
47
|
+
locale: assetComponentViewerLocale(context, resolved.path),
|
|
46
48
|
fragment: excerpt.viewerLineAvailable ? `L${excerpt.startLine}` : void 0
|
|
47
49
|
});
|
|
48
50
|
const shown = Math.max(0, excerpt.endLine - excerpt.startLine + 1);
|
|
@@ -7,9 +7,14 @@ export interface AssetComponentContext {
|
|
|
7
7
|
assetManifest: AssetManifest | null;
|
|
8
8
|
routePrefix: string;
|
|
9
9
|
dir: string;
|
|
10
|
+
/** Non-default locale segment for viewer links. */
|
|
11
|
+
locale?: string;
|
|
12
|
+
/** Match viewer paths that intentionally remain default-locale-only. */
|
|
13
|
+
isDefaultLocaleOnlyPath?: (path: string) => boolean;
|
|
10
14
|
/** Locale-bound package translator. Omitted callers retain English fallbacks. */
|
|
11
15
|
t?: (key: string) => string;
|
|
12
16
|
}
|
|
17
|
+
export declare function assetComponentViewerLocale(context: AssetComponentContext, path: string): string | undefined;
|
|
13
18
|
export declare function assetComponentText(context: AssetComponentContext, key: string, fallback: string, values?: Record<string, string | number>): string;
|
|
14
19
|
export declare function resolveAssetEntry(src: string, context: AssetComponentContext): {
|
|
15
20
|
path: string;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { jsx, jsxs } from "preact/jsx-runtime";
|
|
2
2
|
import { decodeAuthoredHref } from "../asset-path/index.js";
|
|
3
|
+
function assetComponentViewerLocale(context, path) {
|
|
4
|
+
if (context.isDefaultLocaleOnlyPath?.(`/${context.routePrefix}/${path}`)) {
|
|
5
|
+
return void 0;
|
|
6
|
+
}
|
|
7
|
+
return context.locale;
|
|
8
|
+
}
|
|
3
9
|
function assetComponentText(context, key, fallback, values = {}) {
|
|
4
10
|
let text = context.t?.(key) ?? fallback;
|
|
5
11
|
for (const [name, value] of Object.entries(values)) {
|
|
@@ -83,6 +89,7 @@ export {
|
|
|
83
89
|
AssetFileIcon,
|
|
84
90
|
MissingAssetWarning,
|
|
85
91
|
assetComponentText,
|
|
92
|
+
assetComponentViewerLocale,
|
|
86
93
|
formatAssetBytes,
|
|
87
94
|
formatAssetLanguage,
|
|
88
95
|
resolveAssetEntry
|
|
@@ -14,6 +14,7 @@ export interface AssetTreeNode {
|
|
|
14
14
|
}
|
|
15
15
|
export interface AssetIndexPageViewProps {
|
|
16
16
|
entries: AssetIndexEntry[];
|
|
17
|
+
locale?: string;
|
|
17
18
|
}
|
|
18
19
|
/** Build a sorted directory tree and aggregate every directory's subtree totals. */
|
|
19
20
|
export declare function buildAssetTree(entries: AssetIndexEntry[]): AssetTreeNode;
|
|
@@ -86,7 +86,7 @@ function iconFor(asset) {
|
|
|
86
86
|
function countLabel(count, plural, single) {
|
|
87
87
|
return (count === 1 ? single : plural).replace("{count}", String(count));
|
|
88
88
|
}
|
|
89
|
-
function AssetTree({ node, base, routePrefix, fileCountLabel, fileCountSingleLabel, linesLabel, root = false }) {
|
|
89
|
+
function AssetTree({ node, base, routePrefix, locale, fileCountLabel, fileCountSingleLabel, linesLabel, root = false }) {
|
|
90
90
|
return /* @__PURE__ */ jsxs("ul", { "data-zd-asset-tree": root ? true : void 0, children: [
|
|
91
91
|
node.dirs.map((dir) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("details", { open: true, children: [
|
|
92
92
|
/* @__PURE__ */ jsxs("summary", { class: "flex cursor-pointer items-center gap-hsp-xs rounded px-hsp-sm py-vsp-3xs text-small hover:bg-accent/10 focus-visible:bg-accent/10", children: [
|
|
@@ -103,13 +103,13 @@ function AssetTree({ node, base, routePrefix, fileCountLabel, fileCountSingleLab
|
|
|
103
103
|
formatAssetBytes(dir.bytes)
|
|
104
104
|
] })
|
|
105
105
|
] }),
|
|
106
|
-
/* @__PURE__ */ jsx(AssetTree, { node: dir, base, routePrefix, fileCountLabel, fileCountSingleLabel, linesLabel })
|
|
106
|
+
/* @__PURE__ */ jsx(AssetTree, { node: dir, base, routePrefix, locale, fileCountLabel, fileCountSingleLabel, linesLabel })
|
|
107
107
|
] }) })),
|
|
108
108
|
node.files.map((asset) => {
|
|
109
109
|
const Icon = iconFor(asset);
|
|
110
110
|
const facet = facetLabel(asset, linesLabel);
|
|
111
111
|
const meta = [kindLabel(asset), facet, formatAssetBytes(asset.bytes)].filter(Boolean).join(" \xB7 ");
|
|
112
|
-
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("a", { href: assetViewerHref({ base, routePrefix, path: asset.path }), title: asset.name, class: "flex min-w-0 items-center gap-hsp-xs rounded px-hsp-sm py-vsp-3xs text-small text-fg hover:bg-accent/10 hover:text-accent hover:underline focus-visible:bg-accent/10 focus-visible:text-accent focus-visible:underline", children: [
|
|
112
|
+
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("a", { href: assetViewerHref({ base, routePrefix, path: asset.path, locale }), title: asset.name, class: "flex min-w-0 items-center gap-hsp-xs rounded px-hsp-sm py-vsp-3xs text-small text-fg hover:bg-accent/10 hover:text-accent hover:underline focus-visible:bg-accent/10 focus-visible:text-accent focus-visible:underline", children: [
|
|
113
113
|
/* @__PURE__ */ jsx(Icon, { className: "h-icon-sm w-icon-sm shrink-0 text-muted" }),
|
|
114
114
|
/* @__PURE__ */ jsx("span", { class: "min-w-0 truncate font-mono", children: basename(asset.path) }),
|
|
115
115
|
/* @__PURE__ */ jsx("span", { class: "ml-auto hidden whitespace-nowrap pl-hsp-lg text-caption text-muted sm:block", children: meta })
|
|
@@ -120,17 +120,18 @@ function AssetTree({ node, base, routePrefix, fileCountLabel, fileCountSingleLab
|
|
|
120
120
|
function createAssetIndexPageView(ctx) {
|
|
121
121
|
assertChromeContext(ctx, "createAssetIndexPageView");
|
|
122
122
|
const settings = ctx.settings;
|
|
123
|
-
const locale = ctx.defaultLocale;
|
|
124
123
|
const t = ctx.t;
|
|
125
124
|
const composeMetaTitle = deriveComposeMetaTitle(ctx);
|
|
126
125
|
const HeadWithDefaults = createHeadWithDefaults(ctx);
|
|
127
126
|
const { Header: HeaderWithDefaults, Footer: FooterWithDefaults, Breadcrumb: BreadcrumbWithDefaults } = derivePrimaryChromeSlots(ctx);
|
|
128
127
|
const BodyEndIslands = deriveBodyEndIslands(ctx);
|
|
129
128
|
const dataThemePack = resolveThemePackSsrSlug(ctx.themePackRegistry, settings);
|
|
130
|
-
return function AssetIndexPageView({ entries }) {
|
|
129
|
+
return function AssetIndexPageView({ entries, locale = ctx.defaultLocale }) {
|
|
130
|
+
const localeSegment = locale === ctx.defaultLocale ? void 0 : locale;
|
|
131
131
|
const routePrefix = ctx.assetManifest?.routePrefix ?? settings.assetViewerRoutePrefix;
|
|
132
132
|
const dir = ctx.assetManifest?.dir ?? settings.assetViewerDir;
|
|
133
|
-
const indexUrl = ctx.withBase(`/${routePrefix}/`);
|
|
133
|
+
const indexUrl = ctx.withBase(`/${localeSegment ? `${localeSegment}/` : ""}${routePrefix}/`);
|
|
134
|
+
const homeUrl = ctx.withBase(`/${localeSegment ? `${localeSegment}/` : ""}`);
|
|
134
135
|
const tree = buildAssetTree(entries);
|
|
135
136
|
const folders = folderCount(tree);
|
|
136
137
|
const fileCountLabel = t("asset.fileCount", locale);
|
|
@@ -138,13 +139,13 @@ function createAssetIndexPageView(ctx) {
|
|
|
138
139
|
const folderCountLabel = t("asset.folderCount", locale);
|
|
139
140
|
const folderCountSingleLabel = t("asset.folderCountSingle", locale);
|
|
140
141
|
const title = t("asset.crumb", locale);
|
|
141
|
-
return /* @__PURE__ */ jsx(DocLayoutWithDefaults, { title: composeMetaTitle(title), head: /* @__PURE__ */ jsx(HeadWithDefaults, { title, description: t("asset.indexDescription", locale), canonical: ctx.absoluteUrl(indexUrl) }), lang: locale, dataThemePack, noindex: settings.noindex, hideSidebar: true, hideToc: true, sidebarOverride: false, contentWide: true, breadcrumbOverride: /* @__PURE__ */ jsx(BreadcrumbWithDefaults, { items: [{ label: "", href:
|
|
142
|
+
return /* @__PURE__ */ jsx(DocLayoutWithDefaults, { title: composeMetaTitle(title), head: /* @__PURE__ */ jsx(HeadWithDefaults, { title, description: t("asset.indexDescription", locale), canonical: ctx.absoluteUrl(indexUrl) }), lang: locale, dataThemePack, noindex: settings.noindex, hideSidebar: true, hideToc: true, sidebarOverride: false, contentWide: true, breadcrumbOverride: /* @__PURE__ */ jsx(BreadcrumbWithDefaults, { items: [{ label: "", href: homeUrl }, { label: title }] }), headerOverride: /* @__PURE__ */ jsx(HeaderWithDefaults, { lang: locale, currentPath: indexUrl, hideSidebarToggle: true }), footerOverride: /* @__PURE__ */ jsx(FooterWithDefaults, { lang: locale }), bodyEndComponents: /* @__PURE__ */ jsx(BodyEndIslands, { basePath: settings.base ?? "/" }), enableClientRouter: settings.dynamicPageTransition, children: /* @__PURE__ */ jsxs("div", { "data-zd-asset-index-page": true, children: [
|
|
142
143
|
/* @__PURE__ */ jsxs("header", { children: [
|
|
143
144
|
/* @__PURE__ */ jsxs("div", { class: "mb-vsp-xs flex flex-wrap items-center gap-hsp-xs text-micro tracking-wide uppercase", children: [
|
|
144
145
|
/* @__PURE__ */ jsx("span", { class: "rounded-full border border-muted px-hsp-sm py-vsp-3xs text-fg", children: title }),
|
|
145
146
|
/* @__PURE__ */ jsx("span", { class: "rounded-full border border-muted px-hsp-sm py-vsp-3xs text-muted", children: t("asset.indexBadge", locale) })
|
|
146
147
|
] }),
|
|
147
|
-
/* @__PURE__ */ jsx("h1", { class: "mb-vsp-xs border-b border-fg pb-vsp-xs font-mono text-heading font-bold leading-tight", children: title }),
|
|
148
|
+
/* @__PURE__ */ jsx("h1", { class: "mb-vsp-xs border-b border-fg pb-vsp-xs font-mono text-heading font-bold leading-tight break-words", children: title }),
|
|
148
149
|
/* @__PURE__ */ jsxs("div", { "data-doc-metainfo": true, class: "mb-vsp-md flex flex-wrap items-center gap-x-hsp-md gap-y-vsp-2xs text-caption text-fg", children: [
|
|
149
150
|
/* @__PURE__ */ jsx("span", { children: countLabel(tree.fileCount, fileCountLabel, fileCountSingleLabel) }),
|
|
150
151
|
/* @__PURE__ */ jsx("span", { children: countLabel(folders, folderCountLabel, folderCountSingleLabel) }),
|
|
@@ -163,7 +164,7 @@ function createAssetIndexPageView(ctx) {
|
|
|
163
164
|
/* @__PURE__ */ jsx("button", { type: "button", disabled: true, "data-zd-asset-index-action": "collapse", class: "text-fg hover:text-accent focus-visible:text-accent", children: t("asset.collapseAll", locale) })
|
|
164
165
|
] })
|
|
165
166
|
] }),
|
|
166
|
-
entries.length > 0 ? /* @__PURE__ */ jsx(AssetTree, { root: true, node: tree, base: settings.base, routePrefix, fileCountLabel, fileCountSingleLabel, linesLabel: t("asset.lines", locale) }) : /* @__PURE__ */ jsx("p", { class: "text-small text-muted", "data-zd-asset-index-empty": true, children: t("asset.indexEmpty", locale) }),
|
|
167
|
+
entries.length > 0 ? /* @__PURE__ */ jsx(AssetTree, { root: true, node: tree, base: settings.base, routePrefix, locale: localeSegment, fileCountLabel, fileCountSingleLabel, linesLabel: t("asset.lines", locale) }) : /* @__PURE__ */ jsx("p", { class: "text-small text-muted", "data-zd-asset-index-empty": true, children: t("asset.indexEmpty", locale) }),
|
|
167
168
|
/* @__PURE__ */ jsx("script", { dangerouslySetInnerHTML: { __html: ASSET_INDEX_PAGE_SCRIPT } })
|
|
168
169
|
] }) });
|
|
169
170
|
};
|
|
@@ -8,6 +8,7 @@ export { ASSET_PAGE_SCRIPT } from "./script.js";
|
|
|
8
8
|
export type { AssetRecord } from "../plugins/internal/asset-viewer/types.js";
|
|
9
9
|
export interface AssetPageViewProps {
|
|
10
10
|
entry: AssetRecord;
|
|
11
|
+
locale?: string;
|
|
11
12
|
}
|
|
12
13
|
export declare function AssetEyebrow({ asset, badge }: {
|
|
13
14
|
asset: AssetRecord;
|
|
@@ -36,9 +37,17 @@ export declare function AssetCodeBody({ asset, copyLabel, wrapLabel, truncatedLa
|
|
|
36
37
|
truncatedLabel: string;
|
|
37
38
|
linesLabel?: string;
|
|
38
39
|
}): VNode;
|
|
39
|
-
export
|
|
40
|
+
export interface AssetImageStageLabels {
|
|
41
|
+
fit: string;
|
|
42
|
+
actualSize: string;
|
|
43
|
+
checker: string;
|
|
44
|
+
dark: string;
|
|
45
|
+
enlarge: string;
|
|
46
|
+
}
|
|
47
|
+
export declare function AssetImageStage({ asset, rawUrl, labels }: {
|
|
40
48
|
asset: AssetRecord;
|
|
41
49
|
rawUrl: string;
|
|
50
|
+
labels: AssetImageStageLabels;
|
|
42
51
|
}): VNode;
|
|
43
52
|
export declare function AssetVideoStage({ asset, rawUrl }: {
|
|
44
53
|
asset: AssetRecord;
|
|
@@ -60,8 +69,17 @@ export declare function AssetLinkedFrom({ asset, label }: {
|
|
|
60
69
|
asset: AssetRecord;
|
|
61
70
|
label: string;
|
|
62
71
|
}): VNode | null;
|
|
63
|
-
export
|
|
72
|
+
export interface AssetDetailsLabels {
|
|
73
|
+
heading: string;
|
|
74
|
+
type: string;
|
|
75
|
+
size: string;
|
|
76
|
+
path: string;
|
|
77
|
+
dimensions: string;
|
|
78
|
+
updated: string;
|
|
79
|
+
}
|
|
80
|
+
export declare function AssetDetails({ asset, labels }: {
|
|
64
81
|
asset: AssetRecord;
|
|
82
|
+
labels: AssetDetailsLabels;
|
|
65
83
|
}): VNode;
|
|
66
84
|
/** Build the package-owned wide asset viewer page from a chrome context. */
|
|
67
85
|
export declare function createAssetPageView<S extends Settings = Settings>(ctx: ChromeContext<S>): (props: AssetPageViewProps) => JSX.Element;
|
package/dist/asset-page/index.js
CHANGED
|
@@ -42,7 +42,7 @@ function AssetHeader({ asset, locale, badge, updatedLabel, linesLabel }) {
|
|
|
42
42
|
const facet = facetLabel(asset, linesLabel);
|
|
43
43
|
return /* @__PURE__ */ jsxs("header", { children: [
|
|
44
44
|
/* @__PURE__ */ jsx(AssetEyebrow, { asset, badge }),
|
|
45
|
-
/* @__PURE__ */ jsx("h1", { class: "mb-vsp-xs border-b border-fg pb-vsp-xs font-mono text-heading font-bold leading-tight", children: asset.name }),
|
|
45
|
+
/* @__PURE__ */ jsx("h1", { class: "mb-vsp-xs border-b border-fg pb-vsp-xs font-mono text-heading font-bold leading-tight break-words", children: asset.name }),
|
|
46
46
|
/* @__PURE__ */ jsxs("div", { "data-doc-metainfo": true, class: "mb-vsp-md flex flex-wrap items-center gap-x-hsp-md gap-y-vsp-2xs text-caption text-fg", children: [
|
|
47
47
|
asset.dir && /* @__PURE__ */ jsx("span", { children: asset.dir }),
|
|
48
48
|
facet && /* @__PURE__ */ jsx("span", { children: facet }),
|
|
@@ -93,21 +93,21 @@ function AssetCodeBody({ asset, copyLabel, wrapLabel, truncatedLabel, linesLabel
|
|
|
93
93
|
function EnlargeIcon() {
|
|
94
94
|
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { fill: "none", stroke: "currentColor", "stroke-linecap": "round", "stroke-linejoin": "round", "stroke-width": "2", d: "M8 3H3v5m13-5h5v5M8 21H3v-5m13 5h5v-5M3 8l6-6m12 6-6-6M3 16l6 6m12-6-6 6" }) });
|
|
95
95
|
}
|
|
96
|
-
function AssetImageStage({ asset, rawUrl }) {
|
|
96
|
+
function AssetImageStage({ asset, rawUrl, labels }) {
|
|
97
97
|
return /* @__PURE__ */ jsxs("section", { children: [
|
|
98
98
|
/* @__PURE__ */ jsxs("div", { class: "mb-vsp-xs flex flex-wrap gap-hsp-sm text-caption", children: [
|
|
99
99
|
/* @__PURE__ */ jsxs("div", { class: "flex rounded border border-muted", children: [
|
|
100
|
-
/* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": "true", "data-zd-asset-action": "fit", class: "px-hsp-sm py-vsp-3xs", children:
|
|
101
|
-
/* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": "false", "data-zd-asset-action": "1to1", class: "border-l border-muted px-hsp-sm py-vsp-3xs", children:
|
|
100
|
+
/* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": "true", "data-zd-asset-action": "fit", class: "px-hsp-sm py-vsp-3xs", children: labels.fit }),
|
|
101
|
+
/* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": "false", "data-zd-asset-action": "1to1", class: "border-l border-muted px-hsp-sm py-vsp-3xs", children: labels.actualSize })
|
|
102
102
|
] }),
|
|
103
103
|
/* @__PURE__ */ jsxs("div", { class: "flex rounded border border-muted", children: [
|
|
104
|
-
/* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": "true", "data-zd-asset-action": "checker", class: "px-hsp-sm py-vsp-3xs", children:
|
|
105
|
-
/* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": "false", "data-zd-asset-action": "dark", class: "border-l border-muted px-hsp-sm py-vsp-3xs", children:
|
|
104
|
+
/* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": "true", "data-zd-asset-action": "checker", class: "px-hsp-sm py-vsp-3xs", children: labels.checker }),
|
|
105
|
+
/* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": "false", "data-zd-asset-action": "dark", class: "border-l border-muted px-hsp-sm py-vsp-3xs", children: labels.dark })
|
|
106
106
|
] })
|
|
107
107
|
] }),
|
|
108
108
|
/* @__PURE__ */ jsxs("figure", { class: "zd-enlargeable zd-asset-stage is-checker flex min-h-[20rem] items-center justify-center overflow-auto rounded border border-muted bg-surface p-hsp-lg", children: [
|
|
109
109
|
/* @__PURE__ */ jsx("img", { src: rawUrl, alt: asset.description ?? asset.name, width: asset.width, height: asset.height }),
|
|
110
|
-
/* @__PURE__ */ jsx("button", { type: "button", class: "zd-enlarge-btn", hidden: true, "aria-label":
|
|
110
|
+
/* @__PURE__ */ jsx("button", { type: "button", class: "zd-enlarge-btn", hidden: true, "aria-label": labels.enlarge, children: /* @__PURE__ */ jsx(EnlargeIcon, {}) })
|
|
111
111
|
] })
|
|
112
112
|
] });
|
|
113
113
|
}
|
|
@@ -147,12 +147,12 @@ function AssetLinkedFrom({ asset, label }) {
|
|
|
147
147
|
] })) })
|
|
148
148
|
] });
|
|
149
149
|
}
|
|
150
|
-
function AssetDetails({ asset }) {
|
|
151
|
-
const rows = [[
|
|
152
|
-
if (asset.width !== void 0 && asset.height !== void 0) rows.splice(1, 0, [
|
|
153
|
-
if (asset.updatedDate) rows.push([
|
|
150
|
+
function AssetDetails({ asset, labels }) {
|
|
151
|
+
const rows = [[labels.type, asset.mime], [labels.size, formatAssetBytes(asset.bytes)], [labels.path, asset.path]];
|
|
152
|
+
if (asset.width !== void 0 && asset.height !== void 0) rows.splice(1, 0, [labels.dimensions, `${asset.width} \xD7 ${asset.height}`]);
|
|
153
|
+
if (asset.updatedDate) rows.push([labels.updated, asset.updatedDate]);
|
|
154
154
|
return /* @__PURE__ */ jsxs("section", { children: [
|
|
155
|
-
/* @__PURE__ */ jsx("h2", { class: "mb-vsp-xs text-title font-bold", children:
|
|
155
|
+
/* @__PURE__ */ jsx("h2", { class: "mb-vsp-xs text-title font-bold", children: labels.heading }),
|
|
156
156
|
/* @__PURE__ */ jsx("dl", { class: "grid grid-cols-[auto_1fr] gap-x-hsp-md gap-y-vsp-2xs text-caption", children: rows.map(([term, value]) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
157
157
|
/* @__PURE__ */ jsx("dt", { class: "font-medium text-muted", children: term }),
|
|
158
158
|
/* @__PURE__ */ jsx("dd", { class: "min-w-0 break-words text-fg", children: value })
|
|
@@ -171,53 +171,72 @@ function MediaLayout({ stage, details, linked }) {
|
|
|
171
171
|
function createAssetPageView(ctx) {
|
|
172
172
|
assertChromeContext(ctx, "createAssetPageView");
|
|
173
173
|
const settings = ctx.settings;
|
|
174
|
-
const locale = ctx.defaultLocale;
|
|
175
174
|
const t = ctx.t;
|
|
176
175
|
const composeMetaTitle = deriveComposeMetaTitle(ctx);
|
|
177
176
|
const HeadWithDefaults = createHeadWithDefaults(ctx);
|
|
178
177
|
const { Header: HeaderWithDefaults, Footer: FooterWithDefaults, Breadcrumb: BreadcrumbWithDefaults } = derivePrimaryChromeSlots(ctx);
|
|
179
178
|
const BodyEndIslands = deriveBodyEndIslands(ctx);
|
|
180
179
|
const dataThemePack = resolveThemePackSsrSlug(ctx.themePackRegistry, settings);
|
|
181
|
-
return function AssetPageView({ entry: asset }) {
|
|
180
|
+
return function AssetPageView({ entry: asset, locale = ctx.defaultLocale }) {
|
|
181
|
+
const localeSegment = locale === ctx.defaultLocale ? void 0 : locale;
|
|
182
182
|
const routePrefix = ctx.assetManifest?.routePrefix ?? settings.assetViewerRoutePrefix;
|
|
183
183
|
const dir = ctx.assetManifest?.dir ?? settings.assetViewerDir;
|
|
184
|
-
const viewerUrl = assetViewerHref({ base: settings.base, routePrefix, path: asset.path });
|
|
184
|
+
const viewerUrl = assetViewerHref({ base: settings.base, routePrefix, path: asset.path, locale: localeSegment });
|
|
185
185
|
const rawUrl = assetRawHref({ base: settings.base, dir, path: asset.path });
|
|
186
186
|
const linesLabel = t("asset.lines", locale).replace(
|
|
187
187
|
"{count}",
|
|
188
188
|
String(asset.lines ?? 0)
|
|
189
189
|
);
|
|
190
190
|
const dirSegments = asset.dir.split("/").filter(Boolean);
|
|
191
|
-
const indexUrl = ctx.withBase(`/${routePrefix}/`);
|
|
191
|
+
const indexUrl = ctx.withBase(`/${localeSegment ? `${localeSegment}/` : ""}${routePrefix}/`);
|
|
192
|
+
const homeUrl = ctx.withBase(`/${localeSegment ? `${localeSegment}/` : ""}`);
|
|
193
|
+
const backLink = locale === ctx.defaultLocale ? asset.linkedFrom[0] : asset.linkedFrom.find((link) => link.locale === locale) ?? asset.linkedFrom[0];
|
|
192
194
|
const breadcrumbItems = [
|
|
193
|
-
{ label: "", href:
|
|
195
|
+
{ label: "", href: homeUrl },
|
|
194
196
|
{ label: t("asset.crumb", locale), ...settings.assetViewerIndex ? { href: indexUrl } : {} },
|
|
195
197
|
...dirSegments.map((label) => ({ label })),
|
|
196
198
|
{ label: asset.name }
|
|
197
199
|
];
|
|
198
200
|
const linked = /* @__PURE__ */ jsx(AssetLinkedFrom, { asset, label: t("asset.linkedFrom", locale) });
|
|
199
|
-
const
|
|
201
|
+
const detailsLabels = {
|
|
202
|
+
heading: t("asset.details", locale),
|
|
203
|
+
type: t("asset.type", locale),
|
|
204
|
+
size: t("asset.size", locale),
|
|
205
|
+
path: t("asset.path", locale),
|
|
206
|
+
dimensions: t("asset.dimensions", locale),
|
|
207
|
+
updated: t("doc.updated", locale)
|
|
208
|
+
};
|
|
209
|
+
const imageStageLabels = {
|
|
210
|
+
fit: t("asset.fit", locale),
|
|
211
|
+
actualSize: t("asset.actualSize", locale),
|
|
212
|
+
checker: t("asset.checker", locale),
|
|
213
|
+
dark: t("asset.dark", locale),
|
|
214
|
+
enlarge: t("asset.enlarge", locale)
|
|
215
|
+
};
|
|
216
|
+
const details = /* @__PURE__ */ jsx(AssetDetails, { asset, labels: detailsLabels });
|
|
200
217
|
const downloadPanel = /* @__PURE__ */ jsx(AssetDownloadPanel, { asset, rawUrl, noPreview: t("asset.noPreview", locale), downloadLabel: t("asset.download", locale), copyLabel: t("asset.copy", locale) });
|
|
201
218
|
let body;
|
|
202
219
|
const isMedia = asset.previewable && asset.sniffOk && ["image", "video", "pdf"].includes(asset.kind);
|
|
203
220
|
if (!asset.previewable || !asset.sniffOk) body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
204
221
|
downloadPanel,
|
|
205
|
-
/* @__PURE__ */ jsx(AssetDetails, { asset }),
|
|
222
|
+
/* @__PURE__ */ jsx(AssetDetails, { asset, labels: detailsLabels }),
|
|
206
223
|
linked
|
|
207
224
|
] });
|
|
208
|
-
else if (asset.kind === "image") body = /* @__PURE__ */ jsx(MediaLayout, { stage: /* @__PURE__ */ jsx(AssetImageStage, { asset, rawUrl }), details, linked });
|
|
225
|
+
else if (asset.kind === "image") body = /* @__PURE__ */ jsx(MediaLayout, { stage: /* @__PURE__ */ jsx(AssetImageStage, { asset, rawUrl, labels: imageStageLabels }), details, linked });
|
|
209
226
|
else if (asset.kind === "video") body = /* @__PURE__ */ jsx(MediaLayout, { stage: /* @__PURE__ */ jsx(AssetVideoStage, { asset, rawUrl }), details, linked });
|
|
210
227
|
else if (asset.kind === "pdf") body = /* @__PURE__ */ jsx(MediaLayout, { stage: /* @__PURE__ */ jsx(AssetPdfStage, { asset, rawUrl, children: downloadPanel }), details, linked });
|
|
211
228
|
else body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
212
229
|
/* @__PURE__ */ jsx(AssetCodeBody, { asset, copyLabel: t("asset.copy", locale), wrapLabel: t("asset.wrap", locale), truncatedLabel: t("asset.truncated", locale), linesLabel }),
|
|
213
|
-
/* @__PURE__ */ jsx(AssetDetails, { asset }),
|
|
230
|
+
/* @__PURE__ */ jsx(AssetDetails, { asset, labels: detailsLabels }),
|
|
214
231
|
linked
|
|
215
232
|
] });
|
|
216
233
|
const showSource = settings.bodyFootUtilArea !== false && settings.bodyFootUtilArea.viewSourceLink !== false;
|
|
217
234
|
return /* @__PURE__ */ jsx(DocLayoutWithDefaults, { title: composeMetaTitle(asset.name), head: /* @__PURE__ */ jsx(HeadWithDefaults, { title: asset.name, description: asset.description, canonical: ctx.absoluteUrl(viewerUrl) }), lang: locale, dataThemePack, noindex: settings.noindex, hideSidebar: true, hideToc: true, sidebarOverride: false, contentWide: true, breadcrumbOverride: /* @__PURE__ */ jsx(BreadcrumbWithDefaults, { items: breadcrumbItems }), headerOverride: /* @__PURE__ */ jsx(HeaderWithDefaults, { lang: locale, currentPath: viewerUrl, hideSidebarToggle: true }), footerOverride: /* @__PURE__ */ jsx(FooterWithDefaults, { lang: locale }), bodyEndComponents: /* @__PURE__ */ jsx(BodyEndIslands, { basePath: settings.base ?? "/", forceImageEnlarge: asset.kind === "image" && asset.previewable && asset.sniffOk }), enableClientRouter: settings.dynamicPageTransition, children: /* @__PURE__ */ jsxs("div", { class: "zd-asset-page", "data-zd-asset-page": true, children: [
|
|
218
|
-
|
|
219
|
-
"\u2190
|
|
220
|
-
asset.
|
|
235
|
+
backLink && /* @__PURE__ */ jsx("p", { class: "mb-vsp-xs text-caption", children: /* @__PURE__ */ jsxs("a", { href: backLink.href, class: "text-muted hover:text-accent focus-visible:text-accent hover:underline focus-visible:underline", children: [
|
|
236
|
+
"\u2190 ",
|
|
237
|
+
t("asset.backTo", locale),
|
|
238
|
+
" ",
|
|
239
|
+
backLink.title
|
|
221
240
|
] }) }),
|
|
222
241
|
/* @__PURE__ */ jsx(AssetHeader, { asset, locale, badge: t("asset.badge", locale), updatedLabel: t("doc.updated", locale), linesLabel }),
|
|
223
242
|
/* @__PURE__ */ jsx(AssetActions, { rawUrl, downloadLabel: t("asset.download", locale), openRawLabel: t("asset.openRaw", locale), copyLabel: t("asset.copy", locale), wrapLabel: t("asset.wrap", locale), code: !isMedia && asset.previewable && asset.sniffOk }),
|
|
@@ -9,6 +9,8 @@ export interface AssetViewerHrefOptions {
|
|
|
9
9
|
base: string;
|
|
10
10
|
routePrefix: string;
|
|
11
11
|
path: string;
|
|
12
|
+
/** Non-default locale segment. Omit for the unprefixed default locale. */
|
|
13
|
+
locale?: string;
|
|
12
14
|
/** A fragment with or without its leading `#`. */
|
|
13
15
|
fragment?: string;
|
|
14
16
|
}
|
package/dist/asset-path/index.js
CHANGED
|
@@ -59,9 +59,10 @@ function decodeAuthoredHref(href, options) {
|
|
|
59
59
|
}
|
|
60
60
|
function assetViewerHref(options) {
|
|
61
61
|
const routePrefix = normalizeSettingPath(options.routePrefix, "routePrefix");
|
|
62
|
+
const localePrefix = options.locale === void 0 ? "" : `/${encodeURIComponent(normalizeLocaleSegment(options.locale))}`;
|
|
62
63
|
const href = withBase(
|
|
63
64
|
options.base,
|
|
64
|
-
|
|
65
|
+
`${localePrefix}/${routePrefix}/${encodeAssetPathForUrl(options.path)}/`
|
|
65
66
|
);
|
|
66
67
|
if (options.fragment == null || options.fragment === "") return href;
|
|
67
68
|
if (CONTROL_CHARS.test(options.fragment)) {
|
|
@@ -69,6 +70,15 @@ function assetViewerHref(options) {
|
|
|
69
70
|
}
|
|
70
71
|
return href + (options.fragment.startsWith("#") ? options.fragment : `#${options.fragment}`);
|
|
71
72
|
}
|
|
73
|
+
function normalizeLocaleSegment(locale) {
|
|
74
|
+
if (locale.length === 0 || locale.includes("/") || locale.includes("\\")) {
|
|
75
|
+
throw new Error("Asset viewer locale must be a non-empty URL segment");
|
|
76
|
+
}
|
|
77
|
+
if (locale === "." || locale === ".." || CONTROL_CHARS.test(locale)) {
|
|
78
|
+
throw new Error("Asset viewer locale must be a safe URL segment");
|
|
79
|
+
}
|
|
80
|
+
return locale.normalize("NFC");
|
|
81
|
+
}
|
|
72
82
|
function assetRawHref(options) {
|
|
73
83
|
const dir = normalizeSettingPath(options.dir, "dir");
|
|
74
84
|
return withBase(options.base, `/${dir}/${encodeAssetPathForUrl(options.path)}`);
|
package/dist/chrome/derive.js
CHANGED
|
@@ -314,12 +314,6 @@ function deriveMdxComponents(ctx) {
|
|
|
314
314
|
t: (key, locale) => ctx.t(key, locale),
|
|
315
315
|
versionedDocsUrl: ctx.versionedDocsUrl
|
|
316
316
|
});
|
|
317
|
-
function HtmlPreviewBound(props) {
|
|
318
|
-
return HtmlPreviewWrapper({
|
|
319
|
-
globalConfig: ctx.settings.htmlPreview ?? null,
|
|
320
|
-
...props
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
317
|
const assetComponentContext = {
|
|
324
318
|
base: ctx.settings.base,
|
|
325
319
|
assetManifest: ctx.assetManifest,
|
|
@@ -329,8 +323,37 @@ function deriveMdxComponents(ctx) {
|
|
|
329
323
|
function createMdxComponentsBound(lang = ctx.defaultLocale, currentVersion, currentSlug = "") {
|
|
330
324
|
const localizedAssetContext = {
|
|
331
325
|
...assetComponentContext,
|
|
326
|
+
locale: lang === ctx.defaultLocale ? void 0 : lang,
|
|
327
|
+
isDefaultLocaleOnlyPath: ctx.isDefaultLocaleOnlyPath,
|
|
332
328
|
t: (key) => ctx.t(key, lang)
|
|
333
329
|
};
|
|
330
|
+
const localizedHtmlPreviewLabels = {
|
|
331
|
+
mobile: ctx.t("htmlPreview.viewport.mobile", lang),
|
|
332
|
+
tablet: ctx.t("htmlPreview.viewport.tablet", lang),
|
|
333
|
+
full: ctx.t("htmlPreview.viewport.full", lang),
|
|
334
|
+
viewportSize: ctx.t("htmlPreview.viewport.label", lang),
|
|
335
|
+
showCode: ctx.t("htmlPreview.source.show", lang),
|
|
336
|
+
hideCode: ctx.t("htmlPreview.source.hide", lang),
|
|
337
|
+
preview: ctx.t("htmlPreview.iframe.title", lang)
|
|
338
|
+
};
|
|
339
|
+
function HtmlPreviewBound(props) {
|
|
340
|
+
const labels = props.labels;
|
|
341
|
+
const effectiveLang = props.lang?.trim() ? props.lang : lang.trim() ? lang : "en";
|
|
342
|
+
return HtmlPreviewWrapper({
|
|
343
|
+
globalConfig: ctx.settings.htmlPreview ?? null,
|
|
344
|
+
...props,
|
|
345
|
+
lang: effectiveLang,
|
|
346
|
+
labels: {
|
|
347
|
+
mobile: labels?.mobile ?? localizedHtmlPreviewLabels.mobile,
|
|
348
|
+
tablet: labels?.tablet ?? localizedHtmlPreviewLabels.tablet,
|
|
349
|
+
full: labels?.full ?? localizedHtmlPreviewLabels.full,
|
|
350
|
+
viewportSize: labels?.viewportSize ?? localizedHtmlPreviewLabels.viewportSize,
|
|
351
|
+
showCode: labels?.showCode ?? localizedHtmlPreviewLabels.showCode,
|
|
352
|
+
hideCode: labels?.hideCode ?? localizedHtmlPreviewLabels.hideCode,
|
|
353
|
+
preview: labels?.preview ?? localizedHtmlPreviewLabels.preview
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
}
|
|
334
357
|
const mdxExtrasDefault = {
|
|
335
358
|
Asset: createAssetCard(localizedAssetContext),
|
|
336
359
|
AssetCode: createAssetCode(localizedAssetContext),
|
|
@@ -348,6 +371,8 @@ function deriveMdxComponents(ctx) {
|
|
|
348
371
|
return createMdxComponents({
|
|
349
372
|
settings: ctx.settings,
|
|
350
373
|
assetManifest: ctx.assetManifest,
|
|
374
|
+
assetViewerLocale: lang === ctx.defaultLocale ? void 0 : lang,
|
|
375
|
+
isDefaultLocaleOnlyPath: ctx.isDefaultLocaleOnlyPath,
|
|
351
376
|
locale: lang,
|
|
352
377
|
currentVersion,
|
|
353
378
|
currentSlug,
|
package/dist/compiled.css
CHANGED
|
@@ -658,6 +658,9 @@
|
|
|
658
658
|
.min-h-\[20rem\] {
|
|
659
659
|
min-height: 20rem;
|
|
660
660
|
}
|
|
661
|
+
.min-h-\[44px\] {
|
|
662
|
+
min-height: 44px;
|
|
663
|
+
}
|
|
661
664
|
.min-h-\[60vh\] {
|
|
662
665
|
min-height: 60vh;
|
|
663
666
|
}
|
|
@@ -754,6 +757,9 @@
|
|
|
754
757
|
.w-icon-xs {
|
|
755
758
|
width: var(--spacing-icon-xs);
|
|
756
759
|
}
|
|
760
|
+
.max-w-\[16rem\] {
|
|
761
|
+
max-width: 16rem;
|
|
762
|
+
}
|
|
757
763
|
.max-w-\[64rem\] {
|
|
758
764
|
max-width: 64rem;
|
|
759
765
|
}
|
|
@@ -772,6 +778,9 @@
|
|
|
772
778
|
.max-w-\[calc\(100vw-2rem\)\] {
|
|
773
779
|
max-width: calc(100vw - 2rem);
|
|
774
780
|
}
|
|
781
|
+
.max-w-\[calc\(100vw-var\(--spacing-hsp-xl\)\)\] {
|
|
782
|
+
max-width: calc(100vw - var(--spacing-hsp-xl));
|
|
783
|
+
}
|
|
775
784
|
.max-w-\[clamp\(50rem\,75vw\,90rem\)\] {
|
|
776
785
|
max-width: clamp(50rem, 75vw, 90rem);
|
|
777
786
|
}
|
|
@@ -793,6 +802,9 @@
|
|
|
793
802
|
.min-w-\[10rem\] {
|
|
794
803
|
min-width: 10rem;
|
|
795
804
|
}
|
|
805
|
+
.min-w-\[44px\] {
|
|
806
|
+
min-width: 44px;
|
|
807
|
+
}
|
|
796
808
|
.flex-1 {
|
|
797
809
|
flex: 1;
|
|
798
810
|
}
|
package/dist/config.d.ts
CHANGED
|
@@ -18,11 +18,13 @@
|
|
|
18
18
|
* `zudoDoc()` SHALLOW-merges the user's fields over {@link DEFAULT_SETTINGS} —
|
|
19
19
|
* top-level fields only (`{ ...DEFAULT_SETTINGS, ...user }`). A supplied nested
|
|
20
20
|
* object (e.g. `colorMode`, `metaTags`) REPLACES the default wholesale; it is
|
|
21
|
-
* NOT deep-merged key-by-key.
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
21
|
+
* NOT deep-merged key-by-key. Nested config types that intentionally expose
|
|
22
|
+
* optional keys (such as `FrontmatterPreviewConfig` and
|
|
23
|
+
* `AssetViewerIndexingConfig`) get their per-key defaults at the read site;
|
|
24
|
+
* this shallow merge never fills nested keys. `FaviconConfig` is also
|
|
25
|
+
* all-optional — wholesale replacement IS its semantics (only the supplied
|
|
26
|
+
* slots emit a `<link rel="icon">`), and its default is `undefined`, so there
|
|
27
|
+
* is nothing for a partial object to clobber.
|
|
26
28
|
* `zudoDoc()` also supplies the Wave-3 package defaults
|
|
27
29
|
* (`buildDocsSchema`/`directiveVocabulary`/`translations`/`colorSchemes`/tag
|
|
28
30
|
* vocabulary) unless overridden, and returns a **complete `ZfbConfig`** — the
|
|
@@ -65,7 +67,7 @@ import type { ZfbConfig, BundleConfig } from "@takazudo/zfb/config";
|
|
|
65
67
|
import type { ZodType } from "zod";
|
|
66
68
|
import type { DirectiveVocabulary, PresetTranslations, PresetTagVocabularyEntry } from "./preset.js";
|
|
67
69
|
import type { ColorScheme } from "./color-scheme-utils.js";
|
|
68
|
-
import type { Settings, ColorModeConfig, LocaleConfig, MetaTagsConfig, SiteHeadConfig, TagPlacement, TagGovernanceMode, VersionConfig, FooterConfig, HeaderNavItem, HeaderRightItem, HomeConfig, FrontmatterPreviewConfig, BodyFootUtilAreaConfig, HtmlPreviewConfig, FaviconConfig } from "./settings.js";
|
|
70
|
+
import type { Settings, ColorModeConfig, LocaleConfig, MetaTagsConfig, SiteHeadConfig, TagPlacement, TagGovernanceMode, VersionConfig, FooterConfig, HeaderNavItem, HeaderRightItem, HomeConfig, AssetViewerIndexingConfig, FrontmatterPreviewConfig, BodyFootUtilAreaConfig, HtmlPreviewConfig, FaviconConfig } from "./settings.js";
|
|
69
71
|
/** The `settings.claudeResources` block (or `false` when disabled). */
|
|
70
72
|
type ClaudeResourcesConfig = {
|
|
71
73
|
claudeDir: string;
|
|
@@ -188,6 +190,11 @@ export interface ZudoDocConfig {
|
|
|
188
190
|
* @default true
|
|
189
191
|
*/
|
|
190
192
|
mermaid?: boolean;
|
|
193
|
+
/**
|
|
194
|
+
* Enable transclusion of other Markdown/MDX files via `:::include`.
|
|
195
|
+
* @default false
|
|
196
|
+
*/
|
|
197
|
+
transclude?: boolean;
|
|
191
198
|
/**
|
|
192
199
|
* Add `noindex,nofollow` to every page (for internal docs).
|
|
193
200
|
* @default false
|
|
@@ -377,6 +384,8 @@ export interface ZudoDocConfig {
|
|
|
377
384
|
assetViewerExclude?: string[];
|
|
378
385
|
/** When `true` (and `assetViewer` is `true`), generate a listing page at `/<assetViewerRoutePrefix>/` showing every managed asset as a folder tree. No effect when `assetViewer` is `false`. @default false */
|
|
379
386
|
assetViewerIndex?: boolean;
|
|
387
|
+
/** Per-output opt-in controls for indexing generated asset-viewer pages. Omitted keys are off; `false` disables all asset-page indexing. @default false */
|
|
388
|
+
assetViewerIndexing?: AssetViewerIndexingConfig | false;
|
|
380
389
|
/**
|
|
381
390
|
* Body-foot utility area (doc-history / view-source), or `false` to disable.
|
|
382
391
|
* @default false
|
package/dist/config.js
CHANGED
|
@@ -53,6 +53,7 @@ const DEFAULT_SETTINGS = {
|
|
|
53
53
|
defaultLocale: "en",
|
|
54
54
|
locales: {},
|
|
55
55
|
mermaid: true,
|
|
56
|
+
transclude: false,
|
|
56
57
|
noindex: false,
|
|
57
58
|
editUrl: false,
|
|
58
59
|
githubUrl: false,
|
|
@@ -98,6 +99,7 @@ const DEFAULT_SETTINGS = {
|
|
|
98
99
|
assetViewerRoutePrefix: "files",
|
|
99
100
|
assetViewerExclude: [],
|
|
100
101
|
assetViewerIndex: false,
|
|
102
|
+
assetViewerIndexing: false,
|
|
101
103
|
bodyFootUtilArea: false,
|
|
102
104
|
htmlPreview: void 0,
|
|
103
105
|
versions: false,
|
|
@@ -9,10 +9,14 @@ export interface CreateContentLinkOptions {
|
|
|
9
9
|
assetManifest: AssetManifest | null;
|
|
10
10
|
routePrefix: string;
|
|
11
11
|
dir: string;
|
|
12
|
+
/** Non-default locale segment used by asset-viewer links. */
|
|
13
|
+
locale?: string;
|
|
14
|
+
/** Match viewer paths that intentionally remain default-locale-only. */
|
|
15
|
+
isDefaultLocaleOnlyPath?: (path: string) => boolean;
|
|
12
16
|
}
|
|
13
17
|
/**
|
|
14
18
|
* Bind ContentLink to an asset manifest. Only exact manifest entries are
|
|
15
19
|
* decorated and redirected; every other anchor follows ContentLink verbatim.
|
|
16
20
|
*/
|
|
17
|
-
export declare function createContentLink({ base, assetManifest, routePrefix, dir, }: CreateContentLinkOptions): (props: Props) => JSX.Element;
|
|
21
|
+
export declare function createContentLink({ base, assetManifest, routePrefix, dir, locale, isDefaultLocaleOnlyPath, }: CreateContentLinkOptions): (props: Props) => JSX.Element;
|
|
18
22
|
export {};
|