@takazudo/zudo-doc 5.28.2 → 6.0.1

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 (511) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +49 -16
  3. package/bin/gen-z-index.mjs +18 -18
  4. package/dist/agent-docs/identity.d.ts +4 -0
  5. package/dist/agent-docs/identity.js +24 -0
  6. package/dist/agent-docs/index.d.ts +5 -0
  7. package/dist/agent-docs/index.js +5 -0
  8. package/dist/agent-docs/limits.d.ts +11 -0
  9. package/dist/agent-docs/limits.js +24 -0
  10. package/dist/agent-docs/search.d.ts +14 -0
  11. package/dist/agent-docs/search.js +82 -0
  12. package/dist/agent-docs/tokenize.d.ts +2 -0
  13. package/dist/agent-docs/tokenize.js +22 -0
  14. package/dist/agent-docs/types.d.ts +68 -0
  15. package/dist/agent-docs/types.js +0 -0
  16. package/dist/ai-chat-modal/index.d.ts +1 -4
  17. package/dist/ai-chat-modal/index.js +183 -123
  18. package/dist/asset-components/asset-card.d.ts +1 -2
  19. package/dist/asset-components/asset-card.js +12 -12
  20. package/dist/asset-components/asset-code.d.ts +1 -2
  21. package/dist/asset-components/asset-code.js +10 -10
  22. package/dist/asset-components/shared.d.ts +3 -4
  23. package/dist/asset-components/shared.js +4 -4
  24. package/dist/asset-index-page/body.d.ts +5 -6
  25. package/dist/asset-index-page/body.js +6 -6
  26. package/dist/asset-index-page/index.d.ts +1 -2
  27. package/dist/asset-index-page/index.js +1 -1
  28. package/dist/asset-page/body.d.ts +5 -9
  29. package/dist/asset-page/body.js +3 -3
  30. package/dist/asset-page/components.d.ts +16 -17
  31. package/dist/asset-page/components.js +10 -9
  32. package/dist/asset-page/index.d.ts +1 -2
  33. package/dist/asset-page/index.js +1 -1
  34. package/dist/auto-logo/index.d.ts +1 -2
  35. package/dist/auto-logo/index.js +2 -2
  36. package/dist/body-foot-util/body-foot-util-area.d.ts +3 -4
  37. package/dist/body-foot-util/body-foot-util-area.js +1 -2
  38. package/dist/body-foot-util/edit-link.d.ts +2 -3
  39. package/dist/body-foot-util/edit-link.js +1 -2
  40. package/dist/breadcrumb/breadcrumb.d.ts +6 -6
  41. package/dist/breadcrumb/breadcrumb.js +3 -4
  42. package/dist/catalog.js +1 -1
  43. package/dist/category-nav/index.d.ts +1 -2
  44. package/dist/category-nav/index.js +11 -5
  45. package/dist/category-tree-nav/index.d.ts +1 -2
  46. package/dist/category-tree-nav/index.js +3 -3
  47. package/dist/chrome/derive.d.ts +18 -27
  48. package/dist/chrome/derive.js +47 -29
  49. package/dist/chrome/index.d.ts +5 -5
  50. package/dist/chrome/index.js +1 -1
  51. package/dist/chrome/island-data.d.ts +4 -0
  52. package/dist/chrome/island-data.js +52 -0
  53. package/dist/chrome/primary-slots.d.ts +2 -3
  54. package/dist/chrome-bindings.d.ts +30 -22
  55. package/dist/code-group/index.d.ts +3 -4
  56. package/dist/code-group/index.js +3 -7
  57. package/dist/code-syntax/code-block-enhancer.d.ts +1 -2
  58. package/dist/code-syntax/code-block-enhancer.js +2 -2
  59. package/dist/code-syntax/mermaid-init.d.ts +1 -2
  60. package/dist/code-syntax/mermaid-init.js +5 -2
  61. package/dist/code-syntax/tabs-init-script.js +1 -1
  62. package/dist/code-syntax/tabs-init.d.ts +1 -2
  63. package/dist/code-syntax/tabs-init.js +2 -2
  64. package/dist/code-syntax/tabs.d.ts +6 -6
  65. package/dist/code-syntax/tabs.js +8 -8
  66. package/dist/compiled.css +2937 -2942
  67. package/dist/config/component-tokens.d.ts +1 -1
  68. package/dist/config/component-tokens.js +22 -0
  69. package/dist/config-assertions/index.d.ts +13 -0
  70. package/dist/config-assertions/index.js +14 -0
  71. package/dist/config.d.ts +36 -17
  72. package/dist/config.js +23 -95
  73. package/dist/content/content-blockquote.d.ts +2 -3
  74. package/dist/content/content-blockquote.js +3 -3
  75. package/dist/content/content-code.d.ts +3 -4
  76. package/dist/content/content-code.js +5 -5
  77. package/dist/content/content-link.d.ts +3 -4
  78. package/dist/content/content-link.js +10 -10
  79. package/dist/content/content-ol.d.ts +2 -3
  80. package/dist/content/content-ol.js +5 -4
  81. package/dist/content/content-paragraph.d.ts +2 -3
  82. package/dist/content/content-paragraph.js +1 -1
  83. package/dist/content/content-strong.d.ts +2 -3
  84. package/dist/content/content-strong.js +3 -3
  85. package/dist/content/content-table.d.ts +2 -3
  86. package/dist/content/content-table.js +4 -4
  87. package/dist/content/content-ul.d.ts +2 -3
  88. package/dist/content/content-ul.js +4 -4
  89. package/dist/content/heading-h2.d.ts +2 -3
  90. package/dist/content/heading-h2.js +4 -4
  91. package/dist/content/heading-h3.d.ts +2 -3
  92. package/dist/content/heading-h3.js +4 -4
  93. package/dist/content/heading-h4.d.ts +2 -3
  94. package/dist/content/heading-h4.js +4 -4
  95. package/dist/content-admonition/index.d.ts +3 -4
  96. package/dist/content-admonition/index.js +2 -2
  97. package/dist/content.css +35 -33
  98. package/dist/design-token-panel-bootstrap-controller.d.ts +178 -0
  99. package/dist/design-token-panel-bootstrap-controller.js +359 -0
  100. package/dist/design-token-panel-bootstrap-island.d.ts +5 -0
  101. package/dist/design-token-panel-bootstrap-island.js +19 -0
  102. package/dist/design-token-panel-bootstrap.d.ts +5 -195
  103. package/dist/design-token-panel-bootstrap.js +3 -288
  104. package/dist/desktop-sidebar-toggle-island/index.d.ts +2 -7
  105. package/dist/desktop-sidebar-toggle-island/index.js +2 -58
  106. package/dist/desktop-sidebar-toggle-island/island.d.ts +4 -0
  107. package/dist/desktop-sidebar-toggle-island/island.js +43 -0
  108. package/dist/desktop-sidebar-toggle-island/storage.d.ts +4 -0
  109. package/dist/desktop-sidebar-toggle-island/storage.js +29 -0
  110. package/dist/desktop-toc-toggle-island/index.d.ts +2 -7
  111. package/dist/desktop-toc-toggle-island/index.js +2 -58
  112. package/dist/desktop-toc-toggle-island/island.d.ts +4 -0
  113. package/dist/desktop-toc-toggle-island/island.js +43 -0
  114. package/dist/desktop-toc-toggle-island/storage.d.ts +4 -0
  115. package/dist/desktop-toc-toggle-island/storage.js +29 -0
  116. package/dist/details/details.d.ts +3 -4
  117. package/dist/details/details.js +1 -1
  118. package/dist/doc-body-end/index.d.ts +1 -2
  119. package/dist/doc-body-end/index.js +1 -1
  120. package/dist/doc-body-end-islands/design-token-panel-island.d.ts +2 -2
  121. package/dist/doc-body-end-islands/design-token-panel-island.js +3 -7
  122. package/dist/doc-body-end-islands/index.d.ts +4 -21
  123. package/dist/doc-body-end-islands/index.js +5 -3
  124. package/dist/doc-body-end-islands/theme-pack-switcher-island.d.ts +3 -13
  125. package/dist/doc-body-end-islands/theme-pack-switcher-island.js +11 -13
  126. package/dist/doc-content-header/index.d.ts +1 -2
  127. package/dist/doc-content-header/index.js +1 -1
  128. package/dist/doc-history/index.d.ts +1 -1
  129. package/dist/doc-history/index.js +166 -141
  130. package/dist/doc-history-area/index.d.ts +6 -4
  131. package/dist/doc-history-area/index.js +17 -16
  132. package/dist/doc-metainfo-area/index.d.ts +2 -3
  133. package/dist/doc-metainfo-area/index.js +1 -1
  134. package/dist/doc-page-renderer/index.d.ts +13 -7
  135. package/dist/doc-page-renderer/index.js +10 -1
  136. package/dist/doc-page-shell/index.d.ts +20 -7
  137. package/dist/doc-page-shell/index.js +17 -6
  138. package/dist/doc-pager/index.d.ts +1 -2
  139. package/dist/doc-pager/index.js +3 -3
  140. package/dist/doc-tags-area/index.d.ts +2 -3
  141. package/dist/doc-tags-area/index.js +1 -1
  142. package/dist/doclayout/doc-layout-with-defaults.d.ts +9 -9
  143. package/dist/doclayout/doc-layout-with-defaults.js +5 -15
  144. package/dist/doclayout/doc-layout.d.ts +26 -27
  145. package/dist/doclayout/doc-layout.js +23 -14
  146. package/dist/docs-schema/index.d.ts +4 -0
  147. package/dist/docs-schema/index.js +1 -0
  148. package/dist/extract-headings/index.js +43 -12
  149. package/dist/factory-context/index.d.ts +22 -19
  150. package/dist/features.css +75 -8
  151. package/dist/find-in-page/find-bar.d.ts +4 -2
  152. package/dist/find-in-page/find-bar.js +58 -69
  153. package/dist/find-in-page/index.d.ts +2 -8
  154. package/dist/find-in-page/index.js +33 -30
  155. package/dist/footer/footer.d.ts +3 -4
  156. package/dist/footer/footer.js +3 -3
  157. package/dist/footer-with-defaults/index.d.ts +2 -3
  158. package/dist/footer-with-defaults/index.js +1 -1
  159. package/dist/frontmatter-preview-defaults/index.js +1 -0
  160. package/dist/head/doc-head.d.ts +1 -1
  161. package/dist/head/doc-head.js +24 -32
  162. package/dist/head/og-tags.d.ts +1 -1
  163. package/dist/head/og-tags.js +8 -7
  164. package/dist/head/twitter-card.d.ts +1 -1
  165. package/dist/head/twitter-card.js +1 -1
  166. package/dist/head-with-defaults/index.d.ts +7 -2
  167. package/dist/head-with-defaults/index.js +46 -32
  168. package/dist/header/header.d.ts +8 -8
  169. package/dist/header/header.js +9 -11
  170. package/dist/header/types.d.ts +7 -7
  171. package/dist/header-with-defaults/index.d.ts +3 -4
  172. package/dist/header-with-defaults/index.js +27 -14
  173. package/dist/home-intro/index.d.ts +2 -5
  174. package/dist/home-intro/index.js +7 -5
  175. package/dist/home-intro/prepare.js +4 -3
  176. package/dist/home-page/index.d.ts +3 -3
  177. package/dist/home-page/index.js +19 -17
  178. package/dist/html-preview-wrapper/highlighted-code.d.ts +3 -4
  179. package/dist/html-preview-wrapper/highlighted-code.js +19 -17
  180. package/dist/html-preview-wrapper/html-preview-wrapper.d.ts +4 -25
  181. package/dist/html-preview-wrapper/html-preview-wrapper.js +2 -87
  182. package/dist/html-preview-wrapper/html-preview.d.ts +3 -10
  183. package/dist/html-preview-wrapper/html-preview.js +13 -37
  184. package/dist/html-preview-wrapper/index.d.ts +2 -1
  185. package/dist/html-preview-wrapper/index.js +1 -1
  186. package/dist/html-preview-wrapper/preview-base.d.ts +3 -5
  187. package/dist/html-preview-wrapper/preview-base.js +56 -59
  188. package/dist/html-preview-wrapper/wrapper.d.ts +20 -0
  189. package/dist/html-preview-wrapper/wrapper.js +37 -0
  190. package/dist/hydration-pending.d.ts +3 -5
  191. package/dist/hydration-pending.js +7 -5
  192. package/dist/i18n-version/language-switcher.d.ts +5 -32
  193. package/dist/i18n-version/language-switcher.js +5 -106
  194. package/dist/i18n-version/switcher-generated-scripts.d.ts +2 -0
  195. package/dist/i18n-version/switcher-generated-scripts.js +107 -0
  196. package/dist/i18n-version/switcher-url-state.d.ts +76 -0
  197. package/dist/i18n-version/switcher-url-state.js +103 -0
  198. package/dist/i18n-version/version-banner.d.ts +2 -3
  199. package/dist/i18n-version/version-banner.js +1 -1
  200. package/dist/i18n-version/version-switcher.d.ts +5 -50
  201. package/dist/i18n-version/version-switcher.js +5 -157
  202. package/dist/icons/index.d.ts +18 -19
  203. package/dist/icons/index.js +17 -33
  204. package/dist/image-enlarge/index.d.ts +1 -10
  205. package/dist/image-enlarge/index.js +80 -55
  206. package/dist/image-enlarge/public.d.ts +2 -0
  207. package/dist/image-enlarge/public.js +6 -0
  208. package/dist/image-enlarge/ssr-fallback.d.ts +2 -0
  209. package/dist/image-enlarge/ssr-fallback.js +8 -0
  210. package/dist/index.d.ts +11 -4
  211. package/dist/inline-version-switcher/index.d.ts +1 -2
  212. package/dist/inline-version-switcher/index.js +1 -1
  213. package/dist/island-types/index.d.ts +2 -2
  214. package/dist/island-types/index.js +1 -5
  215. package/dist/math-block/index.d.ts +4 -7
  216. package/dist/math-block/index.js +5 -5
  217. package/dist/mcp/handler.d.ts +8 -0
  218. package/dist/mcp/handler.js +129 -0
  219. package/dist/mcp/index.d.ts +4 -0
  220. package/dist/mcp/index.js +7 -0
  221. package/dist/mcp/loader.d.ts +19 -0
  222. package/dist/mcp/loader.js +202 -0
  223. package/dist/mdx-components/index.js +40 -108
  224. package/dist/mermaid-enlarge/index.d.ts +1 -8
  225. package/dist/mermaid-enlarge/index.js +174 -158
  226. package/dist/mermaid-enlarge/public.d.ts +2 -0
  227. package/dist/mermaid-enlarge/public.js +6 -0
  228. package/dist/mermaid-enlarge/ssr-fallback.d.ts +2 -0
  229. package/dist/mermaid-enlarge/ssr-fallback.js +8 -0
  230. package/dist/metainfo/doc-metainfo.d.ts +2 -3
  231. package/dist/metainfo/doc-metainfo.js +1 -4
  232. package/dist/metainfo/doc-tags.d.ts +2 -3
  233. package/dist/metainfo/doc-tags.js +1 -1
  234. package/dist/metainfo/frontmatter-preview.d.ts +3 -4
  235. package/dist/metainfo/frontmatter-preview.js +1 -1
  236. package/dist/nav-data-prep/index.js +6 -4
  237. package/dist/nav-indexing/category-nav.d.ts +2 -3
  238. package/dist/nav-indexing/category-nav.js +1 -2
  239. package/dist/nav-indexing/category-tree-nav.d.ts +2 -3
  240. package/dist/nav-indexing/category-tree-nav.js +1 -1
  241. package/dist/nav-indexing/doc-card-grid.d.ts +2 -3
  242. package/dist/nav-indexing/doc-card-grid.js +1 -2
  243. package/dist/nav-indexing/docs-sitemap.d.ts +2 -3
  244. package/dist/nav-indexing/docs-sitemap.js +2 -2
  245. package/dist/nav-indexing/index.d.ts +1 -1
  246. package/dist/nav-indexing/nav-card-grid.d.ts +2 -3
  247. package/dist/nav-indexing/nav-card-grid.js +1 -2
  248. package/dist/nav-indexing/note-tray-index-parts/card-list.d.ts +1 -2
  249. package/dist/nav-indexing/note-tray-index-parts/card-list.js +4 -4
  250. package/dist/nav-indexing/note-tray-index-parts/date-line.d.ts +2 -3
  251. package/dist/nav-indexing/note-tray-index-parts/date-line.js +1 -1
  252. package/dist/nav-indexing/note-tray-index-parts/index-list.d.ts +1 -2
  253. package/dist/nav-indexing/note-tray-index-parts/index-list.js +2 -2
  254. package/dist/nav-indexing/note-tray-index-parts/timeline.d.ts +1 -2
  255. package/dist/nav-indexing/note-tray-index-parts/timeline.js +2 -2
  256. package/dist/nav-indexing/note-tray-index.d.ts +1 -2
  257. package/dist/nav-indexing/note-tray-index.js +1 -1
  258. package/dist/nav-indexing/site-tree-nav-demo.d.ts +2 -3
  259. package/dist/nav-indexing/site-tree-nav-demo.js +2 -2
  260. package/dist/nav-indexing/tag-nav.d.ts +1 -2
  261. package/dist/nav-indexing/tag-nav.js +1 -1
  262. package/dist/nav-indexing/types.d.ts +2 -2
  263. package/dist/nav-indexing/versions-page-content.d.ts +2 -3
  264. package/dist/nav-indexing/versions-page-content.js +8 -8
  265. package/dist/note-tray-index/index.d.ts +1 -2
  266. package/dist/note-tray-index/index.js +1 -1
  267. package/dist/page-loading/page-loading-overlay.d.ts +1 -2
  268. package/dist/page-loading/page-loading-overlay.js +3 -5
  269. package/dist/plugins/agent-export.d.ts +3 -0
  270. package/dist/plugins/agent-export.js +34 -0
  271. package/dist/plugins/internal/agent-export/chunk.d.ts +5 -0
  272. package/dist/plugins/internal/agent-export/chunk.js +90 -0
  273. package/dist/plugins/internal/agent-export/index.d.ts +24 -0
  274. package/dist/plugins/internal/agent-export/index.js +123 -0
  275. package/dist/plugins/internal/agent-export/normalize.d.ts +5 -0
  276. package/dist/plugins/internal/agent-export/normalize.js +73 -0
  277. package/dist/plugins/internal/llms-txt/dev-middleware.d.ts +6 -0
  278. package/dist/plugins/internal/llms-txt/dev-middleware.js +8 -3
  279. package/dist/plugins/internal/llms-txt/emit.js +23 -6
  280. package/dist/plugins/internal/llms-txt/generate.d.ts +7 -1
  281. package/dist/plugins/internal/llms-txt/generate.js +9 -2
  282. package/dist/plugins/internal/llms-txt/load.d.ts +2 -0
  283. package/dist/plugins/internal/llms-txt/load.js +20 -4
  284. package/dist/plugins/internal/llms-txt/types.d.ts +10 -0
  285. package/dist/plugins/routes.js +4 -0
  286. package/dist/preset.d.ts +19 -9
  287. package/dist/preset.js +20 -1
  288. package/dist/route-context-payload/index.js +1 -1
  289. package/dist/routes/404.d.ts +2 -3
  290. package/dist/routes/404.js +1 -1
  291. package/dist/routes/_chrome.d.ts +5 -5
  292. package/dist/routes/_chrome.js +7 -2
  293. package/dist/routes/_context.d.ts +4 -4
  294. package/dist/routes/_design-token-panel-bootstrap.d.ts +1 -4
  295. package/dist/routes/_design-token-panel-bootstrap.js +9 -1
  296. package/dist/routes/docs-slug.d.ts +2 -3
  297. package/dist/routes/docs-tags-index.d.ts +2 -3
  298. package/dist/routes/docs-tags-index.js +1 -1
  299. package/dist/routes/docs-tags-tag.d.ts +2 -3
  300. package/dist/routes/docs-tags-tag.js +1 -1
  301. package/dist/routes/docs-versions.d.ts +2 -3
  302. package/dist/routes/docs-versions.js +1 -1
  303. package/dist/routes/files-path.d.ts +2 -3
  304. package/dist/routes/files-path.js +1 -1
  305. package/dist/routes/index.d.ts +2 -3
  306. package/dist/routes/index.js +1 -1
  307. package/dist/routes/locale-docs-slug.d.ts +2 -3
  308. package/dist/routes/locale-docs-tags-index.d.ts +2 -3
  309. package/dist/routes/locale-docs-tags-index.js +1 -1
  310. package/dist/routes/locale-docs-tags-tag.d.ts +2 -3
  311. package/dist/routes/locale-docs-tags-tag.js +1 -1
  312. package/dist/routes/locale-docs-versions.d.ts +2 -3
  313. package/dist/routes/locale-docs-versions.js +1 -1
  314. package/dist/routes/locale-files-path.d.ts +2 -3
  315. package/dist/routes/locale-files-path.js +1 -1
  316. package/dist/routes/locale-index.d.ts +2 -3
  317. package/dist/routes/locale-index.js +1 -1
  318. package/dist/routes/mcp.d.ts +5 -0
  319. package/dist/routes/mcp.js +25 -0
  320. package/dist/routes/v-docs-slug.d.ts +2 -3
  321. package/dist/routes/v-locale-docs-slug.d.ts +2 -3
  322. package/dist/search-widget/index.d.ts +1 -2
  323. package/dist/search-widget/index.js +4 -7
  324. package/dist/search-widget-script/generated-script.js +12 -5
  325. package/dist/settings-defaults.d.ts +2 -0
  326. package/dist/settings-defaults.js +93 -0
  327. package/dist/settings.d.ts +8 -2
  328. package/dist/sidebar/client-data.d.ts +18 -0
  329. package/dist/sidebar/client-data.js +47 -0
  330. package/dist/sidebar/index.d.ts +3 -1
  331. package/dist/sidebar/index.js +3 -1
  332. package/dist/sidebar/sidebar.d.ts +12 -44
  333. package/dist/sidebar/sidebar.js +4 -3
  334. package/dist/sidebar/types.d.ts +14 -0
  335. package/dist/sidebar-prepaint/index.d.ts +1 -2
  336. package/dist/sidebar-prepaint/index.js +4 -6
  337. package/dist/sidebar-resizer/sidebar-resizer-init.d.ts +2 -3
  338. package/dist/sidebar-resizer/sidebar-resizer-init.js +3 -3
  339. package/dist/sidebar-toggle-island/index.d.ts +8 -11
  340. package/dist/sidebar-toggle-island/index.js +75 -62
  341. package/dist/sidebar-tree/build-tree.js +5 -6
  342. package/dist/sidebar-tree/types.d.ts +2 -0
  343. package/dist/sidebar-tree-island/index.d.ts +4 -19
  344. package/dist/sidebar-tree-island/index.js +782 -436
  345. package/dist/sidebar-tree-island/scope-state.d.ts +38 -0
  346. package/dist/sidebar-tree-island/scope-state.js +151 -0
  347. package/dist/sidebar-tree-island/sidebar-scroll-preserve.js +6 -2
  348. package/dist/sidebar-utils/index.d.ts +17 -19
  349. package/dist/sidebar-utils/index.js +100 -3
  350. package/dist/sidebar-utils/scope.d.ts +11 -0
  351. package/dist/sidebar-utils/scope.js +67 -0
  352. package/dist/sidebar-with-defaults/index.d.ts +1 -2
  353. package/dist/sidebar-with-defaults/index.js +19 -18
  354. package/dist/site-schema/nav-tree.js +15 -15
  355. package/dist/site-schema/types.d.ts +1 -0
  356. package/dist/site-tree-nav/index.d.ts +2 -3
  357. package/dist/site-tree-nav/index.js +11 -12
  358. package/dist/site-tree-nav/normalize-island-props.d.ts +16 -0
  359. package/dist/site-tree-nav/normalize-island-props.js +122 -0
  360. package/dist/site-tree-nav-island/index.d.ts +3 -3
  361. package/dist/site-tree-nav-island/index.js +243 -144
  362. package/dist/smart-break/index.d.ts +3 -4
  363. package/dist/smart-break/index.js +1 -1
  364. package/dist/tab-item/tab-item.d.ts +3 -4
  365. package/dist/tab-item/tab-item.js +1 -1
  366. package/dist/tag-pages/index.d.ts +3 -3
  367. package/dist/tag-pages/index.js +10 -10
  368. package/dist/theme/color-scheme-provider.d.ts +3 -3
  369. package/dist/theme/color-scheme-provider.js +3 -3
  370. package/dist/theme/theme-pack-provider.d.ts +1 -1
  371. package/dist/theme/theme-pack-provider.js +3 -3
  372. package/dist/theme/theme-toggle.d.ts +2 -3
  373. package/dist/theme/theme-toggle.js +1 -1
  374. package/dist/theme-pack-dialog/index.d.ts +1 -1
  375. package/dist/theme-pack-dialog/index.js +69 -75
  376. package/dist/theme-pack-dialog/theme-pack-card.d.ts +3 -4
  377. package/dist/theme-pack-dialog/theme-pack-card.js +19 -17
  378. package/dist/theme-pack-switcher/index.d.ts +4 -5
  379. package/dist/theme-pack-switcher/index.js +52 -49
  380. package/dist/theme-packs/academia/meta.json +1 -1
  381. package/dist/theme-packs/academia/pack.css +1 -1
  382. package/dist/theme-packs/bauhaus/meta.json +1 -1
  383. package/dist/theme-packs/bauhaus/pack.css +2 -2
  384. package/dist/theme-packs/blueprint/meta.json +1 -1
  385. package/dist/theme-packs/blueprint/pack.css +2 -2
  386. package/dist/theme-packs/botanica/meta.json +1 -1
  387. package/dist/theme-packs/botanica/pack.css +2 -2
  388. package/dist/theme-packs/broadsheet/meta.json +1 -1
  389. package/dist/theme-packs/broadsheet/pack.css +2 -2
  390. package/dist/theme-packs/brutalist/meta.json +1 -1
  391. package/dist/theme-packs/brutalist/pack.css +2 -2
  392. package/dist/theme-packs/eink/meta.json +1 -1
  393. package/dist/theme-packs/eink/pack.css +1 -1
  394. package/dist/theme-packs/futura-editorial/meta.json +1 -1
  395. package/dist/theme-packs/futura-editorial/pack.css +2 -2
  396. package/dist/theme-packs/hearth/meta.json +1 -1
  397. package/dist/theme-packs/hearth/pack.css +2 -2
  398. package/dist/theme-packs/ledger/meta.json +1 -1
  399. package/dist/theme-packs/ledger/pack.css +1 -1
  400. package/dist/theme-packs/manuscript/meta.json +1 -1
  401. package/dist/theme-packs/manuscript/pack.css +1 -1
  402. package/dist/theme-packs/matcha/meta.json +1 -1
  403. package/dist/theme-packs/matcha/pack.css +2 -2
  404. package/dist/theme-packs/nocturne/meta.json +1 -1
  405. package/dist/theme-packs/nocturne/pack.css +2 -2
  406. package/dist/theme-packs/observatory/meta.json +1 -1
  407. package/dist/theme-packs/observatory/pack.css +2 -2
  408. package/dist/theme-packs/onyx/meta.json +1 -1
  409. package/dist/theme-packs/onyx/pack.css +2 -2
  410. package/dist/theme-packs/phosphor/meta.json +1 -1
  411. package/dist/theme-packs/phosphor/pack.css +2 -2
  412. package/dist/theme-packs/riso/meta.json +1 -1
  413. package/dist/theme-packs/riso/pack.css +2 -2
  414. package/dist/theme-packs/sakura/meta.json +1 -1
  415. package/dist/theme-packs/sakura/pack.css +2 -2
  416. package/dist/theme-packs/scandi/meta.json +1 -1
  417. package/dist/theme-packs/scandi/pack.css +1 -1
  418. package/dist/theme-packs/solar/meta.json +1 -1
  419. package/dist/theme-packs/solar/pack.css +1 -1
  420. package/dist/theme-packs/sumi/meta.json +1 -1
  421. package/dist/theme-packs/sumi/pack.css +2 -2
  422. package/dist/theme-packs/swissgrid/meta.json +1 -1
  423. package/dist/theme-packs/swissgrid/pack.css +1 -1
  424. package/dist/theme-packs/timberline/meta.json +1 -1
  425. package/dist/theme-packs/timberline/pack.css +2 -2
  426. package/dist/theme-packs/washi/meta.json +1 -1
  427. package/dist/theme-packs/washi/pack.css +2 -2
  428. package/dist/theme-toggle/index.d.ts +1 -1
  429. package/dist/theme-toggle/index.js +154 -167
  430. package/dist/theme.css +47 -121
  431. package/dist/toc/mobile-toc.d.ts +3 -5
  432. package/dist/toc/mobile-toc.js +29 -27
  433. package/dist/toc/toc.d.ts +3 -4
  434. package/dist/toc/toc.js +18 -18
  435. package/dist/toc/use-active-heading.d.ts +5 -4
  436. package/dist/toc/use-active-heading.js +36 -30
  437. package/dist/toc-prepaint/index.d.ts +1 -2
  438. package/dist/toc-prepaint/index.js +4 -6
  439. package/dist/transitions/nested-island-props-refresh.d.ts +3 -16
  440. package/dist/transitions/nested-island-props-refresh.js +133 -151
  441. package/dist/transitions/page-events.d.ts +8 -13
  442. package/dist/tree-nav-shared/index.d.ts +4 -5
  443. package/dist/tree-nav-shared/index.js +6 -7
  444. package/dist/use-modal-dialog/index.d.ts +9 -63
  445. package/dist/use-modal-dialog/index.js +41 -59
  446. package/dist/versions-page/index.d.ts +3 -3
  447. package/dist/versions-page/index.js +5 -5
  448. package/dist/wind/index.d.ts +5 -0
  449. package/dist/wind/index.js +169 -0
  450. package/dist/wind.json +498 -0
  451. package/dist/z-index-defaults/index.d.ts +4 -4
  452. package/dist/zdtp-loader.d.ts +7 -0
  453. package/dist/zdtp-loader.js +8 -0
  454. package/eject/asset-components/asset-card.tsx +14 -16
  455. package/eject/asset-components/asset-code.tsx +10 -12
  456. package/eject/asset-components/shared.tsx +5 -7
  457. package/eject/breadcrumb/breadcrumb.tsx +15 -16
  458. package/eject/code-group/index.tsx +4 -10
  459. package/eject/content-admonition/index.tsx +5 -6
  460. package/eject/desktop-sidebar-toggle-island/index.ts +4 -0
  461. package/eject/desktop-sidebar-toggle-island/island.tsx +50 -0
  462. package/eject/desktop-sidebar-toggle-island/storage.ts +27 -0
  463. package/eject/details/details.tsx +3 -5
  464. package/eject/doc-history/index.tsx +193 -179
  465. package/eject/doc-pager/index.tsx +3 -4
  466. package/eject/footer/footer.tsx +7 -9
  467. package/eject/header/header.tsx +42 -54
  468. package/eject/header/nav-overflow-script.ts +1 -1
  469. package/eject/header/types.ts +12 -13
  470. package/eject/image-enlarge/index.tsx +84 -69
  471. package/eject/image-enlarge/public.ts +2 -0
  472. package/eject/image-enlarge/ssr-fallback.tsx +7 -0
  473. package/eject/page-loading/page-loading-overlay.tsx +8 -15
  474. package/eject/sidebar/client-data.ts +68 -0
  475. package/eject/sidebar/index.ts +3 -0
  476. package/eject/sidebar/sidebar.tsx +16 -97
  477. package/eject/sidebar/types.ts +15 -0
  478. package/eject/sidebar-toggle-island/index.tsx +103 -102
  479. package/eject/sidebar-tree-island/index.tsx +827 -615
  480. package/eject/sidebar-tree-island/scope-state.ts +154 -0
  481. package/eject/sidebar-tree-island/sidebar-scroll-preserve.ts +8 -2
  482. package/eject/site-tree-nav-island/index.tsx +349 -222
  483. package/eject/tab-item/tab-item.tsx +2 -4
  484. package/eject/theme-toggle/hydration-pending.ts +6 -10
  485. package/eject/theme-toggle/index.tsx +133 -173
  486. package/eject/toc/mobile-toc.tsx +27 -31
  487. package/eject/toc/toc.tsx +21 -24
  488. package/eject/toc/use-active-heading.ts +43 -38
  489. package/package.json +40 -22
  490. package/routes-src/404.tsx +2 -3
  491. package/routes-src/_chrome.tsx +7 -2
  492. package/routes-src/_design-token-panel-bootstrap.tsx +1 -63
  493. package/routes-src/docs-slug.tsx +2 -3
  494. package/routes-src/docs-tags-index.tsx +2 -3
  495. package/routes-src/docs-tags-tag.tsx +2 -3
  496. package/routes-src/docs-versions.tsx +2 -3
  497. package/routes-src/files-path.tsx +2 -4
  498. package/routes-src/index.tsx +2 -3
  499. package/routes-src/locale-docs-slug.tsx +2 -3
  500. package/routes-src/locale-docs-tags-index.tsx +2 -3
  501. package/routes-src/locale-docs-tags-tag.tsx +2 -3
  502. package/routes-src/locale-docs-versions.tsx +2 -3
  503. package/routes-src/locale-files-path.tsx +2 -4
  504. package/routes-src/locale-index.tsx +2 -3
  505. package/routes-src/mcp.tsx +25 -0
  506. package/routes-src/v-docs-slug.tsx +2 -3
  507. package/routes-src/v-locale-docs-slug.tsx +2 -3
  508. package/tsconfig.base.json +1 -1
  509. package/dist/safelist.css +0 -2
  510. package/dist/theme-no-reset.css +0 -379
  511. package/eject/desktop-sidebar-toggle-island/index.tsx +0 -110
@@ -1,21 +1,18 @@
1
1
  "use client";
2
2
 
3
3
  /** @jsxRuntime automatic */
4
- /** @jsxImportSource preact */
5
-
6
4
  // Image-enlarge island — relocated from src/components/image-enlarge.tsx
7
5
  // (host showcase) into the package as part of Package-First Wave 3 (S3,
8
- // epic #2344). Uses shared hook + constants from S1a foundation:
9
- // - useModalDialog from @takazudo/zudo-doc/use-modal-dialog
10
- // - IMAGE_ENLARGE_DIALOG_CLASS / ENLARGE_DIALOG_STYLE from @takazudo/zudo-doc/island-types
6
+ // epic #2344). The browser-only observers and delegated listeners are owned
7
+ // by this island's activation scope.
11
8
  //
12
9
  // The `/api/ai-chat` endpoint stays host-side (showcase-only).
13
10
  // CSS blocks (.zd-enlargeable, .zd-enlarge-btn, .zd-enlarge-dialog*) are
14
11
  // shipped in @takazudo/zudo-doc/features.css (moved from src/styles/global.css).
15
12
 
16
- import { useState, useEffect } from "preact/compat";
13
+ import { computed, getScope, Show, signal } from "@takazudo/zfb/zudo-react";
17
14
  import { AFTER_NAVIGATE_EVENT } from "../transitions/index.js";
18
- import { useModalDialog } from "../use-modal-dialog/index.js";
15
+ import { modalDialog } from "../use-modal-dialog/index.js";
19
16
  import {
20
17
  IMAGE_ENLARGE_DIALOG_CLASS,
21
18
  ENLARGE_DIALOG_STYLE,
@@ -32,12 +29,24 @@ interface ImageData {
32
29
  }
33
30
 
34
31
  export function ImageEnlarge() {
35
- const [imgData, setImgData] = useState<ImageData | null>(null);
36
-
37
- // Eligibility detection: toggle .zd-enlarge-btn[hidden] per image
38
- useEffect(() => {
32
+ const scope = getScope();
33
+ const imgData = signal<ImageData | null>(null);
34
+ const isOpen = computed(() => imgData.value !== null);
35
+ const imageSrc = computed(() => {
36
+ const current = imgData.value;
37
+ return current ? current.currentSrc || current.src : "";
38
+ });
39
+ const imageSrcset = computed(() => imgData.value?.srcset ?? "");
40
+ const imageHasSrcset = computed(() => Boolean(imgData.value?.srcset));
41
+ const imageAlt = computed(() => imgData.value?.alt ?? "");
42
+
43
+ // Eligibility detection and route-aware image scanning. All browser access
44
+ // starts at activation so SSR and hydration begin from the same closed shell.
45
+ scope.onActivate(() => {
46
+ let active = true;
39
47
  const observedImages = new Set<HTMLImageElement>();
40
48
  const sharedResizeObserver = new ResizeObserver((entries) => {
49
+ if (!active) return;
41
50
  for (const entry of entries) {
42
51
  evaluateEligibility(entry.target as HTMLImageElement);
43
52
  }
@@ -49,7 +58,7 @@ export function ImageEnlarge() {
49
58
  function evaluateEligibility(img: HTMLImageElement) {
50
59
  const container = img.closest(".zd-enlargeable");
51
60
  if (!container) return;
52
- const btn = container.querySelector(".zd-enlarge-btn") as HTMLElement | null;
61
+ const btn = container.querySelector<HTMLElement>(".zd-enlarge-btn");
53
62
  if (!btn) return;
54
63
  const eligible = img.naturalWidth > img.clientWidth * window.devicePixelRatio;
55
64
  if (eligible) {
@@ -75,26 +84,30 @@ export function ImageEnlarge() {
75
84
  }
76
85
 
77
86
  function scanContent() {
78
- const scope = document.querySelector("main .zd-content");
79
- if (!scope) return;
80
- scope.querySelectorAll<HTMLImageElement>(".zd-enlargeable img").forEach(observeImage);
87
+ const content = document.querySelector("main .zd-content");
88
+ if (!content) return;
89
+ content.querySelectorAll<HTMLImageElement>(".zd-enlargeable img").forEach(observeImage);
81
90
  }
82
91
 
83
92
  function startObserving() {
84
- const scope = document.querySelector("main .zd-content");
85
- if (scope) {
93
+ const content = document.querySelector("main .zd-content");
94
+ if (content) {
86
95
  mutationObserver = new MutationObserver((mutations) => {
96
+ if (!active) return;
87
97
  for (const mutation of mutations) {
88
98
  for (const node of mutation.addedNodes) {
89
99
  if (!(node instanceof Element)) continue;
90
100
  if (node.matches(".zd-enlargeable")) {
91
101
  node.querySelectorAll<HTMLImageElement>("img").forEach(observeImage);
92
102
  }
103
+ if (node instanceof HTMLImageElement && node.closest(".zd-enlargeable")) {
104
+ observeImage(node);
105
+ }
93
106
  node.querySelectorAll<HTMLImageElement>(".zd-enlargeable img").forEach(observeImage);
94
107
  }
95
108
  }
96
109
  });
97
- mutationObserver.observe(scope, { childList: true, subtree: true });
110
+ mutationObserver.observe(content, { childList: true, subtree: true });
98
111
  }
99
112
  scanContent();
100
113
  }
@@ -102,11 +115,13 @@ export function ImageEnlarge() {
102
115
  function handleWindowResize() {
103
116
  clearTimeout(resizeTimer);
104
117
  resizeTimer = window.setTimeout(() => {
118
+ if (!active) return;
105
119
  observedImages.forEach((img) => evaluateEligibility(img));
106
120
  }, 150);
107
121
  }
108
122
 
109
- function handleAfterSwap() {
123
+ function handleAfterNavigate() {
124
+ if (!active) return;
110
125
  sharedResizeObserver.disconnect();
111
126
  observedImages.clear();
112
127
  mutationObserver?.disconnect();
@@ -118,32 +133,36 @@ export function ImageEnlarge() {
118
133
 
119
134
  startObserving();
120
135
  window.addEventListener("resize", handleWindowResize);
121
- document.addEventListener(AFTER_NAVIGATE_EVENT, handleAfterSwap);
136
+ document.addEventListener(AFTER_NAVIGATE_EVENT, handleAfterNavigate);
122
137
 
123
138
  return () => {
139
+ active = false;
124
140
  sharedResizeObserver.disconnect();
125
141
  observedImages.clear();
126
142
  mutationObserver?.disconnect();
127
143
  loadAbortController.abort();
128
144
  window.removeEventListener("resize", handleWindowResize);
129
- document.removeEventListener(AFTER_NAVIGATE_EVENT, handleAfterSwap);
145
+ document.removeEventListener(AFTER_NAVIGATE_EVENT, handleAfterNavigate);
130
146
  clearTimeout(resizeTimer);
131
147
  };
132
- }, []);
148
+ });
133
149
 
134
- useEffect(() => {
135
- function handleDocumentClick(e: MouseEvent) {
136
- const sel = window.getSelection();
137
- if (sel && !sel.isCollapsed) return;
138
- const target = e.target as Element;
150
+ // Click detection is delegated because the images live in authored MDX.
151
+ scope.onActivate(() => {
152
+ let active = true;
153
+ function handleDocumentClick(event: Event) {
154
+ if (!active || !(event.target instanceof Element)) return;
155
+ const target = event.target;
156
+ const selection = window.getSelection();
157
+ if (selection && !selection.isCollapsed) return;
139
158
  const container = target.closest(".zd-enlargeable");
140
159
  if (!container) return;
141
160
  if (!target.closest(".zd-enlarge-btn") && !target.closest("img")) return;
142
- const btn = container.querySelector(".zd-enlarge-btn") as HTMLElement | null;
161
+ const btn = container.querySelector<HTMLElement>(".zd-enlarge-btn");
143
162
  if (!btn || btn.hasAttribute("hidden")) return;
144
- const img = container.querySelector("img") as HTMLImageElement | null;
163
+ const img = container.querySelector<HTMLImageElement>("img");
145
164
  if (!img) return;
146
- setImgData({
165
+ imgData.value = {
147
166
  src: img.src,
148
167
  currentSrc: img.currentSrc,
149
168
  srcset: img.srcset || undefined,
@@ -151,16 +170,20 @@ export function ImageEnlarge() {
151
170
  alt: img.alt,
152
171
  naturalWidth: img.naturalWidth,
153
172
  naturalHeight: img.naturalHeight,
154
- });
173
+ };
155
174
  }
156
175
  document.addEventListener("click", handleDocumentClick);
157
- return () => document.removeEventListener("click", handleDocumentClick);
158
- }, []);
159
-
160
- const handleClose = () => setImgData(null);
176
+ return () => {
177
+ active = false;
178
+ document.removeEventListener("click", handleDocumentClick);
179
+ };
180
+ });
161
181
 
162
- const { dialogRef, handleBackdropClick } = useModalDialog({
163
- isOpen: imgData !== null,
182
+ const handleClose = () => {
183
+ imgData.value = null;
184
+ };
185
+ const { dialogRef, handleBackdropClick } = modalDialog(scope, {
186
+ isOpen,
164
187
  onClose: handleClose,
165
188
  navigateEvent: AFTER_NAVIGATE_EVENT,
166
189
  backdropClickClose: true,
@@ -169,51 +192,43 @@ export function ImageEnlarge() {
169
192
  return (
170
193
  <dialog
171
194
  ref={dialogRef}
172
- onClick={handleBackdropClick}
173
- className={IMAGE_ENLARGE_DIALOG_CLASS}
195
+ on:click={handleBackdropClick}
196
+ class={IMAGE_ENLARGE_DIALOG_CLASS}
174
197
  style={ENLARGE_DIALOG_STYLE}
175
198
  >
176
- {imgData && (
199
+ <Show when={isOpen}>{() => (
177
200
  <>
178
- <div className="relative">
179
- <img
180
- src={imgData.currentSrc || imgData.src}
181
- srcSet={imgData.srcset}
182
- sizes={imgData.srcset ? "85vw" : undefined}
183
- alt={imgData.alt}
184
- className="block max-h-[85vh] max-w-[85vw] object-contain"
185
- />
201
+ <div class="relative">
202
+ <Show when={imageHasSrcset}>{() => (
203
+ <img
204
+ src={imageSrc}
205
+ srcset={imageSrcset}
206
+ sizes="85vw"
207
+ alt={imageAlt}
208
+ class="block max-h-[85vh] max-w-[85vw] object-contain"
209
+ />
210
+ )}</Show>
211
+ <Show when={computed(() => !imageHasSrcset.value)}>{() => (
212
+ <img
213
+ src={imageSrc}
214
+ alt={imageAlt}
215
+ class="block max-h-[85vh] max-w-[85vw] object-contain"
216
+ />
217
+ )}</Show>
186
218
  </div>
187
219
  <button
188
220
  type="button"
189
- onClick={() => dialogRef.current?.close()}
190
- className="zd-enlarge-dialog-close"
221
+ on:click={() => dialogRef.current?.close()}
222
+ class="zd-enlarge-dialog-close"
191
223
  aria-label="Close enlarged image"
192
224
  >
193
- <svg viewBox="0 0 161.03 161.03" fill="currentColor" aria-hidden="true" focusable="false">
225
+ <svg viewBox="0 0 161.03 161.03" fill="currentColor" aria-hidden="true">
194
226
  <polygon points="161.03 10.27 150.76 0 80.51 70.24 10.27 0 0 10.27 70.24 80.51 0 150.76 10.27 161.03 80.51 90.78 150.76 161.03 161.03 150.76 90.78 80.51 161.03 10.27" />
195
227
  </svg>
196
228
  </button>
197
229
  </>
198
- )}
230
+ )}</Show>
199
231
  </dialog>
200
232
  );
201
233
  }
202
234
  ImageEnlarge.displayName = "ImageEnlarge";
203
-
204
- /**
205
- * Static SSR fallback for the {@link ImageEnlarge} island.
206
- *
207
- * Renders an empty, closed `<dialog class="zd-enlarge-dialog ...">` so the
208
- * dist HTML carries the dialog shell even before hydration. Sources its
209
- * class and inline style from the shared constants in island-types so the
210
- * SSR fallback cannot drift from the hydrated dialog above.
211
- */
212
- export function ImageEnlargeSsrFallback() {
213
- return (
214
- <dialog
215
- className={IMAGE_ENLARGE_DIALOG_CLASS}
216
- style={ENLARGE_DIALOG_STYLE}
217
- />
218
- );
219
- }
@@ -0,0 +1,2 @@
1
+ export { ImageEnlarge } from "./index.js";
2
+ export { ImageEnlargeSsrFallback } from "./ssr-fallback.js";
@@ -0,0 +1,7 @@
1
+ /** @jsxRuntime automatic */
2
+ import { IMAGE_ENLARGE_DIALOG_CLASS, ENLARGE_DIALOG_STYLE } from "../island-types/index.js";
3
+
4
+ /** Closed dialog shell rendered before island activation. */
5
+ export function ImageEnlargeSsrFallback() {
6
+ return <dialog class={IMAGE_ENLARGE_DIALOG_CLASS} style={ENLARGE_DIALOG_STYLE} />;
7
+ }
@@ -1,18 +1,12 @@
1
1
  /** @jsxRuntime automatic */
2
- /** @jsxImportSource preact */
3
-
4
2
  // Server-rendered, zero-hydration full-page loading overlay.
5
3
  //
6
- // Renders three things into the document:
4
+ // Renders the overlay and its bootstrap into the document:
7
5
  //
8
6
  // 1. A fixed-position overlay `<div>` with a centered spinner. Hidden
9
7
  // by default (`opacity: 0; pointer-events: none;`) and made
10
8
  // visible by adding `data-visible` to it.
11
- // 2. A `<style>` block that owns the overlay + spinner CSS plus the
12
- // `prefers-reduced-motion` fallback. Inlined via
13
- // `dangerouslySetInnerHTML` (matching the ColorSchemeProvider
14
- // pattern) so no separate stylesheet has to be wired up.
15
- // 3. A small `<script>` that toggles the `data-visible` attribute on
9
+ // 2. A small `<script>` that toggles the `data-visible` attribute on
16
10
  // navigation lifecycle events. The event names come from the
17
11
  // `@takazudo/zudo-doc/transitions` module — this component does
18
12
  // not reach for the underlying browser event names directly. Under
@@ -21,9 +15,8 @@
21
15
  // `zfb:after-swap` (AFTER_NAVIGATE_EVENT); see
22
16
  // `transitions/page-events.ts` for rationale.
23
17
  //
24
- // The component is intentionally not hydrated. Hydrating Preact just to
25
- // attach two listeners would be wasteful given the original Astro file
26
- // shipped a tiny imperative script — this port keeps that profile.
18
+ // Its CSS stays in the host's global stylesheet, and the component is not
19
+ // hydrated: the static script owns its navigation listeners.
27
20
 
28
21
  import {
29
22
  AFTER_NAVIGATE_EVENT,
@@ -52,7 +45,9 @@ export function buildPageLoadingOverlayBootstrap(overlayId: string): string {
52
45
  // (see ColorSchemeProvider). Event names come from the transitions
53
46
  // module's exported constants — no raw `astro:*` strings live in
54
47
  // this file.
55
- const id = JSON.stringify(overlayId);
48
+ // JSON quoting protects JavaScript syntax, and escaping `<` additionally
49
+ // prevents a caller-controlled id from terminating the HTML script element.
50
+ const id = JSON.stringify(overlayId).replaceAll("<", "\\u003c");
56
51
  const before = JSON.stringify(BEFORE_NAVIGATE_EVENT);
57
52
  const after = JSON.stringify(AFTER_NAVIGATE_EVENT);
58
53
  return `(function(){
@@ -94,9 +89,7 @@ export default function PageLoadingOverlay({
94
89
  <span class="page-loading-spinner" />
95
90
  </div>
96
91
  <script
97
- dangerouslySetInnerHTML={{
98
- __html: buildPageLoadingOverlayBootstrap(id),
99
- }}
92
+ rawHtml={buildPageLoadingOverlayBootstrap(id)}
100
93
  />
101
94
  </>
102
95
  );
@@ -0,0 +1,68 @@
1
+ import { normalizeIslandData } from "../chrome/island-data.js";
2
+ import type { SidebarNavNode, SidebarNavigationContext } from "./types.js";
3
+
4
+ /** Navigation data needed by the native sidebar islands, without server prose. */
5
+ export type SidebarClientNode = Omit<SidebarNavNode, "description" | "children"> & {
6
+ children: SidebarClientNode[];
7
+ };
8
+
9
+ export type SidebarClientNavigation = Omit<SidebarNavigationContext, "roots"> & {
10
+ roots: SidebarClientNode[];
11
+ };
12
+
13
+ // Exhaustive policy: new server fields require an explicit transport decision.
14
+ const nodeFields = {
15
+ occurrenceId: true,
16
+ slug: true,
17
+ label: true,
18
+ description: false,
19
+ position: true,
20
+ href: true,
21
+ hasPage: true,
22
+ children: true,
23
+ sortOrder: true,
24
+ collapsed: true,
25
+ shape: true,
26
+ noteTrayDated: true,
27
+ noteTraySidebar: true,
28
+ date: true,
29
+ updated: true,
30
+ rank: true,
31
+ } as const satisfies Record<keyof SidebarNavNode, boolean>;
32
+
33
+ /**
34
+ * Copy navigation for SSR and hydration at an island boundary. Server builders
35
+ * retain descriptions; custom island hosts can opt into this same projection.
36
+ * Validate before selecting fields so discarded data cannot conceal invalid
37
+ * transport values. Preserve the opaque scope ID and editorial topology.
38
+ */
39
+ export function toSidebarClientData(
40
+ nodes: SidebarNavNode[],
41
+ navigation?: SidebarNavigationContext,
42
+ ): { nodes: SidebarClientNode[]; navigation?: SidebarClientNavigation } {
43
+ const source = normalizeIslandData({ nodes, navigation });
44
+ function project(node: SidebarNavNode): SidebarClientNode {
45
+ const result: Record<string, unknown> = {};
46
+ for (const key of Object.keys(nodeFields) as Array<keyof SidebarNavNode>) {
47
+ if (nodeFields[key] && key !== "children" && node[key] !== undefined) {
48
+ result[key] = node[key];
49
+ }
50
+ }
51
+ result.children = node.children.map(project);
52
+ return result as SidebarClientNode;
53
+ }
54
+ return {
55
+ nodes: source.nodes.map(project),
56
+ ...(source.navigation ? {
57
+ navigation: {
58
+ id: source.navigation.id,
59
+ roots: source.navigation.roots.map(project),
60
+ parents: source.navigation.parents,
61
+ ...(source.navigation.initialExpansion !== undefined
62
+ ? { initialExpansion: source.navigation.initialExpansion } : {}),
63
+ ...(source.navigation.localParentId !== undefined
64
+ ? { localParentId: source.navigation.localParentId } : {}),
65
+ },
66
+ } : {}),
67
+ };
68
+ }
@@ -18,10 +18,13 @@
18
18
  */
19
19
 
20
20
  export { Sidebar } from "./sidebar.js";
21
+ export { toSidebarClientData } from "./client-data.js";
22
+ export type { SidebarClientNode, SidebarClientNavigation } from "./client-data.js";
21
23
  export type { SidebarProps } from "./sidebar.js";
22
24
  export type {
23
25
  SidebarLocaleLink,
24
26
  SidebarNavNode,
27
+ SidebarNavigationContext,
25
28
  SidebarRootMenuItem,
26
29
  SidebarTreeIslandProps,
27
30
  } from "./types.js";
@@ -1,108 +1,30 @@
1
- "use client";
2
-
3
1
  /** @jsxRuntime automatic */
4
- /** @jsxImportSource preact */
5
-
6
- // JSX port of src/components/sidebar.
7
- //
8
- // The original Astro template was almost entirely data assembly —
9
- // build root-menu items from `settings.headerNav`, load the locale's
10
- // docs collection, build the nav tree for the active section, optionally
11
- // remap hrefs for versioned routes, and finally render the project's
12
- // `<SidebarTree client:load .../>` Preact island.
13
- //
14
- // All of that data-prep depends on host-only helpers (`@/config/i18n`,
15
- // `@/utils/sidebar`, `@/utils/locale-docs`, `@/utils/base`,
16
- // `@/config/settings`) that v2 must not import. This shell therefore
17
- // keeps the data-prep on the host side and only provides:
18
- //
19
- // - typed props that match the SidebarTree island's prop shape, so
20
- // the host's prep code can be typed against v2's interface;
21
- // - a `treeComponent` prop the host supplies (their existing Preact
22
- // island) — the shell instantiates it with the typed props and
23
- // forwards everything;
24
- // - a `children` fallback for callers that want to render the tree
25
- // themselves (useful for tests, fixtures, and downstream projects
26
- // that swap the tree out wholesale).
27
- //
28
- // Wave 13 ("smoke-toc duplicate-nav regression follow-on", zudolab/zudo-doc#1355):
29
- // before this refactor, this module exported a `Sidebar` wrapper that
30
- // itself called `Island({when:"load", children:<SidebarInner/>})` and
31
- // returned the wrapped div. The zfb island scanner picked the exported
32
- // `Sidebar` (the wrapper) as the bundle's hydration target, so on the
33
- // client `mountIslands` ran `hydrate(<Sidebar/>, dataIslandDiv)` where
34
- // the rendered vnode itself emitted *another* `<div data-zfb-island=
35
- // "Sidebar"><SidebarInner/></div>` inside the existing one. Unlike the
36
- // `Toc` / `MobileToc` case (where the inner re-rendered identical
37
- // content alongside the SSR'd content, producing a visible duplicate),
38
- // the duplicate here was silent: the host passes `treeComponent` (a
39
- // Preact component function) as a prop, and `island.ts`'s
40
- // `captureSerializableProps` does `JSON.stringify` on the props bag,
41
- // which silently drops function values. At hydrate time the
42
- // deserialized props had no `treeComponent`, `SidebarInner` returned
43
- // `null`, and the appended wrapper-div was empty. Net result: an extra
44
- // dead-mount data-zfb-island Sidebar div alongside the SSR'd tree, with
45
- // no observable content — but a wasted hydration slot, and the actual
46
- // user-facing event-handler / state work was being done entirely by
47
- // the host's `SidebarTree` island registration.
48
- //
49
- // Fix: same shape as Toc / MobileToc — drop the `Island`-wrapping
50
- // outer, export the bare component (was `SidebarInner`) as `Sidebar`,
51
- // pin `displayName` explicitly. The `<Island when="load">` wrapper is
52
- // applied at the call site (`<DocLayoutWithDefaults>`).
53
2
 
54
- import type { ComponentChildren, FunctionComponent, VNode } from "preact";
3
+ import type { Child, Component } from "@takazudo/zfb/zudo-react";
55
4
 
56
5
  import type { SidebarTreeIslandProps } from "./types.js";
57
6
 
7
+ /**
8
+ * Props for the server-rendered Sidebar shell. Data preparation stays with the
9
+ * caller, which may supply a tree component or already-rendered children.
10
+ */
58
11
  export interface SidebarProps extends SidebarTreeIslandProps {
59
- /**
60
- * The host's SidebarTree component. When present, the shell renders
61
- * `<TreeComponent {...islandProps} />` with the typed props below.
62
- * Mutually exclusive with `children`: prefer this form so v2 owns the
63
- * prop forwarding contract.
64
- */
65
- treeComponent?: FunctionComponent<SidebarTreeIslandProps>;
66
- /**
67
- * Pre-rendered tree content — falls back to this when
68
- * `treeComponent` is omitted. Useful for tests and for layouts that
69
- * compose the tree separately (e.g. inside a host wrapper
70
- * that needs `client:load` on the actual island element).
71
- */
72
- children?: ComponentChildren;
12
+ /** Component used to render the prepared tree. */
13
+ treeComponent?: Component<SidebarTreeIslandProps>;
14
+ /** Pre-rendered tree content for callers that compose the tree separately. */
15
+ children?: Child;
73
16
  }
74
17
 
75
18
  /**
76
- * Sidebar shell — typed wrapper around the SidebarTree island.
77
- *
78
- * Two usage shapes (matching the breadcrumb shell's pattern):
79
- *
80
- * 1. Pass `treeComponent` plus the data props (`nodes`,
81
- * `rootMenuItems`, `localeLinks`, …). The shell forwards them all
82
- * to the supplied component.
83
- *
84
- * 2. Pass `children` (e.g. a pre-instantiated `<SidebarTree
85
- * client:load … />` from an Astro wrapper). The shell renders
86
- * them as-is — the typed island props are then unused but kept on
87
- * the type signature so call-sites stay self-documenting.
88
- *
89
- * **The caller is responsible for wrapping this in `<Island when="load">`**
90
- * so the SSG output emits the `data-zfb-island="Sidebar"` hydration
91
- * marker around the rendered tree. `<DocLayoutWithDefaults>` does this
92
- * for you; consumers who render `<Sidebar>` outside the default layout
93
- * (e.g. via the `sidebarOverride` prop or in a custom layout) must
94
- * apply the wrapper themselves — otherwise no hydration marker is
95
- * emitted, and the runtime walks past the SSR'd tree without claiming
96
- * it as an island. Either way the actual user-facing interactivity
97
- * comes from the `treeComponent`'s own island registration; the
98
- * `<Island>` wrapper here exists so the shell can host data-only
99
- * variants in the future without losing the marker contract.
19
+ * Server-rendered shell around prepared navigation content. An empty node list
20
+ * has no sidebar output and returns null without creating an island boundary.
100
21
  */
101
- export function Sidebar(props: SidebarProps): VNode | null {
22
+ export function Sidebar(props: SidebarProps): Child {
102
23
  const {
103
24
  treeComponent: TreeComponent,
104
25
  children,
105
26
  nodes,
27
+ navigation,
106
28
  currentSlug,
107
29
  rootMenuItems,
108
30
  backToMenuLabel,
@@ -110,10 +32,13 @@ export function Sidebar(props: SidebarProps): VNode | null {
110
32
  themeDefaultMode,
111
33
  } = props;
112
34
 
35
+ if (nodes.length === 0) return null;
36
+
113
37
  if (TreeComponent) {
114
38
  return (
115
39
  <TreeComponent
116
40
  nodes={nodes}
41
+ navigation={navigation}
117
42
  currentSlug={currentSlug}
118
43
  rootMenuItems={rootMenuItems}
119
44
  backToMenuLabel={backToMenuLabel}
@@ -129,9 +54,3 @@ export function Sidebar(props: SidebarProps): VNode | null {
129
54
 
130
55
  return null;
131
56
  }
132
- // Pin the marker name to "Sidebar" regardless of how Preact's compat
133
- // layer or esbuild minification renames the function. Island's SSR
134
- // pass reads `displayName ?? name` to derive the marker string;
135
- // pinning both means the SSG marker stays `data-zfb-island="Sidebar"`
136
- // independent of the bundle's symbol-renaming.
137
- Sidebar.displayName = "Sidebar";
@@ -26,6 +26,8 @@
26
26
  * Matches `NavNode` in the host project's `src/utils/docs.ts`.
27
27
  */
28
28
  export interface SidebarNavNode {
29
+ /** Stable identity of this editorial occurrence, independent of the page slug. */
30
+ occurrenceId?: string;
29
31
  slug: string;
30
32
  label: string;
31
33
  description?: string;
@@ -71,9 +73,22 @@ export interface SidebarLocaleLink {
71
73
  */
72
74
  export interface SidebarTreeIslandProps {
73
75
  nodes: SidebarNavNode[];
76
+ navigation?: SidebarNavigationContext;
74
77
  currentSlug?: string;
75
78
  rootMenuItems?: SidebarRootMenuItem[];
76
79
  backToMenuLabel?: string;
77
80
  localeLinks?: SidebarLocaleLink[];
78
81
  themeDefaultMode?: "light" | "dark";
79
82
  }
83
+
84
+ /** Complete editorial topology, captured before local scoping or filtering. */
85
+ export interface SidebarNavigationContext {
86
+ /** Locale/version/document-context identity including the topology revision. */
87
+ id: string;
88
+ roots: SidebarNavNode[];
89
+ /** Explicit page/index author defaults; resolved against the current destination. */
90
+ initialExpansion?: Record<string, "collapsed" | "expanded">;
91
+ parents: Record<string, string | null>;
92
+ /** Explicit enclosing occurrence for a local forest spanning emitted children. */
93
+ localParentId?: string;
94
+ }