@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.
Files changed (255) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +18 -0
  3. package/dist/body-foot-util/body-foot-util-area.d.ts +55 -0
  4. package/dist/body-foot-util/body-foot-util-area.js +71 -0
  5. package/dist/body-foot-util/edit-link.d.ts +45 -0
  6. package/dist/body-foot-util/edit-link.js +42 -0
  7. package/dist/body-foot-util/index.d.ts +3 -0
  8. package/dist/body-foot-util/index.js +11 -0
  9. package/dist/breadcrumb/breadcrumb.d.ts +57 -0
  10. package/dist/breadcrumb/breadcrumb.js +113 -0
  11. package/dist/breadcrumb/find-path.d.ts +16 -0
  12. package/dist/breadcrumb/find-path.js +13 -0
  13. package/dist/breadcrumb/index.d.ts +4 -0
  14. package/dist/breadcrumb/index.js +7 -0
  15. package/dist/breadcrumb/types.d.ts +32 -0
  16. package/dist/breadcrumb/types.js +0 -0
  17. package/dist/code-syntax/code-block-enhancer-script.d.ts +3 -0
  18. package/dist/code-syntax/code-block-enhancer-script.js +165 -0
  19. package/dist/code-syntax/code-block-enhancer.d.ts +22 -0
  20. package/dist/code-syntax/code-block-enhancer.js +13 -0
  21. package/dist/code-syntax/index.d.ts +8 -0
  22. package/dist/code-syntax/index.js +29 -0
  23. package/dist/code-syntax/mermaid-init-script.d.ts +51 -0
  24. package/dist/code-syntax/mermaid-init-script.js +225 -0
  25. package/dist/code-syntax/mermaid-init.d.ts +48 -0
  26. package/dist/code-syntax/mermaid-init.js +14 -0
  27. package/dist/code-syntax/tabs-init-script.d.ts +3 -0
  28. package/dist/code-syntax/tabs-init-script.js +106 -0
  29. package/dist/code-syntax/tabs-init.d.ts +24 -0
  30. package/dist/code-syntax/tabs-init.js +10 -0
  31. package/dist/code-syntax/tabs.d.ts +36 -0
  32. package/dist/code-syntax/tabs.js +62 -0
  33. package/dist/content/component-map.d.ts +51 -0
  34. package/dist/content/component-map.js +29 -0
  35. package/dist/content/content-blockquote.d.ts +11 -0
  36. package/dist/content/content-blockquote.js +14 -0
  37. package/dist/content/content-code.d.ts +26 -0
  38. package/dist/content/content-code.js +39 -0
  39. package/dist/content/content-link.d.ts +12 -0
  40. package/dist/content/content-link.js +43 -0
  41. package/dist/content/content-ol.d.ts +11 -0
  42. package/dist/content/content-ol.js +15 -0
  43. package/dist/content/content-paragraph.d.ts +10 -0
  44. package/dist/content/content-paragraph.js +7 -0
  45. package/dist/content/content-strong.d.ts +11 -0
  46. package/dist/content/content-strong.js +14 -0
  47. package/dist/content/content-table.d.ts +11 -0
  48. package/dist/content/content-table.js +14 -0
  49. package/dist/content/content-ul.d.ts +11 -0
  50. package/dist/content/content-ul.js +15 -0
  51. package/dist/content/heading-h2.d.ts +14 -0
  52. package/dist/content/heading-h2.js +18 -0
  53. package/dist/content/heading-h3.d.ts +14 -0
  54. package/dist/content/heading-h3.js +18 -0
  55. package/dist/content/heading-h4.d.ts +14 -0
  56. package/dist/content/heading-h4.js +18 -0
  57. package/dist/content/index.d.ts +13 -0
  58. package/dist/content/index.js +27 -0
  59. package/dist/details/details.d.ts +26 -0
  60. package/dist/details/details.js +10 -0
  61. package/dist/details/index.d.ts +2 -0
  62. package/dist/details/index.js +4 -0
  63. package/dist/doclayout/anchors.d.ts +55 -0
  64. package/dist/doclayout/anchors.js +42 -0
  65. package/dist/doclayout/doc-layout-with-defaults.d.ts +83 -0
  66. package/dist/doclayout/doc-layout-with-defaults.js +159 -0
  67. package/dist/doclayout/doc-layout.d.ts +121 -0
  68. package/dist/doclayout/doc-layout.js +89 -0
  69. package/dist/doclayout/index.d.ts +6 -0
  70. package/dist/doclayout/index.js +17 -0
  71. package/dist/footer/footer.d.ts +42 -0
  72. package/dist/footer/footer.js +79 -0
  73. package/dist/footer/index.d.ts +3 -0
  74. package/dist/footer/index.js +4 -0
  75. package/dist/footer/types.d.ts +58 -0
  76. package/dist/footer/types.js +0 -0
  77. package/dist/head/doc-head.d.ts +33 -0
  78. package/dist/head/doc-head.js +90 -0
  79. package/dist/head/index.d.ts +5 -0
  80. package/dist/head/index.js +8 -0
  81. package/dist/head/og-tags.d.ts +25 -0
  82. package/dist/head/og-tags.js +16 -0
  83. package/dist/head/twitter-card.d.ts +21 -0
  84. package/dist/head/twitter-card.js +14 -0
  85. package/dist/head/types.d.ts +83 -0
  86. package/dist/head/types.js +0 -0
  87. package/dist/header/header.d.ts +158 -0
  88. package/dist/header/header.js +367 -0
  89. package/dist/header/index.d.ts +6 -0
  90. package/dist/header/index.js +18 -0
  91. package/dist/header/nav-active.d.ts +39 -0
  92. package/dist/header/nav-active.js +24 -0
  93. package/dist/header/nav-overflow-script.d.ts +3 -0
  94. package/dist/header/nav-overflow-script.js +169 -0
  95. package/dist/header/right-items.d.ts +38 -0
  96. package/dist/header/right-items.js +30 -0
  97. package/dist/header/types.d.ts +40 -0
  98. package/dist/header/types.js +0 -0
  99. package/dist/html-preview-wrapper/dedent.d.ts +10 -0
  100. package/dist/html-preview-wrapper/dedent.js +16 -0
  101. package/dist/html-preview-wrapper/highlighted-code.d.ts +18 -0
  102. package/dist/html-preview-wrapper/highlighted-code.js +53 -0
  103. package/dist/html-preview-wrapper/html-preview-wrapper.d.ts +60 -0
  104. package/dist/html-preview-wrapper/html-preview-wrapper.js +36 -0
  105. package/dist/html-preview-wrapper/html-preview.d.ts +35 -0
  106. package/dist/html-preview-wrapper/html-preview.js +75 -0
  107. package/dist/html-preview-wrapper/index.d.ts +5 -0
  108. package/dist/html-preview-wrapper/index.js +12 -0
  109. package/dist/html-preview-wrapper/preflight.d.ts +13 -0
  110. package/dist/html-preview-wrapper/preflight.js +108 -0
  111. package/dist/html-preview-wrapper/preview-base.d.ts +29 -0
  112. package/dist/html-preview-wrapper/preview-base.js +127 -0
  113. package/dist/i18n-version/index.d.ts +5 -0
  114. package/dist/i18n-version/index.js +14 -0
  115. package/dist/i18n-version/language-switcher.d.ts +24 -0
  116. package/dist/i18n-version/language-switcher.js +25 -0
  117. package/dist/i18n-version/types.d.ts +43 -0
  118. package/dist/i18n-version/types.js +0 -0
  119. package/dist/i18n-version/version-banner.d.ts +30 -0
  120. package/dist/i18n-version/version-banner.js +21 -0
  121. package/dist/i18n-version/version-switcher.d.ts +112 -0
  122. package/dist/i18n-version/version-switcher.js +157 -0
  123. package/dist/index.d.ts +2 -0
  124. package/dist/index.js +0 -0
  125. package/dist/integrations/claude-resources/escape-for-mdx.d.ts +8 -0
  126. package/dist/integrations/claude-resources/escape-for-mdx.js +131 -0
  127. package/dist/integrations/claude-resources/generate.d.ts +13 -0
  128. package/dist/integrations/claude-resources/generate.js +404 -0
  129. package/dist/integrations/claude-resources/index.d.ts +46 -0
  130. package/dist/integrations/claude-resources/index.js +24 -0
  131. package/dist/integrations/doc-history/index.d.ts +137 -0
  132. package/dist/integrations/doc-history/index.js +138 -0
  133. package/dist/integrations/doc-history/pre-build.d.ts +58 -0
  134. package/dist/integrations/doc-history/pre-build.js +67 -0
  135. package/dist/integrations/llms-txt/dev-middleware.d.ts +40 -0
  136. package/dist/integrations/llms-txt/dev-middleware.js +76 -0
  137. package/dist/integrations/llms-txt/emit.d.ts +22 -0
  138. package/dist/integrations/llms-txt/emit.js +55 -0
  139. package/dist/integrations/llms-txt/generate.d.ts +26 -0
  140. package/dist/integrations/llms-txt/generate.js +36 -0
  141. package/dist/integrations/llms-txt/index.d.ts +7 -0
  142. package/dist/integrations/llms-txt/index.js +27 -0
  143. package/dist/integrations/llms-txt/load.d.ts +51 -0
  144. package/dist/integrations/llms-txt/load.js +83 -0
  145. package/dist/integrations/llms-txt/strip.d.ts +22 -0
  146. package/dist/integrations/llms-txt/strip.js +10 -0
  147. package/dist/integrations/llms-txt/types.d.ts +145 -0
  148. package/dist/integrations/llms-txt/types.js +0 -0
  149. package/dist/integrations/search-index/build-emitter.d.ts +30 -0
  150. package/dist/integrations/search-index/build-emitter.js +15 -0
  151. package/dist/integrations/search-index/collect.d.ts +12 -0
  152. package/dist/integrations/search-index/collect.js +48 -0
  153. package/dist/integrations/search-index/content-files.d.ts +32 -0
  154. package/dist/integrations/search-index/content-files.js +50 -0
  155. package/dist/integrations/search-index/dev-middleware.d.ts +16 -0
  156. package/dist/integrations/search-index/dev-middleware.js +30 -0
  157. package/dist/integrations/search-index/index.d.ts +5 -0
  158. package/dist/integrations/search-index/index.js +14 -0
  159. package/dist/integrations/search-index/types.d.ts +38 -0
  160. package/dist/integrations/search-index/types.js +6 -0
  161. package/dist/metainfo/doc-metainfo.d.ts +50 -0
  162. package/dist/metainfo/doc-metainfo.js +107 -0
  163. package/dist/metainfo/doc-tags.d.ts +66 -0
  164. package/dist/metainfo/doc-tags.js +53 -0
  165. package/dist/metainfo/frontmatter-preview.d.ts +95 -0
  166. package/dist/metainfo/frontmatter-preview.js +55 -0
  167. package/dist/metainfo/index.d.ts +4 -0
  168. package/dist/metainfo/index.js +28 -0
  169. package/dist/nav-indexing/category-nav.d.ts +28 -0
  170. package/dist/nav-indexing/category-nav.js +41 -0
  171. package/dist/nav-indexing/category-tree-nav.d.ts +27 -0
  172. package/dist/nav-indexing/category-tree-nav.js +49 -0
  173. package/dist/nav-indexing/doc-card-grid.d.ts +38 -0
  174. package/dist/nav-indexing/doc-card-grid.js +40 -0
  175. package/dist/nav-indexing/docs-sitemap.d.ts +25 -0
  176. package/dist/nav-indexing/docs-sitemap.js +40 -0
  177. package/dist/nav-indexing/index.d.ts +10 -0
  178. package/dist/nav-indexing/index.js +18 -0
  179. package/dist/nav-indexing/nav-card-grid.d.ts +31 -0
  180. package/dist/nav-indexing/nav-card-grid.js +43 -0
  181. package/dist/nav-indexing/site-tree-nav-demo.d.ts +39 -0
  182. package/dist/nav-indexing/site-tree-nav-demo.js +65 -0
  183. package/dist/nav-indexing/tag-nav.d.ts +38 -0
  184. package/dist/nav-indexing/tag-nav.js +96 -0
  185. package/dist/nav-indexing/types.d.ts +95 -0
  186. package/dist/nav-indexing/types.js +0 -0
  187. package/dist/nav-indexing/versions-page-content.d.ts +29 -0
  188. package/dist/nav-indexing/versions-page-content.js +76 -0
  189. package/dist/page-loading/index.d.ts +2 -0
  190. package/dist/page-loading/index.js +10 -0
  191. package/dist/page-loading/page-loading-overlay.d.ts +35 -0
  192. package/dist/page-loading/page-loading-overlay.js +50 -0
  193. package/dist/sidebar/index.d.ts +3 -0
  194. package/dist/sidebar/index.js +4 -0
  195. package/dist/sidebar/sidebar.d.ts +54 -0
  196. package/dist/sidebar/sidebar.js +35 -0
  197. package/dist/sidebar/types.d.ts +71 -0
  198. package/dist/sidebar/types.js +0 -0
  199. package/dist/sidebar-resizer/index.d.ts +14 -0
  200. package/dist/sidebar-resizer/index.js +165 -0
  201. package/dist/sidebar-resizer/sidebar-resizer-init.d.ts +20 -0
  202. package/dist/sidebar-resizer/sidebar-resizer-init.js +119 -0
  203. package/dist/sidebar-tree/build-tree.d.ts +43 -0
  204. package/dist/sidebar-tree/build-tree.js +127 -0
  205. package/dist/sidebar-tree/category-meta.d.ts +19 -0
  206. package/dist/sidebar-tree/category-meta.js +63 -0
  207. package/dist/sidebar-tree/index.d.ts +3 -0
  208. package/dist/sidebar-tree/index.js +13 -0
  209. package/dist/sidebar-tree/types.d.ts +120 -0
  210. package/dist/sidebar-tree/types.js +0 -0
  211. package/dist/tab-item/index.d.ts +2 -0
  212. package/dist/tab-item/index.js +5 -0
  213. package/dist/tab-item/tab-item.d.ts +38 -0
  214. package/dist/tab-item/tab-item.js +25 -0
  215. package/dist/theme/color-scheme-provider.d.ts +32 -0
  216. package/dist/theme/color-scheme-provider.js +43 -0
  217. package/dist/theme/color-tweak-export-modal.d.ts +20 -0
  218. package/dist/theme/color-tweak-export-modal.js +138 -0
  219. package/dist/theme/design-token-serde.d.ts +136 -0
  220. package/dist/theme/design-token-serde.js +254 -0
  221. package/dist/theme/design-token-tweak-panel.d.ts +11 -0
  222. package/dist/theme/design-token-tweak-panel.js +10 -0
  223. package/dist/theme/design-token-types.d.ts +19 -0
  224. package/dist/theme/design-token-types.js +6 -0
  225. package/dist/theme/iframe-bridge.d.ts +44 -0
  226. package/dist/theme/iframe-bridge.js +70 -0
  227. package/dist/theme/index.d.ts +9 -0
  228. package/dist/theme/index.js +42 -0
  229. package/dist/theme/theme-toggle.d.ts +17 -0
  230. package/dist/theme/theme-toggle.js +91 -0
  231. package/dist/toc/cx.d.ts +16 -0
  232. package/dist/toc/cx.js +22 -0
  233. package/dist/toc/index.d.ts +5 -0
  234. package/dist/toc/index.js +9 -0
  235. package/dist/toc/mobile-toc.d.ts +46 -0
  236. package/dist/toc/mobile-toc.js +88 -0
  237. package/dist/toc/smart-break.d.ts +27 -0
  238. package/dist/toc/smart-break.js +36 -0
  239. package/dist/toc/toc-title.d.ts +10 -0
  240. package/dist/toc/toc-title.js +14 -0
  241. package/dist/toc/toc.d.ts +60 -0
  242. package/dist/toc/toc.js +56 -0
  243. package/dist/toc/types.d.ts +23 -0
  244. package/dist/toc/types.js +0 -0
  245. package/dist/toc/use-active-heading.d.ts +30 -0
  246. package/dist/toc/use-active-heading.js +106 -0
  247. package/dist/transitions/index.d.ts +1 -0
  248. package/dist/transitions/index.js +12 -0
  249. package/dist/transitions/page-events.d.ts +41 -0
  250. package/dist/transitions/page-events.js +20 -0
  251. package/dist/url-normalizer/index.d.ts +1 -0
  252. package/dist/url-normalizer/index.js +6 -0
  253. package/dist/url-normalizer/normalize.d.ts +104 -0
  254. package/dist/url-normalizer/normalize.js +22 -0
  255. 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
+ };
@@ -0,0 +1,3 @@
1
+ declare const NAV_OVERFLOW_SCRIPT: string;
2
+
3
+ export { NAV_OVERFLOW_SCRIPT };