@takazudo/zudo-doc 5.28.2 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +49 -16
- package/bin/gen-z-index.mjs +18 -18
- package/dist/agent-docs/identity.d.ts +4 -0
- package/dist/agent-docs/identity.js +24 -0
- package/dist/agent-docs/index.d.ts +5 -0
- package/dist/agent-docs/index.js +5 -0
- package/dist/agent-docs/limits.d.ts +11 -0
- package/dist/agent-docs/limits.js +24 -0
- package/dist/agent-docs/search.d.ts +14 -0
- package/dist/agent-docs/search.js +82 -0
- package/dist/agent-docs/tokenize.d.ts +2 -0
- package/dist/agent-docs/tokenize.js +22 -0
- package/dist/agent-docs/types.d.ts +68 -0
- package/dist/agent-docs/types.js +0 -0
- package/dist/ai-chat-modal/index.d.ts +1 -4
- package/dist/ai-chat-modal/index.js +183 -123
- package/dist/asset-components/asset-card.d.ts +1 -2
- package/dist/asset-components/asset-card.js +12 -12
- package/dist/asset-components/asset-code.d.ts +1 -2
- package/dist/asset-components/asset-code.js +10 -10
- package/dist/asset-components/shared.d.ts +3 -4
- package/dist/asset-components/shared.js +4 -4
- package/dist/asset-index-page/body.d.ts +5 -6
- package/dist/asset-index-page/body.js +6 -6
- package/dist/asset-index-page/index.d.ts +1 -2
- package/dist/asset-index-page/index.js +1 -1
- package/dist/asset-page/body.d.ts +5 -9
- package/dist/asset-page/body.js +3 -3
- package/dist/asset-page/components.d.ts +16 -17
- package/dist/asset-page/components.js +10 -9
- package/dist/asset-page/index.d.ts +1 -2
- package/dist/asset-page/index.js +1 -1
- package/dist/auto-logo/index.d.ts +1 -2
- package/dist/auto-logo/index.js +2 -2
- package/dist/body-foot-util/body-foot-util-area.d.ts +3 -4
- package/dist/body-foot-util/body-foot-util-area.js +1 -2
- package/dist/body-foot-util/edit-link.d.ts +2 -3
- package/dist/body-foot-util/edit-link.js +1 -2
- package/dist/breadcrumb/breadcrumb.d.ts +6 -6
- package/dist/breadcrumb/breadcrumb.js +3 -4
- package/dist/category-nav/index.d.ts +1 -2
- package/dist/category-nav/index.js +11 -5
- package/dist/category-tree-nav/index.d.ts +1 -2
- package/dist/category-tree-nav/index.js +3 -3
- package/dist/chrome/derive.d.ts +18 -27
- package/dist/chrome/derive.js +47 -29
- package/dist/chrome/index.d.ts +5 -5
- package/dist/chrome/index.js +1 -1
- package/dist/chrome/island-data.d.ts +4 -0
- package/dist/chrome/island-data.js +52 -0
- package/dist/chrome/primary-slots.d.ts +2 -3
- package/dist/chrome-bindings.d.ts +28 -22
- package/dist/code-group/index.d.ts +3 -4
- package/dist/code-group/index.js +3 -7
- package/dist/code-syntax/code-block-enhancer.d.ts +1 -2
- package/dist/code-syntax/code-block-enhancer.js +2 -2
- package/dist/code-syntax/mermaid-init.d.ts +1 -2
- package/dist/code-syntax/mermaid-init.js +5 -2
- package/dist/code-syntax/tabs-init-script.js +1 -1
- package/dist/code-syntax/tabs-init.d.ts +1 -2
- package/dist/code-syntax/tabs-init.js +2 -2
- package/dist/code-syntax/tabs.d.ts +6 -6
- package/dist/code-syntax/tabs.js +8 -8
- package/dist/compiled.css +2933 -2943
- package/dist/config-assertions/index.d.ts +13 -0
- package/dist/config-assertions/index.js +14 -0
- package/dist/config.d.ts +36 -17
- package/dist/config.js +23 -95
- package/dist/content/content-blockquote.d.ts +2 -3
- package/dist/content/content-blockquote.js +3 -3
- package/dist/content/content-code.d.ts +3 -4
- package/dist/content/content-code.js +5 -5
- package/dist/content/content-link.d.ts +3 -4
- package/dist/content/content-link.js +10 -10
- package/dist/content/content-ol.d.ts +2 -3
- package/dist/content/content-ol.js +5 -4
- package/dist/content/content-paragraph.d.ts +2 -3
- package/dist/content/content-paragraph.js +1 -1
- package/dist/content/content-strong.d.ts +2 -3
- package/dist/content/content-strong.js +3 -3
- package/dist/content/content-table.d.ts +2 -3
- package/dist/content/content-table.js +4 -4
- package/dist/content/content-ul.d.ts +2 -3
- package/dist/content/content-ul.js +4 -4
- package/dist/content/heading-h2.d.ts +2 -3
- package/dist/content/heading-h2.js +4 -4
- package/dist/content/heading-h3.d.ts +2 -3
- package/dist/content/heading-h3.js +4 -4
- package/dist/content/heading-h4.d.ts +2 -3
- package/dist/content/heading-h4.js +4 -4
- package/dist/content-admonition/index.d.ts +3 -4
- package/dist/content-admonition/index.js +2 -2
- package/dist/content.css +35 -33
- package/dist/design-token-panel-bootstrap-controller.d.ts +178 -0
- package/dist/design-token-panel-bootstrap-controller.js +359 -0
- package/dist/design-token-panel-bootstrap-island.d.ts +5 -0
- package/dist/design-token-panel-bootstrap-island.js +19 -0
- package/dist/design-token-panel-bootstrap.d.ts +5 -195
- package/dist/design-token-panel-bootstrap.js +3 -288
- package/dist/desktop-sidebar-toggle-island/index.d.ts +2 -7
- package/dist/desktop-sidebar-toggle-island/index.js +2 -58
- package/dist/desktop-sidebar-toggle-island/island.d.ts +4 -0
- package/dist/desktop-sidebar-toggle-island/island.js +43 -0
- package/dist/desktop-sidebar-toggle-island/storage.d.ts +4 -0
- package/dist/desktop-sidebar-toggle-island/storage.js +29 -0
- package/dist/desktop-toc-toggle-island/index.d.ts +2 -7
- package/dist/desktop-toc-toggle-island/index.js +2 -58
- package/dist/desktop-toc-toggle-island/island.d.ts +4 -0
- package/dist/desktop-toc-toggle-island/island.js +43 -0
- package/dist/desktop-toc-toggle-island/storage.d.ts +4 -0
- package/dist/desktop-toc-toggle-island/storage.js +29 -0
- package/dist/details/details.d.ts +3 -4
- package/dist/details/details.js +1 -1
- package/dist/doc-body-end/index.d.ts +1 -2
- package/dist/doc-body-end/index.js +1 -1
- package/dist/doc-body-end-islands/design-token-panel-island.d.ts +2 -2
- package/dist/doc-body-end-islands/design-token-panel-island.js +3 -7
- package/dist/doc-body-end-islands/index.d.ts +4 -21
- package/dist/doc-body-end-islands/index.js +5 -3
- package/dist/doc-body-end-islands/theme-pack-switcher-island.d.ts +3 -13
- package/dist/doc-body-end-islands/theme-pack-switcher-island.js +11 -13
- package/dist/doc-content-header/index.d.ts +1 -2
- package/dist/doc-content-header/index.js +1 -1
- package/dist/doc-history/index.d.ts +1 -1
- package/dist/doc-history/index.js +166 -141
- package/dist/doc-history-area/index.d.ts +6 -4
- package/dist/doc-history-area/index.js +17 -16
- package/dist/doc-metainfo-area/index.d.ts +2 -3
- package/dist/doc-metainfo-area/index.js +1 -1
- package/dist/doc-page-renderer/index.d.ts +13 -7
- package/dist/doc-page-renderer/index.js +10 -1
- package/dist/doc-page-shell/index.d.ts +20 -7
- package/dist/doc-page-shell/index.js +17 -6
- package/dist/doc-pager/index.d.ts +1 -2
- package/dist/doc-pager/index.js +3 -3
- package/dist/doc-tags-area/index.d.ts +2 -3
- package/dist/doc-tags-area/index.js +1 -1
- package/dist/doclayout/doc-layout-with-defaults.d.ts +9 -9
- package/dist/doclayout/doc-layout-with-defaults.js +5 -15
- package/dist/doclayout/doc-layout.d.ts +26 -27
- package/dist/doclayout/doc-layout.js +23 -14
- package/dist/docs-schema/index.d.ts +4 -0
- package/dist/docs-schema/index.js +1 -0
- package/dist/extract-headings/index.js +43 -12
- package/dist/factory-context/index.d.ts +22 -19
- package/dist/features.css +70 -8
- package/dist/find-in-page/find-bar.d.ts +4 -2
- package/dist/find-in-page/find-bar.js +58 -69
- package/dist/find-in-page/index.d.ts +2 -8
- package/dist/find-in-page/index.js +33 -30
- package/dist/footer/footer.d.ts +3 -4
- package/dist/footer/footer.js +3 -3
- package/dist/footer-with-defaults/index.d.ts +2 -3
- package/dist/footer-with-defaults/index.js +1 -1
- package/dist/frontmatter-preview-defaults/index.js +1 -0
- package/dist/head/doc-head.d.ts +1 -1
- package/dist/head/doc-head.js +24 -32
- package/dist/head/og-tags.d.ts +1 -1
- package/dist/head/og-tags.js +8 -7
- package/dist/head/twitter-card.d.ts +1 -1
- package/dist/head/twitter-card.js +1 -1
- package/dist/head-with-defaults/index.d.ts +7 -2
- package/dist/head-with-defaults/index.js +46 -32
- package/dist/header/header.d.ts +8 -8
- package/dist/header/header.js +9 -11
- package/dist/header/types.d.ts +7 -7
- package/dist/header-with-defaults/index.d.ts +1 -2
- package/dist/header-with-defaults/index.js +18 -8
- package/dist/home-intro/index.d.ts +2 -5
- package/dist/home-intro/index.js +7 -5
- package/dist/home-intro/prepare.js +4 -3
- package/dist/home-page/index.d.ts +3 -3
- package/dist/home-page/index.js +19 -17
- package/dist/html-preview-wrapper/highlighted-code.d.ts +3 -4
- package/dist/html-preview-wrapper/highlighted-code.js +19 -17
- package/dist/html-preview-wrapper/html-preview-wrapper.d.ts +4 -25
- package/dist/html-preview-wrapper/html-preview-wrapper.js +2 -87
- package/dist/html-preview-wrapper/html-preview.d.ts +3 -10
- package/dist/html-preview-wrapper/html-preview.js +13 -37
- package/dist/html-preview-wrapper/index.d.ts +2 -1
- package/dist/html-preview-wrapper/index.js +1 -1
- package/dist/html-preview-wrapper/preview-base.d.ts +3 -5
- package/dist/html-preview-wrapper/preview-base.js +56 -59
- package/dist/html-preview-wrapper/wrapper.d.ts +20 -0
- package/dist/html-preview-wrapper/wrapper.js +37 -0
- package/dist/hydration-pending.d.ts +3 -5
- package/dist/hydration-pending.js +7 -5
- package/dist/i18n-version/language-switcher.d.ts +5 -32
- package/dist/i18n-version/language-switcher.js +5 -106
- package/dist/i18n-version/switcher-generated-scripts.d.ts +2 -0
- package/dist/i18n-version/switcher-generated-scripts.js +107 -0
- package/dist/i18n-version/switcher-url-state.d.ts +76 -0
- package/dist/i18n-version/switcher-url-state.js +103 -0
- package/dist/i18n-version/version-banner.d.ts +2 -3
- package/dist/i18n-version/version-banner.js +1 -1
- package/dist/i18n-version/version-switcher.d.ts +5 -50
- package/dist/i18n-version/version-switcher.js +5 -157
- package/dist/icons/index.d.ts +18 -19
- package/dist/icons/index.js +17 -33
- package/dist/image-enlarge/index.d.ts +1 -10
- package/dist/image-enlarge/index.js +80 -55
- package/dist/image-enlarge/public.d.ts +2 -0
- package/dist/image-enlarge/public.js +6 -0
- package/dist/image-enlarge/ssr-fallback.d.ts +2 -0
- package/dist/image-enlarge/ssr-fallback.js +8 -0
- package/dist/index.d.ts +11 -4
- package/dist/inline-version-switcher/index.d.ts +1 -2
- package/dist/inline-version-switcher/index.js +1 -1
- package/dist/island-types/index.d.ts +2 -2
- package/dist/island-types/index.js +1 -5
- package/dist/math-block/index.d.ts +4 -7
- package/dist/math-block/index.js +5 -5
- package/dist/mcp/handler.d.ts +8 -0
- package/dist/mcp/handler.js +129 -0
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/index.js +7 -0
- package/dist/mcp/loader.d.ts +19 -0
- package/dist/mcp/loader.js +202 -0
- package/dist/mdx-components/index.js +40 -108
- package/dist/mermaid-enlarge/index.d.ts +1 -8
- package/dist/mermaid-enlarge/index.js +174 -158
- package/dist/mermaid-enlarge/public.d.ts +2 -0
- package/dist/mermaid-enlarge/public.js +6 -0
- package/dist/mermaid-enlarge/ssr-fallback.d.ts +2 -0
- package/dist/mermaid-enlarge/ssr-fallback.js +8 -0
- package/dist/metainfo/doc-metainfo.d.ts +2 -3
- package/dist/metainfo/doc-metainfo.js +1 -4
- package/dist/metainfo/doc-tags.d.ts +2 -3
- package/dist/metainfo/doc-tags.js +1 -1
- package/dist/metainfo/frontmatter-preview.d.ts +3 -4
- package/dist/metainfo/frontmatter-preview.js +1 -1
- package/dist/nav-data-prep/index.js +6 -4
- package/dist/nav-indexing/category-nav.d.ts +2 -3
- package/dist/nav-indexing/category-nav.js +1 -2
- package/dist/nav-indexing/category-tree-nav.d.ts +2 -3
- package/dist/nav-indexing/category-tree-nav.js +1 -1
- package/dist/nav-indexing/doc-card-grid.d.ts +2 -3
- package/dist/nav-indexing/doc-card-grid.js +1 -2
- package/dist/nav-indexing/docs-sitemap.d.ts +2 -3
- package/dist/nav-indexing/docs-sitemap.js +2 -2
- package/dist/nav-indexing/index.d.ts +1 -1
- package/dist/nav-indexing/nav-card-grid.d.ts +2 -3
- package/dist/nav-indexing/nav-card-grid.js +1 -2
- package/dist/nav-indexing/note-tray-index-parts/card-list.d.ts +1 -2
- package/dist/nav-indexing/note-tray-index-parts/card-list.js +4 -4
- package/dist/nav-indexing/note-tray-index-parts/date-line.d.ts +2 -3
- package/dist/nav-indexing/note-tray-index-parts/date-line.js +1 -1
- package/dist/nav-indexing/note-tray-index-parts/index-list.d.ts +1 -2
- package/dist/nav-indexing/note-tray-index-parts/index-list.js +2 -2
- package/dist/nav-indexing/note-tray-index-parts/timeline.d.ts +1 -2
- package/dist/nav-indexing/note-tray-index-parts/timeline.js +2 -2
- package/dist/nav-indexing/note-tray-index.d.ts +1 -2
- package/dist/nav-indexing/note-tray-index.js +1 -1
- package/dist/nav-indexing/site-tree-nav-demo.d.ts +2 -3
- package/dist/nav-indexing/site-tree-nav-demo.js +2 -2
- package/dist/nav-indexing/tag-nav.d.ts +1 -2
- package/dist/nav-indexing/tag-nav.js +1 -1
- package/dist/nav-indexing/types.d.ts +2 -2
- package/dist/nav-indexing/versions-page-content.d.ts +2 -3
- package/dist/nav-indexing/versions-page-content.js +8 -8
- package/dist/note-tray-index/index.d.ts +1 -2
- package/dist/note-tray-index/index.js +1 -1
- package/dist/page-loading/page-loading-overlay.d.ts +1 -2
- package/dist/page-loading/page-loading-overlay.js +3 -5
- package/dist/plugins/agent-export.d.ts +3 -0
- package/dist/plugins/agent-export.js +34 -0
- package/dist/plugins/internal/agent-export/chunk.d.ts +5 -0
- package/dist/plugins/internal/agent-export/chunk.js +90 -0
- package/dist/plugins/internal/agent-export/index.d.ts +24 -0
- package/dist/plugins/internal/agent-export/index.js +123 -0
- package/dist/plugins/internal/agent-export/normalize.d.ts +5 -0
- package/dist/plugins/internal/agent-export/normalize.js +73 -0
- package/dist/plugins/internal/llms-txt/dev-middleware.d.ts +6 -0
- package/dist/plugins/internal/llms-txt/dev-middleware.js +8 -3
- package/dist/plugins/internal/llms-txt/emit.js +23 -6
- package/dist/plugins/internal/llms-txt/generate.d.ts +7 -1
- package/dist/plugins/internal/llms-txt/generate.js +9 -2
- package/dist/plugins/internal/llms-txt/load.d.ts +2 -0
- package/dist/plugins/internal/llms-txt/load.js +20 -4
- package/dist/plugins/internal/llms-txt/types.d.ts +10 -0
- package/dist/plugins/routes.js +4 -0
- package/dist/preset.d.ts +19 -9
- package/dist/preset.js +20 -1
- package/dist/route-context-payload/index.js +1 -1
- package/dist/routes/404.d.ts +2 -3
- package/dist/routes/404.js +1 -1
- package/dist/routes/_chrome.d.ts +5 -5
- package/dist/routes/_chrome.js +7 -2
- package/dist/routes/_context.d.ts +4 -4
- package/dist/routes/_design-token-panel-bootstrap.d.ts +1 -4
- package/dist/routes/_design-token-panel-bootstrap.js +9 -1
- package/dist/routes/docs-slug.d.ts +2 -3
- package/dist/routes/docs-tags-index.d.ts +2 -3
- package/dist/routes/docs-tags-index.js +1 -1
- package/dist/routes/docs-tags-tag.d.ts +2 -3
- package/dist/routes/docs-tags-tag.js +1 -1
- package/dist/routes/docs-versions.d.ts +2 -3
- package/dist/routes/docs-versions.js +1 -1
- package/dist/routes/files-path.d.ts +2 -3
- package/dist/routes/files-path.js +1 -1
- package/dist/routes/index.d.ts +2 -3
- package/dist/routes/index.js +1 -1
- package/dist/routes/locale-docs-slug.d.ts +2 -3
- package/dist/routes/locale-docs-tags-index.d.ts +2 -3
- package/dist/routes/locale-docs-tags-index.js +1 -1
- package/dist/routes/locale-docs-tags-tag.d.ts +2 -3
- package/dist/routes/locale-docs-tags-tag.js +1 -1
- package/dist/routes/locale-docs-versions.d.ts +2 -3
- package/dist/routes/locale-docs-versions.js +1 -1
- package/dist/routes/locale-files-path.d.ts +2 -3
- package/dist/routes/locale-files-path.js +1 -1
- package/dist/routes/locale-index.d.ts +2 -3
- package/dist/routes/locale-index.js +1 -1
- package/dist/routes/mcp.d.ts +5 -0
- package/dist/routes/mcp.js +25 -0
- package/dist/routes/v-docs-slug.d.ts +2 -3
- package/dist/routes/v-locale-docs-slug.d.ts +2 -3
- package/dist/search-widget/index.d.ts +1 -2
- package/dist/search-widget/index.js +4 -7
- package/dist/search-widget-script/generated-script.js +12 -5
- package/dist/settings-defaults.d.ts +2 -0
- package/dist/settings-defaults.js +93 -0
- package/dist/settings.d.ts +8 -2
- package/dist/sidebar/index.d.ts +1 -1
- package/dist/sidebar/sidebar.d.ts +12 -44
- package/dist/sidebar/sidebar.js +4 -3
- package/dist/sidebar/types.d.ts +14 -0
- package/dist/sidebar-prepaint/index.d.ts +1 -2
- package/dist/sidebar-prepaint/index.js +4 -6
- package/dist/sidebar-resizer/sidebar-resizer-init.d.ts +2 -3
- package/dist/sidebar-resizer/sidebar-resizer-init.js +3 -3
- package/dist/sidebar-toggle-island/index.d.ts +8 -11
- package/dist/sidebar-toggle-island/index.js +75 -62
- package/dist/sidebar-tree/build-tree.js +5 -6
- package/dist/sidebar-tree/types.d.ts +2 -0
- package/dist/sidebar-tree-island/index.d.ts +4 -19
- package/dist/sidebar-tree-island/index.js +782 -436
- package/dist/sidebar-tree-island/scope-state.d.ts +38 -0
- package/dist/sidebar-tree-island/scope-state.js +151 -0
- package/dist/sidebar-tree-island/sidebar-scroll-preserve.js +6 -2
- package/dist/sidebar-utils/index.d.ts +17 -19
- package/dist/sidebar-utils/index.js +100 -3
- package/dist/sidebar-utils/scope.d.ts +11 -0
- package/dist/sidebar-utils/scope.js +67 -0
- package/dist/sidebar-with-defaults/index.d.ts +1 -2
- package/dist/sidebar-with-defaults/index.js +19 -18
- package/dist/site-schema/nav-tree.js +15 -15
- package/dist/site-schema/types.d.ts +1 -0
- package/dist/site-tree-nav/index.d.ts +2 -3
- package/dist/site-tree-nav/index.js +11 -12
- package/dist/site-tree-nav/normalize-island-props.d.ts +16 -0
- package/dist/site-tree-nav/normalize-island-props.js +122 -0
- package/dist/site-tree-nav-island/index.d.ts +3 -3
- package/dist/site-tree-nav-island/index.js +243 -144
- package/dist/smart-break/index.d.ts +3 -4
- package/dist/smart-break/index.js +1 -1
- package/dist/tab-item/tab-item.d.ts +3 -4
- package/dist/tab-item/tab-item.js +1 -1
- package/dist/tag-pages/index.d.ts +3 -3
- package/dist/tag-pages/index.js +10 -10
- package/dist/theme/color-scheme-provider.d.ts +3 -3
- package/dist/theme/color-scheme-provider.js +3 -3
- package/dist/theme/theme-pack-provider.d.ts +1 -1
- package/dist/theme/theme-pack-provider.js +3 -3
- package/dist/theme/theme-toggle.d.ts +2 -3
- package/dist/theme/theme-toggle.js +1 -1
- package/dist/theme-pack-dialog/index.d.ts +1 -1
- package/dist/theme-pack-dialog/index.js +69 -75
- package/dist/theme-pack-dialog/theme-pack-card.d.ts +3 -4
- package/dist/theme-pack-dialog/theme-pack-card.js +19 -17
- package/dist/theme-pack-switcher/index.d.ts +4 -5
- package/dist/theme-pack-switcher/index.js +52 -49
- package/dist/theme-toggle/index.d.ts +1 -1
- package/dist/theme-toggle/index.js +154 -167
- package/dist/theme.css +47 -121
- package/dist/toc/mobile-toc.d.ts +3 -5
- package/dist/toc/mobile-toc.js +29 -27
- package/dist/toc/toc.d.ts +3 -4
- package/dist/toc/toc.js +18 -18
- package/dist/toc/use-active-heading.d.ts +5 -4
- package/dist/toc/use-active-heading.js +36 -30
- package/dist/toc-prepaint/index.d.ts +1 -2
- package/dist/toc-prepaint/index.js +4 -6
- package/dist/transitions/nested-island-props-refresh.d.ts +3 -16
- package/dist/transitions/nested-island-props-refresh.js +133 -151
- package/dist/transitions/page-events.d.ts +8 -13
- package/dist/tree-nav-shared/index.d.ts +4 -5
- package/dist/tree-nav-shared/index.js +6 -7
- package/dist/use-modal-dialog/index.d.ts +9 -63
- package/dist/use-modal-dialog/index.js +41 -59
- package/dist/versions-page/index.d.ts +3 -3
- package/dist/versions-page/index.js +5 -5
- package/dist/wind/index.d.ts +5 -0
- package/dist/wind/index.js +169 -0
- package/dist/wind.json +498 -0
- package/dist/z-index-defaults/index.d.ts +4 -4
- package/dist/zdtp-loader.d.ts +7 -0
- package/dist/zdtp-loader.js +8 -0
- package/eject/asset-components/asset-card.tsx +14 -16
- package/eject/asset-components/asset-code.tsx +10 -12
- package/eject/asset-components/shared.tsx +5 -7
- package/eject/breadcrumb/breadcrumb.tsx +15 -16
- package/eject/code-group/index.tsx +4 -10
- package/eject/content-admonition/index.tsx +5 -6
- package/eject/desktop-sidebar-toggle-island/index.ts +4 -0
- package/eject/desktop-sidebar-toggle-island/island.tsx +50 -0
- package/eject/desktop-sidebar-toggle-island/storage.ts +27 -0
- package/eject/details/details.tsx +3 -5
- package/eject/doc-history/index.tsx +193 -179
- package/eject/doc-pager/index.tsx +3 -4
- package/eject/footer/footer.tsx +7 -9
- package/eject/header/header.tsx +42 -54
- package/eject/header/nav-overflow-script.ts +1 -1
- package/eject/header/types.ts +12 -13
- package/eject/image-enlarge/index.tsx +84 -69
- package/eject/image-enlarge/public.ts +2 -0
- package/eject/image-enlarge/ssr-fallback.tsx +7 -0
- package/eject/page-loading/page-loading-overlay.tsx +8 -15
- package/eject/sidebar/index.ts +1 -0
- package/eject/sidebar/sidebar.tsx +16 -97
- package/eject/sidebar/types.ts +15 -0
- package/eject/sidebar-toggle-island/index.tsx +103 -102
- package/eject/sidebar-tree-island/index.tsx +827 -615
- package/eject/sidebar-tree-island/scope-state.ts +154 -0
- package/eject/sidebar-tree-island/sidebar-scroll-preserve.ts +8 -2
- package/eject/site-tree-nav-island/index.tsx +349 -222
- package/eject/tab-item/tab-item.tsx +2 -4
- package/eject/theme-toggle/hydration-pending.ts +6 -10
- package/eject/theme-toggle/index.tsx +133 -173
- package/eject/toc/mobile-toc.tsx +27 -31
- package/eject/toc/toc.tsx +21 -24
- package/eject/toc/use-active-heading.ts +43 -38
- package/package.json +40 -22
- package/routes-src/404.tsx +2 -3
- package/routes-src/_chrome.tsx +7 -2
- package/routes-src/_design-token-panel-bootstrap.tsx +1 -63
- package/routes-src/docs-slug.tsx +2 -3
- package/routes-src/docs-tags-index.tsx +2 -3
- package/routes-src/docs-tags-tag.tsx +2 -3
- package/routes-src/docs-versions.tsx +2 -3
- package/routes-src/files-path.tsx +2 -4
- package/routes-src/index.tsx +2 -3
- package/routes-src/locale-docs-slug.tsx +2 -3
- package/routes-src/locale-docs-tags-index.tsx +2 -3
- package/routes-src/locale-docs-tags-tag.tsx +2 -3
- package/routes-src/locale-docs-versions.tsx +2 -3
- package/routes-src/locale-files-path.tsx +2 -4
- package/routes-src/locale-index.tsx +2 -3
- package/routes-src/mcp.tsx +25 -0
- package/routes-src/v-docs-slug.tsx +2 -3
- package/routes-src/v-locale-docs-slug.tsx +2 -3
- package/tsconfig.base.json +1 -1
- package/dist/safelist.css +0 -2
- package/dist/theme-no-reset.css +0 -379
- package/eject/desktop-sidebar-toggle-island/index.tsx +0 -110
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
/** @jsxRuntime automatic */
|
|
4
|
-
/** @jsxImportSource preact */
|
|
5
|
-
|
|
6
4
|
// DocHistory island — relocated from src/components/doc-history.tsx (epic #2344, S4).
|
|
7
|
-
// Uses the shared
|
|
8
|
-
// -
|
|
5
|
+
// Uses the shared modal helper and types instead of re-inlining them:
|
|
6
|
+
// - modalDialog from @takazudo/zudo-doc/use-modal-dialog (open/close sync, focus management)
|
|
9
7
|
// - DocHistoryData / DocHistoryEntry from @takazudo/zudo-doc/island-types
|
|
10
8
|
// - SmartBreak from @takazudo/zudo-doc/smart-break
|
|
11
9
|
//
|
|
12
10
|
// CSS: island-coupled .diff-* rules are now in packages/zudo-doc/src/features.css
|
|
13
11
|
// (moved from src/styles/global.css in this same commit).
|
|
14
12
|
|
|
15
|
-
import {
|
|
13
|
+
import { computed, For, getScope, Show, signal } from "@takazudo/zfb/zudo-react";
|
|
14
|
+
import type { Ref } from "@takazudo/zfb/zudo-react";
|
|
16
15
|
import type { DocHistoryData, DocHistoryEntry } from "../island-types/index.js";
|
|
17
16
|
import { SmartBreak } from "../smart-break/index.js";
|
|
18
17
|
import { History, Close, ArrowLeft } from "../icons/index.js";
|
|
19
18
|
import { AFTER_NAVIGATE_EVENT } from "../transitions/index.js";
|
|
20
|
-
import {
|
|
19
|
+
import { modalDialog } from "../use-modal-dialog/index.js";
|
|
21
20
|
import { formatDate } from "../format-date/index.js";
|
|
22
21
|
import type { ResolvedDateFormats } from "../settings.js";
|
|
23
22
|
|
|
@@ -55,14 +54,14 @@ interface DiffSelection {
|
|
|
55
54
|
|
|
56
55
|
function Spinner() {
|
|
57
56
|
return (
|
|
58
|
-
<div
|
|
57
|
+
<div class="flex items-center justify-center py-vsp-xl">
|
|
59
58
|
<span
|
|
60
|
-
|
|
59
|
+
class="inline-block box-border rounded-full page-loading-spinner"
|
|
61
60
|
style={{
|
|
62
|
-
width:
|
|
63
|
-
height:
|
|
61
|
+
width: "48px",
|
|
62
|
+
height: "48px",
|
|
64
63
|
border: "5px solid var(--color-fg, #fff)",
|
|
65
|
-
|
|
64
|
+
"border-bottom-color": "transparent",
|
|
66
65
|
}}
|
|
67
66
|
/>
|
|
68
67
|
</div>
|
|
@@ -170,6 +169,7 @@ async function getCachedDiff(
|
|
|
170
169
|
newerHash: string,
|
|
171
170
|
olderContent: string,
|
|
172
171
|
newerContent: string,
|
|
172
|
+
isCurrent: () => boolean,
|
|
173
173
|
): Promise<DiffChanges> {
|
|
174
174
|
const key = `${olderHash}::${newerHash}`;
|
|
175
175
|
const hit = diffCache.get(key);
|
|
@@ -190,6 +190,9 @@ async function getCachedDiff(
|
|
|
190
190
|
throw new Error('Compare requires the optional peer "diff": install it to use docHistory');
|
|
191
191
|
},
|
|
192
192
|
);
|
|
193
|
+
// The module import cannot be aborted; a replaced comparison must not do
|
|
194
|
+
// work or populate the cache after its owning scope has been disposed.
|
|
195
|
+
if (!isCurrent()) throw new Error("Comparison cancelled");
|
|
193
196
|
const changes = diffLines(olderContent, newerContent);
|
|
194
197
|
diffCache.set(key, changes);
|
|
195
198
|
if (diffCache.size > DIFF_CACHE_LIMIT) {
|
|
@@ -208,63 +211,67 @@ function DiffViewer({
|
|
|
208
211
|
onBack: () => void;
|
|
209
212
|
showBackButton: boolean;
|
|
210
213
|
}) {
|
|
211
|
-
const
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
214
|
+
const scope = getScope();
|
|
215
|
+
const changes = signal<DiffChanges | null>(null);
|
|
216
|
+
const diffError = signal<string | null>(null);
|
|
217
|
+
const tableRevision = signal(0);
|
|
218
|
+
scope.onActivate(() => {
|
|
215
219
|
let cancelled = false;
|
|
216
|
-
setDiffError(null);
|
|
217
220
|
getCachedDiff(
|
|
218
221
|
selection.older.hash,
|
|
219
222
|
selection.newer.hash,
|
|
220
223
|
selection.older.content,
|
|
221
224
|
selection.newer.content,
|
|
225
|
+
() => !cancelled && !scope.abortSignal.aborted,
|
|
222
226
|
).then((result) => {
|
|
223
|
-
if (!cancelled)
|
|
227
|
+
if (!cancelled && !scope.abortSignal.aborted) {
|
|
228
|
+
changes.value = result;
|
|
229
|
+
tableRevision.value++;
|
|
230
|
+
}
|
|
224
231
|
}).catch((e: unknown) => {
|
|
225
|
-
if (!cancelled) {
|
|
226
|
-
|
|
232
|
+
if (!cancelled && !scope.abortSignal.aborted) {
|
|
233
|
+
diffError.value = e instanceof Error ? e.message : "Failed to compute diff";
|
|
227
234
|
}
|
|
228
235
|
});
|
|
229
236
|
return () => { cancelled = true; };
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
[changes],
|
|
235
|
-
);
|
|
237
|
+
});
|
|
238
|
+
const tableSnapshots = computed(() => changes.value
|
|
239
|
+
? [{ revision: tableRevision.value, rows: buildSideBySideRows(changes.value) }]
|
|
240
|
+
: []);
|
|
236
241
|
|
|
237
242
|
return (
|
|
238
|
-
<div
|
|
243
|
+
<div class="flex flex-col h-full">
|
|
239
244
|
{/* Header */}
|
|
240
|
-
<div
|
|
245
|
+
<div class="flex items-center gap-hsp-sm px-hsp-lg py-vsp-xs border-b border-muted">
|
|
241
246
|
{showBackButton && (
|
|
242
247
|
<button
|
|
243
248
|
type="button"
|
|
244
|
-
|
|
245
|
-
|
|
249
|
+
on:click={onBack}
|
|
250
|
+
class="text-muted hover:text-fg lg:hidden"
|
|
246
251
|
aria-label="Back to revisions"
|
|
247
252
|
>
|
|
248
|
-
<ArrowLeft
|
|
253
|
+
<ArrowLeft class="h-icon-sm w-icon-sm" />
|
|
249
254
|
</button>
|
|
250
255
|
)}
|
|
251
|
-
<div
|
|
252
|
-
<div
|
|
256
|
+
<div class="flex-1 min-w-0 flex">
|
|
257
|
+
<div class="w-1/2 text-small text-muted font-mono truncate pr-hsp-sm">
|
|
253
258
|
{selection.older.hash.slice(0, 7)}
|
|
254
259
|
</div>
|
|
255
|
-
<div
|
|
260
|
+
<div class="w-1/2 text-small text-muted font-mono truncate pl-hsp-sm">
|
|
256
261
|
{selection.newer.hash.slice(0, 7)}
|
|
257
262
|
</div>
|
|
258
263
|
</div>
|
|
259
264
|
</div>
|
|
260
265
|
|
|
261
266
|
{/* Side-by-side diff — shows a spinner while the diff module lazy-loads */}
|
|
262
|
-
{diffError
|
|
263
|
-
<div
|
|
264
|
-
|
|
265
|
-
{!changes && !diffError
|
|
266
|
-
<div
|
|
267
|
-
<
|
|
267
|
+
<Show when={computed(() => diffError.value !== null)}>
|
|
268
|
+
{() => <div class="px-hsp-lg py-vsp-lg text-danger text-small">{diffError}</div>}
|
|
269
|
+
</Show>
|
|
270
|
+
<Show when={computed(() => !changes.value && !diffError.value)}>{() => <Spinner />}</Show>
|
|
271
|
+
<div class={computed(() => `flex-1 overflow-auto${!changes.value ? " hidden" : ""}`)}>
|
|
272
|
+
<For each={tableSnapshots} by={(snapshot) => snapshot.revision}>
|
|
273
|
+
{(snapshot) => (
|
|
274
|
+
<table class="w-full border-collapse" style={{ "table-layout": "fixed" }}>
|
|
268
275
|
<colgroup>
|
|
269
276
|
<col style={{ width: "2.5rem" }} />
|
|
270
277
|
<col />
|
|
@@ -272,7 +279,7 @@ function DiffViewer({
|
|
|
272
279
|
<col />
|
|
273
280
|
</colgroup>
|
|
274
281
|
<tbody>
|
|
275
|
-
{rows.map((row
|
|
282
|
+
{snapshot.value.rows.map((row) => {
|
|
276
283
|
const leftBg =
|
|
277
284
|
row.type === "removed" || row.type === "changed"
|
|
278
285
|
? "diff-line-removed"
|
|
@@ -285,21 +292,21 @@ function DiffViewer({
|
|
|
285
292
|
const rightEmpty = row.rightLine === null;
|
|
286
293
|
|
|
287
294
|
return (
|
|
288
|
-
<tr
|
|
295
|
+
<tr class="diff-row">
|
|
289
296
|
{/* Left line number */}
|
|
290
|
-
<td
|
|
297
|
+
<td class={`diff-line-num ${leftBg}`}>
|
|
291
298
|
{row.leftNum ?? ""}
|
|
292
299
|
</td>
|
|
293
300
|
{/* Left content */}
|
|
294
|
-
<td
|
|
301
|
+
<td class={`diff-line-content ${leftBg}${leftEmpty ? " diff-line-empty" : ""}`}>
|
|
295
302
|
{row.leftLine ?? ""}
|
|
296
303
|
</td>
|
|
297
304
|
{/* Right line number */}
|
|
298
|
-
<td
|
|
305
|
+
<td class={`diff-line-num ${rightBg}`}>
|
|
299
306
|
{row.rightNum ?? ""}
|
|
300
307
|
</td>
|
|
301
308
|
{/* Right content */}
|
|
302
|
-
<td
|
|
309
|
+
<td class={`diff-line-content ${rightBg}${rightEmpty ? " diff-line-empty" : ""}`}>
|
|
303
310
|
{row.rightLine ?? ""}
|
|
304
311
|
</td>
|
|
305
312
|
</tr>
|
|
@@ -307,6 +314,8 @@ function DiffViewer({
|
|
|
307
314
|
})}
|
|
308
315
|
</tbody>
|
|
309
316
|
</table>
|
|
317
|
+
)}
|
|
318
|
+
</For>
|
|
310
319
|
</div>
|
|
311
320
|
</div>
|
|
312
321
|
);
|
|
@@ -327,28 +336,29 @@ function RevisionList({
|
|
|
327
336
|
displayLocale?: string;
|
|
328
337
|
dateFormats?: ResolvedDateFormats;
|
|
329
338
|
}) {
|
|
330
|
-
const
|
|
331
|
-
const
|
|
339
|
+
const revisionEntries = signal(entries);
|
|
340
|
+
const selectedA = signal(1); // older (default: second entry)
|
|
341
|
+
const selectedB = signal(0); // newer (default: first entry)
|
|
332
342
|
|
|
333
343
|
if (entries.length === 0) {
|
|
334
344
|
return (
|
|
335
|
-
<div
|
|
345
|
+
<div class="px-hsp-lg py-vsp-lg text-muted text-small">
|
|
336
346
|
No revision history available.
|
|
337
347
|
</div>
|
|
338
348
|
);
|
|
339
349
|
}
|
|
340
350
|
|
|
341
|
-
const canCompare =
|
|
342
|
-
selectedA !== selectedB &&
|
|
343
|
-
selectedA >= 0 &&
|
|
344
|
-
selectedB >= 0 &&
|
|
345
|
-
selectedA < entries.length &&
|
|
346
|
-
selectedB < entries.length;
|
|
351
|
+
const canCompare = computed(() =>
|
|
352
|
+
selectedA.value !== selectedB.value &&
|
|
353
|
+
selectedA.value >= 0 &&
|
|
354
|
+
selectedB.value >= 0 &&
|
|
355
|
+
selectedA.value < entries.length &&
|
|
356
|
+
selectedB.value < entries.length);
|
|
347
357
|
|
|
348
358
|
function handleCompare() {
|
|
349
|
-
if (!canCompare) return;
|
|
350
|
-
const idxOlder = Math.max(selectedA, selectedB);
|
|
351
|
-
const idxNewer = Math.min(selectedA, selectedB);
|
|
359
|
+
if (!canCompare.value) return;
|
|
360
|
+
const idxOlder = Math.max(selectedA.value, selectedB.value);
|
|
361
|
+
const idxNewer = Math.min(selectedA.value, selectedB.value);
|
|
352
362
|
const olderEntry = entries[idxOlder];
|
|
353
363
|
const newerEntry = entries[idxNewer];
|
|
354
364
|
if (!olderEntry || !newerEntry) return;
|
|
@@ -359,33 +369,33 @@ function RevisionList({
|
|
|
359
369
|
}
|
|
360
370
|
|
|
361
371
|
return (
|
|
362
|
-
<div
|
|
372
|
+
<div class="flex flex-col h-full">
|
|
363
373
|
{/* Compare bar */}
|
|
364
374
|
{entries.length >= 2 && (
|
|
365
|
-
<div
|
|
375
|
+
<div class="px-hsp-lg py-vsp-xs border-b border-muted flex items-center gap-hsp-sm">
|
|
366
376
|
<button
|
|
367
377
|
type="button"
|
|
368
|
-
disabled={!canCompare}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
canCompare
|
|
378
|
+
disabled={computed(() => !canCompare.value)}
|
|
379
|
+
on:click={handleCompare}
|
|
380
|
+
class={computed(() =>
|
|
381
|
+
canCompare.value
|
|
372
382
|
? "px-hsp-md py-vsp-2xs text-small rounded bg-accent text-bg hover:bg-accent-hover"
|
|
373
383
|
: "px-hsp-md py-vsp-2xs text-small rounded bg-surface text-muted cursor-not-allowed"
|
|
374
|
-
}
|
|
384
|
+
)}
|
|
375
385
|
>
|
|
376
386
|
Compare
|
|
377
387
|
</button>
|
|
378
|
-
<span
|
|
388
|
+
<span class="text-caption text-muted">
|
|
379
389
|
Select two revisions (A / B)
|
|
380
390
|
</span>
|
|
381
391
|
</div>
|
|
382
392
|
)}
|
|
383
393
|
|
|
384
394
|
{/* Revision entries */}
|
|
385
|
-
<div
|
|
386
|
-
{
|
|
387
|
-
const isA = selectedA === idx;
|
|
388
|
-
const isB = selectedB === idx;
|
|
395
|
+
<div class="flex-1 overflow-auto">
|
|
396
|
+
<For each={revisionEntries} by={(entry) => entry.hash}>{(entry, idx) => {
|
|
397
|
+
const isA = computed(() => selectedA.value === idx.value);
|
|
398
|
+
const isB = computed(() => selectedB.value === idx.value);
|
|
389
399
|
// Renders in UTC (via the shared formatter) rather than the
|
|
390
400
|
// visitor's local time zone — a deliberate correction over the
|
|
391
401
|
// previous ambient-browser-locale-dependent formatting, not a
|
|
@@ -393,45 +403,44 @@ function RevisionList({
|
|
|
393
403
|
// shift by one day versus the prior behavior; the wave-6
|
|
394
404
|
// default-parity gate exempts doc-history on this basis (#4073).
|
|
395
405
|
const dateStr = formatDate(
|
|
396
|
-
entry.date,
|
|
406
|
+
entry.value.date,
|
|
397
407
|
displayLocale ?? "en",
|
|
398
408
|
dateFormats?.full,
|
|
399
409
|
);
|
|
400
410
|
|
|
401
411
|
return (
|
|
402
412
|
<div
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
isA || isB
|
|
413
|
+
class={computed(() =>
|
|
414
|
+
isA.value || isB.value
|
|
406
415
|
? "px-hsp-lg py-vsp-xs border-b border-muted bg-surface"
|
|
407
416
|
: "px-hsp-lg py-vsp-xs border-b border-muted hover:bg-surface"
|
|
408
|
-
}
|
|
417
|
+
)}
|
|
409
418
|
>
|
|
410
|
-
<div
|
|
419
|
+
<div class="flex items-start gap-hsp-sm">
|
|
411
420
|
{/* Selection badges */}
|
|
412
421
|
{entries.length >= 2 && (
|
|
413
|
-
<div
|
|
422
|
+
<div class="flex flex-col gap-vsp-2xs pt-[2px] shrink-0">
|
|
414
423
|
<button
|
|
415
424
|
type="button"
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
isA
|
|
425
|
+
on:click={() => { selectedA.value = idx.value; }}
|
|
426
|
+
class={computed(() =>
|
|
427
|
+
isA.value
|
|
419
428
|
? "w-[1.5rem] h-[1.25rem] text-caption rounded flex items-center justify-center bg-accent text-bg"
|
|
420
429
|
: "w-[1.5rem] h-[1.25rem] text-caption rounded flex items-center justify-center border border-muted text-muted hover:border-fg hover:text-fg"
|
|
421
|
-
}
|
|
422
|
-
aria-label={`Select revision ${entry.hash.slice(0, 7)} as A`}
|
|
430
|
+
)}
|
|
431
|
+
aria-label={`Select revision ${entry.value.hash.slice(0, 7)} as A`}
|
|
423
432
|
>
|
|
424
433
|
A
|
|
425
434
|
</button>
|
|
426
435
|
<button
|
|
427
436
|
type="button"
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
isB
|
|
437
|
+
on:click={() => { selectedB.value = idx.value; }}
|
|
438
|
+
class={computed(() =>
|
|
439
|
+
isB.value
|
|
431
440
|
? "w-[1.5rem] h-[1.25rem] text-caption rounded flex items-center justify-center bg-accent text-bg"
|
|
432
441
|
: "w-[1.5rem] h-[1.25rem] text-caption rounded flex items-center justify-center border border-muted text-muted hover:border-fg hover:text-fg"
|
|
433
|
-
}
|
|
434
|
-
aria-label={`Select revision ${entry.hash.slice(0, 7)} as B`}
|
|
442
|
+
)}
|
|
443
|
+
aria-label={`Select revision ${entry.value.hash.slice(0, 7)} as B`}
|
|
435
444
|
>
|
|
436
445
|
B
|
|
437
446
|
</button>
|
|
@@ -439,22 +448,22 @@ function RevisionList({
|
|
|
439
448
|
)}
|
|
440
449
|
|
|
441
450
|
{/* Revision info */}
|
|
442
|
-
<div
|
|
443
|
-
<div
|
|
444
|
-
<code
|
|
445
|
-
{entry.hash.slice(0, 7)}
|
|
451
|
+
<div class="min-w-0 flex-1">
|
|
452
|
+
<div class="flex items-baseline gap-hsp-sm">
|
|
453
|
+
<code class="text-caption text-accent font-mono">
|
|
454
|
+
{entry.value.hash.slice(0, 7)}
|
|
446
455
|
</code>
|
|
447
|
-
<span
|
|
456
|
+
<span class="text-caption text-muted">{dateStr}</span>
|
|
448
457
|
</div>
|
|
449
|
-
<div
|
|
450
|
-
<SmartBreak>{entry.message}</SmartBreak>
|
|
458
|
+
<div class="text-small text-fg mt-vsp-2xs truncate">
|
|
459
|
+
<SmartBreak>{entry.value.message}</SmartBreak>
|
|
451
460
|
</div>
|
|
452
|
-
<div
|
|
461
|
+
<div class="text-caption text-muted">{entry.value.author}</div>
|
|
453
462
|
</div>
|
|
454
463
|
</div>
|
|
455
464
|
</div>
|
|
456
465
|
);
|
|
457
|
-
}
|
|
466
|
+
}}</For>
|
|
458
467
|
</div>
|
|
459
468
|
</div>
|
|
460
469
|
);
|
|
@@ -471,19 +480,16 @@ export function DocHistory({
|
|
|
471
480
|
displayLocale,
|
|
472
481
|
dateFormats,
|
|
473
482
|
}: DocHistoryProps) {
|
|
474
|
-
const
|
|
475
|
-
const
|
|
476
|
-
const
|
|
477
|
-
const
|
|
478
|
-
const
|
|
479
|
-
|
|
480
|
-
);
|
|
483
|
+
const scope = getScope();
|
|
484
|
+
const view = signal<PanelView>("closed");
|
|
485
|
+
const data = signal<DocHistoryData | null>(null);
|
|
486
|
+
const loading = signal(false);
|
|
487
|
+
const error = signal<string | null>(null);
|
|
488
|
+
const diffSelection = signal<DiffSelection | null>(null);
|
|
481
489
|
// Holds the history trigger button element captured in handleOpen() so the
|
|
482
|
-
//
|
|
483
|
-
//
|
|
484
|
-
|
|
485
|
-
// (conditional render) — by the time the open-effect fires, it's gone (#2295).
|
|
486
|
-
const returnFocusRef = useRef<HTMLElement | null>(null);
|
|
490
|
+
// helper can restore focus to it when the dialog closes. Capture it in the
|
|
491
|
+
// click handler so the connected trigger remains the return target (#2295).
|
|
492
|
+
const returnFocusRef: Ref<HTMLElement> = { current: null };
|
|
487
493
|
|
|
488
494
|
const base = basePath.replace(/\/+$/, "");
|
|
489
495
|
// Doc-history storage sentinel ("" -> "index"): a root index page has the
|
|
@@ -499,74 +505,85 @@ export function DocHistory({
|
|
|
499
505
|
? `${base}/doc-history/${locale}/${historySlug}.json`
|
|
500
506
|
: `${base}/doc-history/${historySlug}.json`;
|
|
501
507
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
508
|
+
let fetchController: AbortController | null = null;
|
|
509
|
+
let fetchRun = 0;
|
|
510
|
+
const fetchHistory = async () => {
|
|
511
|
+
if (data.value || loading.value) return;
|
|
512
|
+
fetchController?.abort();
|
|
513
|
+
const controller = new AbortController();
|
|
514
|
+
fetchController = controller;
|
|
515
|
+
const run = ++fetchRun;
|
|
516
|
+
loading.value = true;
|
|
517
|
+
error.value = null;
|
|
506
518
|
try {
|
|
507
|
-
const res = await fetch(fetchPath);
|
|
519
|
+
const res = await fetch(fetchPath, { signal: controller.signal });
|
|
520
|
+
if (controller.signal.aborted || scope.abortSignal.aborted || run !== fetchRun) return;
|
|
508
521
|
if (!res.ok) {
|
|
509
522
|
throw new Error(`Failed to load history (${res.status})`);
|
|
510
523
|
}
|
|
511
524
|
const json: DocHistoryData = await res.json();
|
|
525
|
+
if (controller.signal.aborted || scope.abortSignal.aborted || run !== fetchRun) return;
|
|
512
526
|
if (!json || !Array.isArray(json.entries)) {
|
|
513
527
|
throw new Error("Malformed history response");
|
|
514
528
|
}
|
|
515
|
-
|
|
529
|
+
data.value = json;
|
|
516
530
|
} catch (e) {
|
|
517
|
-
|
|
531
|
+
if (!controller.signal.aborted && !scope.abortSignal.aborted && run === fetchRun)
|
|
532
|
+
error.value = e instanceof Error ? e.message : "Failed to load history";
|
|
518
533
|
} finally {
|
|
519
|
-
|
|
534
|
+
if (!scope.abortSignal.aborted && run === fetchRun) loading.value = false;
|
|
520
535
|
}
|
|
521
|
-
}
|
|
536
|
+
};
|
|
537
|
+
scope.onActivate(() => () => { fetchController?.abort(); fetchRun++; });
|
|
522
538
|
|
|
523
|
-
function handleOpen(e:
|
|
539
|
+
function handleOpen(e: Event) {
|
|
524
540
|
// Capture the trigger so the dialog hook can restore focus to it on close
|
|
525
541
|
// (a11y #2295). The button now stays mounted while the panel is open (see
|
|
526
542
|
// the render below), so this ref stays a *connected* node — required for
|
|
527
543
|
// .focus() to actually land on close (zudolab/zudo-doc#2303).
|
|
528
|
-
returnFocusRef.current = e.currentTarget;
|
|
529
|
-
|
|
530
|
-
fetchHistory();
|
|
544
|
+
returnFocusRef.current = e.currentTarget as HTMLButtonElement;
|
|
545
|
+
view.value = "revisions";
|
|
546
|
+
void fetchHistory();
|
|
531
547
|
}
|
|
532
548
|
|
|
533
|
-
const handleClose =
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
549
|
+
const handleClose = () => {
|
|
550
|
+
view.value = "closed";
|
|
551
|
+
diffSelection.value = null;
|
|
552
|
+
fetchController?.abort();
|
|
553
|
+
fetchRun++;
|
|
554
|
+
loading.value = false;
|
|
555
|
+
};
|
|
537
556
|
|
|
538
557
|
function handleSelectDiff(selection: DiffSelection) {
|
|
539
|
-
|
|
540
|
-
|
|
558
|
+
diffSelection.value = selection;
|
|
559
|
+
view.value = "diff";
|
|
541
560
|
}
|
|
542
561
|
|
|
543
562
|
function handleBackToRevisions() {
|
|
544
|
-
|
|
545
|
-
|
|
563
|
+
diffSelection.value = null;
|
|
564
|
+
view.value = "revisions";
|
|
546
565
|
}
|
|
547
566
|
|
|
548
567
|
// Lock body scroll when panel is open
|
|
549
|
-
|
|
550
|
-
if (view
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
return () => {
|
|
556
|
-
document.body.style.overflow = "";
|
|
557
|
-
};
|
|
558
|
-
}, [view]);
|
|
568
|
+
scope.effect(() => {
|
|
569
|
+
if (view.value === "closed") return;
|
|
570
|
+
const previousOverflow = document.body.style.overflow;
|
|
571
|
+
document.body.style.overflow = "hidden";
|
|
572
|
+
return () => { document.body.style.overflow = previousOverflow; };
|
|
573
|
+
});
|
|
559
574
|
|
|
560
|
-
const isOpen = view !== "closed";
|
|
561
|
-
const hasDiff = view === "diff" && diffSelection;
|
|
575
|
+
const isOpen = computed(() => view.value !== "closed");
|
|
576
|
+
const hasDiff = computed(() => view.value === "diff" && diffSelection.value !== null);
|
|
577
|
+
const diffPairs = computed(() => diffSelection.value && view.value === "diff"
|
|
578
|
+
? [{ key: `${diffSelection.value.older.hash}:${diffSelection.value.newer.hash}`, selection: diffSelection.value }]
|
|
579
|
+
: []);
|
|
562
580
|
|
|
563
581
|
// Shared dialog lifecycle: showModal/close sync, native-close callback,
|
|
564
|
-
// and navigation-close — delegated to
|
|
582
|
+
// and navigation-close — delegated to modalDialog.
|
|
565
583
|
// manageFocus: move focus to the close button on open, restore to the
|
|
566
584
|
// history trigger button on close (a11y interaction #2295).
|
|
567
|
-
// returnFocusRef: pre-captured trigger element
|
|
568
|
-
|
|
569
|
-
const { dialogRef } = useModalDialog({
|
|
585
|
+
// returnFocusRef: pre-captured, still-connected trigger element.
|
|
586
|
+
const { dialogRef } = modalDialog(scope, {
|
|
570
587
|
isOpen,
|
|
571
588
|
onClose: handleClose,
|
|
572
589
|
navigateEvent: AFTER_NAVIGATE_EVENT,
|
|
@@ -585,15 +602,16 @@ export function DocHistory({
|
|
|
585
602
|
(the old `{!isOpen && …}`) left the ref pointing at a detached node,
|
|
586
603
|
so `.focus()` no-op'd and focus fell to <body> on close
|
|
587
604
|
(zudolab/zudo-doc#2303). */}
|
|
588
|
-
<div
|
|
605
|
+
<div class="flex justify-end mt-vsp-xl">
|
|
589
606
|
<button
|
|
590
607
|
type="button"
|
|
591
|
-
|
|
592
|
-
|
|
608
|
+
on:click={handleOpen}
|
|
609
|
+
data-doc-history-trigger=""
|
|
610
|
+
class="flex items-center gap-hsp-xs px-hsp-md py-vsp-xs rounded-lg bg-surface border border-muted text-muted hover:text-accent hover:border-accent focus-visible:text-accent focus-visible:border-accent transition-colors duration-0"
|
|
593
611
|
aria-label="View document history"
|
|
594
612
|
>
|
|
595
|
-
<History
|
|
596
|
-
<span
|
|
613
|
+
<History class="h-icon-md w-icon-md" />
|
|
614
|
+
<span class="text-small">History</span>
|
|
597
615
|
</button>
|
|
598
616
|
</div>
|
|
599
617
|
|
|
@@ -609,47 +627,46 @@ export function DocHistory({
|
|
|
609
627
|
<dialog
|
|
610
628
|
ref={dialogRef}
|
|
611
629
|
aria-label="Document revision history"
|
|
612
|
-
|
|
630
|
+
data-doc-history-panel=""
|
|
631
|
+
class="z-modal fixed inset-0 m-0 h-full w-full max-h-full max-w-full bg-bg border-none p-0 backdrop:z-modal-backdrop backdrop:bg-bg/30"
|
|
613
632
|
style={{ color: "var(--color-fg)" }}
|
|
614
633
|
>
|
|
615
634
|
{/* Panel header */}
|
|
616
|
-
<div
|
|
617
|
-
<h2
|
|
618
|
-
{view === "diff" ? "Diff" : "Revision History"}
|
|
635
|
+
<div class="flex items-center justify-between px-hsp-lg py-vsp-xs border-b border-muted">
|
|
636
|
+
<h2 class="text-body font-semibold text-fg">
|
|
637
|
+
{computed(() => view.value === "diff" ? "Diff" : "Revision History")}
|
|
619
638
|
</h2>
|
|
620
639
|
<button
|
|
621
640
|
type="button"
|
|
622
|
-
|
|
623
|
-
|
|
641
|
+
on:click={handleClose}
|
|
642
|
+
class="text-muted hover:text-fg"
|
|
624
643
|
aria-label="Close history panel"
|
|
625
644
|
>
|
|
626
|
-
<Close
|
|
645
|
+
<Close class="h-icon-md w-icon-md" />
|
|
627
646
|
</button>
|
|
628
647
|
</div>
|
|
629
648
|
|
|
630
649
|
{/* Panel body */}
|
|
631
|
-
<div
|
|
632
|
-
{loading
|
|
650
|
+
<div class="h-[calc(100%_-_3rem)] overflow-hidden">
|
|
651
|
+
<Show when={loading}>{() => <Spinner />}</Show>
|
|
633
652
|
|
|
634
|
-
{error
|
|
635
|
-
<div
|
|
636
|
-
|
|
637
|
-
</div>
|
|
638
|
-
)}
|
|
653
|
+
<Show when={computed(() => error.value !== null)}>
|
|
654
|
+
{() => <div class="px-hsp-lg py-vsp-lg text-danger text-small">{error}</div>}
|
|
655
|
+
</Show>
|
|
639
656
|
|
|
640
657
|
{/* Difit-style LR split: revision sidebar | diff area */}
|
|
641
|
-
{!loading && !error && data
|
|
642
|
-
<div
|
|
658
|
+
<Show when={computed(() => !loading.value && !error.value && data.value !== null)}>{() => (
|
|
659
|
+
<div class="flex h-full">
|
|
643
660
|
{/* Left sidebar: revision list — always visible on lg */}
|
|
644
661
|
<div
|
|
645
|
-
|
|
646
|
-
hasDiff
|
|
662
|
+
class={computed(() =>
|
|
663
|
+
hasDiff.value
|
|
647
664
|
? "hidden lg:flex lg:flex-col lg:w-[clamp(16rem,25%,22rem)] shrink-0 border-r border-muted h-full"
|
|
648
665
|
: "flex flex-col w-full h-full"
|
|
649
|
-
}
|
|
666
|
+
)}
|
|
650
667
|
>
|
|
651
668
|
<RevisionList
|
|
652
|
-
entries={data.entries}
|
|
669
|
+
entries={data.value!.entries}
|
|
653
670
|
onSelectDiff={handleSelectDiff}
|
|
654
671
|
displayLocale={displayLocale}
|
|
655
672
|
dateFormats={dateFormats}
|
|
@@ -657,22 +674,19 @@ export function DocHistory({
|
|
|
657
674
|
</div>
|
|
658
675
|
|
|
659
676
|
{/* Right: diff viewer (on mobile, replaces the sidebar) */}
|
|
660
|
-
{hasDiff
|
|
661
|
-
<div
|
|
677
|
+
<Show when={hasDiff}>{() => (
|
|
678
|
+
<div class="flex-1 min-w-0 h-full">
|
|
662
679
|
{/* Key on the compared pair forces a fresh mount whenever the
|
|
663
680
|
selection changes, so the previous pair's diff rows can
|
|
664
681
|
never render under the new header hashes while the lazy
|
|
665
682
|
diff recompute is in flight (#2068). */}
|
|
666
|
-
<
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
onBack={handleBackToRevisions}
|
|
670
|
-
showBackButton={true}
|
|
671
|
-
/>
|
|
683
|
+
<For each={diffPairs} by={(pair) => pair.key}>{(pair) => (
|
|
684
|
+
<DiffViewer selection={pair.value.selection} onBack={handleBackToRevisions} showBackButton={true} />
|
|
685
|
+
)}</For>
|
|
672
686
|
</div>
|
|
673
|
-
)}
|
|
687
|
+
)}</Show>
|
|
674
688
|
</div>
|
|
675
|
-
)}
|
|
689
|
+
)}</Show>
|
|
676
690
|
</div>
|
|
677
691
|
</dialog>
|
|
678
692
|
</>
|