@takazudo/zudo-doc 2.5.0 → 2.5.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.
- package/dist/desktop-sidebar-toggle-island/index.d.ts +2 -0
- package/dist/desktop-sidebar-toggle-island/index.js +3 -1
- package/dist/doc-page-shell/index.js +15 -3
- package/dist/integrations/claude-resources/generate.js +0 -2
- package/dist/sidebar-prepaint/index.d.ts +27 -1
- package/dist/sidebar-prepaint/index.js +33 -13
- package/dist/url-helpers/index.js +5 -3
- package/eject/desktop-sidebar-toggle-island/index.tsx +7 -2
- package/package.json +2 -2
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export declare const SIDEBAR_STORAGE_KEY = "zudo-doc-sidebar-visible";
|
|
2
|
+
export declare function readState(): boolean;
|
|
3
|
+
export declare function setDataAttribute(isVisible: boolean): void;
|
|
2
4
|
export declare function DesktopSidebarToggle(): import("preact").JSX.Element;
|
|
3
5
|
export declare namespace DesktopSidebarToggle {
|
|
4
6
|
var displayName: string;
|
|
@@ -4,7 +4,10 @@ import { DocLayoutWithDefaults } from "../doclayout/index.js";
|
|
|
4
4
|
import { Toc, MobileToc, getTocTitle } from "../toc/index.js";
|
|
5
5
|
import { Breadcrumb } from "../breadcrumb/index.js";
|
|
6
6
|
import { NavCardGrid } from "../nav-indexing/index.js";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
createSidebarPrepaint,
|
|
9
|
+
createSidebarVisibilityPrepaint
|
|
10
|
+
} from "../sidebar-prepaint/index.js";
|
|
8
11
|
import { createHeadWithDefaults } from "../head-with-defaults/index.js";
|
|
9
12
|
import { createSidebarWithDefaults } from "../sidebar-with-defaults/index.js";
|
|
10
13
|
import { createHeaderWithDefaults } from "../header-with-defaults/index.js";
|
|
@@ -21,8 +24,14 @@ function createDocPageShell(ctx) {
|
|
|
21
24
|
const SidebarWithDefaults = createSidebarWithDefaults(ctx);
|
|
22
25
|
const HeaderWithDefaults = createHeaderWithDefaults(ctx);
|
|
23
26
|
const FooterWithDefaults = createFooterWithDefaults(ctx);
|
|
27
|
+
const sidebarToggleEnabled = Boolean(
|
|
28
|
+
ctx.settings.sidebarToggle
|
|
29
|
+
);
|
|
24
30
|
const SidebarPrepaint = createSidebarPrepaint({
|
|
25
|
-
sidebarToggle:
|
|
31
|
+
sidebarToggle: sidebarToggleEnabled
|
|
32
|
+
});
|
|
33
|
+
const SidebarVisibilityPrepaint = createSidebarVisibilityPrepaint({
|
|
34
|
+
sidebarToggle: sidebarToggleEnabled
|
|
26
35
|
});
|
|
27
36
|
const DocBodyEnd = createDocBodyEnd(ctx);
|
|
28
37
|
const DocPager = createDocPager(ctx);
|
|
@@ -69,7 +78,10 @@ function createDocPageShell(ctx) {
|
|
|
69
78
|
{
|
|
70
79
|
title: composeMetaTitle(title),
|
|
71
80
|
description: settings.metaTags.description ? description : void 0,
|
|
72
|
-
head: /* @__PURE__ */
|
|
81
|
+
head: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
82
|
+
/* @__PURE__ */ jsx(HeadWithDefaults, { title, description, canonical }),
|
|
83
|
+
/* @__PURE__ */ jsx(SidebarVisibilityPrepaint, { hideSidebar })
|
|
84
|
+
] }),
|
|
73
85
|
lang: locale,
|
|
74
86
|
noindex: settings.noindex,
|
|
75
87
|
hideSidebar,
|
|
@@ -8,10 +8,36 @@ export interface SidebarPrepaintProps {
|
|
|
8
8
|
*/
|
|
9
9
|
hideSidebar?: boolean;
|
|
10
10
|
}
|
|
11
|
-
/** Settings subset read by
|
|
11
|
+
/** Settings subset read by the sidebar-prepaint factories. */
|
|
12
12
|
export interface SidebarPrepaintSettings {
|
|
13
13
|
sidebarToggle?: boolean;
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Pre-paint inline script body: restore persisted sidebar visibility to
|
|
17
|
+
* `<html data-sidebar-hidden>` before first paint to avoid a hard-reload flash.
|
|
18
|
+
*
|
|
19
|
+
* A tiny synchronous IIFE that reads `localStorage[SIDEBAR_STORAGE_KEY]` and
|
|
20
|
+
* sets `data-sidebar-hidden` only when the stored value is exactly "false"
|
|
21
|
+
* (the collapsed preference) — the default (visible) needs no attribute and
|
|
22
|
+
* causes no layout shift. Silently no-ops in privacy / disabled-storage modes.
|
|
23
|
+
*
|
|
24
|
+
* The storage key is interpolated from `SIDEBAR_STORAGE_KEY` so it stays in
|
|
25
|
+
* sync with the island's reader; the `data-sidebar-hidden` attribute name is a
|
|
26
|
+
* literal here (the island's `setDataAttribute` hardcodes the same literal —
|
|
27
|
+
* keep the two in sync). Intended for `<head>` placement so it executes before
|
|
28
|
+
* the `<aside>` sidebar is painted.
|
|
29
|
+
*/
|
|
30
|
+
export declare const SIDEBAR_VISIBILITY_PREPAINT_SCRIPT: string;
|
|
31
|
+
/**
|
|
32
|
+
* Create a `SidebarVisibilityPrepaint` component bound to the host's settings.
|
|
33
|
+
*
|
|
34
|
+
* Returns the pre-paint `<script>` (for the page `<head>`) when
|
|
35
|
+
* `settings.sidebarToggle` is enabled AND the page actually shows a sidebar;
|
|
36
|
+
* returns `undefined` when the toggle is disabled or the page hides the sidebar
|
|
37
|
+
* — the SAME gating as {@link createSidebarPrepaint}, so the head script and
|
|
38
|
+
* the afterSidebar toggle button always appear together.
|
|
39
|
+
*/
|
|
40
|
+
export declare function createSidebarVisibilityPrepaint(settings: SidebarPrepaintSettings): (props: SidebarPrepaintProps) => JSX.Element | undefined;
|
|
15
41
|
/**
|
|
16
42
|
* Create a `SidebarPrepaint` component bound to the host's settings.
|
|
17
43
|
*
|
|
@@ -1,23 +1,43 @@
|
|
|
1
|
-
import { Fragment, jsx
|
|
1
|
+
import { Fragment, jsx } from "preact/jsx-runtime";
|
|
2
2
|
import { Island } from "@takazudo/zfb";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
DesktopSidebarToggle,
|
|
5
|
+
SIDEBAR_STORAGE_KEY
|
|
6
|
+
} from "../desktop-sidebar-toggle-island/index.js";
|
|
7
|
+
function sidebarPrepaintActive(settings, hideSidebar) {
|
|
8
|
+
return Boolean(settings.sidebarToggle) && !hideSidebar;
|
|
9
|
+
}
|
|
10
|
+
const SIDEBAR_VISIBILITY_PREPAINT_SCRIPT = `(function(){try{if(localStorage.getItem(${JSON.stringify(
|
|
11
|
+
SIDEBAR_STORAGE_KEY
|
|
12
|
+
)})==='false'){document.documentElement.setAttribute('data-sidebar-hidden','');}}catch(e){}})();`;
|
|
13
|
+
function createSidebarVisibilityPrepaint(settings) {
|
|
14
|
+
function SidebarVisibilityPrepaint({
|
|
15
|
+
hideSidebar
|
|
16
|
+
}) {
|
|
17
|
+
if (!sidebarPrepaintActive(settings, hideSidebar)) return void 0;
|
|
18
|
+
return /* @__PURE__ */ jsx(
|
|
19
|
+
"script",
|
|
20
|
+
{
|
|
21
|
+
dangerouslySetInnerHTML: { __html: SIDEBAR_VISIBILITY_PREPAINT_SCRIPT }
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
return SidebarVisibilityPrepaint;
|
|
26
|
+
}
|
|
4
27
|
function createSidebarPrepaint(settings) {
|
|
5
28
|
function SidebarPrepaint({
|
|
6
29
|
hideSidebar
|
|
7
30
|
}) {
|
|
8
|
-
if (!settings
|
|
9
|
-
return /* @__PURE__ */
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Island({
|
|
14
|
-
when: "load",
|
|
15
|
-
children: /* @__PURE__ */ jsx(DesktopSidebarToggle, {})
|
|
16
|
-
})
|
|
17
|
-
] });
|
|
31
|
+
if (!sidebarPrepaintActive(settings, hideSidebar)) return void 0;
|
|
32
|
+
return /* @__PURE__ */ jsx(Fragment, { children: Island({
|
|
33
|
+
when: "load",
|
|
34
|
+
children: /* @__PURE__ */ jsx(DesktopSidebarToggle, {})
|
|
35
|
+
}) });
|
|
18
36
|
}
|
|
19
37
|
return SidebarPrepaint;
|
|
20
38
|
}
|
|
21
39
|
export {
|
|
22
|
-
|
|
40
|
+
SIDEBAR_VISIBILITY_PREPAINT_SCRIPT,
|
|
41
|
+
createSidebarPrepaint,
|
|
42
|
+
createSidebarVisibilityPrepaint
|
|
23
43
|
};
|
|
@@ -25,7 +25,8 @@ function makeUrlHelpers(settings, i18n) {
|
|
|
25
25
|
return settings.siteUrl ? settings.siteUrl.replace(/\/$/, "") + pageUrl : void 0;
|
|
26
26
|
}
|
|
27
27
|
function docsUrl(slug, lang = defaultLocale) {
|
|
28
|
-
const
|
|
28
|
+
const defaultPath = `/docs/${slug}`;
|
|
29
|
+
const path = lang === defaultLocale || isDefaultLocaleOnlyPath(defaultPath) ? defaultPath : `/${lang}/docs/${slug}`;
|
|
29
30
|
return withBase(path);
|
|
30
31
|
}
|
|
31
32
|
function isExternal(href) {
|
|
@@ -35,7 +36,7 @@ function makeUrlHelpers(settings, i18n) {
|
|
|
35
36
|
return isExternal(href) ? href : withBase(href);
|
|
36
37
|
}
|
|
37
38
|
function navHref(path, lang, currentVersion) {
|
|
38
|
-
const isNonDefaultLocale = lang != null && lang !== defaultLocale;
|
|
39
|
+
const isNonDefaultLocale = lang != null && lang !== defaultLocale && !isDefaultLocaleOnlyPath(path);
|
|
39
40
|
const versionPrefix = currentVersion ? `/v/${currentVersion}` : "";
|
|
40
41
|
return withBase(
|
|
41
42
|
isNonDefaultLocale ? `${versionPrefix}/${lang}${path}` : `${versionPrefix}${path}`
|
|
@@ -82,7 +83,8 @@ function makeUrlHelpers(settings, i18n) {
|
|
|
82
83
|
}));
|
|
83
84
|
}
|
|
84
85
|
function versionedDocsUrl(slug, versionSlug, lang = defaultLocale) {
|
|
85
|
-
const
|
|
86
|
+
const localePrefixed = lang !== defaultLocale && !isDefaultLocaleOnlyPath(`/docs/${slug}`);
|
|
87
|
+
const path = localePrefixed ? `/v/${versionSlug}/${lang}/docs/${slug}` : `/v/${versionSlug}/docs/${slug}`;
|
|
86
88
|
return withBase(path);
|
|
87
89
|
}
|
|
88
90
|
return {
|
|
@@ -8,7 +8,12 @@ import { AFTER_NAVIGATE_EVENT } from "../transitions/index.js";
|
|
|
8
8
|
|
|
9
9
|
export const SIDEBAR_STORAGE_KEY = "zudo-doc-sidebar-visible";
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
// Exported for unit testing the mount-reconcile logic in a plain Node env
|
|
12
|
+
// (no jsdom in the package vitest config) — the same convention the sibling
|
|
13
|
+
// ThemeToggle uses via color-scheme-sync.ts. `readState` is the localStorage
|
|
14
|
+
// reader the mount effect uses to reconcile `visible` on initial load;
|
|
15
|
+
// `setDataAttribute` is the `<html data-sidebar-hidden>` writer.
|
|
16
|
+
export function readState(): boolean {
|
|
12
17
|
if (typeof window === "undefined") return true;
|
|
13
18
|
try {
|
|
14
19
|
return localStorage.getItem(SIDEBAR_STORAGE_KEY) !== "false";
|
|
@@ -17,7 +22,7 @@ function readState(): boolean {
|
|
|
17
22
|
}
|
|
18
23
|
}
|
|
19
24
|
|
|
20
|
-
function setDataAttribute(isVisible: boolean) {
|
|
25
|
+
export function setDataAttribute(isVisible: boolean) {
|
|
21
26
|
if (isVisible) {
|
|
22
27
|
document.documentElement.removeAttribute("data-sidebar-hidden");
|
|
23
28
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@takazudo/zudo-doc",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "zudo-doc framework primitives layer that sits on top of zfb's engine — sidebar, theme, TOC, breadcrumb, layouts, head injection, View Transitions, SSR-skip wrappers (per ADR-003).",
|
|
6
6
|
"license": "MIT",
|
|
@@ -586,7 +586,7 @@
|
|
|
586
586
|
"zod": "^4.3.6",
|
|
587
587
|
"@takazudo/zfb": "0.1.0-next.76",
|
|
588
588
|
"@takazudo/zfb-runtime": "0.1.0-next.76",
|
|
589
|
-
"@takazudo/zudo-doc-history-server": "2.5.
|
|
589
|
+
"@takazudo/zudo-doc-history-server": "2.5.1"
|
|
590
590
|
},
|
|
591
591
|
"scripts": {
|
|
592
592
|
"build": "tsup && tsc -p tsconfig.build.json",
|