@takazudo/zudo-doc 3.2.0 → 3.3.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 +29 -0
- package/dist/chrome/derive.d.ts +7 -1
- package/dist/chrome/derive.js +13 -2
- package/dist/chrome-bindings.d.ts +159 -0
- package/dist/chrome-bindings.js +6 -0
- package/dist/color-scheme-utils.d.ts +1 -1
- package/dist/color-schemes-defaults/index.d.ts +23 -0
- package/dist/color-schemes-defaults/index.js +121 -0
- package/dist/config.d.ts +443 -0
- package/dist/config.js +116 -0
- package/dist/design-token-panel-bootstrap.d.ts +57 -7
- package/dist/design-token-panel-bootstrap.js +12 -0
- package/dist/design-token-panel-config/index.d.ts +49 -0
- package/dist/design-token-panel-config/index.js +214 -0
- package/dist/design-token-panel-config/manifest.d.ts +46 -0
- package/dist/design-token-panel-config/manifest.js +105 -0
- package/dist/directive-vocabulary-defaults/index.d.ts +16 -0
- package/dist/directive-vocabulary-defaults/index.js +12 -0
- package/dist/doc-body-end-islands/index.d.ts +30 -7
- package/dist/doc-body-end-islands/index.js +27 -0
- package/dist/docs-schema/index.d.ts +67 -0
- package/dist/docs-schema/index.js +47 -0
- package/dist/factory-context/index.d.ts +14 -0
- package/dist/features.css +10 -0
- package/dist/find-in-page/find-bar.d.ts +9 -0
- package/dist/find-in-page/find-bar.js +114 -0
- package/dist/find-in-page/find-in-page.d.ts +17 -0
- package/dist/find-in-page/find-in-page.js +131 -0
- package/dist/find-in-page/index.d.ts +11 -0
- package/dist/find-in-page/index.js +49 -0
- package/dist/frontmatter-preview-defaults/index.d.ts +16 -0
- package/dist/frontmatter-preview-defaults/index.js +25 -0
- package/dist/i18n-defaults/index.d.ts +22 -0
- package/dist/i18n-defaults/index.js +167 -0
- package/dist/plugins/routes.js +44 -20
- package/dist/preset.d.ts +9 -0
- package/dist/routes/_chrome.js +2 -1
- package/dist/safelist.css +1 -1
- package/dist/settings.d.ts +37 -0
- package/dist/theme.css +319 -0
- package/dist/z-index-defaults/index.d.ts +45 -0
- package/dist/z-index-defaults/index.js +34 -0
- package/package.json +50 -3
- package/routes-src/_chrome.tsx +30 -8
- package/routes-src/_virtual.d.ts +34 -2
- package/tsconfig.base.json +29 -0
- package/virtual-modules.d.ts +79 -0
- package/zfb-config-shim.d.ts +188 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
function buildTagsSchema(opts) {
|
|
3
|
+
const vocabulary = opts?.tagVocabulary ?? [];
|
|
4
|
+
const vocabularyActive = vocabulary.length > 0 && opts?.tagGovernance === "strict";
|
|
5
|
+
if (!vocabularyActive) return z.array(z.string()).optional();
|
|
6
|
+
const allowed = /* @__PURE__ */ new Set();
|
|
7
|
+
for (const entry of vocabulary) {
|
|
8
|
+
allowed.add(entry.id);
|
|
9
|
+
for (const alias of entry.aliases ?? []) allowed.add(alias);
|
|
10
|
+
}
|
|
11
|
+
const allowedList = [...allowed];
|
|
12
|
+
if (allowedList.length === 0) return z.array(z.string()).optional();
|
|
13
|
+
const [first, ...rest] = allowedList;
|
|
14
|
+
return z.array(z.enum([first, ...rest])).optional();
|
|
15
|
+
}
|
|
16
|
+
function buildDocsSchema(opts) {
|
|
17
|
+
return z.object({
|
|
18
|
+
title: z.string(),
|
|
19
|
+
description: z.string().optional(),
|
|
20
|
+
category: z.string().optional(),
|
|
21
|
+
sidebar_position: z.number().optional(),
|
|
22
|
+
sidebar_label: z.string().optional(),
|
|
23
|
+
tags: buildTagsSchema(opts),
|
|
24
|
+
search_exclude: z.boolean().optional(),
|
|
25
|
+
pagination_next: z.string().nullable().optional(),
|
|
26
|
+
pagination_prev: z.string().nullable().optional(),
|
|
27
|
+
draft: z.boolean().optional(),
|
|
28
|
+
unlisted: z.boolean().optional(),
|
|
29
|
+
hide_sidebar: z.boolean().optional(),
|
|
30
|
+
hide_toc: z.boolean().optional(),
|
|
31
|
+
wide: z.boolean().optional(),
|
|
32
|
+
doc_history: z.boolean().optional(),
|
|
33
|
+
standalone: z.boolean().optional(),
|
|
34
|
+
slug: z.string().optional(),
|
|
35
|
+
generated: z.boolean().optional(),
|
|
36
|
+
// Category metadata expressed as a directory index.mdx's frontmatter — the
|
|
37
|
+
// frontmatter form of `_category_.json`. `category_no_page` makes the index
|
|
38
|
+
// a non-linked sidebar header excluded from routes/sitemap/search;
|
|
39
|
+
// `category_sort_order` sets the child sort direction. Frontmatter wins
|
|
40
|
+
// over the sidecar.
|
|
41
|
+
category_no_page: z.boolean().optional(),
|
|
42
|
+
category_sort_order: z.enum(["asc", "desc"]).optional()
|
|
43
|
+
}).passthrough();
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
buildDocsSchema
|
|
47
|
+
};
|
|
@@ -221,6 +221,20 @@ export interface ChromeHostBindings {
|
|
|
221
221
|
BodyEndIslands?: FactoryComponent;
|
|
222
222
|
/** DocHistory island. Default: a no-op stub rendering an empty fragment. */
|
|
223
223
|
DocHistory?: FactoryComponent;
|
|
224
|
+
/**
|
|
225
|
+
* Design-token panel bootstrap island (#2658). Default: the PACKAGE-DEFAULT
|
|
226
|
+
* `DesignTokenPanelBootstrap` from
|
|
227
|
+
* `@takazudo/zudo-doc/design-token-panel-bootstrap`, statically imported by
|
|
228
|
+
* `chrome/derive.tsx` (`deriveBodyEndIslands`) so EVERY `createChrome`
|
|
229
|
+
* consumer — the injected `routes/_chrome.tsx` path and the locked-manifest
|
|
230
|
+
* self-contained doc stub alike — gets the settings-gated panel island with
|
|
231
|
+
* no explicit wiring (#2659 gate-2 fix; scanner reachability holds through
|
|
232
|
+
* the static route → chrome → derive → bootstrap chain, the #2480
|
|
233
|
+
* contract). Supply this slot only to REPLACE the island with a host's own
|
|
234
|
+
* bootstrap component. Mounting is still gated on
|
|
235
|
+
* `settings.designTokenPanel` inside `createBodyEndIslands` either way.
|
|
236
|
+
*/
|
|
237
|
+
DesignTokenPanelBootstrap?: FactoryComponent;
|
|
224
238
|
/** MDX content-component overrides (Details / HtmlPreview / Island /
|
|
225
239
|
* PresetGenerator). Default: package SSR impls + a `PresetGenerator` stub. */
|
|
226
240
|
mdxExtras?: Record<string, FactoryComponent>;
|
package/dist/features.css
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* --spacing-{hsp-sm,hsp-2xs,hsp-lg,hsp-md,hsp-xl,vsp-xs,vsp-2xs,vsp-md,
|
|
15
15
|
* icon-sm}
|
|
16
16
|
* --z-index-local-1
|
|
17
|
+
* --z-index-toolbar
|
|
17
18
|
* --radius-{DEFAULT,lg}
|
|
18
19
|
* --font-{mono,sans}
|
|
19
20
|
* --text-{small,caption}
|
|
@@ -28,6 +29,15 @@
|
|
|
28
29
|
* pre-condition before @importing this file).
|
|
29
30
|
* ─────────────────────────────────────────────────────────────────────────── */
|
|
30
31
|
|
|
32
|
+
/* ========================================
|
|
33
|
+
* Shared chrome defaults
|
|
34
|
+
* ======================================== */
|
|
35
|
+
|
|
36
|
+
header[data-header] {
|
|
37
|
+
background-color: var(--color-surface, var(--color-bg));
|
|
38
|
+
z-index: var(--z-index-toolbar, 20);
|
|
39
|
+
}
|
|
40
|
+
|
|
31
41
|
/* ========================================
|
|
32
42
|
* Code block buttons (copy + word wrap)
|
|
33
43
|
* ======================================== */
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FindInPage } from "./find-in-page.js";
|
|
2
|
+
interface FindBarProps {
|
|
3
|
+
visible: boolean;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
findInPage: FindInPage;
|
|
6
|
+
containerSelector: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function FindBar({ visible, onClose, findInPage, containerSelector }: FindBarProps): import("preact").JSX.Element | null;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "preact/jsx-runtime";
|
|
3
|
+
import { useState, useRef, useEffect, useCallback } from "preact/hooks";
|
|
4
|
+
function toMatchInfo(result) {
|
|
5
|
+
return result.matches > 0 ? result : null;
|
|
6
|
+
}
|
|
7
|
+
function FindBar({ visible, onClose, findInPage, containerSelector }) {
|
|
8
|
+
const [query, setQuery] = useState("");
|
|
9
|
+
const [matchInfo, setMatchInfo] = useState(null);
|
|
10
|
+
const inputRef = useRef(null);
|
|
11
|
+
const findInPageRef = useRef(findInPage);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
findInPageRef.current = findInPage;
|
|
14
|
+
}, [findInPage]);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (visible) {
|
|
17
|
+
inputRef.current?.focus();
|
|
18
|
+
inputRef.current?.select();
|
|
19
|
+
}
|
|
20
|
+
}, [visible]);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (!visible) {
|
|
23
|
+
setQuery("");
|
|
24
|
+
setMatchInfo(null);
|
|
25
|
+
findInPageRef.current.stop();
|
|
26
|
+
}
|
|
27
|
+
}, [visible]);
|
|
28
|
+
const handleFind = useCallback(
|
|
29
|
+
(text) => {
|
|
30
|
+
const container = document.querySelector(containerSelector);
|
|
31
|
+
if (!text || !(container instanceof HTMLElement)) {
|
|
32
|
+
setMatchInfo(null);
|
|
33
|
+
findInPage.stop();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const result = findInPage.find(container, text);
|
|
37
|
+
setMatchInfo(toMatchInfo(result));
|
|
38
|
+
},
|
|
39
|
+
[findInPage, containerSelector]
|
|
40
|
+
);
|
|
41
|
+
const handleKeyDown = useCallback(
|
|
42
|
+
// Plain DOM `KeyboardEvent` — matches the ai-chat-modal onKeyDown
|
|
43
|
+
// precedent (`../ai-chat-modal/index.tsx`); Preact's JSX
|
|
44
|
+
// `onKeyDown` prop accepts it directly, no React-namespace type needed.
|
|
45
|
+
(e) => {
|
|
46
|
+
if (e.key === "Escape") {
|
|
47
|
+
onClose();
|
|
48
|
+
} else if (e.key === "Enter") {
|
|
49
|
+
const result = e.shiftKey ? findInPage.prev() : findInPage.next();
|
|
50
|
+
setMatchInfo(toMatchInfo(result));
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
[onClose, findInPage]
|
|
54
|
+
);
|
|
55
|
+
if (!visible) return null;
|
|
56
|
+
return /* @__PURE__ */ jsxs("div", { className: "fixed top-[3.5rem] right-0 z-dropdown flex items-center gap-hsp-sm py-hsp-xs px-hsp-md bg-surface border-b border-l border-muted rounded-bl-lg shadow-md", children: [
|
|
57
|
+
/* @__PURE__ */ jsx(
|
|
58
|
+
"input",
|
|
59
|
+
{
|
|
60
|
+
ref: inputRef,
|
|
61
|
+
className: "w-48 py-[4px] px-hsp-sm rounded text-small bg-bg border border-muted text-fg outline-none focus:border-accent",
|
|
62
|
+
type: "text",
|
|
63
|
+
value: query,
|
|
64
|
+
placeholder: "Find in page...",
|
|
65
|
+
"aria-label": "Find in page",
|
|
66
|
+
onChange: (e) => {
|
|
67
|
+
setQuery(e.currentTarget.value);
|
|
68
|
+
handleFind(e.currentTarget.value);
|
|
69
|
+
},
|
|
70
|
+
onKeyDown: handleKeyDown
|
|
71
|
+
}
|
|
72
|
+
),
|
|
73
|
+
/* @__PURE__ */ jsx("span", { className: "text-caption whitespace-nowrap min-w-[3rem] text-center text-fg/60", children: matchInfo ? `${matchInfo.activeMatchOrdinal}/${matchInfo.matches}` : "" }),
|
|
74
|
+
/* @__PURE__ */ jsx(
|
|
75
|
+
"button",
|
|
76
|
+
{
|
|
77
|
+
type: "button",
|
|
78
|
+
className: "py-hsp-2xs px-hsp-sm rounded text-caption bg-bg border border-muted text-fg hover:bg-surface",
|
|
79
|
+
onClick: () => {
|
|
80
|
+
const result = findInPage.prev();
|
|
81
|
+
setMatchInfo(toMatchInfo(result));
|
|
82
|
+
},
|
|
83
|
+
title: "Previous (Shift+Enter)",
|
|
84
|
+
children: "Prev"
|
|
85
|
+
}
|
|
86
|
+
),
|
|
87
|
+
/* @__PURE__ */ jsx(
|
|
88
|
+
"button",
|
|
89
|
+
{
|
|
90
|
+
type: "button",
|
|
91
|
+
className: "py-hsp-2xs px-hsp-sm rounded text-caption bg-bg border border-muted text-fg hover:bg-surface",
|
|
92
|
+
onClick: () => {
|
|
93
|
+
const result = findInPage.next();
|
|
94
|
+
setMatchInfo(toMatchInfo(result));
|
|
95
|
+
},
|
|
96
|
+
title: "Next (Enter)",
|
|
97
|
+
children: "Next"
|
|
98
|
+
}
|
|
99
|
+
),
|
|
100
|
+
/* @__PURE__ */ jsx(
|
|
101
|
+
"button",
|
|
102
|
+
{
|
|
103
|
+
type: "button",
|
|
104
|
+
className: "py-hsp-2xs px-hsp-sm rounded text-caption bg-bg border border-muted text-fg hover:bg-surface",
|
|
105
|
+
onClick: onClose,
|
|
106
|
+
title: "Close (Esc)",
|
|
107
|
+
children: "Close"
|
|
108
|
+
}
|
|
109
|
+
)
|
|
110
|
+
] });
|
|
111
|
+
}
|
|
112
|
+
export {
|
|
113
|
+
FindBar
|
|
114
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface FindResult {
|
|
2
|
+
matches: number;
|
|
3
|
+
activeMatchOrdinal: number;
|
|
4
|
+
}
|
|
5
|
+
export interface FindInPage {
|
|
6
|
+
find(container: HTMLElement, query: string): FindResult;
|
|
7
|
+
next(): FindResult;
|
|
8
|
+
prev(): FindResult;
|
|
9
|
+
stop(): void;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Create a DOM-based find-in-page utility.
|
|
13
|
+
*
|
|
14
|
+
* Limitation: only matches within single text nodes. Cross-element matching
|
|
15
|
+
* (e.g. "Hello world" spanning `<strong>Hello</strong> world`) is not supported.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createFindInPage(): FindInPage;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
const MATCH_CLASS = "find-match";
|
|
2
|
+
const ACTIVE_CLASS = "find-match-active";
|
|
3
|
+
const MATCH_ATTR = "data-find-match";
|
|
4
|
+
const ACTIVE_ATTR = "data-find-active";
|
|
5
|
+
const EMPTY_RESULT = Object.freeze({ matches: 0, activeMatchOrdinal: 0 });
|
|
6
|
+
function createFindInPage() {
|
|
7
|
+
let matchElements = [];
|
|
8
|
+
let activeIndex = -1;
|
|
9
|
+
function clearMarks() {
|
|
10
|
+
const parentsToNormalize = /* @__PURE__ */ new Set();
|
|
11
|
+
for (let i = matchElements.length - 1; i >= 0; i--) {
|
|
12
|
+
const mark = matchElements[i];
|
|
13
|
+
const parent = mark.parentNode;
|
|
14
|
+
if (parent) {
|
|
15
|
+
const textNode = document.createTextNode(mark.textContent || "");
|
|
16
|
+
parent.replaceChild(textNode, mark);
|
|
17
|
+
parentsToNormalize.add(parent);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
for (const parent of parentsToNormalize) {
|
|
21
|
+
parent.normalize();
|
|
22
|
+
}
|
|
23
|
+
matchElements = [];
|
|
24
|
+
activeIndex = -1;
|
|
25
|
+
}
|
|
26
|
+
function setActive(index) {
|
|
27
|
+
if (activeIndex >= 0 && activeIndex < matchElements.length) {
|
|
28
|
+
const prev2 = matchElements[activeIndex];
|
|
29
|
+
prev2.classList.remove(ACTIVE_CLASS);
|
|
30
|
+
prev2.removeAttribute(ACTIVE_ATTR);
|
|
31
|
+
}
|
|
32
|
+
activeIndex = index;
|
|
33
|
+
if (activeIndex >= 0 && activeIndex < matchElements.length) {
|
|
34
|
+
const current = matchElements[activeIndex];
|
|
35
|
+
current.classList.add(ACTIVE_CLASS);
|
|
36
|
+
current.setAttribute(ACTIVE_ATTR, "true");
|
|
37
|
+
current.scrollIntoView?.({ block: "center" });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function currentResult() {
|
|
41
|
+
if (matchElements.length === 0) {
|
|
42
|
+
return EMPTY_RESULT;
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
matches: matchElements.length,
|
|
46
|
+
activeMatchOrdinal: activeIndex + 1
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function find(container, query) {
|
|
50
|
+
clearMarks();
|
|
51
|
+
if (!query) {
|
|
52
|
+
return EMPTY_RESULT;
|
|
53
|
+
}
|
|
54
|
+
const lowerQuery = query.toLowerCase();
|
|
55
|
+
const walker = document.createTreeWalker(
|
|
56
|
+
container,
|
|
57
|
+
NodeFilter.SHOW_TEXT,
|
|
58
|
+
null
|
|
59
|
+
);
|
|
60
|
+
const textNodes = [];
|
|
61
|
+
let node;
|
|
62
|
+
while (node = walker.nextNode()) {
|
|
63
|
+
textNodes.push(node);
|
|
64
|
+
}
|
|
65
|
+
for (const textNode of textNodes) {
|
|
66
|
+
const text = textNode.textContent || "";
|
|
67
|
+
const lowerText = text.toLowerCase();
|
|
68
|
+
const positions = [];
|
|
69
|
+
let searchFrom = 0;
|
|
70
|
+
while (searchFrom < lowerText.length) {
|
|
71
|
+
const idx = lowerText.indexOf(lowerQuery, searchFrom);
|
|
72
|
+
if (idx === -1) break;
|
|
73
|
+
positions.push(idx);
|
|
74
|
+
searchFrom = idx + lowerQuery.length;
|
|
75
|
+
}
|
|
76
|
+
if (positions.length === 0) continue;
|
|
77
|
+
const parent = textNode.parentNode;
|
|
78
|
+
if (!parent) continue;
|
|
79
|
+
let remainingNode = textNode;
|
|
80
|
+
const nodeMarks = [];
|
|
81
|
+
for (let i = positions.length - 1; i >= 0; i--) {
|
|
82
|
+
const pos = positions[i];
|
|
83
|
+
const matchLen = query.length;
|
|
84
|
+
if (pos + matchLen < remainingNode.length) {
|
|
85
|
+
remainingNode.splitText(pos + matchLen);
|
|
86
|
+
}
|
|
87
|
+
let matchNode;
|
|
88
|
+
if (pos > 0) {
|
|
89
|
+
matchNode = remainingNode.splitText(pos);
|
|
90
|
+
} else {
|
|
91
|
+
matchNode = remainingNode;
|
|
92
|
+
}
|
|
93
|
+
const mark = document.createElement("mark");
|
|
94
|
+
mark.className = MATCH_CLASS;
|
|
95
|
+
mark.setAttribute(MATCH_ATTR, "true");
|
|
96
|
+
mark.textContent = matchNode.textContent;
|
|
97
|
+
parent.replaceChild(mark, matchNode);
|
|
98
|
+
nodeMarks.unshift(mark);
|
|
99
|
+
}
|
|
100
|
+
matchElements.push(...nodeMarks);
|
|
101
|
+
}
|
|
102
|
+
if (matchElements.length === 0) {
|
|
103
|
+
return EMPTY_RESULT;
|
|
104
|
+
}
|
|
105
|
+
setActive(0);
|
|
106
|
+
return currentResult();
|
|
107
|
+
}
|
|
108
|
+
function next() {
|
|
109
|
+
if (matchElements.length === 0) {
|
|
110
|
+
return EMPTY_RESULT;
|
|
111
|
+
}
|
|
112
|
+
const newIndex = (activeIndex + 1) % matchElements.length;
|
|
113
|
+
setActive(newIndex);
|
|
114
|
+
return currentResult();
|
|
115
|
+
}
|
|
116
|
+
function prev() {
|
|
117
|
+
if (matchElements.length === 0) {
|
|
118
|
+
return EMPTY_RESULT;
|
|
119
|
+
}
|
|
120
|
+
const newIndex = (activeIndex - 1 + matchElements.length) % matchElements.length;
|
|
121
|
+
setActive(newIndex);
|
|
122
|
+
return currentResult();
|
|
123
|
+
}
|
|
124
|
+
function stop() {
|
|
125
|
+
clearMarks();
|
|
126
|
+
}
|
|
127
|
+
return { find, next, prev, stop };
|
|
128
|
+
}
|
|
129
|
+
export {
|
|
130
|
+
createFindInPage
|
|
131
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { JSX } from "preact";
|
|
2
|
+
/**
|
|
3
|
+
* `displayName` pinned explicitly (matching
|
|
4
|
+
* `AiChatModal`/`ImageEnlarge`/`MermaidEnlarge`/`DesignTokenPanelBootstrap`)
|
|
5
|
+
* so zfb's `captureComponentName` emits a stable
|
|
6
|
+
* `data-zfb-island="FindInPageInit"` marker independent of minification.
|
|
7
|
+
*/
|
|
8
|
+
export declare function FindInPageInit(): JSX.Element | null;
|
|
9
|
+
export declare namespace FindInPageInit {
|
|
10
|
+
var displayName: string;
|
|
11
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "preact/jsx-runtime";
|
|
3
|
+
import { useState, useEffect, useRef } from "preact/compat";
|
|
4
|
+
import { FindBar } from "./find-bar.js";
|
|
5
|
+
import { createFindInPage } from "./find-in-page.js";
|
|
6
|
+
const CONTENT_SELECTOR = "article.zd-content";
|
|
7
|
+
function FindInPageInit() {
|
|
8
|
+
const [isTauri, setIsTauri] = useState(false);
|
|
9
|
+
const [visible, setVisible] = useState(false);
|
|
10
|
+
const findInPageRef = useRef(createFindInPage());
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (typeof window !== "undefined" && "__TAURI_INTERNALS__" in window) {
|
|
13
|
+
setIsTauri(true);
|
|
14
|
+
}
|
|
15
|
+
}, []);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!isTauri) return;
|
|
18
|
+
const handler = (e) => {
|
|
19
|
+
if ((e.metaKey || e.ctrlKey) && e.key === "f") {
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
setVisible((prev) => !prev);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
document.addEventListener("keydown", handler);
|
|
25
|
+
return () => document.removeEventListener("keydown", handler);
|
|
26
|
+
}, [isTauri]);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const handler = () => {
|
|
29
|
+
findInPageRef.current.stop();
|
|
30
|
+
setVisible(false);
|
|
31
|
+
};
|
|
32
|
+
document.addEventListener("zfb:before-preparation", handler);
|
|
33
|
+
return () => document.removeEventListener("zfb:before-preparation", handler);
|
|
34
|
+
}, []);
|
|
35
|
+
if (!isTauri) return null;
|
|
36
|
+
return /* @__PURE__ */ jsx(
|
|
37
|
+
FindBar,
|
|
38
|
+
{
|
|
39
|
+
visible,
|
|
40
|
+
onClose: () => setVisible(false),
|
|
41
|
+
findInPage: findInPageRef.current,
|
|
42
|
+
containerSelector: CONTENT_SELECTOR
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
FindInPageInit.displayName = "FindInPageInit";
|
|
47
|
+
export {
|
|
48
|
+
FindInPageInit
|
|
49
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default frontmatter-preview ignore-key list.
|
|
3
|
+
*
|
|
4
|
+
* Ported verbatim from the `create-zudo-doc` base template's
|
|
5
|
+
* `src/config/frontmatter-preview-defaults.ts`
|
|
6
|
+
* `DEFAULT_FRONTMATTER_IGNORE_KEYS` export (epic zudolab/zudo-doc#2651,
|
|
7
|
+
* S4 #2654).
|
|
8
|
+
*
|
|
9
|
+
* These are the schema-managed frontmatter keys handled by the framework
|
|
10
|
+
* that should be hidden from the frontmatter preview by default. Every
|
|
11
|
+
* entry corresponds to a field declared in the default docs schema
|
|
12
|
+
* (`@takazudo/zudo-doc/docs-schema`'s `buildDocsSchema`). A project adding
|
|
13
|
+
* custom frontmatter fields via its own schema should extend this list via
|
|
14
|
+
* `ZudoDocConfig`, not edit it in place.
|
|
15
|
+
*/
|
|
16
|
+
export declare const defaultFrontmatterPreviewIgnoreKeys: readonly string[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const defaultFrontmatterPreviewIgnoreKeys = [
|
|
2
|
+
"title",
|
|
3
|
+
"description",
|
|
4
|
+
"category",
|
|
5
|
+
"sidebar_position",
|
|
6
|
+
"sidebar_label",
|
|
7
|
+
"tags",
|
|
8
|
+
"search_exclude",
|
|
9
|
+
"pagination_next",
|
|
10
|
+
"pagination_prev",
|
|
11
|
+
"draft",
|
|
12
|
+
"unlisted",
|
|
13
|
+
"hide_sidebar",
|
|
14
|
+
"hide_toc",
|
|
15
|
+
"wide",
|
|
16
|
+
"doc_history",
|
|
17
|
+
"standalone",
|
|
18
|
+
"slug",
|
|
19
|
+
"generated",
|
|
20
|
+
"category_no_page",
|
|
21
|
+
"category_sort_order"
|
|
22
|
+
];
|
|
23
|
+
export {
|
|
24
|
+
defaultFrontmatterPreviewIgnoreKeys
|
|
25
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default UI-string translation table.
|
|
3
|
+
*
|
|
4
|
+
* Ported verbatim from the `create-zudo-doc` base template's
|
|
5
|
+
* `src/config/i18n.ts` `translations` export (epic zudolab/zudo-doc#2651,
|
|
6
|
+
* S4 #2654) so a generated project needs no i18n config file of its own.
|
|
7
|
+
*
|
|
8
|
+
* Locale code → key → translated string. Fully populated for `en`, `ja`, and
|
|
9
|
+
* `de`; the other locales in the generator's `SUPPORTED_LANGS` list
|
|
10
|
+
* (zh-cn/zh-tw/ko/es/fr/pt) fall back to `en` at lookup time (the template's
|
|
11
|
+
* `t()` helper does `translations[locale]?.[key] ?? translations[defaultLocale]?.[key] ?? key`)
|
|
12
|
+
* rather than shipping their own fully-translated table here.
|
|
13
|
+
*
|
|
14
|
+
* Locale label/derivation (mapping a locale code to its display label,
|
|
15
|
+
* detecting the active locale from a URL, etc.) stays settings-driven and is
|
|
16
|
+
* reconstructed by `route-context`/`url-helpers` — this module is DATA only.
|
|
17
|
+
* A project's `ZudoDocConfig.translations` override is merged over this
|
|
18
|
+
* default by `zudoDoc()` (#2657); the merge/lookup helper itself is not part
|
|
19
|
+
* of this module.
|
|
20
|
+
*/
|
|
21
|
+
import type { PresetTranslations } from "../preset.js";
|
|
22
|
+
export declare const defaultTranslations: PresetTranslations;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
const defaultTranslations = {
|
|
2
|
+
en: {
|
|
3
|
+
"nav.gettingStarted": "Getting Started",
|
|
4
|
+
"nav.learn": "Learn",
|
|
5
|
+
"nav.guides": "Guides",
|
|
6
|
+
"nav.components": "Components",
|
|
7
|
+
"nav.reference": "Reference",
|
|
8
|
+
"nav.claude": "Claude",
|
|
9
|
+
"nav.changelog": "Changelog",
|
|
10
|
+
"nav.develop": "Develop",
|
|
11
|
+
"nav.previous": "Previous",
|
|
12
|
+
"nav.next": "Next",
|
|
13
|
+
"nav.overview": "Overview",
|
|
14
|
+
"toc.title": "On this page",
|
|
15
|
+
"docs.browseAll": "Browse all documentation sections.",
|
|
16
|
+
"search.label": "Search",
|
|
17
|
+
"search.placeholder": "Type to search...",
|
|
18
|
+
"search.shortcutHint": "to open search from anywhere",
|
|
19
|
+
"search.resultCount": "{count} results",
|
|
20
|
+
"search.unavailable": "Search unavailable",
|
|
21
|
+
"search.loadingIndex": "Loading search index\u2026",
|
|
22
|
+
"search.noResults": "No results found.",
|
|
23
|
+
"code.copy": "Copy code",
|
|
24
|
+
"code.copied": "Copied!",
|
|
25
|
+
"code.wrapToggle": "Toggle word wrap",
|
|
26
|
+
"doc.editPage": "Edit this page",
|
|
27
|
+
"doc.viewSource": "View source on GitHub",
|
|
28
|
+
"header.github": "GitHub repository",
|
|
29
|
+
"doc.tags": "Tags",
|
|
30
|
+
"doc.taggedWith": "Pages tagged with",
|
|
31
|
+
"doc.allTags": "All Tags",
|
|
32
|
+
"doc.created": "Created",
|
|
33
|
+
"doc.updated": "Updated",
|
|
34
|
+
"doc.noTags": "No tags found.",
|
|
35
|
+
"doc.pageCount": "{count} pages",
|
|
36
|
+
"doc.pageCountSingle": "{count} page",
|
|
37
|
+
"nav.backToMenu": "Back to main menu",
|
|
38
|
+
"doc.fallbackNotice": "This page has not been translated yet and is shown in the original language.",
|
|
39
|
+
"frontmatter.preview.title": "Frontmatter",
|
|
40
|
+
"frontmatter.preview.keyCol": "Key",
|
|
41
|
+
"frontmatter.preview.valueCol": "Value",
|
|
42
|
+
"version.latest": "Latest",
|
|
43
|
+
"version.switcher.label": "Version",
|
|
44
|
+
"version.banner.unmaintained": "You are viewing documentation for an older version.",
|
|
45
|
+
"version.banner.unreleased": "You are viewing unreleased documentation.",
|
|
46
|
+
"version.banner.latestLink": "View the latest version",
|
|
47
|
+
"version.switcher.unavailable": "Not available in this version",
|
|
48
|
+
"version.switcher.allVersions": "All versions",
|
|
49
|
+
"version.page.title": "Documentation Versions",
|
|
50
|
+
"version.page.latest.title": "Latest Version (Current)",
|
|
51
|
+
"version.page.latest.description": "The most up-to-date documentation for the latest stable release.",
|
|
52
|
+
"version.page.latest.link": "View latest docs",
|
|
53
|
+
"version.page.past.title": "Past Versions",
|
|
54
|
+
"version.page.past.description": "Documentation for previously released versions.",
|
|
55
|
+
"version.page.unmaintained": "Unmaintained",
|
|
56
|
+
"version.page.unreleased": "Unreleased",
|
|
57
|
+
"version.page.status": "Status",
|
|
58
|
+
"version.page.docs": "Docs"
|
|
59
|
+
},
|
|
60
|
+
ja: {
|
|
61
|
+
"nav.gettingStarted": "\u306F\u3058\u3081\u306B",
|
|
62
|
+
"nav.learn": "\u5B66\u3076",
|
|
63
|
+
"nav.guides": "\u30AC\u30A4\u30C9",
|
|
64
|
+
"nav.components": "\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8",
|
|
65
|
+
"nav.reference": "\u30EA\u30D5\u30A1\u30EC\u30F3\u30B9",
|
|
66
|
+
"nav.claude": "Claude",
|
|
67
|
+
"nav.changelog": "\u5909\u66F4\u5C65\u6B74",
|
|
68
|
+
"nav.develop": "\u958B\u767A",
|
|
69
|
+
"nav.previous": "\u524D\u3078",
|
|
70
|
+
"nav.next": "\u6B21\u3078",
|
|
71
|
+
"nav.overview": "\u6982\u8981",
|
|
72
|
+
"toc.title": "\u76EE\u6B21",
|
|
73
|
+
"docs.browseAll": "\u3059\u3079\u3066\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u30BB\u30AF\u30B7\u30E7\u30F3\u3092\u95B2\u89A7",
|
|
74
|
+
"search.label": "\u691C\u7D22",
|
|
75
|
+
"search.placeholder": "\u691C\u7D22\u3057\u305F\u3044\u5358\u8A9E\u3092\u5165\u529B",
|
|
76
|
+
"search.shortcutHint": "\u3044\u3064\u3067\u3082\u691C\u7D22\u30D0\u30FC\u3092\u958B\u3051\u308B",
|
|
77
|
+
"search.resultCount": "{count} \u4EF6",
|
|
78
|
+
"search.unavailable": "\u691C\u7D22\u3092\u5229\u7528\u3067\u304D\u307E\u305B\u3093",
|
|
79
|
+
"search.loadingIndex": "\u691C\u7D22\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u3092\u8AAD\u307F\u8FBC\u307F\u4E2D\u2026",
|
|
80
|
+
"search.noResults": "\u691C\u7D22\u7D50\u679C\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002",
|
|
81
|
+
"code.copy": "\u30B3\u30FC\u30C9\u3092\u30B3\u30D4\u30FC",
|
|
82
|
+
"code.copied": "\u30B3\u30D4\u30FC\u3057\u307E\u3057\u305F\uFF01",
|
|
83
|
+
"code.wrapToggle": "\u6298\u308A\u8FD4\u3057\u5207\u66FF",
|
|
84
|
+
"doc.editPage": "\u3053\u306E\u30DA\u30FC\u30B8\u3092\u7DE8\u96C6",
|
|
85
|
+
"doc.viewSource": "GitHub \u3067\u30BD\u30FC\u30B9\u3092\u898B\u308B",
|
|
86
|
+
"header.github": "GitHub \u30EA\u30DD\u30B8\u30C8\u30EA",
|
|
87
|
+
"doc.tags": "\u30BF\u30B0",
|
|
88
|
+
"doc.taggedWith": "\u30BF\u30B0\u4ED8\u304D\u30DA\u30FC\u30B8",
|
|
89
|
+
"doc.allTags": "\u3059\u3079\u3066\u306E\u30BF\u30B0",
|
|
90
|
+
"doc.created": "\u4F5C\u6210",
|
|
91
|
+
"doc.updated": "\u66F4\u65B0",
|
|
92
|
+
"doc.noTags": "\u30BF\u30B0\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002",
|
|
93
|
+
"doc.pageCount": "{count}\u30DA\u30FC\u30B8",
|
|
94
|
+
"doc.pageCountSingle": "{count}\u30DA\u30FC\u30B8",
|
|
95
|
+
"nav.backToMenu": "\u30E1\u30A4\u30F3\u30E1\u30CB\u30E5\u30FC\u306B\u623B\u308B",
|
|
96
|
+
"doc.fallbackNotice": "\u3053\u306E\u30DA\u30FC\u30B8\u306F\u307E\u3060\u7FFB\u8A33\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u539F\u6587\u306E\u307E\u307E\u8868\u793A\u3057\u3066\u3044\u307E\u3059\u3002",
|
|
97
|
+
"frontmatter.preview.title": "\u30D5\u30ED\u30F3\u30C8\u30DE\u30BF\u30FC",
|
|
98
|
+
"frontmatter.preview.keyCol": "\u30AD\u30FC",
|
|
99
|
+
"frontmatter.preview.valueCol": "\u5024",
|
|
100
|
+
"version.latest": "\u6700\u65B0",
|
|
101
|
+
"version.switcher.label": "\u30D0\u30FC\u30B8\u30E7\u30F3",
|
|
102
|
+
"version.banner.unmaintained": "\u3053\u308C\u306F\u65E7\u30D0\u30FC\u30B8\u30E7\u30F3\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3067\u3059\u3002",
|
|
103
|
+
"version.banner.unreleased": "\u3053\u308C\u306F\u672A\u30EA\u30EA\u30FC\u30B9\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3067\u3059\u3002",
|
|
104
|
+
"version.banner.latestLink": "\u6700\u65B0\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u898B\u308B",
|
|
105
|
+
"version.switcher.unavailable": "\u3053\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u3067\u306F\u5229\u7528\u3067\u304D\u307E\u305B\u3093",
|
|
106
|
+
"version.switcher.allVersions": "\u3059\u3079\u3066\u306E\u30D0\u30FC\u30B8\u30E7\u30F3",
|
|
107
|
+
"version.page.title": "\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u30D0\u30FC\u30B8\u30E7\u30F3",
|
|
108
|
+
"version.page.latest.title": "\u6700\u65B0\u30D0\u30FC\u30B8\u30E7\u30F3\uFF08\u73FE\u5728\uFF09",
|
|
109
|
+
"version.page.latest.description": "\u6700\u65B0\u306E\u5B89\u5B9A\u7248\u30EA\u30EA\u30FC\u30B9\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3067\u3059\u3002",
|
|
110
|
+
"version.page.latest.link": "\u6700\u65B0\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u898B\u308B",
|
|
111
|
+
"version.page.past.title": "\u904E\u53BB\u306E\u30D0\u30FC\u30B8\u30E7\u30F3",
|
|
112
|
+
"version.page.past.description": "\u4EE5\u524D\u306B\u30EA\u30EA\u30FC\u30B9\u3055\u308C\u305F\u30D0\u30FC\u30B8\u30E7\u30F3\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3067\u3059\u3002",
|
|
113
|
+
"version.page.unmaintained": "\u30E1\u30F3\u30C6\u30CA\u30F3\u30B9\u7D42\u4E86",
|
|
114
|
+
"version.page.unreleased": "\u672A\u30EA\u30EA\u30FC\u30B9",
|
|
115
|
+
"version.page.status": "\u30B9\u30C6\u30FC\u30BF\u30B9",
|
|
116
|
+
"version.page.docs": "\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8"
|
|
117
|
+
},
|
|
118
|
+
de: {
|
|
119
|
+
"nav.gettingStarted": "Erste Schritte",
|
|
120
|
+
"nav.learn": "Lernen",
|
|
121
|
+
"nav.guides": "Anleitungen",
|
|
122
|
+
"nav.components": "Komponenten",
|
|
123
|
+
"nav.reference": "Referenz",
|
|
124
|
+
"nav.claude": "Claude",
|
|
125
|
+
"nav.changelog": "Changelog",
|
|
126
|
+
"nav.develop": "Entwicklung",
|
|
127
|
+
"nav.previous": "Zur\xFCck",
|
|
128
|
+
"nav.next": "Weiter",
|
|
129
|
+
"nav.overview": "\xDCberblick",
|
|
130
|
+
"toc.title": "Auf dieser Seite",
|
|
131
|
+
"docs.browseAll": "Alle Dokumentationsabschnitte durchsuchen.",
|
|
132
|
+
"search.label": "Suche",
|
|
133
|
+
"search.placeholder": "Suchbegriff eingeben...",
|
|
134
|
+
"search.shortcutHint": "Suche von \xFCberall \xF6ffnen",
|
|
135
|
+
"search.resultCount": "{count} Ergebnisse",
|
|
136
|
+
"search.unavailable": "Suche nicht verf\xFCgbar",
|
|
137
|
+
"search.loadingIndex": "Suchindex wird geladen\u2026",
|
|
138
|
+
"search.noResults": "Keine Ergebnisse gefunden.",
|
|
139
|
+
"code.copy": "Code kopieren",
|
|
140
|
+
"code.copied": "Kopiert!",
|
|
141
|
+
"code.wrapToggle": "Zeilenumbruch umschalten",
|
|
142
|
+
"nav.backToMenu": "Zur\xFCck zum Hauptmen\xFC",
|
|
143
|
+
"doc.editPage": "Diese Seite bearbeiten",
|
|
144
|
+
"doc.viewSource": "Quellcode auf GitHub ansehen",
|
|
145
|
+
"header.github": "GitHub-Repository",
|
|
146
|
+
"doc.tags": "Tags",
|
|
147
|
+
"doc.taggedWith": "Seiten mit Tag",
|
|
148
|
+
"doc.allTags": "Alle Tags",
|
|
149
|
+
"doc.created": "Erstellt",
|
|
150
|
+
"doc.updated": "Aktualisiert",
|
|
151
|
+
"doc.noTags": "Keine Tags gefunden.",
|
|
152
|
+
"doc.pageCount": "{count} Seiten",
|
|
153
|
+
"doc.pageCountSingle": "{count} Seite",
|
|
154
|
+
"doc.fallbackNotice": "Diese Seite wurde noch nicht \xFCbersetzt und wird in der Originalsprache angezeigt.",
|
|
155
|
+
"frontmatter.preview.title": "Frontmatter",
|
|
156
|
+
"frontmatter.preview.keyCol": "Schl\xFCssel",
|
|
157
|
+
"frontmatter.preview.valueCol": "Wert",
|
|
158
|
+
"version.latest": "Neueste",
|
|
159
|
+
"version.switcher.label": "Version",
|
|
160
|
+
"version.banner.unmaintained": "Sie sehen die Dokumentation einer \xE4lteren Version.",
|
|
161
|
+
"version.banner.unreleased": "Sie sehen unver\xF6ffentlichte Dokumentation.",
|
|
162
|
+
"version.banner.latestLink": "Neueste Version anzeigen"
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
export {
|
|
166
|
+
defaultTranslations
|
|
167
|
+
};
|