@takazudo/zudo-doc 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +18 -0
- package/dist/body-foot-util/body-foot-util-area.d.ts +55 -0
- package/dist/body-foot-util/body-foot-util-area.js +71 -0
- package/dist/body-foot-util/edit-link.d.ts +45 -0
- package/dist/body-foot-util/edit-link.js +42 -0
- package/dist/body-foot-util/index.d.ts +3 -0
- package/dist/body-foot-util/index.js +11 -0
- package/dist/breadcrumb/breadcrumb.d.ts +57 -0
- package/dist/breadcrumb/breadcrumb.js +113 -0
- package/dist/breadcrumb/find-path.d.ts +16 -0
- package/dist/breadcrumb/find-path.js +13 -0
- package/dist/breadcrumb/index.d.ts +4 -0
- package/dist/breadcrumb/index.js +7 -0
- package/dist/breadcrumb/types.d.ts +32 -0
- package/dist/breadcrumb/types.js +0 -0
- package/dist/code-syntax/code-block-enhancer-script.d.ts +3 -0
- package/dist/code-syntax/code-block-enhancer-script.js +165 -0
- package/dist/code-syntax/code-block-enhancer.d.ts +22 -0
- package/dist/code-syntax/code-block-enhancer.js +13 -0
- package/dist/code-syntax/index.d.ts +8 -0
- package/dist/code-syntax/index.js +29 -0
- package/dist/code-syntax/mermaid-init-script.d.ts +51 -0
- package/dist/code-syntax/mermaid-init-script.js +225 -0
- package/dist/code-syntax/mermaid-init.d.ts +48 -0
- package/dist/code-syntax/mermaid-init.js +14 -0
- package/dist/code-syntax/tabs-init-script.d.ts +3 -0
- package/dist/code-syntax/tabs-init-script.js +106 -0
- package/dist/code-syntax/tabs-init.d.ts +24 -0
- package/dist/code-syntax/tabs-init.js +10 -0
- package/dist/code-syntax/tabs.d.ts +36 -0
- package/dist/code-syntax/tabs.js +62 -0
- package/dist/content/component-map.d.ts +51 -0
- package/dist/content/component-map.js +29 -0
- package/dist/content/content-blockquote.d.ts +11 -0
- package/dist/content/content-blockquote.js +14 -0
- package/dist/content/content-code.d.ts +26 -0
- package/dist/content/content-code.js +39 -0
- package/dist/content/content-link.d.ts +12 -0
- package/dist/content/content-link.js +43 -0
- package/dist/content/content-ol.d.ts +11 -0
- package/dist/content/content-ol.js +15 -0
- package/dist/content/content-paragraph.d.ts +10 -0
- package/dist/content/content-paragraph.js +7 -0
- package/dist/content/content-strong.d.ts +11 -0
- package/dist/content/content-strong.js +14 -0
- package/dist/content/content-table.d.ts +11 -0
- package/dist/content/content-table.js +14 -0
- package/dist/content/content-ul.d.ts +11 -0
- package/dist/content/content-ul.js +15 -0
- package/dist/content/heading-h2.d.ts +14 -0
- package/dist/content/heading-h2.js +18 -0
- package/dist/content/heading-h3.d.ts +14 -0
- package/dist/content/heading-h3.js +18 -0
- package/dist/content/heading-h4.d.ts +14 -0
- package/dist/content/heading-h4.js +18 -0
- package/dist/content/index.d.ts +13 -0
- package/dist/content/index.js +27 -0
- package/dist/details/details.d.ts +26 -0
- package/dist/details/details.js +10 -0
- package/dist/details/index.d.ts +2 -0
- package/dist/details/index.js +4 -0
- package/dist/doclayout/anchors.d.ts +55 -0
- package/dist/doclayout/anchors.js +42 -0
- package/dist/doclayout/doc-layout-with-defaults.d.ts +83 -0
- package/dist/doclayout/doc-layout-with-defaults.js +159 -0
- package/dist/doclayout/doc-layout.d.ts +121 -0
- package/dist/doclayout/doc-layout.js +89 -0
- package/dist/doclayout/index.d.ts +6 -0
- package/dist/doclayout/index.js +17 -0
- package/dist/footer/footer.d.ts +42 -0
- package/dist/footer/footer.js +79 -0
- package/dist/footer/index.d.ts +3 -0
- package/dist/footer/index.js +4 -0
- package/dist/footer/types.d.ts +58 -0
- package/dist/footer/types.js +0 -0
- package/dist/head/doc-head.d.ts +33 -0
- package/dist/head/doc-head.js +90 -0
- package/dist/head/index.d.ts +5 -0
- package/dist/head/index.js +8 -0
- package/dist/head/og-tags.d.ts +25 -0
- package/dist/head/og-tags.js +16 -0
- package/dist/head/twitter-card.d.ts +21 -0
- package/dist/head/twitter-card.js +14 -0
- package/dist/head/types.d.ts +83 -0
- package/dist/head/types.js +0 -0
- package/dist/header/header.d.ts +158 -0
- package/dist/header/header.js +367 -0
- package/dist/header/index.d.ts +6 -0
- package/dist/header/index.js +18 -0
- package/dist/header/nav-active.d.ts +39 -0
- package/dist/header/nav-active.js +24 -0
- package/dist/header/nav-overflow-script.d.ts +3 -0
- package/dist/header/nav-overflow-script.js +169 -0
- package/dist/header/right-items.d.ts +38 -0
- package/dist/header/right-items.js +30 -0
- package/dist/header/types.d.ts +40 -0
- package/dist/header/types.js +0 -0
- package/dist/html-preview-wrapper/dedent.d.ts +10 -0
- package/dist/html-preview-wrapper/dedent.js +16 -0
- package/dist/html-preview-wrapper/highlighted-code.d.ts +18 -0
- package/dist/html-preview-wrapper/highlighted-code.js +53 -0
- package/dist/html-preview-wrapper/html-preview-wrapper.d.ts +60 -0
- package/dist/html-preview-wrapper/html-preview-wrapper.js +36 -0
- package/dist/html-preview-wrapper/html-preview.d.ts +35 -0
- package/dist/html-preview-wrapper/html-preview.js +75 -0
- package/dist/html-preview-wrapper/index.d.ts +5 -0
- package/dist/html-preview-wrapper/index.js +12 -0
- package/dist/html-preview-wrapper/preflight.d.ts +13 -0
- package/dist/html-preview-wrapper/preflight.js +108 -0
- package/dist/html-preview-wrapper/preview-base.d.ts +29 -0
- package/dist/html-preview-wrapper/preview-base.js +127 -0
- package/dist/i18n-version/index.d.ts +5 -0
- package/dist/i18n-version/index.js +14 -0
- package/dist/i18n-version/language-switcher.d.ts +24 -0
- package/dist/i18n-version/language-switcher.js +25 -0
- package/dist/i18n-version/types.d.ts +43 -0
- package/dist/i18n-version/types.js +0 -0
- package/dist/i18n-version/version-banner.d.ts +30 -0
- package/dist/i18n-version/version-banner.js +21 -0
- package/dist/i18n-version/version-switcher.d.ts +112 -0
- package/dist/i18n-version/version-switcher.js +157 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +0 -0
- package/dist/integrations/claude-resources/escape-for-mdx.d.ts +8 -0
- package/dist/integrations/claude-resources/escape-for-mdx.js +131 -0
- package/dist/integrations/claude-resources/generate.d.ts +13 -0
- package/dist/integrations/claude-resources/generate.js +404 -0
- package/dist/integrations/claude-resources/index.d.ts +46 -0
- package/dist/integrations/claude-resources/index.js +24 -0
- package/dist/integrations/doc-history/index.d.ts +137 -0
- package/dist/integrations/doc-history/index.js +138 -0
- package/dist/integrations/doc-history/pre-build.d.ts +58 -0
- package/dist/integrations/doc-history/pre-build.js +67 -0
- package/dist/integrations/llms-txt/dev-middleware.d.ts +40 -0
- package/dist/integrations/llms-txt/dev-middleware.js +76 -0
- package/dist/integrations/llms-txt/emit.d.ts +22 -0
- package/dist/integrations/llms-txt/emit.js +55 -0
- package/dist/integrations/llms-txt/generate.d.ts +26 -0
- package/dist/integrations/llms-txt/generate.js +36 -0
- package/dist/integrations/llms-txt/index.d.ts +7 -0
- package/dist/integrations/llms-txt/index.js +27 -0
- package/dist/integrations/llms-txt/load.d.ts +51 -0
- package/dist/integrations/llms-txt/load.js +83 -0
- package/dist/integrations/llms-txt/strip.d.ts +22 -0
- package/dist/integrations/llms-txt/strip.js +10 -0
- package/dist/integrations/llms-txt/types.d.ts +145 -0
- package/dist/integrations/llms-txt/types.js +0 -0
- package/dist/integrations/search-index/build-emitter.d.ts +30 -0
- package/dist/integrations/search-index/build-emitter.js +15 -0
- package/dist/integrations/search-index/collect.d.ts +12 -0
- package/dist/integrations/search-index/collect.js +48 -0
- package/dist/integrations/search-index/content-files.d.ts +32 -0
- package/dist/integrations/search-index/content-files.js +50 -0
- package/dist/integrations/search-index/dev-middleware.d.ts +16 -0
- package/dist/integrations/search-index/dev-middleware.js +30 -0
- package/dist/integrations/search-index/index.d.ts +5 -0
- package/dist/integrations/search-index/index.js +14 -0
- package/dist/integrations/search-index/types.d.ts +38 -0
- package/dist/integrations/search-index/types.js +6 -0
- package/dist/metainfo/doc-metainfo.d.ts +50 -0
- package/dist/metainfo/doc-metainfo.js +107 -0
- package/dist/metainfo/doc-tags.d.ts +66 -0
- package/dist/metainfo/doc-tags.js +53 -0
- package/dist/metainfo/frontmatter-preview.d.ts +95 -0
- package/dist/metainfo/frontmatter-preview.js +55 -0
- package/dist/metainfo/index.d.ts +4 -0
- package/dist/metainfo/index.js +28 -0
- package/dist/nav-indexing/category-nav.d.ts +28 -0
- package/dist/nav-indexing/category-nav.js +41 -0
- package/dist/nav-indexing/category-tree-nav.d.ts +27 -0
- package/dist/nav-indexing/category-tree-nav.js +49 -0
- package/dist/nav-indexing/doc-card-grid.d.ts +38 -0
- package/dist/nav-indexing/doc-card-grid.js +40 -0
- package/dist/nav-indexing/docs-sitemap.d.ts +25 -0
- package/dist/nav-indexing/docs-sitemap.js +40 -0
- package/dist/nav-indexing/index.d.ts +10 -0
- package/dist/nav-indexing/index.js +18 -0
- package/dist/nav-indexing/nav-card-grid.d.ts +31 -0
- package/dist/nav-indexing/nav-card-grid.js +43 -0
- package/dist/nav-indexing/site-tree-nav-demo.d.ts +39 -0
- package/dist/nav-indexing/site-tree-nav-demo.js +65 -0
- package/dist/nav-indexing/tag-nav.d.ts +38 -0
- package/dist/nav-indexing/tag-nav.js +96 -0
- package/dist/nav-indexing/types.d.ts +95 -0
- package/dist/nav-indexing/types.js +0 -0
- package/dist/nav-indexing/versions-page-content.d.ts +29 -0
- package/dist/nav-indexing/versions-page-content.js +76 -0
- package/dist/page-loading/index.d.ts +2 -0
- package/dist/page-loading/index.js +10 -0
- package/dist/page-loading/page-loading-overlay.d.ts +35 -0
- package/dist/page-loading/page-loading-overlay.js +50 -0
- package/dist/sidebar/index.d.ts +3 -0
- package/dist/sidebar/index.js +4 -0
- package/dist/sidebar/sidebar.d.ts +54 -0
- package/dist/sidebar/sidebar.js +35 -0
- package/dist/sidebar/types.d.ts +71 -0
- package/dist/sidebar/types.js +0 -0
- package/dist/sidebar-resizer/index.d.ts +14 -0
- package/dist/sidebar-resizer/index.js +165 -0
- package/dist/sidebar-resizer/sidebar-resizer-init.d.ts +20 -0
- package/dist/sidebar-resizer/sidebar-resizer-init.js +119 -0
- package/dist/sidebar-tree/build-tree.d.ts +43 -0
- package/dist/sidebar-tree/build-tree.js +127 -0
- package/dist/sidebar-tree/category-meta.d.ts +19 -0
- package/dist/sidebar-tree/category-meta.js +63 -0
- package/dist/sidebar-tree/index.d.ts +3 -0
- package/dist/sidebar-tree/index.js +13 -0
- package/dist/sidebar-tree/types.d.ts +120 -0
- package/dist/sidebar-tree/types.js +0 -0
- package/dist/tab-item/index.d.ts +2 -0
- package/dist/tab-item/index.js +5 -0
- package/dist/tab-item/tab-item.d.ts +38 -0
- package/dist/tab-item/tab-item.js +25 -0
- package/dist/theme/color-scheme-provider.d.ts +32 -0
- package/dist/theme/color-scheme-provider.js +43 -0
- package/dist/theme/color-tweak-export-modal.d.ts +20 -0
- package/dist/theme/color-tweak-export-modal.js +138 -0
- package/dist/theme/design-token-serde.d.ts +136 -0
- package/dist/theme/design-token-serde.js +254 -0
- package/dist/theme/design-token-tweak-panel.d.ts +11 -0
- package/dist/theme/design-token-tweak-panel.js +10 -0
- package/dist/theme/design-token-types.d.ts +19 -0
- package/dist/theme/design-token-types.js +6 -0
- package/dist/theme/iframe-bridge.d.ts +44 -0
- package/dist/theme/iframe-bridge.js +70 -0
- package/dist/theme/index.d.ts +9 -0
- package/dist/theme/index.js +42 -0
- package/dist/theme/theme-toggle.d.ts +17 -0
- package/dist/theme/theme-toggle.js +91 -0
- package/dist/toc/cx.d.ts +16 -0
- package/dist/toc/cx.js +22 -0
- package/dist/toc/index.d.ts +5 -0
- package/dist/toc/index.js +9 -0
- package/dist/toc/mobile-toc.d.ts +46 -0
- package/dist/toc/mobile-toc.js +88 -0
- package/dist/toc/smart-break.d.ts +27 -0
- package/dist/toc/smart-break.js +36 -0
- package/dist/toc/toc-title.d.ts +10 -0
- package/dist/toc/toc-title.js +14 -0
- package/dist/toc/toc.d.ts +60 -0
- package/dist/toc/toc.js +56 -0
- package/dist/toc/types.d.ts +23 -0
- package/dist/toc/types.js +0 -0
- package/dist/toc/use-active-heading.d.ts +30 -0
- package/dist/toc/use-active-heading.js +106 -0
- package/dist/transitions/index.d.ts +1 -0
- package/dist/transitions/index.js +12 -0
- package/dist/transitions/page-events.d.ts +41 -0
- package/dist/transitions/page-events.js +20 -0
- package/dist/url-normalizer/index.d.ts +1 -0
- package/dist/url-normalizer/index.js +6 -0
- package/dist/url-normalizer/normalize.d.ts +104 -0
- package/dist/url-normalizer/normalize.js +22 -0
- package/package.json +186 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Takeshi Takatsudo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# @takazudo/zudo-doc
|
|
2
|
+
|
|
3
|
+
Framework primitives that sit on top of zfb's engine — the framework layer that zfb deliberately doesn't ship (per ADR-003).
|
|
4
|
+
|
|
5
|
+
This package is part of the **Astro→zfb migration** (super-epic [#473](https://github.com/zudolab/zudo-doc/issues/473)). It implements the [E5 epic](https://github.com/zudolab/zudo-doc/issues/474) and provides the missing-by-design framework concerns:
|
|
6
|
+
|
|
7
|
+
- **Sidebar tree builder** (`./sidebar-tree`) — turns collection entries + `_category_.json` into a sidebar `SidebarNode[]`.
|
|
8
|
+
- **Theme controls** (`./theme`) — color scheme provider + design-token tweak panel (Preact island that wraps an iframe).
|
|
9
|
+
- **TOC** (`./toc`) — desktop and mobile TOC Preact islands fed by MDX `headings` export.
|
|
10
|
+
- **Breadcrumb** (`./breadcrumb`) — JSX breadcrumb fed by the sidebar tree.
|
|
11
|
+
- **DocLayout** (`./doclayout`) — composable layout shell with explicit `<Header>`, `<Sidebar>`, `<Main>`, `<Toc>`, `<Footer>` props; ships a `<DocLayoutWithDefaults>` wrapper that holds the 16 `create-zudo-doc` injection anchors.
|
|
12
|
+
- **View Transitions** (`./transitions`) — native View Transitions API shim (Chrome/Edge/Safari 18+); persistent regions via `view-transition-name`. No-op fallback in Firefox.
|
|
13
|
+
- **Head injection** (`./head`) — canonical, og:\*, twitter:\*, robots, preload hints, RSS link, sitemap link, theme-color — byte-equal to today's Astro output.
|
|
14
|
+
- **SSR-skip wrappers** (`./ssr-skip`) — `<AiChatModalIsland>`, `<ImageEnlargeIsland>`, `<DesignTokenTweakPanelIsland>`, `<MockInitIsland>` — wrap zfb's `<Island ssrFallback>` with the right fallback markup so doc pages don't have to re-implement the SSR-skip pattern.
|
|
15
|
+
|
|
16
|
+
## Pre-publish dev workflow
|
|
17
|
+
|
|
18
|
+
Phase A npm publish is deferred (see super-epic comment 2026-04-28). During pre-publish dev, this package references zfb via the local checkout at `$HOME/repos/myoss/zfb`. Use `/refer-another-project zfb` to read zfb's APIs. If a zfb bug is discovered, fix it directly on zfb's `main` and push (zfb is not public yet).
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { VNode } from 'preact';
|
|
2
|
+
|
|
3
|
+
/** @jsxRuntime automatic */
|
|
4
|
+
/** @jsxImportSource preact */
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Default label used when the consumer doesn't pass one. The legacy
|
|
8
|
+
* Astro template translated `doc.viewSource` via the project's i18n
|
|
9
|
+
* module; v2 stays framework-agnostic, so callers resolve their
|
|
10
|
+
* translation upstream and pass the result here. The English string
|
|
11
|
+
* is mirrored verbatim from the legacy translations table so the
|
|
12
|
+
* component degrades to the original wording when no override is
|
|
13
|
+
* supplied.
|
|
14
|
+
*/
|
|
15
|
+
declare const DEFAULT_VIEW_SOURCE_LABEL = "View source on GitHub";
|
|
16
|
+
interface BodyFootUtilAreaProps {
|
|
17
|
+
/**
|
|
18
|
+
* Final, pre-computed GitHub source URL. The legacy template
|
|
19
|
+
* derived this from `settings.githubUrl + contentDir + entryId`; the
|
|
20
|
+
* v2 component delegates that computation to the consumer (no
|
|
21
|
+
* upstream dependency on the project settings module).
|
|
22
|
+
*
|
|
23
|
+
* When falsy, the view-source link is suppressed.
|
|
24
|
+
*/
|
|
25
|
+
sourceUrl?: string | null;
|
|
26
|
+
/**
|
|
27
|
+
* Display text for the view-source link. Defaults to
|
|
28
|
+
* `"View source on GitHub"`; pass the i18n-resolved string from
|
|
29
|
+
* upstream to localise.
|
|
30
|
+
*/
|
|
31
|
+
viewSourceLabel?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Pre-built doc-history island — typically a zfb `<Island ssrFallback>`
|
|
34
|
+
* that renders the host's real DocHistory component. The host is
|
|
35
|
+
* responsible for assembling this so the page → real-component import
|
|
36
|
+
* chain is preserved (zfb's island scanner relies on that walk; see
|
|
37
|
+
* issue zudolab/zudo-doc#1355 Wave 8 Path A).
|
|
38
|
+
*
|
|
39
|
+
* Pass `null` / `undefined` to suppress the history trigger entirely.
|
|
40
|
+
*/
|
|
41
|
+
docHistoryIsland?: VNode | null;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Footer utility area shown below an article body — composes the
|
|
45
|
+
* "View source on GitHub" link and the host-supplied doc-history
|
|
46
|
+
* island. JSX port of `src/components/body-foot-util-area.astro`.
|
|
47
|
+
*
|
|
48
|
+
* Returns `null` when neither slot has anything to render, mirroring
|
|
49
|
+
* the `hasContent && (...)` guard in the original template so the
|
|
50
|
+
* surrounding `<section>` (with its top border + spacing) doesn't
|
|
51
|
+
* appear as an empty band.
|
|
52
|
+
*/
|
|
53
|
+
declare function BodyFootUtilArea(props: BodyFootUtilAreaProps): VNode | null;
|
|
54
|
+
|
|
55
|
+
export { BodyFootUtilArea, type BodyFootUtilAreaProps, DEFAULT_VIEW_SOURCE_LABEL };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
2
|
+
const DEFAULT_VIEW_SOURCE_LABEL = "View source on GitHub";
|
|
3
|
+
function BodyFootUtilArea(props) {
|
|
4
|
+
const {
|
|
5
|
+
sourceUrl,
|
|
6
|
+
viewSourceLabel = DEFAULT_VIEW_SOURCE_LABEL,
|
|
7
|
+
docHistoryIsland
|
|
8
|
+
} = props;
|
|
9
|
+
const showSource = Boolean(sourceUrl);
|
|
10
|
+
const showHistory = Boolean(docHistoryIsland);
|
|
11
|
+
if (!showSource && !showHistory) return null;
|
|
12
|
+
return /* @__PURE__ */ jsxs(
|
|
13
|
+
"section",
|
|
14
|
+
{
|
|
15
|
+
class: "mt-vsp-xl border-t border-muted pt-vsp-md",
|
|
16
|
+
"aria-label": "Document utilities",
|
|
17
|
+
children: [
|
|
18
|
+
showSource && /* @__PURE__ */ jsx("div", { class: "mb-vsp-md", children: /* @__PURE__ */ jsxs(
|
|
19
|
+
"a",
|
|
20
|
+
{
|
|
21
|
+
href: sourceUrl,
|
|
22
|
+
target: "_blank",
|
|
23
|
+
rel: "noopener noreferrer",
|
|
24
|
+
class: "inline-flex items-center gap-hsp-2xs text-small text-muted hover:text-accent",
|
|
25
|
+
children: [
|
|
26
|
+
/* @__PURE__ */ jsxs(
|
|
27
|
+
"svg",
|
|
28
|
+
{
|
|
29
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
30
|
+
class: "h-[0.875rem] w-[0.875rem]",
|
|
31
|
+
fill: "none",
|
|
32
|
+
viewBox: "0 0 24 24",
|
|
33
|
+
stroke: "currentColor",
|
|
34
|
+
"stroke-width": "2",
|
|
35
|
+
"aria-hidden": "true",
|
|
36
|
+
children: [
|
|
37
|
+
/* @__PURE__ */ jsx(
|
|
38
|
+
"path",
|
|
39
|
+
{
|
|
40
|
+
"stroke-linecap": "round",
|
|
41
|
+
"stroke-linejoin": "round",
|
|
42
|
+
d: "M14 3h7m0 0v7m0-7L10 14"
|
|
43
|
+
}
|
|
44
|
+
),
|
|
45
|
+
/* @__PURE__ */ jsx(
|
|
46
|
+
"path",
|
|
47
|
+
{
|
|
48
|
+
"stroke-linecap": "round",
|
|
49
|
+
"stroke-linejoin": "round",
|
|
50
|
+
d: "M5 5h5m-5 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2v-5"
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
),
|
|
56
|
+
/* @__PURE__ */ jsx("span", { children: viewSourceLabel })
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
) }),
|
|
60
|
+
showHistory && docHistoryIsland && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
61
|
+
/* @__PURE__ */ jsx("h2", { class: "sr-only", children: "Revision History" }),
|
|
62
|
+
docHistoryIsland
|
|
63
|
+
] })
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
export {
|
|
69
|
+
BodyFootUtilArea,
|
|
70
|
+
DEFAULT_VIEW_SOURCE_LABEL
|
|
71
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { VNode } from 'preact';
|
|
2
|
+
|
|
3
|
+
/** @jsxRuntime automatic */
|
|
4
|
+
/** @jsxImportSource preact */
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Default label used when the consumer doesn't pass one. The legacy
|
|
8
|
+
* Astro template translated `doc.editPage` via the project's i18n
|
|
9
|
+
* module; v2 stays framework-agnostic and lets the caller pass the
|
|
10
|
+
* already-translated label as `label` instead. The English string is
|
|
11
|
+
* mirrored verbatim from the legacy translations table.
|
|
12
|
+
*/
|
|
13
|
+
declare const DEFAULT_EDIT_LINK_LABEL = "Edit this page";
|
|
14
|
+
interface EditLinkProps {
|
|
15
|
+
/**
|
|
16
|
+
* Final, pre-computed edit URL. The legacy Astro version derived
|
|
17
|
+
* this from `settings.editUrl + contentDir + entryId`; that
|
|
18
|
+
* computation belongs in the consumer (so this v2 component has no
|
|
19
|
+
* upward dependency on the project settings module).
|
|
20
|
+
*
|
|
21
|
+
* When `null` / `undefined` / empty string the link is suppressed
|
|
22
|
+
* entirely — the component returns `null` to mirror the
|
|
23
|
+
* `editUrl && (...)` guard in the original template.
|
|
24
|
+
*/
|
|
25
|
+
editUrl?: string | null;
|
|
26
|
+
/**
|
|
27
|
+
* Display text for the link. The legacy template called
|
|
28
|
+
* `t("doc.editPage", locale)`; consumers should resolve their i18n
|
|
29
|
+
* lookup upstream and pass the result here. Defaults to
|
|
30
|
+
* `"Edit this page"` so the component degrades to the original
|
|
31
|
+
* English label when no translation is provided.
|
|
32
|
+
*/
|
|
33
|
+
label?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* "Edit this page" link — JSX port of `src/components/edit-link.astro`.
|
|
37
|
+
*
|
|
38
|
+
* The legacy component owned three concerns: URL computation, i18n
|
|
39
|
+
* lookup, and presentation. v2 keeps only presentation; URL and label
|
|
40
|
+
* are pre-resolved by the caller. This matches the breadcrumb subpath
|
|
41
|
+
* pattern of "no settings/i18n imports inside the v2 package".
|
|
42
|
+
*/
|
|
43
|
+
declare function EditLink(props: EditLinkProps): VNode | null;
|
|
44
|
+
|
|
45
|
+
export { DEFAULT_EDIT_LINK_LABEL, EditLink, type EditLinkProps };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsx, jsxs } from "preact/jsx-runtime";
|
|
2
|
+
const DEFAULT_EDIT_LINK_LABEL = "Edit this page";
|
|
3
|
+
function EditLink(props) {
|
|
4
|
+
const { editUrl, label = DEFAULT_EDIT_LINK_LABEL } = props;
|
|
5
|
+
if (!editUrl) return null;
|
|
6
|
+
return /* @__PURE__ */ jsxs(
|
|
7
|
+
"a",
|
|
8
|
+
{
|
|
9
|
+
href: editUrl,
|
|
10
|
+
target: "_blank",
|
|
11
|
+
rel: "noopener noreferrer",
|
|
12
|
+
class: "inline-flex items-center gap-hsp-2xs text-small text-muted hover:text-accent",
|
|
13
|
+
children: [
|
|
14
|
+
/* @__PURE__ */ jsx(
|
|
15
|
+
"svg",
|
|
16
|
+
{
|
|
17
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
18
|
+
class: "h-[0.875rem] w-[0.875rem]",
|
|
19
|
+
fill: "none",
|
|
20
|
+
viewBox: "0 0 24 24",
|
|
21
|
+
stroke: "currentColor",
|
|
22
|
+
"stroke-width": "2",
|
|
23
|
+
"aria-hidden": "true",
|
|
24
|
+
children: /* @__PURE__ */ jsx(
|
|
25
|
+
"path",
|
|
26
|
+
{
|
|
27
|
+
"stroke-linecap": "round",
|
|
28
|
+
"stroke-linejoin": "round",
|
|
29
|
+
d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
),
|
|
34
|
+
/* @__PURE__ */ jsx("span", { children: label })
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
DEFAULT_EDIT_LINK_LABEL,
|
|
41
|
+
EditLink
|
|
42
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BodyFootUtilArea,
|
|
3
|
+
DEFAULT_VIEW_SOURCE_LABEL
|
|
4
|
+
} from "./body-foot-util-area.js";
|
|
5
|
+
import { EditLink, DEFAULT_EDIT_LINK_LABEL } from "./edit-link.js";
|
|
6
|
+
export {
|
|
7
|
+
BodyFootUtilArea,
|
|
8
|
+
DEFAULT_EDIT_LINK_LABEL,
|
|
9
|
+
DEFAULT_VIEW_SOURCE_LABEL,
|
|
10
|
+
EditLink
|
|
11
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ComponentChildren, VNode } from 'preact';
|
|
2
|
+
import { BreadcrumbItem, SidebarNode } from './types.js';
|
|
3
|
+
|
|
4
|
+
/** @jsxRuntime automatic */
|
|
5
|
+
/** @jsxImportSource preact */
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Convert a sidebar tree + the current page's id into the ordered list
|
|
9
|
+
* of crumbs the renderer walks. The first crumb is the home rung
|
|
10
|
+
* (icon-only, label is the empty string), followed by each ancestor in
|
|
11
|
+
* the tree, ending with the current page (no `href` so the renderer
|
|
12
|
+
* paints it as plain text).
|
|
13
|
+
*
|
|
14
|
+
* Mirrors the legacy buildBreadcrumbs() behaviour from
|
|
15
|
+
* src/utils/docs.ts so the rendered output stays parity-equivalent
|
|
16
|
+
* with the original Astro breadcrumb component.
|
|
17
|
+
*/
|
|
18
|
+
declare function buildBreadcrumbItems(tree: SidebarNode[], currentId: string, homeHref: string): BreadcrumbItem[];
|
|
19
|
+
interface BreadcrumbProps {
|
|
20
|
+
/** Pre-built items, or omit and pass `tree` + `currentId` instead. */
|
|
21
|
+
items?: BreadcrumbItem[];
|
|
22
|
+
/** Sidebar tree to derive the trail from. Required when `items` is omitted. */
|
|
23
|
+
tree?: SidebarNode[];
|
|
24
|
+
/** Id of the current page (matches SidebarNode.id). Required when `items` is omitted. */
|
|
25
|
+
currentId?: string;
|
|
26
|
+
/** Href for the leading home rung. Defaults to "/". */
|
|
27
|
+
homeHref?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Optional slot rendered at the right end of the breadcrumb row.
|
|
30
|
+
* When provided, the breadcrumb nav and this slot are wrapped in a
|
|
31
|
+
* flex row that matches the original Astro doc-layout's combined
|
|
32
|
+
* breadcrumb + version-switcher row:
|
|
33
|
+
*
|
|
34
|
+
* class="mb-vsp-sm flex flex-col items-start gap-vsp-xs
|
|
35
|
+
* sm:flex-row sm:items-center sm:justify-between [&_nav]:mb-0"
|
|
36
|
+
*
|
|
37
|
+
* The `[&_nav]:mb-0` rule strips the nav's own `mb-vsp-md` so the
|
|
38
|
+
* wrapper margin controls spacing instead. Use this to place the
|
|
39
|
+
* VersionSwitcher pill inline at the right of the breadcrumb row,
|
|
40
|
+
* matching the reference site's layout on category index pages.
|
|
41
|
+
*/
|
|
42
|
+
rightSlot?: ComponentChildren;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Breadcrumb trail — JSX port of src/components/breadcrumb.astro.
|
|
46
|
+
*
|
|
47
|
+
* Two usage shapes:
|
|
48
|
+
* 1. Pass pre-built `items` (existing call-sites that already
|
|
49
|
+
* compute crumbs upstream).
|
|
50
|
+
* 2. Pass `tree` + `currentId` and the component derives the trail.
|
|
51
|
+
*
|
|
52
|
+
* Returns null when no items resolve, matching the Astro template's
|
|
53
|
+
* `items.length > 0 &&` guard.
|
|
54
|
+
*/
|
|
55
|
+
declare function Breadcrumb(props: BreadcrumbProps): VNode | null;
|
|
56
|
+
|
|
57
|
+
export { Breadcrumb, type BreadcrumbProps, buildBreadcrumbItems };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
2
|
+
import { findPath } from "./find-path.js";
|
|
3
|
+
function buildBreadcrumbItems(tree, currentId, homeHref) {
|
|
4
|
+
const items = [{ label: "", href: homeHref }];
|
|
5
|
+
const path = findPath(tree, currentId);
|
|
6
|
+
for (let i = 0; i < path.length; i++) {
|
|
7
|
+
const node = path[i];
|
|
8
|
+
const isLast = i === path.length - 1;
|
|
9
|
+
items.push({
|
|
10
|
+
label: node.label,
|
|
11
|
+
href: isLast ? void 0 : node.href
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
return items;
|
|
15
|
+
}
|
|
16
|
+
function SmartLabel({ label }) {
|
|
17
|
+
if (!isPathLike(label)) return label;
|
|
18
|
+
const parts = label.split(DELIM_SPLIT);
|
|
19
|
+
const nodes = [];
|
|
20
|
+
for (let i = 0; i < parts.length; i++) {
|
|
21
|
+
const part = parts[i];
|
|
22
|
+
if (part === "") continue;
|
|
23
|
+
nodes.push(part);
|
|
24
|
+
if (i % 2 === 1) nodes.push(/* @__PURE__ */ jsx("wbr", {}, `wbr-${i}`));
|
|
25
|
+
}
|
|
26
|
+
return /* @__PURE__ */ jsx(Fragment, { children: nodes });
|
|
27
|
+
}
|
|
28
|
+
const DELIM_SPLIT = /([/\\\-_.:?#&=])/;
|
|
29
|
+
function isPathLike(text) {
|
|
30
|
+
if (!text) return false;
|
|
31
|
+
if (text.includes("://")) return true;
|
|
32
|
+
if (/^\.{0,2}\//.test(text)) return true;
|
|
33
|
+
if (/^[A-Za-z]:[\\/]/.test(text)) return true;
|
|
34
|
+
const forwardMatches = text.match(/[A-Za-z0-9]\/[A-Za-z0-9]/g);
|
|
35
|
+
if (forwardMatches && forwardMatches.length >= 2) return true;
|
|
36
|
+
const backMatches = text.match(/[A-Za-z0-9]\\[A-Za-z0-9]/g);
|
|
37
|
+
if (backMatches && backMatches.length >= 2) return true;
|
|
38
|
+
const hasDomainDot = /[A-Za-z0-9]\.[A-Za-z0-9]/.test(text);
|
|
39
|
+
const hasSlash = /[\\/]/.test(text);
|
|
40
|
+
if (hasDomainDot && hasSlash) return true;
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
function ChevronIcon() {
|
|
44
|
+
return /* @__PURE__ */ jsx(
|
|
45
|
+
"svg",
|
|
46
|
+
{
|
|
47
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
48
|
+
class: "h-icon-xs w-icon-xs text-muted shrink-0",
|
|
49
|
+
fill: "none",
|
|
50
|
+
viewBox: "0 0 24 24",
|
|
51
|
+
stroke: "currentColor",
|
|
52
|
+
"stroke-width": "2",
|
|
53
|
+
"aria-hidden": "true",
|
|
54
|
+
children: /* @__PURE__ */ jsx(
|
|
55
|
+
"path",
|
|
56
|
+
{
|
|
57
|
+
"stroke-linecap": "round",
|
|
58
|
+
"stroke-linejoin": "round",
|
|
59
|
+
d: "M9 5l7 7-7 7"
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
function HomeIcon() {
|
|
66
|
+
return /* @__PURE__ */ jsx(
|
|
67
|
+
"svg",
|
|
68
|
+
{
|
|
69
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
70
|
+
class: "h-[1.575rem] w-[1.575rem] shrink-0",
|
|
71
|
+
fill: "none",
|
|
72
|
+
viewBox: "0 0 24 24",
|
|
73
|
+
stroke: "currentColor",
|
|
74
|
+
"stroke-width": "2",
|
|
75
|
+
"aria-hidden": "true",
|
|
76
|
+
children: /* @__PURE__ */ jsx(
|
|
77
|
+
"path",
|
|
78
|
+
{
|
|
79
|
+
"stroke-linecap": "round",
|
|
80
|
+
"stroke-linejoin": "round",
|
|
81
|
+
d: "M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0a1 1 0 01-1-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 01-1 1h-2z"
|
|
82
|
+
}
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
function Breadcrumb(props) {
|
|
88
|
+
const items = props.items ?? (props.tree && props.currentId !== void 0 ? buildBreadcrumbItems(props.tree, props.currentId, props.homeHref ?? "/") : []);
|
|
89
|
+
if (items.length === 0) return null;
|
|
90
|
+
const nav = /* @__PURE__ */ jsx("nav", { class: "mb-vsp-md text-small", "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsx("ol", { class: "flex flex-wrap items-center gap-x-hsp-xs", children: items.map((item, i) => /* @__PURE__ */ jsxs("li", { class: "flex items-center gap-x-hsp-xs", children: [
|
|
91
|
+
i > 0 && /* @__PURE__ */ jsx(ChevronIcon, {}),
|
|
92
|
+
item.href ? /* @__PURE__ */ jsxs(
|
|
93
|
+
"a",
|
|
94
|
+
{
|
|
95
|
+
href: item.href,
|
|
96
|
+
class: "text-muted underline hover:text-fg flex items-center gap-x-hsp-2xs",
|
|
97
|
+
children: [
|
|
98
|
+
i === 0 && /* @__PURE__ */ jsx(HomeIcon, {}),
|
|
99
|
+
/* @__PURE__ */ jsx(SmartLabel, { label: item.label })
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
) : /* @__PURE__ */ jsx("span", { class: "text-fg", children: /* @__PURE__ */ jsx(SmartLabel, { label: item.label }) })
|
|
103
|
+
] }, `crumb-${i}`)) }) });
|
|
104
|
+
if (props.rightSlot === void 0) return nav;
|
|
105
|
+
return /* @__PURE__ */ jsxs("div", { class: "mb-vsp-sm flex flex-col items-start gap-vsp-xs sm:flex-row sm:items-center sm:justify-between [&_nav]:mb-0", children: [
|
|
106
|
+
nav,
|
|
107
|
+
props.rightSlot
|
|
108
|
+
] });
|
|
109
|
+
}
|
|
110
|
+
export {
|
|
111
|
+
Breadcrumb,
|
|
112
|
+
buildBreadcrumbItems
|
|
113
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BreadcrumbNode, SidebarNode } from './types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Walk the sidebar tree and return the chain of nodes from the root
|
|
5
|
+
* level down to (and including) the node whose `id` matches `targetId`.
|
|
6
|
+
*
|
|
7
|
+
* Returns an empty array when no node matches. Pure: never mutates the
|
|
8
|
+
* input tree, never reads anything outside of it.
|
|
9
|
+
*
|
|
10
|
+
* Used by the breadcrumb component to derive the current page's
|
|
11
|
+
* ancestry. The home/root crumb is the renderer's responsibility — this
|
|
12
|
+
* helper deals strictly with the tree itself.
|
|
13
|
+
*/
|
|
14
|
+
declare function findPath<T extends BreadcrumbNode = SidebarNode>(nodes: readonly T[], targetId: string): T[];
|
|
15
|
+
|
|
16
|
+
export { findPath };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
function findPath(nodes, targetId) {
|
|
2
|
+
for (const node of nodes) {
|
|
3
|
+
if (node.id === targetId) return [node];
|
|
4
|
+
if (node.children && node.children.length > 0) {
|
|
5
|
+
const sub = findPath(node.children, targetId);
|
|
6
|
+
if (sub.length > 0) return [node, ...sub];
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return [];
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
findPath
|
|
13
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type contract for the breadcrumb component.
|
|
3
|
+
*
|
|
4
|
+
* Breadcrumb only walks the tree to find an ancestor chain — it does not
|
|
5
|
+
* need the full SidebarNode shape from sidebar-tree. We declare a minimal
|
|
6
|
+
* structural interface here. The canonical SidebarNode (from sidebar-tree)
|
|
7
|
+
* is structurally assignable to this, so callers can pass either shape
|
|
8
|
+
* unchanged.
|
|
9
|
+
*/
|
|
10
|
+
interface BreadcrumbNode {
|
|
11
|
+
type: "doc" | "category";
|
|
12
|
+
id: string;
|
|
13
|
+
label: string;
|
|
14
|
+
href?: string;
|
|
15
|
+
sidebar_position?: number;
|
|
16
|
+
children?: readonly BreadcrumbNode[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Backward-compatible alias retained for callers that previously imported
|
|
20
|
+
* `SidebarNode` from this subpath.
|
|
21
|
+
*/
|
|
22
|
+
type SidebarNode = BreadcrumbNode;
|
|
23
|
+
/**
|
|
24
|
+
* One rung of the breadcrumb trail. `href` is omitted on the final
|
|
25
|
+
* (current-page) item so the renderer can present it as plain text.
|
|
26
|
+
*/
|
|
27
|
+
interface BreadcrumbItem {
|
|
28
|
+
label: string;
|
|
29
|
+
href?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type { BreadcrumbItem, BreadcrumbNode, SidebarNode };
|
|
File without changes
|