@dreamlake/dockit 0.2.14 → 0.2.16
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/components/SearchPalette.js +11 -24
- package/dist/components/Sidebar.js +2 -2
- package/dist/components/StatusTable.js +7 -6
- package/dist/components/Table.d.ts +3 -0
- package/dist/components/Table.js +58 -0
- package/dist/components/Topbar.js +3 -1
- package/dist/components/VersionBadge.d.ts +6 -2
- package/dist/components/VersionBadge.js +23 -30
- package/dist/components/mdx-components.d.ts +2 -1
- package/dist/components/mdx-components.js +2 -3
- package/dist/index.d.ts +11 -6
- package/dist/index.js +6 -1
- package/dist/lib/mdx-frontmatter-loader.d.ts +3 -0
- package/dist/lib/mdx-frontmatter-loader.js +29 -0
- package/dist/lib/search-preview.d.ts +10 -0
- package/dist/lib/search-preview.js +33 -0
- package/dist/lib/version-badge.d.ts +22 -0
- package/dist/lib/version-badge.js +44 -0
- package/dist/renderer/Layout.js +1 -1
- package/dist/renderer/onRenderClient.js +1 -1
- package/dist/site-config.d.ts +4 -0
- package/dist/styles.css +45 -0
- package/dist/vike.d.ts +1 -0
- package/dist/vike.js +2 -0
- package/dist/vite.js +2 -0
- package/package.json +5 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { loadSearchPreview } from "../lib/search-preview.js";
|
|
2
3
|
import { useState, useRef, useEffect } from "react";
|
|
3
4
|
import { defaultResults, searchPages } from "../lib/pagefind-search.js";
|
|
4
5
|
import { useMediaQuery } from "../lib/use-media-query.js";
|
|
@@ -76,20 +77,13 @@ function SearchPalette({ open, onClose, query }) {
|
|
|
76
77
|
const [pageHtml, setPageHtml] = useState("");
|
|
77
78
|
const pageCacheRef = useRef(/* @__PURE__ */ new Map());
|
|
78
79
|
const activePath = hits[active]?.path;
|
|
79
|
-
useEffect(() => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
setPageHtml(cached);
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
setPageHtml("");
|
|
90
|
-
let cancelled = false;
|
|
91
|
-
fetch(activePath).then((r) => r.ok ? r.text() : "").then((html) => {
|
|
92
|
-
if (cancelled) return;
|
|
80
|
+
useEffect(() => loadSearchPreview({
|
|
81
|
+
open,
|
|
82
|
+
path: activePath,
|
|
83
|
+
singleColumn: isSingleCol,
|
|
84
|
+
cache: pageCacheRef.current,
|
|
85
|
+
onPreview: setPageHtml,
|
|
86
|
+
extract: (html) => {
|
|
93
87
|
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
94
88
|
const main = doc.querySelector("[data-pagefind-body]");
|
|
95
89
|
main?.querySelectorAll("[data-pagefind-ignore], script, style").forEach((el) => el.remove());
|
|
@@ -99,16 +93,9 @@ function SearchPalette({ open, onClose, query }) {
|
|
|
99
93
|
el.removeAttribute("style");
|
|
100
94
|
el.removeAttribute("class");
|
|
101
95
|
});
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}).catch(() => {
|
|
106
|
-
if (!cancelled) setPageHtml("");
|
|
107
|
-
});
|
|
108
|
-
return () => {
|
|
109
|
-
cancelled = true;
|
|
110
|
-
};
|
|
111
|
-
}, [active, activePath, isSingleCol]);
|
|
96
|
+
return main?.innerHTML ?? "";
|
|
97
|
+
}
|
|
98
|
+
}), [open, activePath, isSingleCol]);
|
|
112
99
|
useEffect(() => {
|
|
113
100
|
if (!open) return;
|
|
114
101
|
setActive(0);
|
|
@@ -51,7 +51,7 @@ function Sidebar() {
|
|
|
51
51
|
"aside",
|
|
52
52
|
{
|
|
53
53
|
"aria-label": "Sections",
|
|
54
|
-
className: "hidden md:flex sticky overflow-y-auto flex-col",
|
|
54
|
+
className: "doc-sidebar hidden md:flex sticky overflow-y-auto flex-col",
|
|
55
55
|
style: { top: 40, height: "calc(100vh - 40px)", padding: "22px 12px 32px 18px", gap: 2 },
|
|
56
56
|
children: groups.map((group) => {
|
|
57
57
|
const soleSection = groups.length === 1;
|
|
@@ -65,7 +65,7 @@ function Sidebar() {
|
|
|
65
65
|
className: "group sidebar-section",
|
|
66
66
|
"data-folded": isFolded || void 0,
|
|
67
67
|
children: [
|
|
68
|
-
/* @__PURE__ */ jsx("span", { children: group.label }),
|
|
68
|
+
/* @__PURE__ */ jsx("span", { title: group.label, children: group.label }),
|
|
69
69
|
/* @__PURE__ */ jsx(
|
|
70
70
|
"span",
|
|
71
71
|
{
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useEffect } from "react";
|
|
3
3
|
import { Chip } from "./Chip.js";
|
|
4
|
+
import { Table } from "./Table.js";
|
|
4
5
|
const STATUS_COLOR = {
|
|
5
6
|
pass: "oklch(62% .15 145)",
|
|
6
7
|
fail: "oklch(58% .19 25)",
|
|
@@ -153,13 +154,13 @@ function StatusTable({ kind = "suites" }) {
|
|
|
153
154
|
]
|
|
154
155
|
}
|
|
155
156
|
),
|
|
156
|
-
/* @__PURE__ */ jsxs(
|
|
157
|
+
/* @__PURE__ */ jsxs(Table, { children: [
|
|
157
158
|
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
158
|
-
/* @__PURE__ */ jsx("th", { style: { ...cellStyle, ...monoStyle, textAlign: "left", textTransform: "uppercase", letterSpacing: "0.12em", fontSize: 10 }, children: "Status" }),
|
|
159
|
-
/* @__PURE__ */ jsx("th", { style: { ...cellStyle, ...monoStyle, textAlign: "left", textTransform: "uppercase", letterSpacing: "0.12em", fontSize: 10 }, children: kind === "suites" ? "Suite" : "Example" }),
|
|
160
|
-
/* @__PURE__ */ jsx("th", { style: { ...cellStyle, ...monoStyle, textAlign: "left", textTransform: "uppercase", letterSpacing: "0.12em", fontSize: 10 }, children: kind === "suites" ? "Command" : "Description" }),
|
|
161
|
-
/* @__PURE__ */ jsx("th", { style: { ...cellStyle, ...monoStyle, textAlign: "right", textTransform: "uppercase", letterSpacing: "0.12em", fontSize: 10 }, children: "Tests" }),
|
|
162
|
-
/* @__PURE__ */ jsx("th", { style: { ...cellStyle, ...monoStyle, textAlign: "right", textTransform: "uppercase", letterSpacing: "0.12em", fontSize: 10 }, children: "Time" })
|
|
159
|
+
/* @__PURE__ */ jsx("th", { style: { ...cellStyle, ...monoStyle, borderBottom: 0, textAlign: "left", textTransform: "uppercase", letterSpacing: "0.12em", fontSize: 10 }, children: "Status" }),
|
|
160
|
+
/* @__PURE__ */ jsx("th", { style: { ...cellStyle, ...monoStyle, borderBottom: 0, textAlign: "left", textTransform: "uppercase", letterSpacing: "0.12em", fontSize: 10 }, children: kind === "suites" ? "Suite" : "Example" }),
|
|
161
|
+
/* @__PURE__ */ jsx("th", { style: { ...cellStyle, ...monoStyle, borderBottom: 0, textAlign: "left", textTransform: "uppercase", letterSpacing: "0.12em", fontSize: 10 }, children: kind === "suites" ? "Command" : "Description" }),
|
|
162
|
+
/* @__PURE__ */ jsx("th", { style: { ...cellStyle, ...monoStyle, borderBottom: 0, textAlign: "right", textTransform: "uppercase", letterSpacing: "0.12em", fontSize: 10 }, children: "Tests" }),
|
|
163
|
+
/* @__PURE__ */ jsx("th", { style: { ...cellStyle, ...monoStyle, borderBottom: 0, textAlign: "right", textTransform: "uppercase", letterSpacing: "0.12em", fontSize: 10 }, children: "Time" })
|
|
163
164
|
] }) }),
|
|
164
165
|
/* @__PURE__ */ jsx("tbody", { children: kind === "suites" ? items.map((s) => /* @__PURE__ */ jsxs("tr", { children: [
|
|
165
166
|
/* @__PURE__ */ jsx("td", { style: cellStyle, children: /* @__PURE__ */ jsx(StatusBadge, { status: s.status }) }),
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useId } from "react";
|
|
3
|
+
function Table({
|
|
4
|
+
children,
|
|
5
|
+
className,
|
|
6
|
+
style,
|
|
7
|
+
id,
|
|
8
|
+
...rest
|
|
9
|
+
}) {
|
|
10
|
+
const [wrap, setWrap] = useState(true);
|
|
11
|
+
const generatedId = useId();
|
|
12
|
+
const tableId = id ?? generatedId;
|
|
13
|
+
return /* @__PURE__ */ jsxs("div", { className: "doc-table", "data-wrap": wrap ? "on" : "off", children: [
|
|
14
|
+
/* @__PURE__ */ jsx("div", { className: "doc-table-toolbar", children: /* @__PURE__ */ jsxs(
|
|
15
|
+
"button",
|
|
16
|
+
{
|
|
17
|
+
type: "button",
|
|
18
|
+
className: "doc-table-wrap",
|
|
19
|
+
"aria-label": "Wrap table text",
|
|
20
|
+
"aria-pressed": wrap,
|
|
21
|
+
"aria-controls": tableId,
|
|
22
|
+
title: wrap ? "Turn off text wrapping" : "Wrap table text",
|
|
23
|
+
onClick: () => setWrap((value) => !value),
|
|
24
|
+
children: [
|
|
25
|
+
/* @__PURE__ */ jsx(
|
|
26
|
+
"svg",
|
|
27
|
+
{
|
|
28
|
+
width: "14",
|
|
29
|
+
height: "14",
|
|
30
|
+
viewBox: "0 0 24 24",
|
|
31
|
+
fill: "none",
|
|
32
|
+
stroke: "currentColor",
|
|
33
|
+
strokeWidth: "1.5",
|
|
34
|
+
strokeLinecap: "round",
|
|
35
|
+
strokeLinejoin: "round",
|
|
36
|
+
"aria-hidden": "true",
|
|
37
|
+
children: /* @__PURE__ */ jsx("path", { d: "M3 6h18M3 12h14a3 3 0 0 1 0 6h-4m3-3-3 3 3 3M3 18h4" })
|
|
38
|
+
}
|
|
39
|
+
),
|
|
40
|
+
"Wrap"
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
) }),
|
|
44
|
+
/* @__PURE__ */ jsx(
|
|
45
|
+
"div",
|
|
46
|
+
{
|
|
47
|
+
className: "doc-table-scroll",
|
|
48
|
+
role: "region",
|
|
49
|
+
"aria-label": "Scrollable table",
|
|
50
|
+
tabIndex: 0,
|
|
51
|
+
children: /* @__PURE__ */ jsx("table", { ...rest, id: tableId, className, style, children })
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
] });
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
Table
|
|
58
|
+
};
|
|
@@ -342,7 +342,9 @@ function Topbar({ searchOpen, onOpenSearch, onCloseSearch, query, setQuery }) {
|
|
|
342
342
|
label: chip.label,
|
|
343
343
|
version: chip.version,
|
|
344
344
|
collapsed: merged,
|
|
345
|
-
dropdown: chip.dropdown
|
|
345
|
+
dropdown: chip.dropdown,
|
|
346
|
+
prefix: chip.prefix,
|
|
347
|
+
manifestUrl: chip.manifestUrl
|
|
346
348
|
},
|
|
347
349
|
chip.label
|
|
348
350
|
)),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export interface VersionBadgeProps {
|
|
2
2
|
/** Left segment text (e.g. the package name). */
|
|
3
3
|
label: string;
|
|
4
|
-
/** Build-time version shown in the right segment (may be overridden on
|
|
4
|
+
/** Build-time version shown in the right segment (with dropdown enabled, may be overridden on
|
|
5
5
|
* the client from the hostname / manifest — see below). */
|
|
6
6
|
version: string;
|
|
7
7
|
/** Collapse to width 0 (the Topbar drives this from its merged state).
|
|
@@ -10,6 +10,10 @@ export interface VersionBadgeProps {
|
|
|
10
10
|
/** Turn the version segment into a popover listing the deploys from
|
|
11
11
|
* `/versions.json`. */
|
|
12
12
|
dropdown?: boolean;
|
|
13
|
+
/** Text before versions; defaults to 'v'. Use '' for commit previews. */
|
|
14
|
+
prefix?: string;
|
|
15
|
+
/** Manifest path or absolute URL; defaults to '/versions.json'. */
|
|
16
|
+
manifestUrl?: string;
|
|
13
17
|
}
|
|
14
18
|
/**
|
|
15
19
|
* Two-segment version chip: `[ label | v<version> ]`.
|
|
@@ -33,4 +37,4 @@ export interface VersionBadgeProps {
|
|
|
33
37
|
* radius, hairline border. The two-segment (label | version) layout is
|
|
34
38
|
* bespoke, so this component does not compose `Chip` internally.
|
|
35
39
|
*/
|
|
36
|
-
export declare function VersionBadge({ label, version, collapsed, dropdown, }: VersionBadgeProps): import("react").JSX.Element;
|
|
40
|
+
export declare function VersionBadge({ label, version, collapsed, dropdown, prefix, manifestUrl, }: VersionBadgeProps): import("react").JSX.Element;
|
|
@@ -1,46 +1,39 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useRef, useEffect } from "react";
|
|
3
3
|
import { siteConfig } from "../site-config.js";
|
|
4
|
+
import { badgeScope, manifestForScope, resolveBadgeVersion, loadVersionManifest } from "../lib/version-badge.js";
|
|
4
5
|
const SPRING = "cubic-bezier(0.4, 0.7, 0.3, 1)";
|
|
5
6
|
function VersionBadge({
|
|
6
7
|
label,
|
|
7
8
|
version,
|
|
8
9
|
collapsed = false,
|
|
9
|
-
dropdown = false
|
|
10
|
+
dropdown = false,
|
|
11
|
+
prefix = "v",
|
|
12
|
+
manifestUrl = "/versions.json"
|
|
10
13
|
}) {
|
|
11
14
|
const transition = `opacity 0.4s ease, transform 0.4s ${SPRING}, width 0.4s ${SPRING}, margin 0.4s ${SPRING}, padding 0.4s ${SPRING}`;
|
|
12
15
|
const [open, setOpen] = useState(false);
|
|
13
|
-
const [
|
|
14
|
-
const [
|
|
16
|
+
const [manifestState, setManifestState] = useState(null);
|
|
17
|
+
const [hostname, setHostname] = useState("");
|
|
18
|
+
const scope = badgeScope(label, version, dropdown, manifestUrl);
|
|
19
|
+
const manifest = manifestForScope(manifestState, scope);
|
|
20
|
+
const displayVersion = resolveBadgeVersion(version, dropdown, hostname, manifest, manifestUrl);
|
|
15
21
|
const wrapperRef = useRef(null);
|
|
16
22
|
useEffect(() => {
|
|
23
|
+
setHostname(window.location.hostname);
|
|
24
|
+
}, []);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
setOpen(false);
|
|
27
|
+
setManifestState(null);
|
|
17
28
|
if (!dropdown) return;
|
|
18
29
|
let cancelled = false;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const sameOrigin = () => fetch("/versions.json").then((r) => r.ok ? r.json() : null);
|
|
22
|
-
const fromOrigin = () => fetch(`${origin}/versions.json`).then((r) => r.ok ? r.json() : Promise.reject(new Error(String(r.status))));
|
|
23
|
-
const load = !origin ? sameOrigin() : isLocal ? sameOrigin().then((m) => m ?? fromOrigin().catch(() => null)) : fromOrigin().catch(sameOrigin);
|
|
24
|
-
load.then((m) => {
|
|
25
|
-
if (!cancelled && m) setManifest(m);
|
|
26
|
-
}).catch(() => {
|
|
30
|
+
loadVersionManifest(manifestUrl, siteConfig.url || "", window.location.hostname).then((manifest2) => {
|
|
31
|
+
if (!cancelled && manifest2) setManifestState({ scope, manifest: manifest2 });
|
|
27
32
|
});
|
|
28
33
|
return () => {
|
|
29
34
|
cancelled = true;
|
|
30
35
|
};
|
|
31
|
-
}, [dropdown]);
|
|
32
|
-
useEffect(() => {
|
|
33
|
-
if (typeof window === "undefined") return;
|
|
34
|
-
const host = window.location.hostname;
|
|
35
|
-
const m = host.match(/^v(\d+(?:-\d+)+(?:[a-z]+\d+)?)\./i);
|
|
36
|
-
if (m) {
|
|
37
|
-
setDisplayVersion(m[1].replace(/-/g, "."));
|
|
38
|
-
} else if (host.startsWith("stable.") && manifest?.stable) {
|
|
39
|
-
setDisplayVersion(manifest.stable);
|
|
40
|
-
} else if (manifest?.current) {
|
|
41
|
-
setDisplayVersion(manifest.current);
|
|
42
|
-
}
|
|
43
|
-
}, [manifest]);
|
|
36
|
+
}, [scope, dropdown, manifestUrl]);
|
|
44
37
|
useEffect(() => {
|
|
45
38
|
if (!open) return;
|
|
46
39
|
function onDown(e) {
|
|
@@ -144,11 +137,11 @@ function VersionBadge({
|
|
|
144
137
|
},
|
|
145
138
|
"aria-haspopup": "listbox",
|
|
146
139
|
"aria-expanded": open,
|
|
147
|
-
title: `Switch ${label} version (current
|
|
140
|
+
title: `Switch ${label} version (current ${prefix}${displayVersion})`,
|
|
148
141
|
className: "text-doc-template-ink hover:bg-doc-template-search",
|
|
149
142
|
style: versionSegStyle,
|
|
150
143
|
children: [
|
|
151
|
-
|
|
144
|
+
prefix,
|
|
152
145
|
displayVersion,
|
|
153
146
|
chevron
|
|
154
147
|
]
|
|
@@ -159,7 +152,7 @@ function VersionBadge({
|
|
|
159
152
|
className: "inline-flex items-center text-doc-template-ink",
|
|
160
153
|
style: versionSegStyle,
|
|
161
154
|
children: [
|
|
162
|
-
|
|
155
|
+
prefix,
|
|
163
156
|
displayVersion
|
|
164
157
|
]
|
|
165
158
|
}
|
|
@@ -250,11 +243,11 @@ function VersionBadge({
|
|
|
250
243
|
children: [
|
|
251
244
|
name,
|
|
252
245
|
name === "stable" && manifest.stable && /* @__PURE__ */ jsxs("span", { style: { opacity: 0.5, marginLeft: 6 }, children: [
|
|
253
|
-
|
|
246
|
+
prefix,
|
|
254
247
|
manifest.stable
|
|
255
248
|
] }),
|
|
256
249
|
name === "latest" && manifest.current && /* @__PURE__ */ jsxs("span", { style: { opacity: 0.5, marginLeft: 6 }, children: [
|
|
257
|
-
|
|
250
|
+
prefix,
|
|
258
251
|
manifest.current
|
|
259
252
|
] })
|
|
260
253
|
]
|
|
@@ -293,7 +286,7 @@ function VersionBadge({
|
|
|
293
286
|
},
|
|
294
287
|
children: [
|
|
295
288
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
296
|
-
|
|
289
|
+
prefix,
|
|
297
290
|
v.version,
|
|
298
291
|
isCurrent && /* @__PURE__ */ jsx("span", { style: { opacity: 0.55, marginLeft: 6 }, children: "current" })
|
|
299
292
|
] }),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
import { Table } from './Table';
|
|
2
3
|
import { Callout } from './Callout';
|
|
3
4
|
import { Chip } from './Chip';
|
|
4
5
|
import { Preview } from './Preview';
|
|
@@ -18,7 +19,7 @@ export declare const mdxComponents: {
|
|
|
18
19
|
li: import('react').FC<Omit<import('react').DetailedHTMLProps<import('react').LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "ref">>;
|
|
19
20
|
a: import('react').FC<Omit<import('react').DetailedHTMLProps<import('react').AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, "ref">>;
|
|
20
21
|
blockquote: import('react').FC<Omit<import('react').DetailedHTMLProps<import('react').BlockquoteHTMLAttributes<HTMLQuoteElement>, HTMLQuoteElement>, "ref">>;
|
|
21
|
-
table:
|
|
22
|
+
table: typeof Table;
|
|
22
23
|
th: import('react').FC<Omit<import('react').DetailedHTMLProps<import('react').ThHTMLAttributes<HTMLTableHeaderCellElement>, HTMLTableHeaderCellElement>, "ref">>;
|
|
23
24
|
td: import('react').FC<Omit<import('react').DetailedHTMLProps<import('react').TdHTMLAttributes<HTMLTableDataCellElement>, HTMLTableDataCellElement>, "ref">>;
|
|
24
25
|
code: import('react').FC<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLElement>, HTMLElement>, "ref">>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useContext, createContext, useState } from "react";
|
|
3
3
|
import { CodeBlock } from "./CodeBlock.js";
|
|
4
|
+
import { Table } from "./Table.js";
|
|
4
5
|
import { Callout } from "./Callout.js";
|
|
5
6
|
import { Chip } from "./Chip.js";
|
|
6
7
|
import { Preview } from "./Preview.js";
|
|
@@ -270,19 +271,17 @@ const A = ({ children, style, ...rest }) => /* @__PURE__ */ jsx(
|
|
|
270
271
|
children
|
|
271
272
|
}
|
|
272
273
|
);
|
|
273
|
-
const Table = ({ children, style, ...rest }) => /* @__PURE__ */ jsx("table", { ...rest, style: { width: "100%", borderCollapse: "collapse", fontSize: 13, margin: "0 0 14px", ...style }, children });
|
|
274
274
|
const Th = ({ children, style, ...rest }) => /* @__PURE__ */ jsx(
|
|
275
275
|
"th",
|
|
276
276
|
{
|
|
277
277
|
...rest,
|
|
278
|
-
className: "text-doc-template-muted uppercase
|
|
278
|
+
className: "text-doc-template-muted uppercase",
|
|
279
279
|
style: {
|
|
280
280
|
fontFamily: "var(--font-doc-template-mono)",
|
|
281
281
|
fontSize: 10,
|
|
282
282
|
letterSpacing: "0.12em",
|
|
283
283
|
textAlign: "left",
|
|
284
284
|
fontWeight: 600,
|
|
285
|
-
background: "color-mix(in srgb, var(--color-doc-template-ink) 2%, transparent)",
|
|
286
285
|
padding: "9px 10px",
|
|
287
286
|
...style
|
|
288
287
|
},
|
package/dist/index.d.ts
CHANGED
|
@@ -11,8 +11,8 @@ import { TabEntry as _TabEntry } from './lib/tabs';
|
|
|
11
11
|
*
|
|
12
12
|
* initDocs({
|
|
13
13
|
* site: { brand: 'DreamLake', subtitle: 'Dockit', … },
|
|
14
|
-
*
|
|
15
|
-
* rawPages: import.meta.glob('./pages/** /+Page.mdx', { eager: true, query: '?raw', import: 'default' }),
|
|
14
|
+
* pageMetadata: import.meta.glob('./pages/** /+Page.mdx', { eager: true, query: '?frontmatter', import: 'default' }),
|
|
15
|
+
* rawPages: import.meta.env.DEV ? import.meta.glob('./pages/** /+Page.mdx', { eager: true, query: '?raw', import: 'default' }) : undefined,
|
|
16
16
|
* sectionOrder: ['Getting started', 'Reference'],
|
|
17
17
|
* tabs: [{ id: 'overview', label: 'Get Started', numeral: 'I', landing: '/', urlPrefix: '/get-started' }],
|
|
18
18
|
* })
|
|
@@ -47,12 +47,17 @@ export { Layout, useMerge } from './renderer/Layout';
|
|
|
47
47
|
export interface InitDocsOptions {
|
|
48
48
|
/** Site branding, URLs, version chips, git hash. */
|
|
49
49
|
site: Partial<_SiteConfig>;
|
|
50
|
-
/**
|
|
51
|
-
|
|
50
|
+
/** Metadata-only glob: `{ eager: true, query: '?frontmatter', import: 'default' }`.
|
|
51
|
+
* Keeps compiled page bodies out of the shared startup bundle.
|
|
52
|
+
* Use this or `pages`, not both. */
|
|
53
|
+
pageMetadata?: Record<string, _PageFrontmatter>;
|
|
54
|
+
/** Backward-compatible module map. Prefer `pageMetadata` for large sites. */
|
|
55
|
+
pages?: Record<string, {
|
|
52
56
|
frontmatter?: _PageFrontmatter;
|
|
53
57
|
}>;
|
|
54
|
-
/**
|
|
55
|
-
*
|
|
58
|
+
/** Raw sources for fallback/dev search. Usually pass a `?raw` glob only
|
|
59
|
+
* when `import.meta.env.DEV`; production Pagefind searches built HTML.
|
|
60
|
+
* Omitting this retains title/description search if Pagefind is unavailable. */
|
|
56
61
|
rawPages?: Record<string, string>;
|
|
57
62
|
/** Authored sidebar section order; unknown sections fall to the end. */
|
|
58
63
|
sectionOrder?: string[];
|
package/dist/index.js
CHANGED
|
@@ -30,8 +30,13 @@ import { Topbar } from "./components/Topbar.js";
|
|
|
30
30
|
import { VersionBadge } from "./components/VersionBadge.js";
|
|
31
31
|
import { Layout, useMerge } from "./renderer/Layout.js";
|
|
32
32
|
function initDocs(opts) {
|
|
33
|
+
if (opts.pages && opts.pageMetadata) {
|
|
34
|
+
throw new Error("initDocs: provide pageMetadata or pages, not both");
|
|
35
|
+
}
|
|
36
|
+
const modules = opts.pageMetadata ? Object.fromEntries(Object.entries(opts.pageMetadata).map(([file, frontmatter]) => [file, { frontmatter }])) : opts.pages;
|
|
37
|
+
if (!modules) throw new Error("initDocs: pageMetadata or pages is required");
|
|
33
38
|
defineSiteConfig(opts.search ? { ...opts.site, search: opts.search } : opts.site);
|
|
34
|
-
initNavigation(
|
|
39
|
+
initNavigation(modules, opts.sectionOrder ?? []);
|
|
35
40
|
initSearchIndex(opts.rawPages ?? {});
|
|
36
41
|
initTabs(opts.tabs ?? []);
|
|
37
42
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { parse } from "yaml";
|
|
3
|
+
function mdxFrontmatterLoader() {
|
|
4
|
+
const prefix = "\0dockit-frontmatter:";
|
|
5
|
+
return {
|
|
6
|
+
name: "dockit-frontmatter",
|
|
7
|
+
enforce: "pre",
|
|
8
|
+
async resolveId(id, importer) {
|
|
9
|
+
if (!id.endsWith(".mdx?frontmatter")) return null;
|
|
10
|
+
const resolved = await this.resolve(id.slice(0, -"?frontmatter".length), importer, { skipSelf: true });
|
|
11
|
+
return resolved ? prefix + resolved.id : null;
|
|
12
|
+
},
|
|
13
|
+
async load(id) {
|
|
14
|
+
if (!id.startsWith(prefix)) return null;
|
|
15
|
+
const file = id.slice(prefix.length);
|
|
16
|
+
this.addWatchFile(file);
|
|
17
|
+
const source = await readFile(file, "utf8");
|
|
18
|
+
const match = source.match(/^\uFEFF?---\r?\n([\s\S]*?)\r?\n(?:---|\.\.\.)(?:\r?\n|$)/);
|
|
19
|
+
const metadata = match ? parse(match[1]) ?? {} : {};
|
|
20
|
+
if (typeof metadata !== "object" || Array.isArray(metadata)) {
|
|
21
|
+
throw new Error(`Expected a YAML frontmatter mapping in ${file}`);
|
|
22
|
+
}
|
|
23
|
+
return `export default ${JSON.stringify(metadata)};`;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
mdxFrontmatterLoader
|
|
29
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Start one visible search preview; return the React effect cleanup. */
|
|
2
|
+
export declare function loadSearchPreview({ open, path, singleColumn, cache, onPreview, extract, request, }: {
|
|
3
|
+
open: boolean;
|
|
4
|
+
path?: string;
|
|
5
|
+
singleColumn: boolean;
|
|
6
|
+
cache: Map<string, string>;
|
|
7
|
+
onPreview: (html: string) => void;
|
|
8
|
+
extract: (html: string) => string;
|
|
9
|
+
request?: typeof fetch;
|
|
10
|
+
}): (() => void) | undefined;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
function loadSearchPreview({
|
|
2
|
+
open,
|
|
3
|
+
path,
|
|
4
|
+
singleColumn,
|
|
5
|
+
cache,
|
|
6
|
+
onPreview,
|
|
7
|
+
extract,
|
|
8
|
+
request = fetch
|
|
9
|
+
}) {
|
|
10
|
+
if (!open || !path || singleColumn || /^https?:\/\//.test(path)) {
|
|
11
|
+
onPreview("");
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const cached = cache.get(path);
|
|
15
|
+
if (cached !== void 0) {
|
|
16
|
+
onPreview(cached);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
onPreview("");
|
|
20
|
+
const controller = new AbortController();
|
|
21
|
+
request(path, { signal: controller.signal }).then((response) => response.ok ? response.text() : "").then((html) => {
|
|
22
|
+
if (controller.signal.aborted) return;
|
|
23
|
+
const content = extract(html);
|
|
24
|
+
cache.set(path, content);
|
|
25
|
+
onPreview(content);
|
|
26
|
+
}).catch(() => {
|
|
27
|
+
if (!controller.signal.aborted) onPreview("");
|
|
28
|
+
});
|
|
29
|
+
return () => controller.abort();
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
loadSearchPreview
|
|
33
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** State and resolution helpers shared by independently scoped version badges. */
|
|
2
|
+
export interface VersionEntry {
|
|
3
|
+
version: string;
|
|
4
|
+
url: string;
|
|
5
|
+
date?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface VersionManifest {
|
|
8
|
+
current?: string;
|
|
9
|
+
stable?: string;
|
|
10
|
+
aliases?: Record<string, string>;
|
|
11
|
+
versions?: VersionEntry[];
|
|
12
|
+
}
|
|
13
|
+
export interface BadgeManifestState {
|
|
14
|
+
scope: string;
|
|
15
|
+
manifest: VersionManifest;
|
|
16
|
+
}
|
|
17
|
+
export declare function badgeScope(label: string, version: string, dropdown: boolean, manifestUrl: string): string;
|
|
18
|
+
/** Never render a previous tab's manifest, even before effects have run. */
|
|
19
|
+
export declare function manifestForScope(state: BadgeManifestState | null, scope: string): VersionManifest | null;
|
|
20
|
+
export declare function resolveBadgeVersion(version: string, dropdown: boolean, hostname: string, manifest: VersionManifest | null, manifestUrl?: string): string;
|
|
21
|
+
/** Production first, with a same-origin fallback; local development reverses it. */
|
|
22
|
+
export declare function loadVersionManifest(manifestUrl: string, origin: string, hostname: string, request?: typeof fetch): Promise<VersionManifest | null>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
function badgeScope(label, version, dropdown, manifestUrl) {
|
|
2
|
+
return JSON.stringify([label, version, dropdown, manifestUrl]);
|
|
3
|
+
}
|
|
4
|
+
function manifestForScope(state, scope) {
|
|
5
|
+
return state?.scope === scope ? state.manifest : null;
|
|
6
|
+
}
|
|
7
|
+
function resolveBadgeVersion(version, dropdown, hostname, manifest, manifestUrl = "/versions.json") {
|
|
8
|
+
if (!dropdown) return version;
|
|
9
|
+
const match = hostname.match(/^v(\d+(?:-\d+)+(?:[a-z]+\d+)?)\./i);
|
|
10
|
+
if (match) {
|
|
11
|
+
const fromHost = match[1].replace(/-/g, ".");
|
|
12
|
+
if (manifestUrl === "/versions.json" || manifest?.versions?.some((entry) => entry.version === fromHost)) {
|
|
13
|
+
return fromHost;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
if (hostname.startsWith("stable.") && manifest?.stable) return manifest.stable;
|
|
17
|
+
return manifest?.current || version;
|
|
18
|
+
}
|
|
19
|
+
async function loadVersionManifest(manifestUrl, origin, hostname, request = fetch) {
|
|
20
|
+
const read = async (url) => {
|
|
21
|
+
try {
|
|
22
|
+
const response = await request(url);
|
|
23
|
+
return response.ok ? await response.json() : null;
|
|
24
|
+
} catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
if (/^(?:https?:)?\/\//.test(manifestUrl)) return read(manifestUrl);
|
|
29
|
+
const localUrl = `/${manifestUrl.replace(/^\/+/, "")}`;
|
|
30
|
+
const productionUrl = origin ? `${origin.replace(/\/+$/, "")}${localUrl}` : localUrl;
|
|
31
|
+
const local = /^(localhost|127\.|0\.0\.0\.0)/.test(hostname);
|
|
32
|
+
const urls = [...new Set(local ? [localUrl, productionUrl] : [productionUrl, localUrl])];
|
|
33
|
+
for (const url of urls) {
|
|
34
|
+
const manifest = await read(url);
|
|
35
|
+
if (manifest) return manifest;
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
badgeScope,
|
|
41
|
+
loadVersionManifest,
|
|
42
|
+
manifestForScope,
|
|
43
|
+
resolveBadgeVersion
|
|
44
|
+
};
|
package/dist/renderer/Layout.js
CHANGED
|
@@ -138,7 +138,7 @@ function Layout({ children }) {
|
|
|
138
138
|
/* @__PURE__ */ jsxs(
|
|
139
139
|
"div",
|
|
140
140
|
{
|
|
141
|
-
className: isFullscreen ? "grid items-start mx-auto grid-cols-[minmax(0,1fr)] md:grid-cols-[
|
|
141
|
+
className: isFullscreen ? "grid items-start mx-auto grid-cols-[minmax(0,1fr)] md:grid-cols-[var(--doc-sidebar-width,280px)_minmax(0,1fr)]" : "grid items-start mx-auto min-h-screen grid-cols-[minmax(0,1fr)] md:grid-cols-[var(--doc-sidebar-width,280px)_minmax(0,1fr)] lg:grid-cols-[var(--doc-sidebar-width,280px)_minmax(0,1fr)_var(--doc-toc-width,280px)]",
|
|
142
142
|
style: isFullscreen ? { height: "calc(100vh - 40px)" } : { maxWidth: 1320 },
|
|
143
143
|
children: [
|
|
144
144
|
/* @__PURE__ */ jsx(Sidebar, {}),
|
|
@@ -8,7 +8,7 @@ async function onRenderClient(pageContext) {
|
|
|
8
8
|
const container = document.getElementById("root");
|
|
9
9
|
const tree = /* @__PURE__ */ jsx(PageContextProvider, { pageContext, children: /* @__PURE__ */ jsx(Layout, { children: /* @__PURE__ */ jsx(Page, { ...pageProps }) }) });
|
|
10
10
|
if (!root) {
|
|
11
|
-
if (container.innerHTML !== "") {
|
|
11
|
+
if (pageContext.isHydration && container.innerHTML !== "") {
|
|
12
12
|
root = ReactDOM.hydrateRoot(container, tree);
|
|
13
13
|
} else {
|
|
14
14
|
root = ReactDOM.createRoot(container);
|
package/dist/site-config.d.ts
CHANGED
|
@@ -16,6 +16,10 @@ export interface VersionChip {
|
|
|
16
16
|
label: string;
|
|
17
17
|
version: string;
|
|
18
18
|
dropdown?: boolean;
|
|
19
|
+
/** Version prefix; defaults to 'v'. Use '' for commit previews. */
|
|
20
|
+
prefix?: string;
|
|
21
|
+
/** Product-specific manifest path or URL; defaults to '/versions.json'. */
|
|
22
|
+
manifestUrl?: string;
|
|
19
23
|
}
|
|
20
24
|
/** One remote Pagefind index merged into the site's own search via
|
|
21
25
|
* `pagefind.mergeIndex()` — Pagefind's first-class multisite API. The
|
package/dist/styles.css
CHANGED
|
@@ -109,6 +109,44 @@
|
|
|
109
109
|
overflow-x: auto;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
.doc-table { min-width: 0; max-width: 100%; margin: 0 0 14px; }
|
|
113
|
+
.doc-table-toolbar { display: flex; justify-content: flex-end; margin-bottom: 6px; }
|
|
114
|
+
.doc-table-wrap {
|
|
115
|
+
display: inline-flex;
|
|
116
|
+
align-items: center;
|
|
117
|
+
gap: 5px;
|
|
118
|
+
height: 24px;
|
|
119
|
+
padding: 2px 8px;
|
|
120
|
+
border: 1px solid var(--color-doc-template-faint);
|
|
121
|
+
border-radius: var(--radius-doc-template-sm);
|
|
122
|
+
background: transparent;
|
|
123
|
+
color: var(--color-doc-template-muted);
|
|
124
|
+
font-family: var(--font-doc-template-mono);
|
|
125
|
+
font-size: 10px;
|
|
126
|
+
cursor: pointer;
|
|
127
|
+
}
|
|
128
|
+
.doc-table-wrap[aria-pressed='true'] {
|
|
129
|
+
color: var(--color-doc-template-accent);
|
|
130
|
+
background: var(--color-doc-template-accent-soft);
|
|
131
|
+
}
|
|
132
|
+
.doc-table-wrap:hover { border-color: var(--color-doc-template-muted); }
|
|
133
|
+
.doc-table-wrap:focus-visible, .doc-table-scroll:focus-visible {
|
|
134
|
+
outline: 2px solid var(--color-doc-template-accent);
|
|
135
|
+
outline-offset: 2px;
|
|
136
|
+
}
|
|
137
|
+
.doc-table-scroll { overflow-x: auto; border-radius: var(--radius-doc-template-sm); }
|
|
138
|
+
.doc-table-scroll > table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; }
|
|
139
|
+
.doc-table-scroll > table > thead > tr > th {
|
|
140
|
+
border-bottom: 0;
|
|
141
|
+
background: var(--color-doc-template-chip);
|
|
142
|
+
}
|
|
143
|
+
.doc-table-scroll > table > thead > tr:first-child > th:first-child { border-top-left-radius: var(--radius-doc-template-sm); }
|
|
144
|
+
.doc-table-scroll > table > thead > tr:first-child > th:last-child { border-top-right-radius: var(--radius-doc-template-sm); }
|
|
145
|
+
.doc-table-scroll > table > thead > tr:last-child > th:first-child { border-bottom-left-radius: var(--radius-doc-template-sm); }
|
|
146
|
+
.doc-table-scroll > table > thead > tr:last-child > th:last-child { border-bottom-right-radius: var(--radius-doc-template-sm); }
|
|
147
|
+
.doc-table[data-wrap='on'] > .doc-table-scroll > table { white-space: normal; overflow-wrap: anywhere; }
|
|
148
|
+
.doc-table[data-wrap='off'] > .doc-table-scroll > table { white-space: nowrap; overflow-wrap: normal; }
|
|
149
|
+
|
|
112
150
|
/* Pagefind excerpt highlights — matches the inline highlight style
|
|
113
151
|
used by the SearchPalette's custom `highlight()` function. */
|
|
114
152
|
.pagefind-excerpt mark {
|
|
@@ -308,3 +346,10 @@
|
|
|
308
346
|
from { opacity: 0; transform: scale(0.6) rotate(-90deg); }
|
|
309
347
|
to { opacity: 1; transform: scale(1) rotate(0deg); }
|
|
310
348
|
}
|
|
349
|
+
|
|
350
|
+
/* Stable, narrow scrollbar space keeps section labels from reflowing on overflow. */
|
|
351
|
+
.doc-sidebar { min-width: 0; scrollbar-width: thin; scrollbar-gutter: stable; }
|
|
352
|
+
.doc-sidebar::-webkit-scrollbar { width: 6px; }
|
|
353
|
+
.doc-sidebar::-webkit-scrollbar-thumb { background: var(--color-doc-template-faint-strong); border-radius: 3px; }
|
|
354
|
+
.doc-sidebar .sidebar-section > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
355
|
+
.doc-sidebar .sidebar-section > span:last-child { flex-shrink: 0; white-space: nowrap; }
|
package/dist/vike.d.ts
CHANGED
package/dist/vike.js
CHANGED
package/dist/vite.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { mdxFrontmatterLoader } from "./lib/mdx-frontmatter-loader.js";
|
|
1
2
|
import { readFile } from "node:fs/promises";
|
|
2
3
|
import react from "@vitejs/plugin-react";
|
|
3
4
|
import vike from "vike/plugin";
|
|
@@ -31,6 +32,7 @@ function dockit() {
|
|
|
31
32
|
return [
|
|
32
33
|
tailwindcss(),
|
|
33
34
|
mdxRawLoader(),
|
|
35
|
+
mdxFrontmatterLoader(),
|
|
34
36
|
{
|
|
35
37
|
enforce: "pre",
|
|
36
38
|
...mdx({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dreamlake/dockit",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.16",
|
|
4
4
|
"description": "The DreamLake documentation shell — Vike + React + Tailwind v4 + MDX docs framework with sidebar, TOC, search, and theming",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -60,7 +60,8 @@
|
|
|
60
60
|
"remark-frontmatter": "^5.0.0",
|
|
61
61
|
"remark-gfm": "^4.0.0",
|
|
62
62
|
"remark-mdx-frontmatter": "^5.2.0",
|
|
63
|
-
"shiki": "^1.24.0"
|
|
63
|
+
"shiki": "^1.24.0",
|
|
64
|
+
"yaml": "^2.9.0"
|
|
64
65
|
},
|
|
65
66
|
"devDependencies": {
|
|
66
67
|
"@mdx-js/react": "^3.1.0",
|
|
@@ -78,6 +79,7 @@
|
|
|
78
79
|
},
|
|
79
80
|
"scripts": {
|
|
80
81
|
"build": "vite build",
|
|
81
|
-
"typecheck": "tsc --noEmit"
|
|
82
|
+
"typecheck": "tsc --noEmit",
|
|
83
|
+
"test": "node --test tests/*.test.mjs"
|
|
82
84
|
}
|
|
83
85
|
}
|