@takazudo/zudo-doc 5.5.3 → 5.7.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 +51 -0
- package/README.md +39 -0
- package/dist/chrome/derive.d.ts +46 -0
- package/dist/chrome/derive.js +6 -2
- package/dist/config-assertions/index.d.ts +31 -0
- package/dist/config-assertions/index.js +24 -0
- package/dist/config.d.ts +23 -2
- package/dist/config.js +3 -0
- package/dist/current-path/index.d.ts +27 -0
- package/dist/current-path/index.js +11 -0
- package/dist/design-token-panel-bootstrap.d.ts +89 -23
- package/dist/design-token-panel-bootstrap.js +19 -6
- package/dist/doc-page-props/index.d.ts +5 -67
- package/dist/doc-route-entries/index.d.ts +10 -95
- package/dist/doc-route-entries/index.js +1 -78
- package/dist/doc-route-paths/index.d.ts +1 -1
- package/dist/head-with-defaults/index.d.ts +3 -1
- package/dist/head-with-defaults/index.js +76 -4
- package/dist/header/nav-active.d.ts +31 -0
- package/dist/header/nav-active.js +2 -1
- package/dist/header/nav-overflow-generated-script.d.ts +11 -0
- package/dist/header/nav-overflow-generated-script.js +302 -0
- package/dist/header/nav-overflow-script.d.ts +1 -1
- package/dist/header/nav-overflow-script.js +1 -286
- package/dist/header-with-defaults/index.js +11 -2
- package/dist/i18n-version/language-switcher.d.ts +6 -0
- package/dist/i18n-version/language-switcher.js +3 -1
- package/dist/i18n-version/version-switcher.d.ts +6 -0
- package/dist/i18n-version/version-switcher.js +3 -1
- package/dist/md-utils/index.js +33 -1
- package/dist/nav-source-docs/index.d.ts +7 -11
- package/dist/plugins/route-pages-candidates.d.ts +19 -0
- package/dist/plugins/route-pages-candidates.js +17 -0
- package/dist/plugins/routes.d.ts +46 -0
- package/dist/plugins/routes.js +72 -18
- package/dist/preset.d.ts +12 -1
- package/dist/preset.js +2 -0
- package/dist/route-context/index.js +2 -2
- package/dist/routes/_chrome.d.ts +1 -1
- package/dist/routes/_chrome.js +4 -0
- package/dist/routes/_context.d.ts +3 -3
- package/dist/routes/_design-token-panel-bootstrap.d.ts +18 -0
- package/dist/routes/_design-token-panel-bootstrap.js +11 -0
- package/dist/routes/_docs-helpers.d.ts +1 -36
- package/dist/routes/_docs-helpers.js +0 -138
- package/dist/safelist.css +1 -1
- package/dist/search-widget-script/generated-script.d.ts +8 -0
- package/dist/search-widget-script/generated-script.js +465 -0
- package/dist/search-widget-script/index.d.ts +1 -18
- package/dist/search-widget-script/index.js +1 -443
- package/dist/settings.d.ts +82 -1
- package/dist/sidebar-toggle-island/index.js +2 -1
- package/dist/sidebar-tree/category-meta.d.ts +9 -0
- package/dist/sidebar-tree/category-meta.js +21 -12
- package/dist/sidebar-tree-island/index.d.ts +8 -1
- package/dist/sidebar-tree-island/index.js +16 -14
- package/dist/site-schema/doc-route-entries.d.ts +89 -0
- package/dist/site-schema/doc-route-entries.js +83 -0
- package/dist/site-schema/index.d.ts +17 -0
- package/dist/site-schema/index.js +46 -0
- package/dist/site-schema/nav-tree.d.ts +28 -0
- package/dist/site-schema/nav-tree.js +138 -0
- package/dist/site-schema/types.d.ts +97 -0
- package/dist/site-schema/types.js +0 -0
- package/dist/theme/theme-pack-provider.d.ts +34 -3
- package/dist/theme/theme-pack-provider.js +30 -2
- package/dist/transitions/index.d.ts +1 -0
- package/dist/transitions/index.js +2 -0
- package/dist/transitions/nested-island-props-refresh.d.ts +19 -0
- package/dist/transitions/nested-island-props-refresh.js +104 -0
- package/eject/header/header.tsx +13 -5
- package/eject/header/nav-active.ts +16 -1
- package/eject/header/nav-class-tokens.ts +9 -5
- package/eject/header/nav-overflow-generated-script.ts +29 -0
- package/eject/header/nav-overflow-script.ts +26 -304
- package/eject/sidebar-toggle-island/index.tsx +13 -1
- package/eject/sidebar-tree-island/index.tsx +44 -20
- package/package.json +25 -12
- package/routes-src/_chrome.tsx +21 -9
- package/routes-src/_design-token-panel-bootstrap.tsx +63 -0
- package/routes-src/_docs-helpers.ts +18 -225
- package/routes-src/_virtual.d.ts +5 -2
- package/virtual-modules.d.ts +5 -2
|
@@ -2,100 +2,15 @@ import type { DocPageEntry, DocNavNode, AutoIndexNode, DocPageBaseProps } from "
|
|
|
2
2
|
import type { NavSourceDocs } from "../nav-source-docs/index.js";
|
|
3
3
|
import type { BreadcrumbItem } from "../breadcrumb/types.js";
|
|
4
4
|
import type { HeadingItem } from "../extract-headings/index.js";
|
|
5
|
-
import type {
|
|
5
|
+
import type { BuildDocRouteEntriesArgs as BuildDocRouteEntriesArgsGeneric, DocRouteEntriesAPI as DocRouteEntriesAPIGeneric, DocRouteEntriesContext as DocRouteEntriesContextGeneric, DocRouteEntry as DocRouteEntryGeneric } from "../site-schema/doc-route-entries.js";
|
|
6
|
+
export { createDocRouteEntries } from "../site-schema/doc-route-entries.js";
|
|
6
7
|
export type { DocPageEntry, DocNavNode, AutoIndexNode, DocPageBaseProps, NavSourceDocs };
|
|
7
|
-
/** One enumerated doc route: a content entry or an auto-generated category
|
|
8
|
-
* index, with all per-page derived data pre-computed. */
|
|
9
|
-
export interface DocRouteEntry {
|
|
10
|
-
/** Canonical route slug ("" for the docs root index — #1891). */
|
|
11
|
-
slug: string;
|
|
12
|
-
/** Optional-catchall params array — `toSlugParams(slug)` ([] for the root). */
|
|
13
|
-
slugParams: string[];
|
|
14
|
-
/**
|
|
15
|
-
* True when the entry came from the base collection rather than the locale
|
|
16
|
-
* collection (`!localeSlugSet.has(slug)`). Only meaningful on routes whose
|
|
17
|
-
* nav source performs a locale merge — routes without one (default-locale /
|
|
18
|
-
* versioned-EN, where `localeSlugSet` is empty) must ignore this field.
|
|
19
|
-
* Always false for autoIndex items.
|
|
20
|
-
*/
|
|
21
|
-
isFallback: boolean;
|
|
22
|
-
/** Shared page props (kind/entry/autoIndex/breadcrumbs/prev/next/headings). */
|
|
23
|
-
props: DocPageBaseProps;
|
|
24
|
-
}
|
|
25
|
-
export interface BuildDocRouteEntriesArgs {
|
|
26
|
-
/** Identity-stable nav source for this route's (locale, version) context. */
|
|
27
|
-
source: NavSourceDocs;
|
|
28
|
-
/** Active locale for nav-tree labels and breadcrumbs. */
|
|
29
|
-
locale: string;
|
|
30
|
-
/**
|
|
31
|
-
* Unique memo signature for this route context. Each route file passes its
|
|
32
|
-
* own prefix plus the loop variables (version slug / locale), e.g.
|
|
33
|
-
* "docs;en", "locale-docs;ja", "v-docs;1.0", "v-locale-docs;1.0;ja" —
|
|
34
|
-
* call sites that share a docs array identity must never collide on a key.
|
|
35
|
-
*/
|
|
36
|
-
routeSig: string;
|
|
37
|
-
/** Versioned URL closure bound to the route's version (+ locale). Presence
|
|
38
|
-
* switches the versioned behaviors (breadcrumbs, prev/next, child hrefs). */
|
|
39
|
-
urlFor?: (slug: string) => string;
|
|
40
|
-
}
|
|
41
8
|
export type { BreadcrumbItem, HeadingItem };
|
|
42
|
-
/**
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
export interface DocRouteEntriesContext {
|
|
51
|
-
/** Default locale code (drives the breadcrumb base-prefix selection). */
|
|
52
|
-
defaultLocale: string;
|
|
53
|
-
/** Build the nav tree for a locale (4-arg form with an explicit href builder). */
|
|
54
|
-
buildNavTree: (docs: DocPageEntry[], locale: string, categoryMeta: Map<string, CategoryMeta> | undefined, buildHref: (slug: string, locale: string) => string) => DocNavNode[];
|
|
55
|
-
/** Build a docs URL for the given slug and locale. */
|
|
56
|
-
docsUrl: (slug: string, locale?: string) => string;
|
|
57
|
-
/** Prefix a path with the configured base directory. */
|
|
58
|
-
withBase: (path: string) => string;
|
|
59
|
-
/** Collect all auto-generated index nodes (categories without index.mdx). */
|
|
60
|
-
collectAutoIndexNodes: (tree: DocNavNode[]) => AutoIndexNode[];
|
|
61
|
-
/** Determine the nav section (categoryMatch) for a slug. */
|
|
62
|
-
getNavSectionForSlug: (slug: string) => string | undefined;
|
|
63
|
-
/** Filter top-level nav nodes by a categoryMatch value. */
|
|
64
|
-
getNavSubtree: (tree: DocNavNode[], categoryMatch?: string) => DocNavNode[];
|
|
65
|
-
/** Convert a content entry slug to a canonical route slug. */
|
|
66
|
-
toRouteSlug: (entrySlug: string) => string;
|
|
67
|
-
/** Convert a canonical route slug to an optional-catchall params array. */
|
|
68
|
-
toSlugParams: (slug: string) => string[];
|
|
69
|
-
/** Extract headings from a raw MDX body (bound to settings depth/strategy). */
|
|
70
|
-
extractHeadings: (body: string) => HeadingItem[];
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Result of `createDocRouteEntries`. Contains the `buildDocRouteEntries`
|
|
74
|
-
* function bound to the injected context.
|
|
75
|
-
*/
|
|
76
|
-
export interface DocRouteEntriesAPI {
|
|
77
|
-
/**
|
|
78
|
-
* Enumerate all doc routes for one (locale, version) context, with per-entry
|
|
79
|
-
* derived data pre-computed. Memoized per build on the identity-stable
|
|
80
|
-
* `source.docs` array.
|
|
81
|
-
*/
|
|
82
|
-
buildDocRouteEntries: (args: BuildDocRouteEntriesArgs) => DocRouteEntry[];
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Create the `buildDocRouteEntries` function bound to the host's injected
|
|
86
|
-
* context.
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* ```ts
|
|
90
|
-
* // pages/lib/_doc-route-entries.ts (thin stub)
|
|
91
|
-
* import { createDocRouteEntries } from "@takazudo/zudo-doc/doc-route-entries";
|
|
92
|
-
* import { buildNavTree, buildBreadcrumbs, collectAutoIndexNodes } from "@/utils/docs";
|
|
93
|
-
* import { getNavSectionForSlug, getNavSubtree } from "@/utils/nav-scope";
|
|
94
|
-
* import { toRouteSlug, toSlugParams } from "@takazudo/zudo-doc/slug";
|
|
95
|
-
* import { extractHeadings } from "./_extract-headings";
|
|
96
|
-
*
|
|
97
|
-
* export const { buildDocRouteEntries } = createDocRouteEntries(routeContext);
|
|
98
|
-
* export type { DocRouteEntry, BuildDocRouteEntriesArgs };
|
|
99
|
-
* ```
|
|
100
|
-
*/
|
|
101
|
-
export declare function createDocRouteEntries(ctx: DocRouteEntriesContext): DocRouteEntriesAPI;
|
|
9
|
+
/** One enumerated doc route, carrying a zfb collection entry. */
|
|
10
|
+
export type DocRouteEntry = DocRouteEntryGeneric<DocPageEntry>;
|
|
11
|
+
/** Arguments to `buildDocRouteEntries` for one (locale, version) context. */
|
|
12
|
+
export type BuildDocRouteEntriesArgs = BuildDocRouteEntriesArgsGeneric<DocPageEntry>;
|
|
13
|
+
/** The context slice `createDocRouteEntries` derives its bag from. */
|
|
14
|
+
export type DocRouteEntriesContext = DocRouteEntriesContextGeneric<DocPageEntry>;
|
|
15
|
+
/** The functions `createDocRouteEntries` returns. */
|
|
16
|
+
export type DocRouteEntriesAPI = DocRouteEntriesAPIGeneric<DocPageEntry>;
|
|
@@ -1,81 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { buildBreadcrumbs as buildBreadcrumbsImpl } from "../routes/_docs-helpers.js";
|
|
3
|
-
import {
|
|
4
|
-
resolveDocPrevNext,
|
|
5
|
-
flattenSubtree,
|
|
6
|
-
rewriteNavHref,
|
|
7
|
-
remapNavChildHrefs
|
|
8
|
-
} from "../doc-route-paths/index.js";
|
|
9
|
-
function createDocRouteEntries(ctx) {
|
|
10
|
-
const defaultLocale = ctx.defaultLocale;
|
|
11
|
-
const buildNavTree = (docs, locale, categoryMeta) => ctx.buildNavTree(docs, locale, categoryMeta, (slug, loc) => ctx.docsUrl(slug, loc));
|
|
12
|
-
const buildBreadcrumbs = (tree, slug, locale, urlFor) => buildBreadcrumbsImpl(
|
|
13
|
-
tree,
|
|
14
|
-
slug,
|
|
15
|
-
locale === defaultLocale ? ctx.withBase("/") : ctx.withBase(`/${locale}/`),
|
|
16
|
-
urlFor
|
|
17
|
-
);
|
|
18
|
-
const collectAutoIndexNodes = ctx.collectAutoIndexNodes;
|
|
19
|
-
const getNavSectionForSlug = ctx.getNavSectionForSlug;
|
|
20
|
-
const getNavSubtree = ctx.getNavSubtree;
|
|
21
|
-
const toRouteSlug = ctx.toRouteSlug;
|
|
22
|
-
const toSlugParams = ctx.toSlugParams;
|
|
23
|
-
const extractHeadings = ctx.extractHeadings;
|
|
24
|
-
function buildDocRouteEntries(args) {
|
|
25
|
-
const { source, locale, routeSig, urlFor } = args;
|
|
26
|
-
return memoizeDerived([source.docs], `docRouteEntries;${routeSig}`, () => {
|
|
27
|
-
const { docs, navDocs, categoryMeta, localeSlugSet } = source;
|
|
28
|
-
const tree = buildNavTree(navDocs, locale, categoryMeta);
|
|
29
|
-
const breadcrumbTree = urlFor ? tree : buildNavTree(docs, locale, categoryMeta);
|
|
30
|
-
const result = [];
|
|
31
|
-
for (const entry of docs) {
|
|
32
|
-
if (entry.data.category_no_page === true) continue;
|
|
33
|
-
const slug = entry.data.slug ?? toRouteSlug(entry.slug);
|
|
34
|
-
const navSection = getNavSectionForSlug(slug);
|
|
35
|
-
const subtree = getNavSubtree(tree, navSection);
|
|
36
|
-
const { prev: prevNode, next: nextNode } = resolveDocPrevNext(
|
|
37
|
-
tree,
|
|
38
|
-
flattenSubtree(subtree),
|
|
39
|
-
slug,
|
|
40
|
-
entry.data
|
|
41
|
-
);
|
|
42
|
-
result.push({
|
|
43
|
-
slug,
|
|
44
|
-
slugParams: toSlugParams(slug),
|
|
45
|
-
isFallback: !localeSlugSet.has(slug),
|
|
46
|
-
props: {
|
|
47
|
-
kind: "entry",
|
|
48
|
-
entry,
|
|
49
|
-
breadcrumbs: buildBreadcrumbs(breadcrumbTree, slug, locale, urlFor),
|
|
50
|
-
prev: rewriteNavHref(prevNode, urlFor),
|
|
51
|
-
next: rewriteNavHref(nextNode, urlFor),
|
|
52
|
-
headings: extractHeadings(entry.body ?? "")
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
for (const node of collectAutoIndexNodes(tree)) {
|
|
57
|
-
result.push({
|
|
58
|
-
slug: node.slug,
|
|
59
|
-
slugParams: toSlugParams(node.slug),
|
|
60
|
-
isFallback: false,
|
|
61
|
-
props: {
|
|
62
|
-
kind: "autoIndex",
|
|
63
|
-
autoIndex: urlFor ? {
|
|
64
|
-
...node,
|
|
65
|
-
children: remapNavChildHrefs(node.children, urlFor)
|
|
66
|
-
} : node,
|
|
67
|
-
breadcrumbs: buildBreadcrumbs(breadcrumbTree, node.slug, locale, urlFor),
|
|
68
|
-
prev: null,
|
|
69
|
-
next: null,
|
|
70
|
-
headings: []
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
return result;
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
return { buildDocRouteEntries };
|
|
78
|
-
}
|
|
1
|
+
import { createDocRouteEntries } from "../site-schema/doc-route-entries.js";
|
|
79
2
|
export {
|
|
80
3
|
createDocRouteEntries
|
|
81
4
|
};
|
|
@@ -4,7 +4,7 @@ import type { JSX } from "preact";
|
|
|
4
4
|
import type { HeadProps } from "../head/types.js";
|
|
5
5
|
import type { ColorSchemeProviderColorMode } from "../theme/color-scheme-provider.js";
|
|
6
6
|
import type { ChromeContext } from "../factory-context/index.js";
|
|
7
|
-
import type { Settings } from "../settings.js";
|
|
7
|
+
import type { Settings, FaviconConfig } from "../settings.js";
|
|
8
8
|
export interface HeadWithDefaultsProps {
|
|
9
9
|
/** Page title forwarded to og:title. Required. */
|
|
10
10
|
title: string;
|
|
@@ -33,6 +33,8 @@ export interface HeadWithDefaultsSettings {
|
|
|
33
33
|
sidebarResizer?: boolean;
|
|
34
34
|
/** Configured theme-pack slug (ADR `docs/adr/theme-packs.md`, #2822). */
|
|
35
35
|
themePack?: string;
|
|
36
|
+
/** Favicon link set — see {@link resolveFaviconLinks} for the emission table. */
|
|
37
|
+
favicon?: string | FaviconConfig | false;
|
|
36
38
|
}
|
|
37
39
|
/**
|
|
38
40
|
* Create a `HeadWithDefaults` component from the unified {@link ChromeContext}
|
|
@@ -6,8 +6,82 @@ import ThemePackProvider, {
|
|
|
6
6
|
themePackVersionMap
|
|
7
7
|
} from "../theme/theme-pack-provider.js";
|
|
8
8
|
import { DEFAULT_THEME_PACK_SLUG } from "../theme-pack-switcher/theme-pack-sync.js";
|
|
9
|
+
import { renderAutoLogoIconSvg } from "../auto-logo/icon.js";
|
|
9
10
|
import { deriveComposeMetaTitle, deriveColorSchemeGenerators } from "../chrome/derive.js";
|
|
10
11
|
import { assertChromeContext } from "../chrome/assert-chrome-context.js";
|
|
12
|
+
const FAVICON_AUTO = "auto";
|
|
13
|
+
const DEFAULT_FAVICON = {
|
|
14
|
+
svg: "/favicon.svg",
|
|
15
|
+
ico: "/favicon.ico",
|
|
16
|
+
png32: "/favicon-32x32.png",
|
|
17
|
+
png16: "/favicon-16x16.png"
|
|
18
|
+
};
|
|
19
|
+
const FAVICON_TYPE_BY_EXT = {
|
|
20
|
+
svg: "image/svg+xml",
|
|
21
|
+
png: "image/png",
|
|
22
|
+
ico: "image/x-icon",
|
|
23
|
+
jpg: "image/jpeg",
|
|
24
|
+
jpeg: "image/jpeg",
|
|
25
|
+
gif: "image/gif",
|
|
26
|
+
webp: "image/webp",
|
|
27
|
+
avif: "image/avif"
|
|
28
|
+
};
|
|
29
|
+
function faviconType(value) {
|
|
30
|
+
const path = value.split(/[?#]/)[0] ?? "";
|
|
31
|
+
const file = path.slice(path.lastIndexOf("/") + 1);
|
|
32
|
+
const dot = file.lastIndexOf(".");
|
|
33
|
+
if (dot < 0) return void 0;
|
|
34
|
+
return FAVICON_TYPE_BY_EXT[file.slice(dot + 1).toLowerCase()];
|
|
35
|
+
}
|
|
36
|
+
function faviconHref(value, withBase) {
|
|
37
|
+
return value.startsWith("/") ? withBase(value) : value;
|
|
38
|
+
}
|
|
39
|
+
function resolveFaviconLinks(favicon, siteName, withBase) {
|
|
40
|
+
if (favicon === false) return [];
|
|
41
|
+
if (typeof favicon === "string") {
|
|
42
|
+
if (favicon === FAVICON_AUTO) {
|
|
43
|
+
const svg = encodeURIComponent(renderAutoLogoIconSvg(siteName));
|
|
44
|
+
return [{ rel: "icon", type: "image/svg+xml", href: `data:image/svg+xml,${svg}` }];
|
|
45
|
+
}
|
|
46
|
+
const type = faviconType(favicon);
|
|
47
|
+
return [
|
|
48
|
+
{
|
|
49
|
+
rel: "icon",
|
|
50
|
+
...type !== void 0 ? { type } : {},
|
|
51
|
+
href: faviconHref(favicon, withBase)
|
|
52
|
+
}
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
const slots = favicon ?? DEFAULT_FAVICON;
|
|
56
|
+
const links = [];
|
|
57
|
+
if (slots.svg !== void 0) {
|
|
58
|
+
links.push({
|
|
59
|
+
rel: "icon",
|
|
60
|
+
type: faviconType(slots.svg) ?? "image/svg+xml",
|
|
61
|
+
href: faviconHref(slots.svg, withBase)
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
if (slots.ico !== void 0) {
|
|
65
|
+
links.push({ rel: "icon", href: faviconHref(slots.ico, withBase), sizes: "any" });
|
|
66
|
+
}
|
|
67
|
+
if (slots.png32 !== void 0) {
|
|
68
|
+
links.push({
|
|
69
|
+
rel: "icon",
|
|
70
|
+
type: faviconType(slots.png32) ?? "image/png",
|
|
71
|
+
sizes: "32x32",
|
|
72
|
+
href: faviconHref(slots.png32, withBase)
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (slots.png16 !== void 0) {
|
|
76
|
+
links.push({
|
|
77
|
+
rel: "icon",
|
|
78
|
+
type: faviconType(slots.png16) ?? "image/png",
|
|
79
|
+
sizes: "16x16",
|
|
80
|
+
href: faviconHref(slots.png16, withBase)
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return links;
|
|
84
|
+
}
|
|
11
85
|
function createHeadWithDefaults(ctx) {
|
|
12
86
|
assertChromeContext(ctx, "createHeadWithDefaults");
|
|
13
87
|
const settings = ctx.settings;
|
|
@@ -19,6 +93,7 @@ function createHeadWithDefaults(ctx) {
|
|
|
19
93
|
const themePackEnabled = themePackRegistry !== null ? themePackVersionMap(themePackRegistry) : null;
|
|
20
94
|
const themePackConfigured = settings.themePack ?? DEFAULT_THEME_PACK_SLUG;
|
|
21
95
|
const themePackBase = withBase("/");
|
|
96
|
+
const faviconLinks = resolveFaviconLinks(settings.favicon, settings.siteName, withBase);
|
|
22
97
|
function HeadWithDefaults({
|
|
23
98
|
title,
|
|
24
99
|
description,
|
|
@@ -65,10 +140,7 @@ function createHeadWithDefaults(ctx) {
|
|
|
65
140
|
}
|
|
66
141
|
),
|
|
67
142
|
settings.sidebarResizer && /* @__PURE__ */ jsx("script", { dangerouslySetInnerHTML: { __html: SIDEBAR_RESIZER_RESTORE_SCRIPT } }),
|
|
68
|
-
/* @__PURE__ */ jsx("link", {
|
|
69
|
-
/* @__PURE__ */ jsx("link", { rel: "icon", href: withBase("/favicon.ico"), sizes: "any" }),
|
|
70
|
-
/* @__PURE__ */ jsx("link", { rel: "icon", type: "image/png", sizes: "32x32", href: withBase("/favicon-32x32.png") }),
|
|
71
|
-
/* @__PURE__ */ jsx("link", { rel: "icon", type: "image/png", sizes: "16x16", href: withBase("/favicon-16x16.png") }),
|
|
143
|
+
faviconLinks.map((attrs, i) => /* @__PURE__ */ jsx("link", { ...attrs }, i)),
|
|
72
144
|
canonical !== void 0 && /* @__PURE__ */ jsx("link", { rel: "canonical", href: canonical }),
|
|
73
145
|
ctx.settings.head && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
74
146
|
ctx.settings.head.preconnect?.map((p, i) => /* @__PURE__ */ jsx(
|
|
@@ -25,6 +25,37 @@ export interface NavItemLike {
|
|
|
25
25
|
* pathForMatch(null, "ja", "en") === ""
|
|
26
26
|
*/
|
|
27
27
|
export declare function pathForMatch(pathWithoutBase: string, lang: string | undefined, defaultLocale: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Pick the deepest header-nav path that the current page lives under.
|
|
30
|
+
*
|
|
31
|
+
* The legacy template flattens parent + child paths, filters by
|
|
32
|
+
* `pathForMatch.startsWith(p)`, and picks the longest match — this keeps
|
|
33
|
+
* a child link active even when its parent's path is also a prefix of
|
|
34
|
+
* the current page.
|
|
35
|
+
*
|
|
36
|
+
* Returns `undefined` when no nav entry matches; callers should treat
|
|
37
|
+
* that as "no active link."
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* Segment-aware prefix test: nav path `/docs/guides` matches `/docs/guides`
|
|
41
|
+
* and `/docs/guides/...` but NOT `/docs/guideship`.
|
|
42
|
+
*
|
|
43
|
+
* Exported (not just module-private) so `scripts/gen-nav-overflow-script.mjs`
|
|
44
|
+
* can embed it verbatim via `.toString()` alongside `computeActiveNavPath` —
|
|
45
|
+
* that function closes over this one, so a bare `computeActiveNavPath.toString()`
|
|
46
|
+
* embed would reference an undefined `pathMatchesNavPath` in the browser (see
|
|
47
|
+
* the caution note on `computeActiveNavPath` below). Kept self-contained (no
|
|
48
|
+
* outer references) for the same reason. The generator freezes both into the
|
|
49
|
+
* committed `nav-overflow-generated-script.ts` literal at package build time
|
|
50
|
+
* (zudolab/zudo-doc#3534) — this is no longer a live per-module-eval embed.
|
|
51
|
+
*/
|
|
52
|
+
export declare function pathMatchesNavPath(currentPath: string, navPath: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* CAUTION (zudolab/zudo-doc#3398): this closes over `pathMatchesNavPath`
|
|
55
|
+
* above. `scripts/gen-nav-overflow-script.mjs` embeds both via `.toString()`
|
|
56
|
+
* (never this one alone) so the frozen browser script (`./nav-overflow-generated-script.ts`,
|
|
57
|
+
* zudolab/zudo-doc#3534) is self-contained.
|
|
58
|
+
*/
|
|
28
59
|
export declare function computeActiveNavPath(navItems: readonly NavItemLike[], pathForMatchValue: string): string | undefined;
|
|
29
60
|
/**
|
|
30
61
|
* Active-state predicate for a top-level nav item: the item itself, or
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Returns the frozen desktop-nav overflow controller IIFE script. NOTE: the
|
|
2
|
+
* vitest drift guard imports buildNavOverflowScript from
|
|
3
|
+
* scripts/gen-nav-overflow-script.mjs (a fresh re-generation) — NEVER from
|
|
4
|
+
* this module: comparing NAV_OVERFLOW_SCRIPT below against this same file's
|
|
5
|
+
* function would be a vacuous self-comparison. */
|
|
6
|
+
export declare function buildNavOverflowScript(): string;
|
|
7
|
+
/** Client-side script string for the desktop header nav overflow controller.
|
|
8
|
+
* See the module header of this generator for the embedding contract; see
|
|
9
|
+
* current-path/index.ts / header/nav-active.ts / header/nav-class-tokens.ts /
|
|
10
|
+
* transitions/page-events.ts for the frozen sources. */
|
|
11
|
+
export declare const NAV_OVERFLOW_SCRIPT: string;
|