boltdocs 2.8.3 → 2.9.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/bin/boltdocs.js +7 -6
- package/dist/{banner-MynZD_Ox.d.cts → banner-C_xkGxzI.d.cts} +1 -1
- package/dist/{banner-3N4Jd_L9.d.ts → banner-D2NddBfF.d.ts} +1 -1
- package/dist/cache-C2PiGyg8.cjs +6 -0
- package/dist/cache-DFW4R3S0.mjs +6 -0
- package/dist/chunk-Ds5LZdWN.cjs +6 -0
- package/dist/client/index.cjs +693 -488
- package/dist/client/index.d.cts +74 -8
- package/dist/client/index.d.ts +74 -8
- package/dist/client/index.js +692 -489
- package/dist/client/mdx.cjs +1 -1
- package/dist/client/mdx.js +1 -1
- package/dist/client/primitives.cjs +4 -4
- package/dist/client/primitives.d.cts +1 -1
- package/dist/client/primitives.d.ts +1 -1
- package/dist/client/primitives.js +4 -4
- package/dist/client/theme/neutral.css +5 -3
- package/dist/client/theme/reset.css +19 -0
- package/dist/{docs-layout-CwCq42Zt.cjs → docs-layout-3TpAt6MB.cjs} +302 -248
- package/dist/{docs-layout-Dn6S5g59.js → docs-layout-6FQ8__ok.js} +303 -249
- package/dist/doctor-BY1tSmQd.mjs +34 -0
- package/dist/{doctor-DyNUVe96.cjs → doctor-Bknon8f5.cjs} +1 -1
- package/dist/doctor-DcFLi4t1.cjs +34 -0
- package/dist/{doctor-aN_leTbh.mjs → doctor-wsPTzt8Y.mjs} +1 -1
- package/dist/{generator-CC2yHzhZ.cjs → generator-BEIF6MOx.cjs} +2 -2
- package/dist/{generator-BHCrLU6h.mjs → generator-DILs0EFN.mjs} +1 -1
- package/dist/handler-B31cxNw0.mjs +6 -0
- package/dist/handler-DfhH9D1b.mjs +28 -0
- package/dist/handler-Djy0HfsI.cjs +28 -0
- package/dist/{icons-dev-DvJ-hh9x.cjs → icons-dev-BryEFkJu.cjs} +96 -7
- package/dist/{icons-dev-Oju24Wjp.js → icons-dev-kJyGWNeg.js} +79 -8
- package/dist/{image-Ch4-GxdO.cjs → image-B9YA_oQ_.cjs} +24 -10
- package/dist/{image-Do8V9PCW.js → image-CjYu9Eml.js} +24 -10
- package/dist/{mdx-5oeCOFhH.js → mdx-Cy_c2zio.js} +116 -33
- package/dist/{mdx-BGM7LjW5.cjs → mdx-WXjAMS8Y.cjs} +121 -32
- package/dist/{meta-loader-Cv9O0Pzl.cjs → meta-loader-D0V6oOQt.cjs} +1 -1
- package/dist/node/cli-entry.cjs +3 -3
- package/dist/node/cli-entry.mjs +3 -3
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.d.cts +368 -24
- package/dist/node/index.d.mts +369 -24
- package/dist/node/index.mjs +1 -1
- package/dist/node/routes/worker.cjs +1 -1
- package/dist/node/routes/worker.mjs +1 -1
- package/dist/node-DV-EPtMU.mjs +160 -0
- package/dist/node-vOVNRABe.cjs +160 -0
- package/dist/{package-CHxJV4Jy.mjs → package-BK_82QLX.mjs} +1 -1
- package/dist/{package-B_SoaGeu.cjs → package-OxKE0p6j.cjs} +1 -1
- package/dist/{parser-B7-6PyQz.cjs → parser-C2Pw18LY.cjs} +1 -1
- package/dist/{parser-BzB-zCkF.cjs → parser-DJoEF96Y.cjs} +1 -1
- package/dist/{parser-D0PVghVt.mjs → parser-DScG_PTs.mjs} +1 -1
- package/dist/routes--LYHSHT7.cjs +6 -0
- package/dist/routes-BAsfsn_e.mjs +6 -0
- package/dist/routes-C6Kr2HFN.cjs +6 -0
- package/dist/routes-CKgGAy8P.mjs +6 -0
- package/dist/{search-dialog-BXVoecTx.cjs → search-dialog-BhXg05Ri.cjs} +1 -1
- package/dist/{search-dialog-BYhOov4S.cjs → search-dialog-BsAiQgnx.cjs} +2 -2
- package/dist/{search-dialog-C09riYmx.js → search-dialog-CaOO1Q4i.js} +2 -2
- package/dist/{search-dialog-CUeAfy-8.cjs → search-dialog-CzwvKoLW.cjs} +1 -1
- package/dist/{search-dialog-DHc_8FFX.js → search-dialog-DRNJsxOv.js} +1 -1
- package/dist/{search-dialog-D8gLkhUV.js → search-dialog-DaR66wl0.js} +1 -1
- package/dist/shiki-adapter-CUtj-xKv.cjs +6 -0
- package/dist/shiki-adapter-EZptJAmW.mjs +6 -0
- package/dist/shiki-adapter-F-P-lDon.mjs +6 -0
- package/dist/shiki-adapter-PQBl32AN.cjs +6 -0
- package/dist/{sidebar-Dlkgbxs6.d.cts → sidebar-BtJyWHy4.d.cts} +43 -4
- package/dist/{sidebar-DNq4_ZAa.d.ts → sidebar-C4fuRYYS.d.ts} +43 -4
- package/dist/{utils-BYITg7T5.mjs → utils-DC4Wq-S2.mjs} +1 -1
- package/dist/{utils-Cjmx1hhk.cjs → utils-wHud9ny5.cjs} +1 -1
- package/dist/worker-pool-BS1LX67P.cjs +6 -0
- package/dist/worker-pool-DRv8ef4z.mjs +6 -0
- package/package.json +7 -3
- package/src/shared/types.ts +36 -3
- package/dist/cache-BMUyNiiA.mjs +0 -6
- package/dist/cache-CKm45d2w.cjs +0 -6
- package/dist/chunk-CU-zTemE.cjs +0 -6
- package/dist/doctor-BArviV8X.cjs +0 -28
- package/dist/doctor-CgLA7_Uv.mjs +0 -28
- package/dist/node-MsTvOgJN.mjs +0 -159
- package/dist/node-h9HmhAFB.cjs +0 -159
- package/dist/routes-BW6Dif_K.mjs +0 -6
- package/dist/routes-DJNJ-rTt.cjs +0 -6
- package/dist/routes-DiYC4nD2.cjs +0 -6
- package/dist/routes-ERSGuFQK.mjs +0 -6
- package/dist/worker-pool-CtqklOXq.cjs +0 -6
- package/dist/worker-pool-k0DY6k8T.mjs +0 -6
- /package/dist/{meta-loader-DzwDFtdT.mjs → meta-loader-By22EnYa.mjs} +0 -0
|
@@ -35,7 +35,7 @@ function BoltdocsProvider({ children, initialLocale = "", initialVersion = "" })
|
|
|
35
35
|
const getSavedPrefs = () => {
|
|
36
36
|
if (typeof window === "undefined") return {};
|
|
37
37
|
try {
|
|
38
|
-
const raw = localStorage.getItem(PREFERENCES_KEY);
|
|
38
|
+
const raw = window.localStorage.getItem(PREFERENCES_KEY);
|
|
39
39
|
return raw ? JSON.parse(raw) : {};
|
|
40
40
|
} catch {
|
|
41
41
|
return {};
|
|
@@ -61,7 +61,7 @@ function BoltdocsProvider({ children, initialLocale = "", initialVersion = "" })
|
|
|
61
61
|
setLocaleState(newL);
|
|
62
62
|
if (typeof window !== "undefined") try {
|
|
63
63
|
const prefs = getSavedPrefs();
|
|
64
|
-
localStorage.setItem(PREFERENCES_KEY, JSON.stringify({
|
|
64
|
+
window.localStorage.setItem(PREFERENCES_KEY, JSON.stringify({
|
|
65
65
|
...prefs,
|
|
66
66
|
locale: newL
|
|
67
67
|
}));
|
|
@@ -72,7 +72,7 @@ function BoltdocsProvider({ children, initialLocale = "", initialVersion = "" })
|
|
|
72
72
|
setVersionState(newV);
|
|
73
73
|
if (typeof window !== "undefined") try {
|
|
74
74
|
const prefs = getSavedPrefs();
|
|
75
|
-
localStorage.setItem(PREFERENCES_KEY, JSON.stringify({
|
|
75
|
+
window.localStorage.setItem(PREFERENCES_KEY, JSON.stringify({
|
|
76
76
|
...prefs,
|
|
77
77
|
version: newV
|
|
78
78
|
}));
|
|
@@ -137,6 +137,9 @@ var icons_exports = /* @__PURE__ */ __exportAll({
|
|
|
137
137
|
Copy: () => Copy,
|
|
138
138
|
CornerDownLeft: () => CornerDownLeft,
|
|
139
139
|
ExternalLink: () => ExternalLink,
|
|
140
|
+
FaceBad: () => FaceBad,
|
|
141
|
+
FaceGood: () => FaceGood,
|
|
142
|
+
FaceRegular: () => FaceRegular,
|
|
140
143
|
File: () => File,
|
|
141
144
|
FileText: () => FileText,
|
|
142
145
|
Hash: () => Hash,
|
|
@@ -401,6 +404,71 @@ const FileText = createIcon("FileText", /* @__PURE__ */ jsxs(Fragment, { childre
|
|
|
401
404
|
/* @__PURE__ */ jsx("path", { d: "M16 17H8" })
|
|
402
405
|
] }));
|
|
403
406
|
const CornerDownLeft = createIcon("CornerDownLeft", /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("polyline", { points: "9 10 4 15 9 20" }), /* @__PURE__ */ jsx("path", { d: "M20 4v7a4 4 0 0 1-4 4H4" })] }));
|
|
407
|
+
const FaceGood = createIcon("FaceGood", /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
408
|
+
/* @__PURE__ */ jsx("circle", {
|
|
409
|
+
cx: "12",
|
|
410
|
+
cy: "12",
|
|
411
|
+
r: "10"
|
|
412
|
+
}),
|
|
413
|
+
/* @__PURE__ */ jsx("path", { d: "M8 14s1.5 2 4 2 4-2 4-2" }),
|
|
414
|
+
/* @__PURE__ */ jsx("line", {
|
|
415
|
+
x1: "9",
|
|
416
|
+
y1: "9",
|
|
417
|
+
x2: "9.01",
|
|
418
|
+
y2: "9"
|
|
419
|
+
}),
|
|
420
|
+
/* @__PURE__ */ jsx("line", {
|
|
421
|
+
x1: "15",
|
|
422
|
+
y1: "9",
|
|
423
|
+
x2: "15.01",
|
|
424
|
+
y2: "9"
|
|
425
|
+
})
|
|
426
|
+
] }));
|
|
427
|
+
const FaceRegular = createIcon("FaceRegular", /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
428
|
+
/* @__PURE__ */ jsx("circle", {
|
|
429
|
+
cx: "12",
|
|
430
|
+
cy: "12",
|
|
431
|
+
r: "10"
|
|
432
|
+
}),
|
|
433
|
+
/* @__PURE__ */ jsx("line", {
|
|
434
|
+
x1: "8",
|
|
435
|
+
y1: "15",
|
|
436
|
+
x2: "16",
|
|
437
|
+
y2: "15"
|
|
438
|
+
}),
|
|
439
|
+
/* @__PURE__ */ jsx("line", {
|
|
440
|
+
x1: "9",
|
|
441
|
+
y1: "9",
|
|
442
|
+
x2: "9.01",
|
|
443
|
+
y2: "9"
|
|
444
|
+
}),
|
|
445
|
+
/* @__PURE__ */ jsx("line", {
|
|
446
|
+
x1: "15",
|
|
447
|
+
y1: "9",
|
|
448
|
+
x2: "15.01",
|
|
449
|
+
y2: "9"
|
|
450
|
+
})
|
|
451
|
+
] }));
|
|
452
|
+
const FaceBad = createIcon("FaceBad", /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
453
|
+
/* @__PURE__ */ jsx("circle", {
|
|
454
|
+
cx: "12",
|
|
455
|
+
cy: "12",
|
|
456
|
+
r: "10"
|
|
457
|
+
}),
|
|
458
|
+
/* @__PURE__ */ jsx("path", { d: "M16 16s-1.5-2-4-2-4 2-4 2" }),
|
|
459
|
+
/* @__PURE__ */ jsx("line", {
|
|
460
|
+
x1: "9",
|
|
461
|
+
y1: "9",
|
|
462
|
+
x2: "9.01",
|
|
463
|
+
y2: "9"
|
|
464
|
+
}),
|
|
465
|
+
/* @__PURE__ */ jsx("line", {
|
|
466
|
+
x1: "15",
|
|
467
|
+
y1: "9",
|
|
468
|
+
x2: "15.01",
|
|
469
|
+
y2: "9"
|
|
470
|
+
})
|
|
471
|
+
] }));
|
|
404
472
|
|
|
405
473
|
//#endregion
|
|
406
474
|
//#region src/client/app/routes-context.tsx
|
|
@@ -444,7 +512,7 @@ function useRoutes() {
|
|
|
444
512
|
const { routes: allRoutes } = useRoutesContext();
|
|
445
513
|
const config = useConfig();
|
|
446
514
|
const location = useLocation();
|
|
447
|
-
const {
|
|
515
|
+
const { currentLocale: currentLocaleStore, currentVersion: currentVersionStore } = useBoltdocsContext();
|
|
448
516
|
const currentPath = normalizePath(location.pathname);
|
|
449
517
|
const currentRoute = allRoutes?.find?.((r) => normalizePath(r.path) === currentPath);
|
|
450
518
|
const currentLocale = config.i18n ? currentLocaleStore || config.i18n.defaultLocale : void 0;
|
|
@@ -464,8 +532,9 @@ function useRoutes() {
|
|
|
464
532
|
const localeMatch = config.i18n ? (r.locale || config.i18n.defaultLocale) === currentLocale : true;
|
|
465
533
|
const versionMatch = config.versions ? (r.version || config.versions.defaultVersion) === currentVersion : true;
|
|
466
534
|
if (!(localeMatch && versionMatch)) return false;
|
|
467
|
-
const
|
|
468
|
-
const
|
|
535
|
+
const pathParts = location.pathname.split("/").filter(Boolean);
|
|
536
|
+
const isCurrentLocalePrefixed = !!(config.i18n && pathParts.includes(currentLocaleStore || config.i18n.defaultLocale));
|
|
537
|
+
const isCurrentVersionPrefixed = !!(config.versions && pathParts.includes(currentVersionStore || config.versions.defaultVersion));
|
|
469
538
|
const isRouteLocalePrefixed = !!r.locale;
|
|
470
539
|
const isRouteVersionPrefixed = !!r.version;
|
|
471
540
|
const locale = r.locale || defaultLocale;
|
|
@@ -483,7 +552,9 @@ function useRoutes() {
|
|
|
483
552
|
config,
|
|
484
553
|
currentLocale,
|
|
485
554
|
currentVersion,
|
|
486
|
-
|
|
555
|
+
location.pathname,
|
|
556
|
+
currentLocaleStore,
|
|
557
|
+
currentVersionStore
|
|
487
558
|
]);
|
|
488
559
|
const collections = useMemo(() => {
|
|
489
560
|
return new Set((allRoutes || []).map((r) => r.collection).filter(Boolean));
|
|
@@ -842,4 +913,4 @@ const BracketsRed = (props) => /* @__PURE__ */ jsxs("svg", {
|
|
|
842
913
|
});
|
|
843
914
|
|
|
844
915
|
//#endregion
|
|
845
|
-
export {
|
|
916
|
+
export { TextAlignStart as $, ChevronRight as A, Hash as B, RoutesProvider as C, Check as D, ArrowLeft as E, FaceBad as F, Link$2 as G, Info as H, FaceGood as I, Moon as J, Menu as K, FaceRegular as L, Copy as M, CornerDownLeft as N, ChevronDown as O, ExternalLink as P, Sun as Q, File as R, normalizePath as S, AlertTriangle as T, Languages as U, Home as V, Lightbulb as W, Pencil as X, MoreVertical as Y, Search as Z, Link$1 as _, Csv as a, useBoltdocsContext as at, useLocalizedTo as b, JavaScript as c, React$1 as d, X as et, Rust as f, Yaml as g, XSocial as h, Css as i, BoltdocsProvider as it, CircleHelp as j, ChevronLeft as k, Json as l, TypeScript as m, BracketsOrange as n, ConfigContext as nt, Discord as o, Shell as p, Monitor as q, BracketsRed as r, useConfig as rt, Github as s, Bluesky as t, icons_exports as tt, Markdown as u, NavLink as v, AlertCircle as w, useRoutes as x, cn as y, FileText as z };
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Copyright (c) 2026 Jesus Alcala
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
|
-
const require_icons_dev = require('./icons-dev-
|
|
6
|
+
const require_icons_dev = require('./icons-dev-BryEFkJu.cjs');
|
|
7
7
|
let react = require("react");
|
|
8
8
|
react = require_icons_dev.__toESM(react);
|
|
9
9
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -16,8 +16,16 @@ const THEME_INSTANCE_SYMBOL = Symbol.for("__BDOCS_THEME_INSTANCE__");
|
|
|
16
16
|
const THEME_EVENT = "boltdocs-theme-change";
|
|
17
17
|
const ThemeContext = globalThis[THEME_CONTEXT_SYMBOL] || (globalThis[THEME_CONTEXT_SYMBOL] = (0, react.createContext)(void 0));
|
|
18
18
|
function ThemeProvider({ children }) {
|
|
19
|
-
const [theme, setThemeState] = (0, react.useState)(
|
|
20
|
-
|
|
19
|
+
const [theme, setThemeState] = (0, react.useState)(() => {
|
|
20
|
+
if (typeof window !== "undefined") try {
|
|
21
|
+
return window.localStorage.getItem("boltdocs-theme") || "system";
|
|
22
|
+
} catch {}
|
|
23
|
+
return "system";
|
|
24
|
+
});
|
|
25
|
+
const [resolvedTheme, setResolvedTheme] = (0, react.useState)(() => {
|
|
26
|
+
if (typeof window !== "undefined" && typeof document !== "undefined" && document.documentElement) return document.documentElement.classList.contains("dark") ? "dark" : "light";
|
|
27
|
+
return "light";
|
|
28
|
+
});
|
|
21
29
|
const applyTheme = (targetTheme) => {
|
|
22
30
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
23
31
|
const isDark = targetTheme === "dark" || targetTheme === "system" && mediaQuery.matches;
|
|
@@ -27,21 +35,27 @@ function ThemeProvider({ children }) {
|
|
|
27
35
|
setResolvedTheme(isDark ? "dark" : "light");
|
|
28
36
|
};
|
|
29
37
|
(0, react.useEffect)(() => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
try {
|
|
39
|
+
const savedTheme = window.localStorage.getItem("boltdocs-theme");
|
|
40
|
+
if (savedTheme) {
|
|
41
|
+
setThemeState(savedTheme);
|
|
42
|
+
applyTheme(savedTheme);
|
|
43
|
+
} else applyTheme("system");
|
|
44
|
+
} catch {}
|
|
35
45
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
36
46
|
const listener = () => {
|
|
37
|
-
|
|
47
|
+
try {
|
|
48
|
+
if ((window.localStorage.getItem("boltdocs-theme") || "system") === "system") applyTheme("system");
|
|
49
|
+
} catch {}
|
|
38
50
|
};
|
|
39
51
|
mediaQuery.addEventListener("change", listener);
|
|
40
52
|
return () => mediaQuery.removeEventListener("change", listener);
|
|
41
53
|
}, []);
|
|
42
54
|
const setTheme = (newTheme) => {
|
|
43
55
|
setThemeState(newTheme);
|
|
44
|
-
|
|
56
|
+
try {
|
|
57
|
+
window.localStorage.setItem("boltdocs-theme", newTheme);
|
|
58
|
+
} catch {}
|
|
45
59
|
applyTheme(newTheme);
|
|
46
60
|
if (typeof window !== "undefined") window.dispatchEvent(new CustomEvent(THEME_EVENT, { detail: newTheme }));
|
|
47
61
|
};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Copyright (c) 2026 Jesus Alcala
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { G as Link, _ as Link$1, y as cn } from "./icons-dev-kJyGWNeg.js";
|
|
7
7
|
import * as React$1 from "react";
|
|
8
8
|
import { createContext, use, useEffect, useState } from "react";
|
|
9
9
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -15,8 +15,16 @@ const THEME_INSTANCE_SYMBOL = Symbol.for("__BDOCS_THEME_INSTANCE__");
|
|
|
15
15
|
const THEME_EVENT = "boltdocs-theme-change";
|
|
16
16
|
const ThemeContext = globalThis[THEME_CONTEXT_SYMBOL] || (globalThis[THEME_CONTEXT_SYMBOL] = createContext(void 0));
|
|
17
17
|
function ThemeProvider({ children }) {
|
|
18
|
-
const [theme, setThemeState] = useState(
|
|
19
|
-
|
|
18
|
+
const [theme, setThemeState] = useState(() => {
|
|
19
|
+
if (typeof window !== "undefined") try {
|
|
20
|
+
return window.localStorage.getItem("boltdocs-theme") || "system";
|
|
21
|
+
} catch {}
|
|
22
|
+
return "system";
|
|
23
|
+
});
|
|
24
|
+
const [resolvedTheme, setResolvedTheme] = useState(() => {
|
|
25
|
+
if (typeof window !== "undefined" && typeof document !== "undefined" && document.documentElement) return document.documentElement.classList.contains("dark") ? "dark" : "light";
|
|
26
|
+
return "light";
|
|
27
|
+
});
|
|
20
28
|
const applyTheme = (targetTheme) => {
|
|
21
29
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
22
30
|
const isDark = targetTheme === "dark" || targetTheme === "system" && mediaQuery.matches;
|
|
@@ -26,21 +34,27 @@ function ThemeProvider({ children }) {
|
|
|
26
34
|
setResolvedTheme(isDark ? "dark" : "light");
|
|
27
35
|
};
|
|
28
36
|
useEffect(() => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
try {
|
|
38
|
+
const savedTheme = window.localStorage.getItem("boltdocs-theme");
|
|
39
|
+
if (savedTheme) {
|
|
40
|
+
setThemeState(savedTheme);
|
|
41
|
+
applyTheme(savedTheme);
|
|
42
|
+
} else applyTheme("system");
|
|
43
|
+
} catch {}
|
|
34
44
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
35
45
|
const listener = () => {
|
|
36
|
-
|
|
46
|
+
try {
|
|
47
|
+
if ((window.localStorage.getItem("boltdocs-theme") || "system") === "system") applyTheme("system");
|
|
48
|
+
} catch {}
|
|
37
49
|
};
|
|
38
50
|
mediaQuery.addEventListener("change", listener);
|
|
39
51
|
return () => mediaQuery.removeEventListener("change", listener);
|
|
40
52
|
}, []);
|
|
41
53
|
const setTheme = (newTheme) => {
|
|
42
54
|
setThemeState(newTheme);
|
|
43
|
-
|
|
55
|
+
try {
|
|
56
|
+
window.localStorage.setItem("boltdocs-theme", newTheme);
|
|
57
|
+
} catch {}
|
|
44
58
|
applyTheme(newTheme);
|
|
45
59
|
if (typeof window !== "undefined") window.dispatchEvent(new CustomEvent(THEME_EVENT, { detail: newTheme }));
|
|
46
60
|
};
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Copyright (c) 2026 Jesus Alcala
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
|
-
import { D as Check,
|
|
7
|
-
import { a as CodeBlockGroup, i as CodeBlockContent, l as useTheme, n as Tooltip, o as CodeBlockHeader, r as CodeBlock$1, s as Heading$1, t as Image$1 } from "./image-
|
|
6
|
+
import { D as Check, H as Info, M as Copy, R as File, T as AlertTriangle, W as Lightbulb, _ as Link, a as Csv, c as JavaScript, d as React$1, f as Rust, g as Yaml, i as Css, l as Json, m as TypeScript, n as BracketsOrange, p as Shell, r as BracketsRed, rt as useConfig, u as Markdown, w as AlertCircle, y as cn } from "./icons-dev-kJyGWNeg.js";
|
|
7
|
+
import { a as CodeBlockGroup, i as CodeBlockContent, l as useTheme, n as Tooltip, o as CodeBlockHeader, r as CodeBlock$1, s as Heading$1, t as Image$1 } from "./image-CjYu9Eml.js";
|
|
8
8
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
9
9
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10
10
|
import { Button } from "react-aria-components";
|
|
@@ -248,12 +248,66 @@ const copyToClipboard = async (text) => {
|
|
|
248
248
|
|
|
249
249
|
//#endregion
|
|
250
250
|
//#region src/client/components/mdx/use-code-block.ts
|
|
251
|
+
const langIconMap = {
|
|
252
|
+
ts: TypeScript,
|
|
253
|
+
tsx: React$1,
|
|
254
|
+
js: JavaScript,
|
|
255
|
+
jsx: React$1,
|
|
256
|
+
json: Json,
|
|
257
|
+
css: Css,
|
|
258
|
+
html: BracketsOrange,
|
|
259
|
+
md: Markdown,
|
|
260
|
+
mdx: Markdown,
|
|
261
|
+
bash: Shell,
|
|
262
|
+
sh: Shell,
|
|
263
|
+
yaml: Yaml,
|
|
264
|
+
yml: Yaml,
|
|
265
|
+
rs: Rust,
|
|
266
|
+
rust: Rust,
|
|
267
|
+
toml: BracketsRed,
|
|
268
|
+
csv: Csv
|
|
269
|
+
};
|
|
251
270
|
function useCodeBlock(props) {
|
|
252
271
|
const [copied, setCopied] = useState(false);
|
|
253
272
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
254
273
|
const [isExpandable, setIsExpandable] = useState(false);
|
|
255
274
|
const preRef = useRef(null);
|
|
256
275
|
const timerRef = useRef(null);
|
|
276
|
+
const [rated, setRated] = useState(null);
|
|
277
|
+
const customConfig = useConfig().integrations?.feedback?.custom;
|
|
278
|
+
const showCodeBlockFeedback = !!(customConfig?.enabled && !props.plain);
|
|
279
|
+
const lang = props.lang || props["data-lang"] || "";
|
|
280
|
+
const isHighlighted = props["data-highlighted"] === "true" || typeof props.className === "string" && props.className.includes("shiki");
|
|
281
|
+
const rawHighlightedHtml = props.highlightedHtml || props["data-highlighted-html"];
|
|
282
|
+
const effectiveHighlightedHtml = typeof rawHighlightedHtml === "string" ? rawHighlightedHtml.replace(/<span class="line">\s*(?:<span[^>]*>\s*<\/span>)?\s*<\/span>\s*(<\/code>\s*<\/pre>)/g, "$1") : rawHighlightedHtml;
|
|
283
|
+
const effectiveTitle = props.title || props["data-title"];
|
|
284
|
+
const handleRate = useCallback(async (type) => {
|
|
285
|
+
if (rated) return;
|
|
286
|
+
setRated(type);
|
|
287
|
+
try {
|
|
288
|
+
const code = preRef.current?.textContent ?? "";
|
|
289
|
+
const snippet = code.trim().slice(0, 100) + (code.length > 100 ? "..." : "");
|
|
290
|
+
const blockId = `Code Block (${lang || "plain"}): \`${snippet}\``;
|
|
291
|
+
const endpoint = customConfig?.endpoint || "/api/feedback";
|
|
292
|
+
await fetch(endpoint, {
|
|
293
|
+
method: "POST",
|
|
294
|
+
headers: { "Content-Type": "application/json" },
|
|
295
|
+
body: JSON.stringify({
|
|
296
|
+
rating: type === "up" ? "good" : "bad",
|
|
297
|
+
comment: `Rated code block: ${type === "up" ? "Helpful" : "Unhelpful"}`,
|
|
298
|
+
path: window.location.pathname,
|
|
299
|
+
title: document.title,
|
|
300
|
+
blockId
|
|
301
|
+
})
|
|
302
|
+
});
|
|
303
|
+
} catch (err) {
|
|
304
|
+
console.error("Failed to submit code block feedback:", err);
|
|
305
|
+
}
|
|
306
|
+
}, [
|
|
307
|
+
rated,
|
|
308
|
+
lang,
|
|
309
|
+
customConfig?.endpoint
|
|
310
|
+
]);
|
|
257
311
|
useEffect(() => {
|
|
258
312
|
return () => {
|
|
259
313
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
@@ -272,6 +326,7 @@ function useCodeBlock(props) {
|
|
|
272
326
|
const lines = (preRef.current?.textContent ?? "").trim().split("\n").length;
|
|
273
327
|
setIsExpandable(lines > 6);
|
|
274
328
|
}, [props.children, props.highlightedHtml]);
|
|
329
|
+
const LangIcon = langIconMap[lang] || File;
|
|
275
330
|
return {
|
|
276
331
|
copied,
|
|
277
332
|
isExpanded,
|
|
@@ -279,31 +334,20 @@ function useCodeBlock(props) {
|
|
|
279
334
|
isExpandable,
|
|
280
335
|
preRef,
|
|
281
336
|
handleCopy,
|
|
282
|
-
shouldTruncate: isExpandable && !isExpanded
|
|
337
|
+
shouldTruncate: isExpandable && !isExpanded,
|
|
338
|
+
isHighlighted,
|
|
339
|
+
effectiveHighlightedHtml,
|
|
340
|
+
effectiveTitle,
|
|
341
|
+
lang,
|
|
342
|
+
showCodeBlockFeedback,
|
|
343
|
+
rated,
|
|
344
|
+
handleRate,
|
|
345
|
+
LangIcon
|
|
283
346
|
};
|
|
284
347
|
}
|
|
285
348
|
|
|
286
349
|
//#endregion
|
|
287
350
|
//#region src/client/components/mdx/code-block.tsx
|
|
288
|
-
const langIconMap = {
|
|
289
|
-
ts: TypeScript,
|
|
290
|
-
tsx: React$1,
|
|
291
|
-
js: JavaScript,
|
|
292
|
-
jsx: React$1,
|
|
293
|
-
json: Json,
|
|
294
|
-
css: Css,
|
|
295
|
-
html: BracketsOrange,
|
|
296
|
-
md: Markdown,
|
|
297
|
-
mdx: Markdown,
|
|
298
|
-
bash: Shell,
|
|
299
|
-
sh: Shell,
|
|
300
|
-
yaml: Yaml,
|
|
301
|
-
yml: Yaml,
|
|
302
|
-
rs: Rust,
|
|
303
|
-
rust: Rust,
|
|
304
|
-
toml: BracketsRed,
|
|
305
|
-
csv: Csv
|
|
306
|
-
};
|
|
307
351
|
const CopyButton = ({ copied, handleCopy }) => {
|
|
308
352
|
return /* @__PURE__ */ jsx(Tooltip, {
|
|
309
353
|
content: copied ? "Copied!" : "Copy code",
|
|
@@ -315,16 +359,52 @@ const CopyButton = ({ copied, handleCopy }) => {
|
|
|
315
359
|
})
|
|
316
360
|
});
|
|
317
361
|
};
|
|
362
|
+
const CodeBlockFeedback = ({ rated, onRate }) => {
|
|
363
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
364
|
+
className: "flex items-center gap-0.5 border-r border-subtle pr-1.5 mr-1",
|
|
365
|
+
children: [/* @__PURE__ */ jsx(Tooltip, {
|
|
366
|
+
content: rated === "up" ? "Helpful!" : "This code is helpful",
|
|
367
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
368
|
+
onPress: () => onRate("up"),
|
|
369
|
+
disabled: rated !== null,
|
|
370
|
+
className: cn("grid place-items-center size-8 bg-transparent outline-none cursor-pointer transition-all duration-200 hover:scale-110 active:scale-95 [&>svg]:size-4 [&>svg]:stroke-2 z-10", rated === "up" ? "text-emerald-500 dark:text-emerald-400" : rated === "down" ? "opacity-30 cursor-not-allowed text-muted" : "text-muted hover:text-body"),
|
|
371
|
+
"aria-label": "Mark as helpful",
|
|
372
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
373
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
374
|
+
viewBox: "0 0 24 24",
|
|
375
|
+
fill: "none",
|
|
376
|
+
stroke: "currentColor",
|
|
377
|
+
strokeWidth: "2",
|
|
378
|
+
strokeLinecap: "round",
|
|
379
|
+
strokeLinejoin: "round",
|
|
380
|
+
children: /* @__PURE__ */ jsx("path", { d: "M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3" })
|
|
381
|
+
})
|
|
382
|
+
})
|
|
383
|
+
}), /* @__PURE__ */ jsx(Tooltip, {
|
|
384
|
+
content: rated === "down" ? "Unhelpful" : "This code is unhelpful",
|
|
385
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
386
|
+
onPress: () => onRate("down"),
|
|
387
|
+
disabled: rated !== null,
|
|
388
|
+
className: cn("grid place-items-center size-8 bg-transparent outline-none cursor-pointer transition-all duration-200 hover:scale-110 active:scale-95 [&>svg]:size-4 [&>svg]:stroke-2 z-10", rated === "down" ? "text-rose-500 dark:text-rose-400" : rated === "up" ? "opacity-30 cursor-not-allowed text-muted" : "text-muted hover:text-body"),
|
|
389
|
+
"aria-label": "Mark as unhelpful",
|
|
390
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
391
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
392
|
+
viewBox: "0 0 24 24",
|
|
393
|
+
fill: "none",
|
|
394
|
+
stroke: "currentColor",
|
|
395
|
+
strokeWidth: "2",
|
|
396
|
+
strokeLinecap: "round",
|
|
397
|
+
strokeLinejoin: "round",
|
|
398
|
+
children: /* @__PURE__ */ jsx("path", { d: "M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h3a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-3" })
|
|
399
|
+
})
|
|
400
|
+
})
|
|
401
|
+
})]
|
|
402
|
+
});
|
|
403
|
+
};
|
|
318
404
|
function CodeBlock(props) {
|
|
319
405
|
const { children, hideCopy = false, highlightedHtml, "data-highlighted-html": dataHighlightedHtml, title, "data-title": dataTitle, "data-lang": dataLang, plain = false, lineNumbers, showLineNumbers, wordWrap, "word-wrap": wordWrapHyphen, metastring, ...rest } = props;
|
|
320
406
|
const { className: shikiClassName, ...cleanRest } = rest;
|
|
321
|
-
const
|
|
322
|
-
const rawHighlightedHtml = highlightedHtml || dataHighlightedHtml;
|
|
323
|
-
const effectiveHighlightedHtml = typeof rawHighlightedHtml === "string" ? rawHighlightedHtml.replace(/<span class="line">\s*(?:<span[^>]*>\s*<\/span>)?\s*<\/span>\s*(<\/code>\s*<\/pre>)/g, "$1") : rawHighlightedHtml;
|
|
324
|
-
const effectiveTitle = title || dataTitle;
|
|
325
|
-
const lang = props.lang || dataLang || "";
|
|
326
|
-
const { copied, isExpanded, setIsExpanded, isExpandable, preRef, handleCopy, shouldTruncate } = useCodeBlock(props);
|
|
327
|
-
const LangIcon = langIconMap[lang];
|
|
407
|
+
const { copied, isExpanded, setIsExpanded, isExpandable, preRef, handleCopy, shouldTruncate, isHighlighted, effectiveHighlightedHtml, effectiveTitle, showCodeBlockFeedback, rated, handleRate, LangIcon } = useCodeBlock(props);
|
|
328
408
|
return /* @__PURE__ */ jsxs(CodeBlock$1, {
|
|
329
409
|
plain,
|
|
330
410
|
className: props.className,
|
|
@@ -333,12 +413,15 @@ function CodeBlock(props) {
|
|
|
333
413
|
children: [/* @__PURE__ */ jsx(CodeBlockGroup, { children: effectiveTitle && /* @__PURE__ */ jsxs(Fragment, { children: [LangIcon ? /* @__PURE__ */ jsx(LangIcon, { size: 14 }) : /* @__PURE__ */ jsx(File, {
|
|
334
414
|
size: 14,
|
|
335
415
|
className: "opacity-60"
|
|
336
|
-
}), /* @__PURE__ */ jsx("span", { children: effectiveTitle })] }) }), /* @__PURE__ */
|
|
416
|
+
}), /* @__PURE__ */ jsx("span", { children: effectiveTitle })] }) }), /* @__PURE__ */ jsxs("div", {
|
|
337
417
|
className: "flex items-center gap-1",
|
|
338
|
-
children:
|
|
418
|
+
children: [showCodeBlockFeedback && /* @__PURE__ */ jsx(CodeBlockFeedback, {
|
|
419
|
+
rated,
|
|
420
|
+
onRate: handleRate
|
|
421
|
+
}), !hideCopy && /* @__PURE__ */ jsx(CopyButton, {
|
|
339
422
|
copied,
|
|
340
423
|
handleCopy
|
|
341
|
-
})
|
|
424
|
+
})]
|
|
342
425
|
})]
|
|
343
426
|
}), /* @__PURE__ */ jsxs(CodeBlockContent, {
|
|
344
427
|
shouldTruncate,
|
|
@@ -521,4 +604,4 @@ const mdx_components_default = {
|
|
|
521
604
|
};
|
|
522
605
|
|
|
523
606
|
//#endregion
|
|
524
|
-
export {
|
|
607
|
+
export { useCodeBlock as n, copyToClipboard as r, mdx_components_default as t };
|