@takazudo/zudo-doc 0.1.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/LICENSE +21 -0
- package/README.md +18 -0
- package/dist/body-foot-util/body-foot-util-area.d.ts +55 -0
- package/dist/body-foot-util/body-foot-util-area.js +71 -0
- package/dist/body-foot-util/edit-link.d.ts +45 -0
- package/dist/body-foot-util/edit-link.js +42 -0
- package/dist/body-foot-util/index.d.ts +3 -0
- package/dist/body-foot-util/index.js +11 -0
- package/dist/breadcrumb/breadcrumb.d.ts +57 -0
- package/dist/breadcrumb/breadcrumb.js +113 -0
- package/dist/breadcrumb/find-path.d.ts +16 -0
- package/dist/breadcrumb/find-path.js +13 -0
- package/dist/breadcrumb/index.d.ts +4 -0
- package/dist/breadcrumb/index.js +7 -0
- package/dist/breadcrumb/types.d.ts +32 -0
- package/dist/breadcrumb/types.js +0 -0
- package/dist/code-syntax/code-block-enhancer-script.d.ts +3 -0
- package/dist/code-syntax/code-block-enhancer-script.js +165 -0
- package/dist/code-syntax/code-block-enhancer.d.ts +22 -0
- package/dist/code-syntax/code-block-enhancer.js +13 -0
- package/dist/code-syntax/index.d.ts +8 -0
- package/dist/code-syntax/index.js +29 -0
- package/dist/code-syntax/mermaid-init-script.d.ts +51 -0
- package/dist/code-syntax/mermaid-init-script.js +225 -0
- package/dist/code-syntax/mermaid-init.d.ts +48 -0
- package/dist/code-syntax/mermaid-init.js +14 -0
- package/dist/code-syntax/tabs-init-script.d.ts +3 -0
- package/dist/code-syntax/tabs-init-script.js +106 -0
- package/dist/code-syntax/tabs-init.d.ts +24 -0
- package/dist/code-syntax/tabs-init.js +10 -0
- package/dist/code-syntax/tabs.d.ts +36 -0
- package/dist/code-syntax/tabs.js +62 -0
- package/dist/content/component-map.d.ts +51 -0
- package/dist/content/component-map.js +29 -0
- package/dist/content/content-blockquote.d.ts +11 -0
- package/dist/content/content-blockquote.js +14 -0
- package/dist/content/content-code.d.ts +26 -0
- package/dist/content/content-code.js +39 -0
- package/dist/content/content-link.d.ts +12 -0
- package/dist/content/content-link.js +43 -0
- package/dist/content/content-ol.d.ts +11 -0
- package/dist/content/content-ol.js +15 -0
- package/dist/content/content-paragraph.d.ts +10 -0
- package/dist/content/content-paragraph.js +7 -0
- package/dist/content/content-strong.d.ts +11 -0
- package/dist/content/content-strong.js +14 -0
- package/dist/content/content-table.d.ts +11 -0
- package/dist/content/content-table.js +14 -0
- package/dist/content/content-ul.d.ts +11 -0
- package/dist/content/content-ul.js +15 -0
- package/dist/content/heading-h2.d.ts +14 -0
- package/dist/content/heading-h2.js +18 -0
- package/dist/content/heading-h3.d.ts +14 -0
- package/dist/content/heading-h3.js +18 -0
- package/dist/content/heading-h4.d.ts +14 -0
- package/dist/content/heading-h4.js +18 -0
- package/dist/content/index.d.ts +13 -0
- package/dist/content/index.js +27 -0
- package/dist/details/details.d.ts +26 -0
- package/dist/details/details.js +10 -0
- package/dist/details/index.d.ts +2 -0
- package/dist/details/index.js +4 -0
- package/dist/doclayout/anchors.d.ts +55 -0
- package/dist/doclayout/anchors.js +42 -0
- package/dist/doclayout/doc-layout-with-defaults.d.ts +83 -0
- package/dist/doclayout/doc-layout-with-defaults.js +159 -0
- package/dist/doclayout/doc-layout.d.ts +121 -0
- package/dist/doclayout/doc-layout.js +89 -0
- package/dist/doclayout/index.d.ts +6 -0
- package/dist/doclayout/index.js +17 -0
- package/dist/footer/footer.d.ts +42 -0
- package/dist/footer/footer.js +79 -0
- package/dist/footer/index.d.ts +3 -0
- package/dist/footer/index.js +4 -0
- package/dist/footer/types.d.ts +58 -0
- package/dist/footer/types.js +0 -0
- package/dist/head/doc-head.d.ts +33 -0
- package/dist/head/doc-head.js +90 -0
- package/dist/head/index.d.ts +5 -0
- package/dist/head/index.js +8 -0
- package/dist/head/og-tags.d.ts +25 -0
- package/dist/head/og-tags.js +16 -0
- package/dist/head/twitter-card.d.ts +21 -0
- package/dist/head/twitter-card.js +14 -0
- package/dist/head/types.d.ts +83 -0
- package/dist/head/types.js +0 -0
- package/dist/header/header.d.ts +158 -0
- package/dist/header/header.js +367 -0
- package/dist/header/index.d.ts +6 -0
- package/dist/header/index.js +18 -0
- package/dist/header/nav-active.d.ts +39 -0
- package/dist/header/nav-active.js +24 -0
- package/dist/header/nav-overflow-script.d.ts +3 -0
- package/dist/header/nav-overflow-script.js +169 -0
- package/dist/header/right-items.d.ts +38 -0
- package/dist/header/right-items.js +30 -0
- package/dist/header/types.d.ts +40 -0
- package/dist/header/types.js +0 -0
- package/dist/html-preview-wrapper/dedent.d.ts +10 -0
- package/dist/html-preview-wrapper/dedent.js +16 -0
- package/dist/html-preview-wrapper/highlighted-code.d.ts +18 -0
- package/dist/html-preview-wrapper/highlighted-code.js +53 -0
- package/dist/html-preview-wrapper/html-preview-wrapper.d.ts +60 -0
- package/dist/html-preview-wrapper/html-preview-wrapper.js +36 -0
- package/dist/html-preview-wrapper/html-preview.d.ts +35 -0
- package/dist/html-preview-wrapper/html-preview.js +75 -0
- package/dist/html-preview-wrapper/index.d.ts +5 -0
- package/dist/html-preview-wrapper/index.js +12 -0
- package/dist/html-preview-wrapper/preflight.d.ts +13 -0
- package/dist/html-preview-wrapper/preflight.js +108 -0
- package/dist/html-preview-wrapper/preview-base.d.ts +29 -0
- package/dist/html-preview-wrapper/preview-base.js +127 -0
- package/dist/i18n-version/index.d.ts +5 -0
- package/dist/i18n-version/index.js +14 -0
- package/dist/i18n-version/language-switcher.d.ts +24 -0
- package/dist/i18n-version/language-switcher.js +25 -0
- package/dist/i18n-version/types.d.ts +43 -0
- package/dist/i18n-version/types.js +0 -0
- package/dist/i18n-version/version-banner.d.ts +30 -0
- package/dist/i18n-version/version-banner.js +21 -0
- package/dist/i18n-version/version-switcher.d.ts +112 -0
- package/dist/i18n-version/version-switcher.js +157 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +0 -0
- package/dist/integrations/claude-resources/escape-for-mdx.d.ts +8 -0
- package/dist/integrations/claude-resources/escape-for-mdx.js +131 -0
- package/dist/integrations/claude-resources/generate.d.ts +13 -0
- package/dist/integrations/claude-resources/generate.js +404 -0
- package/dist/integrations/claude-resources/index.d.ts +46 -0
- package/dist/integrations/claude-resources/index.js +24 -0
- package/dist/integrations/doc-history/index.d.ts +137 -0
- package/dist/integrations/doc-history/index.js +138 -0
- package/dist/integrations/doc-history/pre-build.d.ts +58 -0
- package/dist/integrations/doc-history/pre-build.js +67 -0
- package/dist/integrations/llms-txt/dev-middleware.d.ts +40 -0
- package/dist/integrations/llms-txt/dev-middleware.js +76 -0
- package/dist/integrations/llms-txt/emit.d.ts +22 -0
- package/dist/integrations/llms-txt/emit.js +55 -0
- package/dist/integrations/llms-txt/generate.d.ts +26 -0
- package/dist/integrations/llms-txt/generate.js +36 -0
- package/dist/integrations/llms-txt/index.d.ts +7 -0
- package/dist/integrations/llms-txt/index.js +27 -0
- package/dist/integrations/llms-txt/load.d.ts +51 -0
- package/dist/integrations/llms-txt/load.js +83 -0
- package/dist/integrations/llms-txt/strip.d.ts +22 -0
- package/dist/integrations/llms-txt/strip.js +10 -0
- package/dist/integrations/llms-txt/types.d.ts +145 -0
- package/dist/integrations/llms-txt/types.js +0 -0
- package/dist/integrations/search-index/build-emitter.d.ts +30 -0
- package/dist/integrations/search-index/build-emitter.js +15 -0
- package/dist/integrations/search-index/collect.d.ts +12 -0
- package/dist/integrations/search-index/collect.js +48 -0
- package/dist/integrations/search-index/content-files.d.ts +32 -0
- package/dist/integrations/search-index/content-files.js +50 -0
- package/dist/integrations/search-index/dev-middleware.d.ts +16 -0
- package/dist/integrations/search-index/dev-middleware.js +30 -0
- package/dist/integrations/search-index/index.d.ts +5 -0
- package/dist/integrations/search-index/index.js +14 -0
- package/dist/integrations/search-index/types.d.ts +38 -0
- package/dist/integrations/search-index/types.js +6 -0
- package/dist/metainfo/doc-metainfo.d.ts +50 -0
- package/dist/metainfo/doc-metainfo.js +107 -0
- package/dist/metainfo/doc-tags.d.ts +66 -0
- package/dist/metainfo/doc-tags.js +53 -0
- package/dist/metainfo/frontmatter-preview.d.ts +95 -0
- package/dist/metainfo/frontmatter-preview.js +55 -0
- package/dist/metainfo/index.d.ts +4 -0
- package/dist/metainfo/index.js +28 -0
- package/dist/nav-indexing/category-nav.d.ts +28 -0
- package/dist/nav-indexing/category-nav.js +41 -0
- package/dist/nav-indexing/category-tree-nav.d.ts +27 -0
- package/dist/nav-indexing/category-tree-nav.js +49 -0
- package/dist/nav-indexing/doc-card-grid.d.ts +38 -0
- package/dist/nav-indexing/doc-card-grid.js +40 -0
- package/dist/nav-indexing/docs-sitemap.d.ts +25 -0
- package/dist/nav-indexing/docs-sitemap.js +40 -0
- package/dist/nav-indexing/index.d.ts +10 -0
- package/dist/nav-indexing/index.js +18 -0
- package/dist/nav-indexing/nav-card-grid.d.ts +31 -0
- package/dist/nav-indexing/nav-card-grid.js +43 -0
- package/dist/nav-indexing/site-tree-nav-demo.d.ts +39 -0
- package/dist/nav-indexing/site-tree-nav-demo.js +65 -0
- package/dist/nav-indexing/tag-nav.d.ts +38 -0
- package/dist/nav-indexing/tag-nav.js +96 -0
- package/dist/nav-indexing/types.d.ts +95 -0
- package/dist/nav-indexing/types.js +0 -0
- package/dist/nav-indexing/versions-page-content.d.ts +29 -0
- package/dist/nav-indexing/versions-page-content.js +76 -0
- package/dist/page-loading/index.d.ts +2 -0
- package/dist/page-loading/index.js +10 -0
- package/dist/page-loading/page-loading-overlay.d.ts +35 -0
- package/dist/page-loading/page-loading-overlay.js +50 -0
- package/dist/sidebar/index.d.ts +3 -0
- package/dist/sidebar/index.js +4 -0
- package/dist/sidebar/sidebar.d.ts +54 -0
- package/dist/sidebar/sidebar.js +35 -0
- package/dist/sidebar/types.d.ts +71 -0
- package/dist/sidebar/types.js +0 -0
- package/dist/sidebar-resizer/index.d.ts +14 -0
- package/dist/sidebar-resizer/index.js +165 -0
- package/dist/sidebar-resizer/sidebar-resizer-init.d.ts +20 -0
- package/dist/sidebar-resizer/sidebar-resizer-init.js +119 -0
- package/dist/sidebar-tree/build-tree.d.ts +43 -0
- package/dist/sidebar-tree/build-tree.js +127 -0
- package/dist/sidebar-tree/category-meta.d.ts +19 -0
- package/dist/sidebar-tree/category-meta.js +63 -0
- package/dist/sidebar-tree/index.d.ts +3 -0
- package/dist/sidebar-tree/index.js +13 -0
- package/dist/sidebar-tree/types.d.ts +120 -0
- package/dist/sidebar-tree/types.js +0 -0
- package/dist/tab-item/index.d.ts +2 -0
- package/dist/tab-item/index.js +5 -0
- package/dist/tab-item/tab-item.d.ts +38 -0
- package/dist/tab-item/tab-item.js +25 -0
- package/dist/theme/color-scheme-provider.d.ts +32 -0
- package/dist/theme/color-scheme-provider.js +43 -0
- package/dist/theme/color-tweak-export-modal.d.ts +20 -0
- package/dist/theme/color-tweak-export-modal.js +138 -0
- package/dist/theme/design-token-serde.d.ts +136 -0
- package/dist/theme/design-token-serde.js +254 -0
- package/dist/theme/design-token-tweak-panel.d.ts +11 -0
- package/dist/theme/design-token-tweak-panel.js +10 -0
- package/dist/theme/design-token-types.d.ts +19 -0
- package/dist/theme/design-token-types.js +6 -0
- package/dist/theme/iframe-bridge.d.ts +44 -0
- package/dist/theme/iframe-bridge.js +70 -0
- package/dist/theme/index.d.ts +9 -0
- package/dist/theme/index.js +42 -0
- package/dist/theme/theme-toggle.d.ts +17 -0
- package/dist/theme/theme-toggle.js +91 -0
- package/dist/toc/cx.d.ts +16 -0
- package/dist/toc/cx.js +22 -0
- package/dist/toc/index.d.ts +5 -0
- package/dist/toc/index.js +9 -0
- package/dist/toc/mobile-toc.d.ts +46 -0
- package/dist/toc/mobile-toc.js +88 -0
- package/dist/toc/smart-break.d.ts +27 -0
- package/dist/toc/smart-break.js +36 -0
- package/dist/toc/toc-title.d.ts +10 -0
- package/dist/toc/toc-title.js +14 -0
- package/dist/toc/toc.d.ts +60 -0
- package/dist/toc/toc.js +56 -0
- package/dist/toc/types.d.ts +23 -0
- package/dist/toc/types.js +0 -0
- package/dist/toc/use-active-heading.d.ts +30 -0
- package/dist/toc/use-active-heading.js +106 -0
- package/dist/transitions/index.d.ts +1 -0
- package/dist/transitions/index.js +12 -0
- package/dist/transitions/page-events.d.ts +41 -0
- package/dist/transitions/page-events.js +20 -0
- package/dist/url-normalizer/index.d.ts +1 -0
- package/dist/url-normalizer/index.js +6 -0
- package/dist/url-normalizer/normalize.d.ts +104 -0
- package/dist/url-normalizer/normalize.js +22 -0
- package/package.json +186 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { ComponentChildren, JSX } from 'preact';
|
|
2
|
+
import { Locale, HeaderNavItem, HeaderRightItem } from './types.js';
|
|
3
|
+
|
|
4
|
+
/** @jsxRuntime automatic */
|
|
5
|
+
/** @jsxImportSource preact */
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Boundary helpers the host injects into `<Header>`. These are the URL
|
|
9
|
+
* builders the legacy header.tsx used to import from `@/utils/base` —
|
|
10
|
+
* pulled into a single prop bag so the v2 package is host-agnostic.
|
|
11
|
+
*/
|
|
12
|
+
interface HeaderUrlHelpers {
|
|
13
|
+
withBase(path: string): string;
|
|
14
|
+
stripBase(path: string): string;
|
|
15
|
+
navHref(path: string, lang?: Locale, currentVersion?: string): string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Boundary helpers for locale-aware behaviour the host injects into
|
|
19
|
+
* `<Header>`. Matches the surface the legacy header.tsx used from
|
|
20
|
+
* `@/config/i18n`.
|
|
21
|
+
*/
|
|
22
|
+
interface HeaderI18n {
|
|
23
|
+
defaultLocale: string;
|
|
24
|
+
locales: readonly string[];
|
|
25
|
+
t(key: string, lang?: string): string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Props for the JSX `<Header />` port. Mirrors the Astro template's
|
|
29
|
+
* `Props` interface plus a small set of slot props that replace child
|
|
30
|
+
* Astro components and named `<slot>` outlets.
|
|
31
|
+
*/
|
|
32
|
+
interface HeaderProps {
|
|
33
|
+
/** Active locale; `undefined` matches the legacy "no-lang" code path. */
|
|
34
|
+
lang?: Locale;
|
|
35
|
+
/** Current page URL path (as the layout passes from `Astro.url.pathname`). */
|
|
36
|
+
currentPath?: string;
|
|
37
|
+
/** Optional active version slug. Forwarded into `navHref` for nav links. */
|
|
38
|
+
currentVersion?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Children projected into the mobile `<SidebarToggle>` island —
|
|
41
|
+
* replaces the legacy `<slot name="sidebar" />`. Consumers pass the
|
|
42
|
+
* sidebar tree they want to surface in the mobile sheet.
|
|
43
|
+
*/
|
|
44
|
+
sidebarSlot?: ComponentChildren;
|
|
45
|
+
/**
|
|
46
|
+
* Replacement for the `<SidebarToggle client:media="...">` element in
|
|
47
|
+
* the legacy template. Consumers wrap their preferred Preact /
|
|
48
|
+
* `<Island>` toggle (with the sidebar slot already nested inside) and
|
|
49
|
+
* the shell drops it in untouched. When omitted nothing renders in
|
|
50
|
+
* that slot — the layout is still valid (e.g. doc pages with
|
|
51
|
+
* `hide_sidebar`).
|
|
52
|
+
*/
|
|
53
|
+
sidebarToggle?: ComponentChildren;
|
|
54
|
+
/**
|
|
55
|
+
* Replacement for `<ThemeToggle client:load />`. Rendered only when
|
|
56
|
+
* `colorModeEnabled` is `true` AND a `theme-toggle` entry survives
|
|
57
|
+
* `filterHeaderRightItems` — matching the original template.
|
|
58
|
+
*/
|
|
59
|
+
themeToggle?: ComponentChildren;
|
|
60
|
+
/** Replacement for the `<LanguageSwitcher />` Astro child. */
|
|
61
|
+
languageSwitcher?: ComponentChildren;
|
|
62
|
+
/** Replacement for the `<VersionSwitcher />` Astro child. */
|
|
63
|
+
versionSwitcher?: ComponentChildren;
|
|
64
|
+
/** Replacement for the `<Search />` Astro child. */
|
|
65
|
+
search?: ComponentChildren;
|
|
66
|
+
/**
|
|
67
|
+
* When provided, emits `data-zfb-transition-persist={persistKey}` on the
|
|
68
|
+
* `<header>` element so zfb's client-router preserves DOM-node identity
|
|
69
|
+
* across same-locale View Transition swaps. Omit to disable persist
|
|
70
|
+
* (back-compat default — the header is re-rendered on every swap).
|
|
71
|
+
*
|
|
72
|
+
* **Locale keying**: callers MUST key by locale (e.g. `"header-en"`,
|
|
73
|
+
* `"header-ja"`). Cross-locale swaps must NOT share the same key; a
|
|
74
|
+
* key mismatch tells the router to replace the header, re-rendering
|
|
75
|
+
* the locale toggle anchors and all other SSR'd locale-specific
|
|
76
|
+
* content with fresh markup. See zudolab/zudo-doc#1546.
|
|
77
|
+
*
|
|
78
|
+
* **headerOverride scope**: hosts that supply their own `<header>`
|
|
79
|
+
* element via `headerOverride` on `<DocLayoutWithDefaults>` are
|
|
80
|
+
* responsible for adding `data-zfb-transition-persist` to their custom
|
|
81
|
+
* element themselves. This package only injects the attribute on the
|
|
82
|
+
* default `<Header>` shell. A key of `"header-${lang}"` is recommended
|
|
83
|
+
* for consistency, matching the Astro reference implementation
|
|
84
|
+
* (zudolab/zudo-doc#1546).
|
|
85
|
+
*/
|
|
86
|
+
persistKey?: string;
|
|
87
|
+
/** Site-name string shown in the logo anchor (host `settings.siteName`). */
|
|
88
|
+
siteName: string;
|
|
89
|
+
/** Header-nav items in render order (host `settings.headerNav`). */
|
|
90
|
+
headerNav: HeaderNavItem[];
|
|
91
|
+
/**
|
|
92
|
+
* Header-right items, **already filtered** by the host via
|
|
93
|
+
* `filterHeaderRightItems` (see `./right-items.ts`). The renderer no
|
|
94
|
+
* longer re-checks `settings.colorMode` / `locales.length` etc — if
|
|
95
|
+
* an item is in this array, the renderer emits its markup. Slot
|
|
96
|
+
* presence (e.g. `languageSwitcher` being supplied) still gates per
|
|
97
|
+
* the legacy template: a slot left undefined renders an empty
|
|
98
|
+
* wrapper, matching prior behaviour.
|
|
99
|
+
*/
|
|
100
|
+
headerRightItems: HeaderRightItem[];
|
|
101
|
+
/**
|
|
102
|
+
* Whether the host has a `colorMode` config. Required because the
|
|
103
|
+
* `theme-toggle` right-item is two-gated: the filter drops it when
|
|
104
|
+
* `colorMode` is off entirely, but the renderer also checks it before
|
|
105
|
+
* emitting the wrapping `<div>` so a `headerRightItems` array that
|
|
106
|
+
* still contains `theme-toggle` but is rendered against a config
|
|
107
|
+
* with `colorMode === false` stays a no-op (the legacy template's
|
|
108
|
+
* shape).
|
|
109
|
+
*/
|
|
110
|
+
colorModeEnabled: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Whether the host has more than one locale configured (`locales.length > 1`
|
|
113
|
+
* in the legacy template's gate). The renderer needs this to keep
|
|
114
|
+
* the language-switcher slot empty on single-locale sites even when
|
|
115
|
+
* `headerRightItems` contains a `language-switcher` entry.
|
|
116
|
+
*/
|
|
117
|
+
hasLocales: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Whether the host has `versions` configured. Currently informational —
|
|
120
|
+
* the version-switcher gate lives entirely in the host slot's
|
|
121
|
+
* presence — but accepted for symmetry with `colorModeEnabled` /
|
|
122
|
+
* `hasLocales` so the prop bag fully describes the feature surface.
|
|
123
|
+
*/
|
|
124
|
+
hasVersions: boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Resolved GitHub repo URL (no trailing slash) or `null` when
|
|
127
|
+
* unconfigured. Replaces the legacy direct call to
|
|
128
|
+
* `buildGitHubRepoUrl()` in this component.
|
|
129
|
+
*/
|
|
130
|
+
githubRepoUrl: string | null;
|
|
131
|
+
/**
|
|
132
|
+
* Localised aria-label / title for the GitHub anchor — host-side
|
|
133
|
+
* translated string (the legacy `t("header.github", lang)`).
|
|
134
|
+
*/
|
|
135
|
+
githubLabel: string;
|
|
136
|
+
/** URL builder helpers — see `HeaderUrlHelpers`. */
|
|
137
|
+
urlHelpers: HeaderUrlHelpers;
|
|
138
|
+
/** i18n helpers and config — see `HeaderI18n`. */
|
|
139
|
+
i18n: HeaderI18n;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Site-header shell — JSX port of `src/components/header.astro`.
|
|
143
|
+
*
|
|
144
|
+
* Responsibilities (matching the legacy template byte-for-byte):
|
|
145
|
+
* 1. Render the sticky `<header>` with the site logo and the desktop
|
|
146
|
+
* nav, including the dropdown-parent / overflow-bucket markup the
|
|
147
|
+
* controller script reshapes at runtime.
|
|
148
|
+
* 2. Iterate `headerRightItems` (already filtered by the caller via
|
|
149
|
+
* `filterHeaderRightItems`), emitting the matching trigger button /
|
|
150
|
+
* icon link / consumer-supplied slot for each entry.
|
|
151
|
+
* 3. Emit the inline overflow controller script. The script wires the
|
|
152
|
+
* "..." overflow menu, manages `aria-expanded` on dropdowns, and
|
|
153
|
+
* re-runs after View Transitions (via `AFTER_NAVIGATE_EVENT` from
|
|
154
|
+
* `../transitions/page-events`).
|
|
155
|
+
*/
|
|
156
|
+
declare function Header(props: HeaderProps): JSX.Element;
|
|
157
|
+
|
|
158
|
+
export { Header, type HeaderI18n, type HeaderProps, type HeaderUrlHelpers };
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
2
|
+
import {
|
|
3
|
+
computeActiveNavPath,
|
|
4
|
+
isNavItemActive,
|
|
5
|
+
pathForMatch
|
|
6
|
+
} from "./nav-active.js";
|
|
7
|
+
import { NAV_OVERFLOW_SCRIPT } from "./nav-overflow-script.js";
|
|
8
|
+
function Header(props) {
|
|
9
|
+
const {
|
|
10
|
+
lang,
|
|
11
|
+
currentPath = "",
|
|
12
|
+
currentVersion,
|
|
13
|
+
sidebarSlot,
|
|
14
|
+
sidebarToggle,
|
|
15
|
+
themeToggle,
|
|
16
|
+
languageSwitcher,
|
|
17
|
+
versionSwitcher,
|
|
18
|
+
search,
|
|
19
|
+
persistKey,
|
|
20
|
+
siteName,
|
|
21
|
+
headerNav,
|
|
22
|
+
headerRightItems,
|
|
23
|
+
colorModeEnabled,
|
|
24
|
+
hasLocales,
|
|
25
|
+
githubRepoUrl,
|
|
26
|
+
githubLabel,
|
|
27
|
+
urlHelpers,
|
|
28
|
+
i18n
|
|
29
|
+
} = props;
|
|
30
|
+
const isNonDefaultLocale = lang != null && lang !== i18n.defaultLocale;
|
|
31
|
+
const pathWithoutBase = urlHelpers.stripBase(currentPath);
|
|
32
|
+
const matchPath = pathForMatch(pathWithoutBase, lang, i18n.defaultLocale);
|
|
33
|
+
const activeNavPath = computeActiveNavPath(headerNav, matchPath);
|
|
34
|
+
return /* @__PURE__ */ jsxs(
|
|
35
|
+
"header",
|
|
36
|
+
{
|
|
37
|
+
class: "sticky top-0 z-50 flex h-[3.5rem] items-center border-b border-muted bg-surface px-hsp-lg",
|
|
38
|
+
"data-header": true,
|
|
39
|
+
"data-zfb-transition-persist": persistKey,
|
|
40
|
+
children: [
|
|
41
|
+
sidebarToggle ?? // Render an inert wrapper so consumers that omit the slot still
|
|
42
|
+
// get the named-slot semantics from the legacy template
|
|
43
|
+
// (mobile sidebar contents stay accessible to assistive tech
|
|
44
|
+
// even without the toggle island).
|
|
45
|
+
/* @__PURE__ */ jsx(SidebarSlotFallback, { children: sidebarSlot }),
|
|
46
|
+
/* @__PURE__ */ jsx(
|
|
47
|
+
"a",
|
|
48
|
+
{
|
|
49
|
+
href: urlHelpers.withBase(isNonDefaultLocale ? `/${lang}/` : "/"),
|
|
50
|
+
class: "whitespace-nowrap text-title font-bold text-fg hover:underline focus:underline shrink-0",
|
|
51
|
+
"data-header-logo": true,
|
|
52
|
+
children: siteName
|
|
53
|
+
}
|
|
54
|
+
),
|
|
55
|
+
/* @__PURE__ */ jsxs(
|
|
56
|
+
"nav",
|
|
57
|
+
{
|
|
58
|
+
"aria-label": "Main",
|
|
59
|
+
class: "relative ml-hsp-xl hidden min-w-0 flex-1 items-center gap-x-hsp-2xs whitespace-nowrap lg:flex",
|
|
60
|
+
"data-header-nav": true,
|
|
61
|
+
children: [
|
|
62
|
+
headerNav.map((item) => renderNavItem(
|
|
63
|
+
item,
|
|
64
|
+
activeNavPath,
|
|
65
|
+
lang,
|
|
66
|
+
currentVersion,
|
|
67
|
+
urlHelpers,
|
|
68
|
+
i18n
|
|
69
|
+
)),
|
|
70
|
+
/* @__PURE__ */ jsxs("div", { class: "relative shrink-0", "data-nav-more": true, style: "display:none", children: [
|
|
71
|
+
/* @__PURE__ */ jsx(
|
|
72
|
+
"button",
|
|
73
|
+
{
|
|
74
|
+
type: "button",
|
|
75
|
+
class: "px-hsp-md py-vsp-2xs text-small font-medium text-muted hover:underline cursor-pointer",
|
|
76
|
+
"data-nav-more-toggle": true,
|
|
77
|
+
"aria-expanded": "false",
|
|
78
|
+
children: "\xB7\xB7\xB7"
|
|
79
|
+
}
|
|
80
|
+
),
|
|
81
|
+
/* @__PURE__ */ jsx(
|
|
82
|
+
"ul",
|
|
83
|
+
{
|
|
84
|
+
class: "absolute right-0 top-full z-10 mt-vsp-3xs hidden min-w-[8rem] border border-muted rounded bg-surface shadow-lg whitespace-nowrap",
|
|
85
|
+
"data-nav-more-menu": true
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
] })
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
/* @__PURE__ */ jsx(
|
|
93
|
+
"div",
|
|
94
|
+
{
|
|
95
|
+
class: "ml-auto flex shrink-0 items-center gap-x-hsp-md",
|
|
96
|
+
"data-header-right": true,
|
|
97
|
+
children: headerRightItems.map((item, i) => renderRightItem(
|
|
98
|
+
item,
|
|
99
|
+
i,
|
|
100
|
+
{
|
|
101
|
+
lang,
|
|
102
|
+
githubRepoUrl,
|
|
103
|
+
githubLabel,
|
|
104
|
+
themeToggle,
|
|
105
|
+
languageSwitcher,
|
|
106
|
+
versionSwitcher,
|
|
107
|
+
search,
|
|
108
|
+
colorModeEnabled,
|
|
109
|
+
hasLocales
|
|
110
|
+
}
|
|
111
|
+
))
|
|
112
|
+
}
|
|
113
|
+
),
|
|
114
|
+
/* @__PURE__ */ jsx("script", { dangerouslySetInnerHTML: { __html: NAV_OVERFLOW_SCRIPT } })
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
function SidebarSlotFallback({
|
|
120
|
+
children
|
|
121
|
+
}) {
|
|
122
|
+
if (children === void 0 || children === null) return null;
|
|
123
|
+
return /* @__PURE__ */ jsx("span", { hidden: true, children });
|
|
124
|
+
}
|
|
125
|
+
function renderNavItem(item, activeNavPath, lang, currentVersion, urlHelpers, i18n) {
|
|
126
|
+
const isActive = isNavItemActive(item, activeNavPath);
|
|
127
|
+
const href = urlHelpers.navHref(item.path, lang, currentVersion);
|
|
128
|
+
const label = item.labelKey ? i18n.t(item.labelKey, lang) : item.label;
|
|
129
|
+
if (item.children && item.children.length > 0) {
|
|
130
|
+
return /* @__PURE__ */ jsxs(
|
|
131
|
+
"div",
|
|
132
|
+
{
|
|
133
|
+
class: "group relative shrink-0",
|
|
134
|
+
"data-nav-item": true,
|
|
135
|
+
"data-nav-item-dropdown": true,
|
|
136
|
+
children: [
|
|
137
|
+
/* @__PURE__ */ jsxs(
|
|
138
|
+
"a",
|
|
139
|
+
{
|
|
140
|
+
href,
|
|
141
|
+
"aria-current": isActive ? "page" : void 0,
|
|
142
|
+
"aria-haspopup": "true",
|
|
143
|
+
"aria-expanded": "false",
|
|
144
|
+
class: [
|
|
145
|
+
"flex items-center gap-x-hsp-xs px-hsp-md py-vsp-2xs text-small font-medium transition-colors",
|
|
146
|
+
isActive ? "bg-fg text-bg" : "text-muted hover:underline focus:underline"
|
|
147
|
+
].join(" "),
|
|
148
|
+
children: [
|
|
149
|
+
label,
|
|
150
|
+
/* @__PURE__ */ jsx(
|
|
151
|
+
"svg",
|
|
152
|
+
{
|
|
153
|
+
class: [
|
|
154
|
+
"h-[0.5rem] w-[0.5rem] shrink-0",
|
|
155
|
+
isActive ? "text-bg" : "text-muted"
|
|
156
|
+
].join(" "),
|
|
157
|
+
fill: "none",
|
|
158
|
+
viewBox: "0 0 24 24",
|
|
159
|
+
stroke: "currentColor",
|
|
160
|
+
"stroke-width": "3",
|
|
161
|
+
"aria-hidden": "true",
|
|
162
|
+
children: /* @__PURE__ */ jsx(
|
|
163
|
+
"path",
|
|
164
|
+
{
|
|
165
|
+
"stroke-linecap": "round",
|
|
166
|
+
"stroke-linejoin": "round",
|
|
167
|
+
d: "M19 9l-7 7-7-7"
|
|
168
|
+
}
|
|
169
|
+
)
|
|
170
|
+
}
|
|
171
|
+
)
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
),
|
|
175
|
+
/* @__PURE__ */ jsx("div", { class: "absolute left-0 top-full z-50 hidden group-hover:block group-focus-within:block pt-vsp-3xs", children: /* @__PURE__ */ jsx("div", { class: "min-w-[10rem] border border-muted rounded bg-surface shadow-lg py-vsp-3xs", children: item.children.map((child) => {
|
|
176
|
+
const childHref = urlHelpers.navHref(child.path, lang, currentVersion);
|
|
177
|
+
const childLabel = child.labelKey ? i18n.t(child.labelKey, lang) : child.label;
|
|
178
|
+
const childActive = activeNavPath === child.path;
|
|
179
|
+
return /* @__PURE__ */ jsx(
|
|
180
|
+
"a",
|
|
181
|
+
{
|
|
182
|
+
href: childHref,
|
|
183
|
+
"data-active": childActive ? "" : void 0,
|
|
184
|
+
class: [
|
|
185
|
+
"block px-hsp-md py-vsp-2xs text-small hover:bg-accent/10 hover:underline",
|
|
186
|
+
childActive ? "font-bold text-accent" : "text-fg"
|
|
187
|
+
].join(" "),
|
|
188
|
+
children: childLabel
|
|
189
|
+
}
|
|
190
|
+
);
|
|
191
|
+
}) }) })
|
|
192
|
+
]
|
|
193
|
+
}
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
return /* @__PURE__ */ jsx(
|
|
197
|
+
"a",
|
|
198
|
+
{
|
|
199
|
+
href,
|
|
200
|
+
"aria-current": isActive ? "page" : void 0,
|
|
201
|
+
"data-nav-item": true,
|
|
202
|
+
class: [
|
|
203
|
+
"px-hsp-md py-vsp-2xs text-small font-medium transition-colors shrink-0",
|
|
204
|
+
isActive ? "bg-fg text-bg" : "text-muted hover:underline focus:underline"
|
|
205
|
+
].join(" "),
|
|
206
|
+
children: label
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
function renderRightItem(item, index, ctx) {
|
|
211
|
+
if (item.type === "trigger" && item.trigger === "design-token-panel") {
|
|
212
|
+
const inlineOnclick = {
|
|
213
|
+
onclick: "window.dispatchEvent(new CustomEvent('toggle-design-token-panel'))"
|
|
214
|
+
};
|
|
215
|
+
return /* @__PURE__ */ jsx(
|
|
216
|
+
"button",
|
|
217
|
+
{
|
|
218
|
+
id: "design-token-trigger",
|
|
219
|
+
type: "button",
|
|
220
|
+
class: "flex items-center justify-center text-muted transition-colors hover:text-fg",
|
|
221
|
+
"aria-label": "Toggle design token panel",
|
|
222
|
+
...inlineOnclick,
|
|
223
|
+
children: /* @__PURE__ */ jsxs(
|
|
224
|
+
"svg",
|
|
225
|
+
{
|
|
226
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
227
|
+
width: "20",
|
|
228
|
+
height: "20",
|
|
229
|
+
viewBox: "0 0 24 24",
|
|
230
|
+
fill: "none",
|
|
231
|
+
stroke: "currentColor",
|
|
232
|
+
"stroke-width": "2",
|
|
233
|
+
"stroke-linecap": "round",
|
|
234
|
+
"stroke-linejoin": "round",
|
|
235
|
+
"aria-hidden": "true",
|
|
236
|
+
children: [
|
|
237
|
+
/* @__PURE__ */ jsx("circle", { cx: "13.5", cy: "6.5", r: "2.5" }),
|
|
238
|
+
/* @__PURE__ */ jsx("circle", { cx: "17.5", cy: "10.5", r: "2.5" }),
|
|
239
|
+
/* @__PURE__ */ jsx("circle", { cx: "8.5", cy: "7.5", r: "2.5" }),
|
|
240
|
+
/* @__PURE__ */ jsx("circle", { cx: "6.5", cy: "12.5", r: "2.5" }),
|
|
241
|
+
/* @__PURE__ */ jsx("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688 0-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 0 1 1.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.012 17.461 2 12 2z" })
|
|
242
|
+
]
|
|
243
|
+
}
|
|
244
|
+
)
|
|
245
|
+
},
|
|
246
|
+
`right-${index}`
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
if (item.type === "trigger" && item.trigger === "ai-chat") {
|
|
250
|
+
const inlineOnclick = {
|
|
251
|
+
onclick: "window.dispatchEvent(new CustomEvent('toggle-ai-chat'))"
|
|
252
|
+
};
|
|
253
|
+
return /* @__PURE__ */ jsx(
|
|
254
|
+
"button",
|
|
255
|
+
{
|
|
256
|
+
id: "ai-chat-trigger",
|
|
257
|
+
type: "button",
|
|
258
|
+
class: "flex items-center justify-center text-muted transition-colors hover:text-fg",
|
|
259
|
+
"aria-label": "Open AI assistant",
|
|
260
|
+
...inlineOnclick,
|
|
261
|
+
children: /* @__PURE__ */ jsxs(
|
|
262
|
+
"svg",
|
|
263
|
+
{
|
|
264
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
265
|
+
width: "20",
|
|
266
|
+
height: "20",
|
|
267
|
+
viewBox: "0 0 24 24",
|
|
268
|
+
fill: "currentColor",
|
|
269
|
+
"aria-hidden": "true",
|
|
270
|
+
children: [
|
|
271
|
+
/* @__PURE__ */ jsx("path", { d: "M9.5 2.5Q10.5 11.5 18 13Q10.5 14.5 9.5 23.5Q8.5 14.5 1 13Q8.5 11.5 9.5 2.5Z" }),
|
|
272
|
+
/* @__PURE__ */ jsx("path", { d: "M19 0.5Q19.5 4 23.5 5Q19.5 6 19 9.5Q18.5 6 14.5 5Q18.5 4 19 0.5Z" })
|
|
273
|
+
]
|
|
274
|
+
}
|
|
275
|
+
)
|
|
276
|
+
},
|
|
277
|
+
`right-${index}`
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
if (item.type === "component" && item.component === "version-switcher") {
|
|
281
|
+
return /* @__PURE__ */ jsx("div", { class: "hidden lg:block", children: ctx.versionSwitcher }, `right-${index}`);
|
|
282
|
+
}
|
|
283
|
+
if (item.type === "component" && item.component === "github-link" && ctx.githubRepoUrl) {
|
|
284
|
+
return /* @__PURE__ */ jsxs(
|
|
285
|
+
"a",
|
|
286
|
+
{
|
|
287
|
+
href: ctx.githubRepoUrl,
|
|
288
|
+
target: "_blank",
|
|
289
|
+
rel: "noopener noreferrer",
|
|
290
|
+
class: "flex items-center justify-center text-muted transition-colors hover:text-fg",
|
|
291
|
+
"aria-label": ctx.githubLabel,
|
|
292
|
+
title: ctx.githubLabel,
|
|
293
|
+
children: [
|
|
294
|
+
/* @__PURE__ */ jsx("span", { class: "sr-only", children: ctx.githubLabel }),
|
|
295
|
+
/* @__PURE__ */ jsx(
|
|
296
|
+
"svg",
|
|
297
|
+
{
|
|
298
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
299
|
+
width: "20",
|
|
300
|
+
height: "20",
|
|
301
|
+
viewBox: "0 0 24 24",
|
|
302
|
+
fill: "currentColor",
|
|
303
|
+
"aria-hidden": "true",
|
|
304
|
+
children: /* @__PURE__ */ jsx("path", { d: "M12 .5C5.649.5.5 5.649.5 12a11.5 11.5 0 0 0 7.86 10.915c.575.106.785-.25.785-.556 0-.274-.01-1-.016-1.962-3.198.695-3.873-1.541-3.873-1.541-.523-1.327-1.277-1.68-1.277-1.68-1.044-.714.079-.699.079-.699 1.154.082 1.761 1.186 1.761 1.186 1.026 1.758 2.692 1.25 3.348.956.104-.743.401-1.25.73-1.537-2.553-.29-5.238-1.276-5.238-5.682 0-1.255.448-2.282 1.182-3.086-.119-.29-.512-1.458.111-3.04 0 0 .964-.309 3.159 1.18A10.98 10.98 0 0 1 12 6.036c.977.005 1.963.132 2.883.387 2.193-1.49 3.155-1.18 3.155-1.18.625 1.582.232 2.75.114 3.04.736.804 1.18 1.831 1.18 3.086 0 4.417-2.689 5.389-5.25 5.673.412.355.779 1.056.779 2.129 0 1.538-.014 2.778-.014 3.156 0 .31.207.668.79.555A11.502 11.502 0 0 0 23.5 12C23.5 5.649 18.351.5 12 .5Z" })
|
|
305
|
+
}
|
|
306
|
+
)
|
|
307
|
+
]
|
|
308
|
+
},
|
|
309
|
+
`right-${index}`
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
if (item.type === "component" && item.component === "theme-toggle") {
|
|
313
|
+
if (!ctx.colorModeEnabled) return null;
|
|
314
|
+
return /* @__PURE__ */ jsx("div", { class: "hidden lg:flex items-center", children: ctx.themeToggle }, `right-${index}`);
|
|
315
|
+
}
|
|
316
|
+
if (item.type === "component" && item.component === "language-switcher") {
|
|
317
|
+
if (!(ctx.lang && ctx.hasLocales)) return null;
|
|
318
|
+
return /* @__PURE__ */ jsx("div", { class: "hidden lg:flex items-center", children: ctx.languageSwitcher }, `right-${index}`);
|
|
319
|
+
}
|
|
320
|
+
if (item.type === "component" && item.component === "search") {
|
|
321
|
+
return /* @__PURE__ */ jsx("div", { children: ctx.search }, `right-${index}`);
|
|
322
|
+
}
|
|
323
|
+
if (item.type === "link") {
|
|
324
|
+
const label = item.label ?? item.ariaLabel;
|
|
325
|
+
const isExternal = /^https?:\/\//.test(item.href);
|
|
326
|
+
return /* @__PURE__ */ jsx(
|
|
327
|
+
"a",
|
|
328
|
+
{
|
|
329
|
+
href: item.href,
|
|
330
|
+
target: isExternal ? "_blank" : void 0,
|
|
331
|
+
rel: isExternal ? "noopener noreferrer" : void 0,
|
|
332
|
+
class: "flex items-center justify-center text-muted transition-colors hover:text-fg",
|
|
333
|
+
"aria-label": item.ariaLabel,
|
|
334
|
+
title: label,
|
|
335
|
+
children: item.icon === "github" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
336
|
+
label && /* @__PURE__ */ jsx("span", { class: "sr-only", children: label }),
|
|
337
|
+
/* @__PURE__ */ jsx(
|
|
338
|
+
"svg",
|
|
339
|
+
{
|
|
340
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
341
|
+
width: "20",
|
|
342
|
+
height: "20",
|
|
343
|
+
viewBox: "0 0 24 24",
|
|
344
|
+
fill: "currentColor",
|
|
345
|
+
"aria-hidden": "true",
|
|
346
|
+
children: /* @__PURE__ */ jsx("path", { d: "M12 .5C5.649.5.5 5.649.5 12a11.5 11.5 0 0 0 7.86 10.915c.575.106.785-.25.785-.556 0-.274-.01-1-.016-1.962-3.198.695-3.873-1.541-3.873-1.541-.523-1.327-1.277-1.68-1.277-1.68-1.044-.714.079-.699.079-.699 1.154.082 1.761 1.186 1.761 1.186 1.026 1.758 2.692 1.25 3.348.956.104-.743.401-1.25.73-1.537-2.553-.29-5.238-1.276-5.238-5.682 0-1.255.448-2.282 1.182-3.086-.119-.29-.512-1.458.111-3.04 0 0 .964-.309 3.159 1.18A10.98 10.98 0 0 1 12 6.036c.977.005 1.963.132 2.883.387 2.193-1.49 3.155-1.18 3.155-1.18.625 1.582.232 2.75.114 3.04.736.804 1.18 1.831 1.18 3.086 0 4.417-2.689 5.389-5.25 5.673.412.355.779 1.056.779 2.129 0 1.538-.014 2.778-.014 3.156 0 .31.207.668.79.555A11.502 11.502 0 0 0 23.5 12C23.5 5.649 18.351.5 12 .5Z" })
|
|
347
|
+
}
|
|
348
|
+
)
|
|
349
|
+
] }) : label
|
|
350
|
+
},
|
|
351
|
+
`right-${index}`
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
if (item.type === "html") {
|
|
355
|
+
return /* @__PURE__ */ jsx(
|
|
356
|
+
"span",
|
|
357
|
+
{
|
|
358
|
+
dangerouslySetInnerHTML: { __html: item.html }
|
|
359
|
+
},
|
|
360
|
+
`right-${index}`
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
export {
|
|
366
|
+
Header
|
|
367
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { HeaderNavChildItem, HeaderNavItem, HeaderRightComponentItem, HeaderRightComponentName, HeaderRightHtmlItem, HeaderRightItem, HeaderRightLinkItem, HeaderRightTriggerItem, HeaderRightTriggerName, Locale } from './types.js';
|
|
2
|
+
export { HeaderRightItemFlags, filterHeaderRightItems } from './right-items.js';
|
|
3
|
+
export { Header, HeaderProps } from './header.js';
|
|
4
|
+
export { NavItemLike, computeActiveNavPath, isNavItemActive, pathForMatch } from './nav-active.js';
|
|
5
|
+
export { NAV_OVERFLOW_SCRIPT } from './nav-overflow-script.js';
|
|
6
|
+
import 'preact';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
filterHeaderRightItems
|
|
3
|
+
} from "./right-items.js";
|
|
4
|
+
import { Header } from "./header.js";
|
|
5
|
+
import {
|
|
6
|
+
computeActiveNavPath,
|
|
7
|
+
isNavItemActive,
|
|
8
|
+
pathForMatch
|
|
9
|
+
} from "./nav-active.js";
|
|
10
|
+
import { NAV_OVERFLOW_SCRIPT } from "./nav-overflow-script.js";
|
|
11
|
+
export {
|
|
12
|
+
Header,
|
|
13
|
+
NAV_OVERFLOW_SCRIPT,
|
|
14
|
+
computeActiveNavPath,
|
|
15
|
+
filterHeaderRightItems,
|
|
16
|
+
isNavItemActive,
|
|
17
|
+
pathForMatch
|
|
18
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** Minimal shape the active-path resolver needs from a header nav item. */
|
|
2
|
+
interface NavItemLike {
|
|
3
|
+
path: string;
|
|
4
|
+
children?: {
|
|
5
|
+
path: string;
|
|
6
|
+
}[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Strip the locale prefix from `pathWithoutBase` when the page is being
|
|
10
|
+
* served under a non-default locale. Mirrors the inline regex inside
|
|
11
|
+
* `header.astro` so the JSX port matches the legacy template's
|
|
12
|
+
* active-link behaviour.
|
|
13
|
+
*
|
|
14
|
+
* Examples:
|
|
15
|
+
* pathForMatch("/ja/docs/intro", "ja", "en") === "/docs/intro"
|
|
16
|
+
* pathForMatch("/docs/intro", "en", "en") === "/docs/intro"
|
|
17
|
+
* pathForMatch(null, "ja", "en") === ""
|
|
18
|
+
*/
|
|
19
|
+
declare function pathForMatch(pathWithoutBase: string, lang: string | undefined, defaultLocale: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Pick the deepest header-nav path that the current page lives under.
|
|
22
|
+
*
|
|
23
|
+
* The legacy template flattens parent + child paths, filters by
|
|
24
|
+
* `pathForMatch.startsWith(p)`, and picks the longest match — this keeps
|
|
25
|
+
* a child link active even when its parent's path is also a prefix of
|
|
26
|
+
* the current page.
|
|
27
|
+
*
|
|
28
|
+
* Returns `undefined` when no nav entry matches; callers should treat
|
|
29
|
+
* that as "no active link."
|
|
30
|
+
*/
|
|
31
|
+
declare function computeActiveNavPath(navItems: readonly NavItemLike[], pathForMatchValue: string): string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Active-state predicate for a top-level nav item: the item itself, or
|
|
34
|
+
* any of its children, matches the active path. Mirrors the inline
|
|
35
|
+
* `isNavItemActive` helper in the legacy template.
|
|
36
|
+
*/
|
|
37
|
+
declare function isNavItemActive(item: NavItemLike, activeNavPath: string | undefined): boolean;
|
|
38
|
+
|
|
39
|
+
export { type NavItemLike, computeActiveNavPath, isNavItemActive, pathForMatch };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
function pathForMatch(pathWithoutBase, lang, defaultLocale) {
|
|
2
|
+
if (lang == null || lang === defaultLocale) return pathWithoutBase;
|
|
3
|
+
return pathWithoutBase.replace(new RegExp(`^/${lang}`), "");
|
|
4
|
+
}
|
|
5
|
+
function computeActiveNavPath(navItems, pathForMatchValue) {
|
|
6
|
+
const allNavPaths = navItems.flatMap((item) => {
|
|
7
|
+
const paths = [item.path];
|
|
8
|
+
if (item.children) {
|
|
9
|
+
paths.push(...item.children.map((child) => child.path));
|
|
10
|
+
}
|
|
11
|
+
return paths;
|
|
12
|
+
});
|
|
13
|
+
return allNavPaths.filter((p) => pathForMatchValue.startsWith(p)).sort((a, b) => b.length - a.length)[0];
|
|
14
|
+
}
|
|
15
|
+
function isNavItemActive(item, activeNavPath) {
|
|
16
|
+
if (activeNavPath === item.path) return true;
|
|
17
|
+
if (item.children?.some((child) => activeNavPath === child.path)) return true;
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
computeActiveNavPath,
|
|
22
|
+
isNavItemActive,
|
|
23
|
+
pathForMatch
|
|
24
|
+
};
|