@dreamlake/dockit 0.1.1 → 0.2.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/components/CodeBlock.js +29 -15
- package/dist/components/Preview.js +110 -3
- package/dist/components/Sidebar.js +4 -3
- package/dist/components/TOC.js +7 -6
- package/dist/components/ThemeToggle.d.ts +3 -0
- package/dist/components/ThemeToggle.js +77 -4
- package/dist/components/Topbar.js +3 -299
- package/dist/components/VersionBadge.d.ts +31 -0
- package/dist/components/VersionBadge.js +315 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -1
- package/dist/lib/navigation.d.ts +15 -0
- package/dist/lib/navigation.js +18 -4
- package/dist/renderer/Layout.js +13 -6
- package/dist/renderer/onRenderHtml.js +2 -2
- package/dist/site-config.d.ts +9 -0
- package/dist/site-config.js +2 -1
- package/package.json +1 -1
- package/templates/netlify.example.toml +11 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useRef, useState, useEffect, useLayoutEffect } from "react";
|
|
3
3
|
import { usePageContext } from "vike-react/usePageContext";
|
|
4
|
-
import {
|
|
4
|
+
import { findPage } from "../lib/navigation.js";
|
|
5
5
|
import { siteConfig } from "../site-config.js";
|
|
6
6
|
import { useMediaQuery } from "../lib/use-media-query.js";
|
|
7
7
|
import { useHiddenToggle } from "../lib/use-hidden-toggle.js";
|
|
8
8
|
import { ThemeToggle } from "./ThemeToggle.js";
|
|
9
|
+
import { VersionBadge } from "./VersionBadge.js";
|
|
9
10
|
import { useMerge } from "../renderer/Layout.js";
|
|
10
11
|
import { TabStrip } from "./TabStrip.js";
|
|
11
12
|
function HiddenRevealChip() {
|
|
@@ -45,303 +46,6 @@ function HiddenRevealChip() {
|
|
|
45
46
|
}
|
|
46
47
|
);
|
|
47
48
|
}
|
|
48
|
-
function VersionBadge({
|
|
49
|
-
label,
|
|
50
|
-
version,
|
|
51
|
-
collapsed,
|
|
52
|
-
dropdown = false
|
|
53
|
-
}) {
|
|
54
|
-
const transition = `opacity 0.4s ease, transform 0.4s ${SPRING}, width 0.4s ${SPRING}, margin 0.4s ${SPRING}, padding 0.4s ${SPRING}`;
|
|
55
|
-
const [open, setOpen] = useState(false);
|
|
56
|
-
const [manifest, setManifest] = useState(null);
|
|
57
|
-
const [displayVersion, setDisplayVersion] = useState(version);
|
|
58
|
-
const wrapperRef = useRef(null);
|
|
59
|
-
useEffect(() => {
|
|
60
|
-
if (!dropdown) return;
|
|
61
|
-
let cancelled = false;
|
|
62
|
-
fetch("/versions.json").then((r) => r.ok ? r.json() : null).then((m) => {
|
|
63
|
-
if (!cancelled && m) setManifest(m);
|
|
64
|
-
}).catch(() => {
|
|
65
|
-
});
|
|
66
|
-
return () => {
|
|
67
|
-
cancelled = true;
|
|
68
|
-
};
|
|
69
|
-
}, [dropdown]);
|
|
70
|
-
useEffect(() => {
|
|
71
|
-
if (typeof window === "undefined") return;
|
|
72
|
-
const host = window.location.hostname;
|
|
73
|
-
const m = host.match(/^v(\d+(?:-\d+)+(?:[a-z]+\d+)?)\./i);
|
|
74
|
-
if (m) {
|
|
75
|
-
setDisplayVersion(m[1].replace(/-/g, "."));
|
|
76
|
-
} else if (host.startsWith("stable.") && manifest?.stable) {
|
|
77
|
-
setDisplayVersion(manifest.stable);
|
|
78
|
-
} else if (manifest?.current) {
|
|
79
|
-
setDisplayVersion(manifest.current);
|
|
80
|
-
}
|
|
81
|
-
}, [manifest]);
|
|
82
|
-
useEffect(() => {
|
|
83
|
-
if (!open) return;
|
|
84
|
-
function onDown(e) {
|
|
85
|
-
if (wrapperRef.current && !wrapperRef.current.contains(e.target)) setOpen(false);
|
|
86
|
-
}
|
|
87
|
-
function onKey(e) {
|
|
88
|
-
if (e.key === "Escape") setOpen(false);
|
|
89
|
-
}
|
|
90
|
-
window.addEventListener("mousedown", onDown);
|
|
91
|
-
window.addEventListener("keydown", onKey);
|
|
92
|
-
return () => {
|
|
93
|
-
window.removeEventListener("mousedown", onDown);
|
|
94
|
-
window.removeEventListener("keydown", onKey);
|
|
95
|
-
};
|
|
96
|
-
}, [open]);
|
|
97
|
-
const labelSegStyle = {
|
|
98
|
-
padding: "2px 6px",
|
|
99
|
-
fontWeight: 600,
|
|
100
|
-
borderTopLeftRadius: 3,
|
|
101
|
-
borderBottomLeftRadius: 3
|
|
102
|
-
};
|
|
103
|
-
const versionSegStyle = {
|
|
104
|
-
padding: "2px 6px",
|
|
105
|
-
background: "color-mix(in srgb, var(--color-doc-template-ink) 5%, var(--color-doc-template-bg))",
|
|
106
|
-
fontWeight: 600,
|
|
107
|
-
borderTopRightRadius: 3,
|
|
108
|
-
borderBottomRightRadius: 3,
|
|
109
|
-
display: "inline-flex",
|
|
110
|
-
alignItems: "center",
|
|
111
|
-
gap: dropdown ? 4 : 0,
|
|
112
|
-
border: 0,
|
|
113
|
-
borderLeft: "1px solid var(--color-doc-template-faint)",
|
|
114
|
-
color: "inherit",
|
|
115
|
-
fontFamily: "inherit",
|
|
116
|
-
fontSize: "inherit",
|
|
117
|
-
letterSpacing: "inherit",
|
|
118
|
-
cursor: dropdown ? "pointer" : "default"
|
|
119
|
-
};
|
|
120
|
-
const wrapperBase = {
|
|
121
|
-
fontFamily: "var(--font-doc-template-mono)",
|
|
122
|
-
fontSize: 10,
|
|
123
|
-
fontWeight: 500,
|
|
124
|
-
letterSpacing: "0.02em",
|
|
125
|
-
marginLeft: 6,
|
|
126
|
-
borderRadius: 4,
|
|
127
|
-
transition,
|
|
128
|
-
...collapsed ? {
|
|
129
|
-
opacity: 0,
|
|
130
|
-
transform: "translateX(-4px)",
|
|
131
|
-
pointerEvents: "none",
|
|
132
|
-
width: 0,
|
|
133
|
-
margin: 0,
|
|
134
|
-
padding: 0,
|
|
135
|
-
overflow: "hidden"
|
|
136
|
-
} : {}
|
|
137
|
-
};
|
|
138
|
-
const chevron = dropdown ? /* @__PURE__ */ jsx(
|
|
139
|
-
"svg",
|
|
140
|
-
{
|
|
141
|
-
width: "8",
|
|
142
|
-
height: "8",
|
|
143
|
-
viewBox: "0 0 24 24",
|
|
144
|
-
fill: "none",
|
|
145
|
-
stroke: "currentColor",
|
|
146
|
-
strokeWidth: "3",
|
|
147
|
-
strokeLinecap: "round",
|
|
148
|
-
strokeLinejoin: "round",
|
|
149
|
-
"aria-hidden": true,
|
|
150
|
-
style: {
|
|
151
|
-
opacity: 0.65,
|
|
152
|
-
transform: open ? "scaleY(-1)" : "none",
|
|
153
|
-
transition: "transform 0.22s ease"
|
|
154
|
-
},
|
|
155
|
-
children: /* @__PURE__ */ jsx("path", { d: "M6 9l6 6 6-6" })
|
|
156
|
-
}
|
|
157
|
-
) : null;
|
|
158
|
-
return /* @__PURE__ */ jsxs(
|
|
159
|
-
"span",
|
|
160
|
-
{
|
|
161
|
-
ref: wrapperRef,
|
|
162
|
-
className: "hidden md:inline-flex items-stretch relative border border-doc-template-faint",
|
|
163
|
-
style: { ...wrapperBase, borderRadius: 4 },
|
|
164
|
-
title: dropdown ? void 0 : `${label} ${version}`,
|
|
165
|
-
children: [
|
|
166
|
-
/* @__PURE__ */ jsx(
|
|
167
|
-
"span",
|
|
168
|
-
{
|
|
169
|
-
className: "inline-flex items-center text-doc-template-muted",
|
|
170
|
-
style: labelSegStyle,
|
|
171
|
-
children: label
|
|
172
|
-
}
|
|
173
|
-
),
|
|
174
|
-
dropdown ? /* @__PURE__ */ jsxs(
|
|
175
|
-
"button",
|
|
176
|
-
{
|
|
177
|
-
type: "button",
|
|
178
|
-
onClick: () => setOpen((o) => !o),
|
|
179
|
-
"aria-haspopup": "listbox",
|
|
180
|
-
"aria-expanded": open,
|
|
181
|
-
title: `Switch ${label} version (current v${displayVersion})`,
|
|
182
|
-
className: "text-doc-template-ink hover:bg-doc-template-search",
|
|
183
|
-
style: versionSegStyle,
|
|
184
|
-
children: [
|
|
185
|
-
"v",
|
|
186
|
-
displayVersion,
|
|
187
|
-
chevron
|
|
188
|
-
]
|
|
189
|
-
}
|
|
190
|
-
) : /* @__PURE__ */ jsxs(
|
|
191
|
-
"span",
|
|
192
|
-
{
|
|
193
|
-
className: "inline-flex items-center text-doc-template-ink",
|
|
194
|
-
style: versionSegStyle,
|
|
195
|
-
children: [
|
|
196
|
-
"v",
|
|
197
|
-
displayVersion
|
|
198
|
-
]
|
|
199
|
-
}
|
|
200
|
-
),
|
|
201
|
-
dropdown && open && manifest && (() => {
|
|
202
|
-
const aliasEntries = manifest.aliases ? Object.entries(manifest.aliases) : [];
|
|
203
|
-
const versionEntries = manifest.versions ?? [];
|
|
204
|
-
const ENTRY_STEP = 0.03;
|
|
205
|
-
const ENTRY_BASE = 0.13;
|
|
206
|
-
let idx = 0;
|
|
207
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
208
|
-
/* @__PURE__ */ jsxs(
|
|
209
|
-
"svg",
|
|
210
|
-
{
|
|
211
|
-
width: "14",
|
|
212
|
-
height: "11",
|
|
213
|
-
viewBox: "0 0 14 11",
|
|
214
|
-
"aria-hidden": true,
|
|
215
|
-
style: {
|
|
216
|
-
position: "absolute",
|
|
217
|
-
top: "calc(100% + 4.5px)",
|
|
218
|
-
right: 4,
|
|
219
|
-
zIndex: 81,
|
|
220
|
-
display: "block",
|
|
221
|
-
pointerEvents: "none",
|
|
222
|
-
animation: "popover-wedge-in 0.24s ease both"
|
|
223
|
-
},
|
|
224
|
-
children: [
|
|
225
|
-
/* @__PURE__ */ jsx("path", { d: "M0 11 L7 1 L14 11", stroke: "var(--color-doc-template-faint)", strokeWidth: "1", fill: "none" }),
|
|
226
|
-
/* @__PURE__ */ jsx("path", { d: "M1 11 L7 2 L13 11 Z", fill: "var(--color-doc-template-bg)" })
|
|
227
|
-
]
|
|
228
|
-
}
|
|
229
|
-
),
|
|
230
|
-
/* @__PURE__ */ jsxs(
|
|
231
|
-
"div",
|
|
232
|
-
{
|
|
233
|
-
role: "listbox",
|
|
234
|
-
"aria-label": `Past ${label} versions`,
|
|
235
|
-
className: "absolute border border-doc-template-faint bg-doc-template-bg",
|
|
236
|
-
style: {
|
|
237
|
-
top: "calc(100% + 14px)",
|
|
238
|
-
left: 0,
|
|
239
|
-
minWidth: 220,
|
|
240
|
-
maxHeight: "min(360px, 60vh)",
|
|
241
|
-
overflowY: "auto",
|
|
242
|
-
borderRadius: 12,
|
|
243
|
-
// Drop shadow + a "negative" 0-blur shadow above using the page bg
|
|
244
|
-
// color: it paints a bg-colored band into the strip between the
|
|
245
|
-
// popover top and the navbar's bottom border, masking the navbar's
|
|
246
|
-
// 1px box-shadow in the popover's column so the two don't visually
|
|
247
|
-
// collide.
|
|
248
|
-
boxShadow: "0 6px 24px rgb(0 0 0 / 0.10), 0 -5px 3px 0 var(--color-doc-template-bg)",
|
|
249
|
-
padding: 4,
|
|
250
|
-
zIndex: 80,
|
|
251
|
-
fontFamily: "var(--font-doc-template-mono)",
|
|
252
|
-
fontSize: 11,
|
|
253
|
-
animation: "popover-in 0.28s ease both",
|
|
254
|
-
animationDelay: "0.04s",
|
|
255
|
-
transformOrigin: "top right"
|
|
256
|
-
},
|
|
257
|
-
children: [
|
|
258
|
-
aliasEntries.length > 0 && /* @__PURE__ */ jsx(
|
|
259
|
-
"div",
|
|
260
|
-
{
|
|
261
|
-
style: {
|
|
262
|
-
padding: "4px 6px 2px",
|
|
263
|
-
opacity: 0.55,
|
|
264
|
-
fontSize: 9,
|
|
265
|
-
letterSpacing: "0.08em",
|
|
266
|
-
textTransform: "uppercase",
|
|
267
|
-
animation: "popover-entry-in 0.28s ease both",
|
|
268
|
-
animationDelay: `${ENTRY_BASE + idx++ * ENTRY_STEP}s`
|
|
269
|
-
},
|
|
270
|
-
children: "Aliases"
|
|
271
|
-
}
|
|
272
|
-
),
|
|
273
|
-
aliasEntries.map(([name, url]) => /* @__PURE__ */ jsxs(
|
|
274
|
-
"a",
|
|
275
|
-
{
|
|
276
|
-
href: url,
|
|
277
|
-
className: "block text-doc-template-ink no-underline hover:bg-doc-template-search",
|
|
278
|
-
style: {
|
|
279
|
-
padding: "5px 8px",
|
|
280
|
-
borderRadius: 8,
|
|
281
|
-
animation: "popover-entry-in 0.28s ease both",
|
|
282
|
-
animationDelay: `${ENTRY_BASE + idx++ * ENTRY_STEP}s`
|
|
283
|
-
},
|
|
284
|
-
children: [
|
|
285
|
-
name,
|
|
286
|
-
name === "stable" && manifest.stable && /* @__PURE__ */ jsxs("span", { style: { opacity: 0.5, marginLeft: 6 }, children: [
|
|
287
|
-
"v",
|
|
288
|
-
manifest.stable
|
|
289
|
-
] })
|
|
290
|
-
]
|
|
291
|
-
},
|
|
292
|
-
`alias-${name}`
|
|
293
|
-
)),
|
|
294
|
-
versionEntries.length > 0 && /* @__PURE__ */ jsx(
|
|
295
|
-
"div",
|
|
296
|
-
{
|
|
297
|
-
style: {
|
|
298
|
-
padding: "6px 6px 2px",
|
|
299
|
-
opacity: 0.55,
|
|
300
|
-
fontSize: 9,
|
|
301
|
-
letterSpacing: "0.08em",
|
|
302
|
-
textTransform: "uppercase",
|
|
303
|
-
animation: "popover-entry-in 0.28s ease both",
|
|
304
|
-
animationDelay: `${ENTRY_BASE + idx++ * ENTRY_STEP}s`
|
|
305
|
-
},
|
|
306
|
-
children: "Versions"
|
|
307
|
-
}
|
|
308
|
-
),
|
|
309
|
-
versionEntries.map((v) => {
|
|
310
|
-
const isCurrent = v.version === manifest.current;
|
|
311
|
-
return /* @__PURE__ */ jsxs(
|
|
312
|
-
"a",
|
|
313
|
-
{
|
|
314
|
-
href: v.url,
|
|
315
|
-
className: "text-doc-template-ink no-underline hover:bg-doc-template-search flex items-baseline justify-between gap-3",
|
|
316
|
-
style: {
|
|
317
|
-
padding: "5px 8px",
|
|
318
|
-
borderRadius: 8,
|
|
319
|
-
fontWeight: isCurrent ? 700 : 400,
|
|
320
|
-
background: isCurrent ? "color-mix(in srgb, var(--color-doc-template-accent) 12%, transparent)" : void 0,
|
|
321
|
-
animation: "popover-entry-in 0.28s ease both",
|
|
322
|
-
animationDelay: `${ENTRY_BASE + idx++ * ENTRY_STEP}s`
|
|
323
|
-
},
|
|
324
|
-
children: [
|
|
325
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
326
|
-
"v",
|
|
327
|
-
v.version,
|
|
328
|
-
isCurrent && /* @__PURE__ */ jsx("span", { style: { opacity: 0.55, marginLeft: 6 }, children: "current" })
|
|
329
|
-
] }),
|
|
330
|
-
v.date && /* @__PURE__ */ jsx("span", { style: { opacity: 0.5, fontVariantNumeric: "tabular-nums", fontSize: 10 }, children: v.date })
|
|
331
|
-
]
|
|
332
|
-
},
|
|
333
|
-
v.version
|
|
334
|
-
);
|
|
335
|
-
})
|
|
336
|
-
]
|
|
337
|
-
}
|
|
338
|
-
)
|
|
339
|
-
] });
|
|
340
|
-
})()
|
|
341
|
-
]
|
|
342
|
-
}
|
|
343
|
-
);
|
|
344
|
-
}
|
|
345
49
|
const SPRING = "cubic-bezier(0.4, 0.7, 0.3, 1)";
|
|
346
50
|
const EXPAND_EASE = "cubic-bezier(0.16, 1, 0.3, 1)";
|
|
347
51
|
const EXPAND_MS = 320;
|
|
@@ -354,7 +58,7 @@ const SEARCH_GUTTER = 24;
|
|
|
354
58
|
const SEARCH_INSET = `max(${SEARCH_GUTTER}px, calc((100vw - ${SEARCH_MAX_W}px) / 2))`;
|
|
355
59
|
function Topbar({ searchOpen, onOpenSearch, onCloseSearch, query, setQuery }) {
|
|
356
60
|
const { urlPathname } = usePageContext();
|
|
357
|
-
const current =
|
|
61
|
+
const current = findPage(urlPathname);
|
|
358
62
|
const inputRef = useRef(null);
|
|
359
63
|
const labelRef = useRef(null);
|
|
360
64
|
const focusTimerRef = useRef(null);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface VersionBadgeProps {
|
|
2
|
+
/** Left segment text (e.g. the package name). */
|
|
3
|
+
label: string;
|
|
4
|
+
/** Build-time version shown in the right segment (may be overridden on
|
|
5
|
+
* the client from the hostname / manifest — see below). */
|
|
6
|
+
version: string;
|
|
7
|
+
/** Collapse to width 0 (the Topbar drives this from its merged state).
|
|
8
|
+
* Standalone placements can omit it. */
|
|
9
|
+
collapsed?: boolean;
|
|
10
|
+
/** Turn the version segment into a popover listing the deploys from
|
|
11
|
+
* `/versions.json`. */
|
|
12
|
+
dropdown?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Two-segment version chip: `[ label | v<version> ]`.
|
|
16
|
+
*
|
|
17
|
+
* With `dropdown: true` the right segment opens a popover listing alias
|
|
18
|
+
* and past-version doc URLs sourced from a `versions.json` manifest
|
|
19
|
+
* (schema: `{ current, stable, aliases, versions: [{version, url, date}] }`).
|
|
20
|
+
*
|
|
21
|
+
* The manifest is fetched from the production origin (`siteConfig.url`)
|
|
22
|
+
* first, so the dropdown on old, immutable version-branch deploys still
|
|
23
|
+
* lists releases published after they were built; the same-origin copy is
|
|
24
|
+
* the fallback (local dev, or when no `url` is configured). Cross-origin
|
|
25
|
+
* fetching needs a CORS header on `/versions.json` — see the
|
|
26
|
+
* `netlify.example.toml` template.
|
|
27
|
+
*
|
|
28
|
+
* Rendered by the Topbar for each `siteConfig.versionChips` entry, and
|
|
29
|
+
* exported from the library index for standalone placement.
|
|
30
|
+
*/
|
|
31
|
+
export declare function VersionBadge({ label, version, collapsed, dropdown, }: VersionBadgeProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useRef, useEffect } from "react";
|
|
3
|
+
import { siteConfig } from "../site-config.js";
|
|
4
|
+
const SPRING = "cubic-bezier(0.4, 0.7, 0.3, 1)";
|
|
5
|
+
function VersionBadge({
|
|
6
|
+
label,
|
|
7
|
+
version,
|
|
8
|
+
collapsed = false,
|
|
9
|
+
dropdown = false
|
|
10
|
+
}) {
|
|
11
|
+
const transition = `opacity 0.4s ease, transform 0.4s ${SPRING}, width 0.4s ${SPRING}, margin 0.4s ${SPRING}, padding 0.4s ${SPRING}`;
|
|
12
|
+
const [open, setOpen] = useState(false);
|
|
13
|
+
const [manifest, setManifest] = useState(null);
|
|
14
|
+
const [displayVersion, setDisplayVersion] = useState(version);
|
|
15
|
+
const wrapperRef = useRef(null);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!dropdown) return;
|
|
18
|
+
let cancelled = false;
|
|
19
|
+
const origin = (siteConfig.url || "").replace(/\/+$/, "");
|
|
20
|
+
const sameOrigin = () => fetch("/versions.json").then((r) => r.ok ? r.json() : null);
|
|
21
|
+
const load = origin ? fetch(`${origin}/versions.json`).then((r) => r.ok ? r.json() : Promise.reject(new Error(String(r.status)))).catch(sameOrigin) : sameOrigin();
|
|
22
|
+
load.then((m) => {
|
|
23
|
+
if (!cancelled && m) setManifest(m);
|
|
24
|
+
}).catch(() => {
|
|
25
|
+
});
|
|
26
|
+
return () => {
|
|
27
|
+
cancelled = true;
|
|
28
|
+
};
|
|
29
|
+
}, [dropdown]);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (typeof window === "undefined") return;
|
|
32
|
+
const host = window.location.hostname;
|
|
33
|
+
const m = host.match(/^v(\d+(?:-\d+)+(?:[a-z]+\d+)?)\./i);
|
|
34
|
+
if (m) {
|
|
35
|
+
setDisplayVersion(m[1].replace(/-/g, "."));
|
|
36
|
+
} else if (host.startsWith("stable.") && manifest?.stable) {
|
|
37
|
+
setDisplayVersion(manifest.stable);
|
|
38
|
+
} else if (manifest?.current) {
|
|
39
|
+
setDisplayVersion(manifest.current);
|
|
40
|
+
}
|
|
41
|
+
}, [manifest]);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (!open) return;
|
|
44
|
+
function onDown(e) {
|
|
45
|
+
if (wrapperRef.current && !wrapperRef.current.contains(e.target)) setOpen(false);
|
|
46
|
+
}
|
|
47
|
+
function onKey(e) {
|
|
48
|
+
if (e.key === "Escape") setOpen(false);
|
|
49
|
+
}
|
|
50
|
+
window.addEventListener("mousedown", onDown);
|
|
51
|
+
window.addEventListener("keydown", onKey);
|
|
52
|
+
return () => {
|
|
53
|
+
window.removeEventListener("mousedown", onDown);
|
|
54
|
+
window.removeEventListener("keydown", onKey);
|
|
55
|
+
};
|
|
56
|
+
}, [open]);
|
|
57
|
+
const labelSegStyle = {
|
|
58
|
+
padding: "2px 6px",
|
|
59
|
+
fontWeight: 600,
|
|
60
|
+
borderTopLeftRadius: 3,
|
|
61
|
+
borderBottomLeftRadius: 3
|
|
62
|
+
};
|
|
63
|
+
const versionSegStyle = {
|
|
64
|
+
padding: "2px 6px",
|
|
65
|
+
background: "color-mix(in srgb, var(--color-doc-template-ink) 5%, var(--color-doc-template-bg))",
|
|
66
|
+
fontWeight: 600,
|
|
67
|
+
borderTopRightRadius: 3,
|
|
68
|
+
borderBottomRightRadius: 3,
|
|
69
|
+
display: "inline-flex",
|
|
70
|
+
alignItems: "center",
|
|
71
|
+
gap: dropdown ? 4 : 0,
|
|
72
|
+
border: 0,
|
|
73
|
+
borderLeft: "1px solid var(--color-doc-template-faint)",
|
|
74
|
+
color: "inherit",
|
|
75
|
+
fontFamily: "inherit",
|
|
76
|
+
fontSize: "inherit",
|
|
77
|
+
letterSpacing: "inherit",
|
|
78
|
+
cursor: dropdown ? "pointer" : "default"
|
|
79
|
+
};
|
|
80
|
+
const wrapperBase = {
|
|
81
|
+
fontFamily: "var(--font-doc-template-mono)",
|
|
82
|
+
fontSize: 10,
|
|
83
|
+
fontWeight: 500,
|
|
84
|
+
letterSpacing: "0.02em",
|
|
85
|
+
marginLeft: 6,
|
|
86
|
+
borderRadius: 4,
|
|
87
|
+
transition,
|
|
88
|
+
...collapsed ? {
|
|
89
|
+
opacity: 0,
|
|
90
|
+
transform: "translateX(-4px)",
|
|
91
|
+
pointerEvents: "none",
|
|
92
|
+
width: 0,
|
|
93
|
+
margin: 0,
|
|
94
|
+
padding: 0,
|
|
95
|
+
overflow: "hidden"
|
|
96
|
+
} : {}
|
|
97
|
+
};
|
|
98
|
+
const chevron = dropdown ? /* @__PURE__ */ jsx(
|
|
99
|
+
"svg",
|
|
100
|
+
{
|
|
101
|
+
width: "8",
|
|
102
|
+
height: "8",
|
|
103
|
+
viewBox: "0 0 24 24",
|
|
104
|
+
fill: "none",
|
|
105
|
+
stroke: "currentColor",
|
|
106
|
+
strokeWidth: "3",
|
|
107
|
+
strokeLinecap: "round",
|
|
108
|
+
strokeLinejoin: "round",
|
|
109
|
+
"aria-hidden": true,
|
|
110
|
+
style: {
|
|
111
|
+
opacity: 0.65,
|
|
112
|
+
transform: open ? "scaleY(-1)" : "none",
|
|
113
|
+
transition: "transform 0.22s ease"
|
|
114
|
+
},
|
|
115
|
+
children: /* @__PURE__ */ jsx("path", { d: "M6 9l6 6 6-6" })
|
|
116
|
+
}
|
|
117
|
+
) : null;
|
|
118
|
+
return /* @__PURE__ */ jsxs(
|
|
119
|
+
"span",
|
|
120
|
+
{
|
|
121
|
+
ref: wrapperRef,
|
|
122
|
+
className: "hidden md:inline-flex items-stretch relative border border-doc-template-faint",
|
|
123
|
+
style: { ...wrapperBase, borderRadius: 4 },
|
|
124
|
+
title: dropdown ? void 0 : `${label} ${version}`,
|
|
125
|
+
children: [
|
|
126
|
+
/* @__PURE__ */ jsx(
|
|
127
|
+
"span",
|
|
128
|
+
{
|
|
129
|
+
className: "inline-flex items-center text-doc-template-muted",
|
|
130
|
+
style: labelSegStyle,
|
|
131
|
+
children: label
|
|
132
|
+
}
|
|
133
|
+
),
|
|
134
|
+
dropdown ? /* @__PURE__ */ jsxs(
|
|
135
|
+
"button",
|
|
136
|
+
{
|
|
137
|
+
type: "button",
|
|
138
|
+
onClick: (e) => {
|
|
139
|
+
e.preventDefault();
|
|
140
|
+
e.stopPropagation();
|
|
141
|
+
setOpen((o) => !o);
|
|
142
|
+
},
|
|
143
|
+
"aria-haspopup": "listbox",
|
|
144
|
+
"aria-expanded": open,
|
|
145
|
+
title: `Switch ${label} version (current v${displayVersion})`,
|
|
146
|
+
className: "text-doc-template-ink hover:bg-doc-template-search",
|
|
147
|
+
style: versionSegStyle,
|
|
148
|
+
children: [
|
|
149
|
+
"v",
|
|
150
|
+
displayVersion,
|
|
151
|
+
chevron
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
) : /* @__PURE__ */ jsxs(
|
|
155
|
+
"span",
|
|
156
|
+
{
|
|
157
|
+
className: "inline-flex items-center text-doc-template-ink",
|
|
158
|
+
style: versionSegStyle,
|
|
159
|
+
children: [
|
|
160
|
+
"v",
|
|
161
|
+
displayVersion
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
),
|
|
165
|
+
dropdown && open && manifest && (() => {
|
|
166
|
+
const aliasEntries = manifest.aliases ? Object.entries(manifest.aliases) : [];
|
|
167
|
+
const versionEntries = manifest.versions ?? [];
|
|
168
|
+
const ENTRY_STEP = 0.03;
|
|
169
|
+
const ENTRY_BASE = 0.13;
|
|
170
|
+
let idx = 0;
|
|
171
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
172
|
+
/* @__PURE__ */ jsxs(
|
|
173
|
+
"svg",
|
|
174
|
+
{
|
|
175
|
+
width: "14",
|
|
176
|
+
height: "11",
|
|
177
|
+
viewBox: "0 0 14 11",
|
|
178
|
+
"aria-hidden": true,
|
|
179
|
+
style: {
|
|
180
|
+
position: "absolute",
|
|
181
|
+
top: "calc(100% + 4.5px)",
|
|
182
|
+
right: 4,
|
|
183
|
+
zIndex: 81,
|
|
184
|
+
display: "block",
|
|
185
|
+
pointerEvents: "none",
|
|
186
|
+
animation: "popover-wedge-in 0.24s ease both"
|
|
187
|
+
},
|
|
188
|
+
children: [
|
|
189
|
+
/* @__PURE__ */ jsx("path", { d: "M0 11 L7 1 L14 11", stroke: "var(--color-doc-template-faint)", strokeWidth: "1", fill: "none" }),
|
|
190
|
+
/* @__PURE__ */ jsx("path", { d: "M1 11 L7 2 L13 11 Z", fill: "var(--color-doc-template-bg)" })
|
|
191
|
+
]
|
|
192
|
+
}
|
|
193
|
+
),
|
|
194
|
+
/* @__PURE__ */ jsxs(
|
|
195
|
+
"div",
|
|
196
|
+
{
|
|
197
|
+
role: "listbox",
|
|
198
|
+
"aria-label": `Past ${label} versions`,
|
|
199
|
+
className: "absolute border border-doc-template-faint bg-doc-template-bg",
|
|
200
|
+
style: {
|
|
201
|
+
top: "calc(100% + 14px)",
|
|
202
|
+
left: 0,
|
|
203
|
+
minWidth: 220,
|
|
204
|
+
maxHeight: "min(360px, 60vh)",
|
|
205
|
+
overflowY: "auto",
|
|
206
|
+
borderRadius: 12,
|
|
207
|
+
// Drop shadow + a "negative" 0-blur shadow above using the page bg
|
|
208
|
+
// color: it paints a bg-colored band into the strip between the
|
|
209
|
+
// popover top and the navbar's bottom border, masking the navbar's
|
|
210
|
+
// 1px box-shadow in the popover's column so the two don't visually
|
|
211
|
+
// collide.
|
|
212
|
+
boxShadow: "0 6px 24px rgb(0 0 0 / 0.10), 0 -5px 3px 0 var(--color-doc-template-bg)",
|
|
213
|
+
padding: 4,
|
|
214
|
+
zIndex: 80,
|
|
215
|
+
fontFamily: "var(--font-doc-template-mono)",
|
|
216
|
+
fontSize: 11,
|
|
217
|
+
animation: "popover-in 0.28s ease both",
|
|
218
|
+
animationDelay: "0.04s",
|
|
219
|
+
transformOrigin: "top right"
|
|
220
|
+
},
|
|
221
|
+
children: [
|
|
222
|
+
aliasEntries.length > 0 && /* @__PURE__ */ jsx(
|
|
223
|
+
"div",
|
|
224
|
+
{
|
|
225
|
+
style: {
|
|
226
|
+
padding: "4px 6px 2px",
|
|
227
|
+
opacity: 0.55,
|
|
228
|
+
fontSize: 9,
|
|
229
|
+
letterSpacing: "0.08em",
|
|
230
|
+
textTransform: "uppercase",
|
|
231
|
+
animation: "popover-entry-in 0.28s ease both",
|
|
232
|
+
animationDelay: `${ENTRY_BASE + idx++ * ENTRY_STEP}s`
|
|
233
|
+
},
|
|
234
|
+
children: "Aliases"
|
|
235
|
+
}
|
|
236
|
+
),
|
|
237
|
+
aliasEntries.map(([name, url]) => /* @__PURE__ */ jsxs(
|
|
238
|
+
"a",
|
|
239
|
+
{
|
|
240
|
+
href: url,
|
|
241
|
+
className: "block text-doc-template-ink no-underline hover:bg-doc-template-search",
|
|
242
|
+
style: {
|
|
243
|
+
padding: "5px 8px",
|
|
244
|
+
borderRadius: 8,
|
|
245
|
+
animation: "popover-entry-in 0.28s ease both",
|
|
246
|
+
animationDelay: `${ENTRY_BASE + idx++ * ENTRY_STEP}s`
|
|
247
|
+
},
|
|
248
|
+
children: [
|
|
249
|
+
name,
|
|
250
|
+
name === "stable" && manifest.stable && /* @__PURE__ */ jsxs("span", { style: { opacity: 0.5, marginLeft: 6 }, children: [
|
|
251
|
+
"v",
|
|
252
|
+
manifest.stable
|
|
253
|
+
] }),
|
|
254
|
+
name === "latest" && manifest.current && /* @__PURE__ */ jsxs("span", { style: { opacity: 0.5, marginLeft: 6 }, children: [
|
|
255
|
+
"v",
|
|
256
|
+
manifest.current
|
|
257
|
+
] })
|
|
258
|
+
]
|
|
259
|
+
},
|
|
260
|
+
`alias-${name}`
|
|
261
|
+
)),
|
|
262
|
+
versionEntries.length > 0 && /* @__PURE__ */ jsx(
|
|
263
|
+
"div",
|
|
264
|
+
{
|
|
265
|
+
style: {
|
|
266
|
+
padding: "6px 6px 2px",
|
|
267
|
+
opacity: 0.55,
|
|
268
|
+
fontSize: 9,
|
|
269
|
+
letterSpacing: "0.08em",
|
|
270
|
+
textTransform: "uppercase",
|
|
271
|
+
animation: "popover-entry-in 0.28s ease both",
|
|
272
|
+
animationDelay: `${ENTRY_BASE + idx++ * ENTRY_STEP}s`
|
|
273
|
+
},
|
|
274
|
+
children: "Versions"
|
|
275
|
+
}
|
|
276
|
+
),
|
|
277
|
+
versionEntries.map((v) => {
|
|
278
|
+
const isCurrent = v.version === manifest.current;
|
|
279
|
+
return /* @__PURE__ */ jsxs(
|
|
280
|
+
"a",
|
|
281
|
+
{
|
|
282
|
+
href: v.url,
|
|
283
|
+
className: "text-doc-template-ink no-underline hover:bg-doc-template-search flex items-baseline justify-between gap-3",
|
|
284
|
+
style: {
|
|
285
|
+
padding: "5px 8px",
|
|
286
|
+
borderRadius: 8,
|
|
287
|
+
fontWeight: isCurrent ? 700 : 400,
|
|
288
|
+
background: isCurrent ? "color-mix(in srgb, var(--color-doc-template-accent) 12%, transparent)" : void 0,
|
|
289
|
+
animation: "popover-entry-in 0.28s ease both",
|
|
290
|
+
animationDelay: `${ENTRY_BASE + idx++ * ENTRY_STEP}s`
|
|
291
|
+
},
|
|
292
|
+
children: [
|
|
293
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
294
|
+
"v",
|
|
295
|
+
v.version,
|
|
296
|
+
isCurrent && /* @__PURE__ */ jsx("span", { style: { opacity: 0.55, marginLeft: 6 }, children: "current" })
|
|
297
|
+
] }),
|
|
298
|
+
v.date && /* @__PURE__ */ jsx("span", { style: { opacity: 0.5, fontVariantNumeric: "tabular-nums", fontSize: 10 }, children: v.date })
|
|
299
|
+
]
|
|
300
|
+
},
|
|
301
|
+
v.version
|
|
302
|
+
);
|
|
303
|
+
})
|
|
304
|
+
]
|
|
305
|
+
}
|
|
306
|
+
)
|
|
307
|
+
] });
|
|
308
|
+
})()
|
|
309
|
+
]
|
|
310
|
+
}
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
export {
|
|
314
|
+
VersionBadge
|
|
315
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ import { TabDef as _TabDef } from './lib/tabs';
|
|
|
18
18
|
* })
|
|
19
19
|
*/
|
|
20
20
|
export { siteConfig, defineSiteConfig, type SiteConfig, type VersionChip, } from './site-config';
|
|
21
|
-
export { pages, groupedPages, groupedVisiblePages, initNavigation, getAdjacentPages, type PageMeta, type PageFrontmatter, type PageModule, type NavGroup, } from './lib/navigation';
|
|
21
|
+
export { pages, groupedPages, groupedVisiblePages, initNavigation, getAdjacentPages, normalizePath, findPage, type PageMeta, type PageFrontmatter, type PageModule, type NavGroup, } from './lib/navigation';
|
|
22
22
|
export { searchIndex, rawMarkdown, initSearchIndex, search, type SearchEntry, type SearchHit, } from './lib/search-index';
|
|
23
23
|
export { searchPages, defaultResults, type SearchResult, type SubResult, } from './lib/pagefind-search';
|
|
24
24
|
export { TABS, initTabs, tabForUrl, urlInTab, type TabDef } from './lib/tabs';
|
|
@@ -41,6 +41,7 @@ export { ThemeProvider, useTheme, type Theme } from './components/ThemeProvider'
|
|
|
41
41
|
export { ThemeToggle } from './components/ThemeToggle';
|
|
42
42
|
export { TOC } from './components/TOC';
|
|
43
43
|
export { Topbar } from './components/Topbar';
|
|
44
|
+
export { VersionBadge, type VersionBadgeProps } from './components/VersionBadge';
|
|
44
45
|
export { Layout, useMerge } from './renderer/Layout';
|
|
45
46
|
export interface InitDocsOptions {
|
|
46
47
|
/** Site branding, URLs, version chips, git hash. */
|