zudoku 0.13.7 → 0.14.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/cli.js +2 -2
- package/dist/app/entry.client.js +2 -2
- package/dist/app/entry.client.js.map +1 -1
- package/dist/app/entry.server.js +3 -0
- package/dist/app/entry.server.js.map +1 -1
- package/dist/app/main.d.ts +1 -0
- package/dist/app/main.js +6 -21
- package/dist/app/main.js.map +1 -1
- package/dist/app/standalone.js.map +1 -1
- package/dist/cli/common/machine-id/lib.js.map +1 -1
- package/dist/cli/common/outdated.js.map +1 -1
- package/dist/cli/common/utils/box.js.map +1 -1
- package/dist/config/validators/InputSidebarSchema.d.ts +2 -2
- package/dist/config/validators/SidebarSchema.d.ts +24 -1
- package/dist/config/validators/SidebarSchema.js +76 -39
- package/dist/config/validators/SidebarSchema.js.map +1 -1
- package/dist/config/validators/validate.d.ts +329 -264
- package/dist/config/validators/validate.js +11 -10
- package/dist/config/validators/validate.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/components/Header.js +5 -1
- package/dist/lib/components/Header.js.map +1 -1
- package/dist/lib/components/Heading.d.ts +1 -1
- package/dist/lib/components/SyntaxHighlight.js +4 -1
- package/dist/lib/components/SyntaxHighlight.js.map +1 -1
- package/dist/lib/components/TopNavigation.js +30 -5
- package/dist/lib/components/TopNavigation.js.map +1 -1
- package/dist/lib/components/context/ZudokuContext.d.ts +6 -12
- package/dist/lib/components/context/ZudokuContext.js +26 -20
- package/dist/lib/components/context/ZudokuContext.js.map +1 -1
- package/dist/lib/components/navigation/Sidebar.js +3 -3
- package/dist/lib/components/navigation/Sidebar.js.map +1 -1
- package/dist/lib/components/navigation/SidebarCategory.js +2 -4
- package/dist/lib/components/navigation/SidebarCategory.js.map +1 -1
- package/dist/lib/components/navigation/SidebarItem.js +1 -3
- package/dist/lib/components/navigation/SidebarItem.js.map +1 -1
- package/dist/lib/components/navigation/utils.js +10 -14
- package/dist/lib/components/navigation/utils.js.map +1 -1
- package/dist/lib/core/DevPortalContext.d.ts +3 -7
- package/dist/lib/core/DevPortalContext.js.map +1 -1
- package/dist/lib/core/plugins.d.ts +1 -0
- package/dist/lib/core/plugins.js.map +1 -1
- package/dist/lib/plugins/markdown/index.d.ts +5 -6
- package/dist/lib/plugins/markdown/index.js +31 -3
- package/dist/lib/plugins/markdown/index.js.map +1 -1
- package/dist/lib/plugins/markdown/resolver.d.ts +38 -0
- package/dist/lib/plugins/markdown/resolver.js +75 -0
- package/dist/lib/plugins/markdown/resolver.js.map +1 -0
- package/dist/lib/plugins/openapi/Endpoint.js.map +1 -1
- package/dist/lib/plugins/openapi/RequestBodySidecarBox.js.map +1 -1
- package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
- package/dist/lib/plugins/openapi/client/worker.js.map +1 -1
- package/dist/lib/plugins/openapi/index.js.map +1 -1
- package/dist/lib/ui/Badge.d.ts +1 -1
- package/dist/lib/ui/Button.d.ts +1 -1
- package/dist/lib/util/MdxComponents.js.map +1 -1
- package/dist/lib/util/useScrollToAnchor.js.map +1 -1
- package/dist/vite/build.js +7 -2
- package/dist/vite/build.js.map +1 -1
- package/dist/vite/config.js +11 -6
- package/dist/vite/config.js.map +1 -1
- package/dist/vite/debug.d.ts +1 -0
- package/dist/vite/debug.js +10 -0
- package/dist/vite/debug.js.map +1 -0
- package/dist/vite/plugin-config-reload.js +0 -2
- package/dist/vite/plugin-config-reload.js.map +1 -1
- package/dist/vite/plugin-docs.js +37 -26
- package/dist/vite/plugin-docs.js.map +1 -1
- package/dist/vite/plugin-frontmatter.d.ts +2 -1
- package/dist/vite/plugin-frontmatter.js +27 -24
- package/dist/vite/plugin-frontmatter.js.map +1 -1
- package/dist/vite/plugin-sidebar.js +7 -6
- package/dist/vite/plugin-sidebar.js.map +1 -1
- package/dist/vite/plugin.js +1 -1
- package/dist/vite/plugin.js.map +1 -1
- package/dist/vite/prerender.d.ts +5 -1
- package/dist/vite/prerender.js +6 -5
- package/dist/vite/prerender.js.map +1 -1
- package/lib/{utils-B2yoT99j.js → AnchorLink-BbB2q-jx.js} +214 -258
- package/lib/AnchorLink-BbB2q-jx.js.map +1 -0
- package/lib/{AuthenticationPlugin-Bpdes0cJ.js → AuthenticationPlugin-C9BHGXlE.js} +2 -2
- package/lib/{AuthenticationPlugin-Bpdes0cJ.js.map → AuthenticationPlugin-C9BHGXlE.js.map} +1 -1
- package/lib/{Markdown-1BO9EA_X.js → Markdown-BDcCAWwm.js} +18 -16
- package/lib/{Markdown-1BO9EA_X.js.map → Markdown-BDcCAWwm.js.map} +1 -1
- package/lib/{MdxPage-BEOcOICU.js → MdxPage-DKMH_t0f.js} +14 -13
- package/lib/{MdxPage-BEOcOICU.js.map → MdxPage-DKMH_t0f.js.map} +1 -1
- package/lib/{OperationList-Cea2Yt8e.js → OperationList-DnaAtLxP.js} +3 -3
- package/lib/OperationList-DnaAtLxP.js.map +1 -0
- package/lib/{Route-BHT-onwf.js → Route-DSbLrlig.js} +2 -2
- package/lib/{Route-BHT-onwf.js.map → Route-DSbLrlig.js.map} +1 -1
- package/lib/{Select-m1aXZGAP.js → Select-Bagt3Bme.js} +3 -3
- package/lib/{Select-m1aXZGAP.js.map → Select-Bagt3Bme.js.map} +1 -1
- package/lib/{SlotletProvider-CPfsBw39.js → SlotletProvider-4Naek_5M.js} +2 -2
- package/lib/{SlotletProvider-CPfsBw39.js.map → SlotletProvider-4Naek_5M.js.map} +1 -1
- package/lib/{ZudokuContext-D1D8Anlj.js → ZudokuContext-BKXGJTmu.js} +459 -410
- package/lib/ZudokuContext-BKXGJTmu.js.map +1 -0
- package/lib/__vite-browser-external-BYRIRx8p.js +9 -0
- package/lib/__vite-browser-external-BYRIRx8p.js.map +1 -0
- package/lib/assets/worker-Bf8vjASY.js.map +1 -1
- package/lib/{hook-JSRuxV1P.js → hook-sn0zMTkE.js} +2 -2
- package/lib/{hook-JSRuxV1P.js.map → hook-sn0zMTkE.js.map} +1 -1
- package/lib/{index-Cj-F-4ME.js → index-B3F9d8oi.js} +430 -433
- package/lib/index-B3F9d8oi.js.map +1 -0
- package/lib/{urql-core-KJnLL26g.js → urql-core-CqTI9H6N.js} +289 -261
- package/lib/urql-core-CqTI9H6N.js.map +1 -0
- package/lib/zudoku.auth-clerk.js +1 -1
- package/lib/zudoku.auth-openid.js +2 -2
- package/lib/zudoku.components.js +454 -444
- package/lib/zudoku.components.js.map +1 -1
- package/lib/zudoku.openapi-worker.js +1 -1
- package/lib/zudoku.plugin-api-keys.js +6 -6
- package/lib/zudoku.plugin-custom-pages.js +1 -1
- package/lib/zudoku.plugin-markdown.js +93 -27
- package/lib/zudoku.plugin-markdown.js.map +1 -1
- package/lib/zudoku.plugin-openapi.js +6 -7
- package/lib/zudoku.plugin-openapi.js.map +1 -1
- package/package.json +3 -3
- package/src/app/entry.client.tsx +4 -2
- package/src/app/entry.server.tsx +4 -0
- package/src/app/main.css +4 -0
- package/src/app/main.tsx +9 -25
- package/src/app/standalone.tsx +1 -1
- package/src/lib/components/Header.tsx +10 -2
- package/src/lib/components/SyntaxHighlight.tsx +5 -1
- package/src/lib/components/TopNavigation.tsx +58 -24
- package/src/lib/components/context/ZudokuContext.ts +28 -20
- package/src/lib/components/navigation/Sidebar.tsx +5 -5
- package/src/lib/components/navigation/SidebarCategory.tsx +2 -4
- package/src/lib/components/navigation/SidebarItem.tsx +1 -3
- package/src/lib/components/navigation/utils.ts +11 -16
- package/src/lib/core/DevPortalContext.ts +3 -7
- package/src/lib/core/plugins.ts +2 -0
- package/src/lib/plugins/markdown/index.tsx +49 -12
- package/src/lib/plugins/markdown/resolver.ts +92 -0
- package/src/lib/plugins/openapi/Endpoint.tsx +2 -2
- package/src/lib/plugins/openapi/RequestBodySidecarBox.tsx +1 -1
- package/src/lib/plugins/openapi/Sidecar.tsx +1 -1
- package/src/lib/plugins/openapi/client/worker.ts +2 -2
- package/src/lib/plugins/openapi/index.tsx +1 -1
- package/src/lib/util/MdxComponents.tsx +0 -1
- package/src/lib/util/useScrollToAnchor.ts +1 -1
- package/dist/lib/plugins/markdown/generateRoutes.d.ts +0 -3
- package/dist/lib/plugins/markdown/generateRoutes.js +0 -21
- package/dist/lib/plugins/markdown/generateRoutes.js.map +0 -1
- package/dist/lib/ui/Note.d.ts +0 -8
- package/dist/lib/ui/Note.js +0 -23
- package/dist/lib/ui/Note.js.map +0 -1
- package/lib/OperationList-Cea2Yt8e.js.map +0 -1
- package/lib/ZudokuContext-D1D8Anlj.js.map +0 -1
- package/lib/index-Cj-F-4ME.js.map +0 -1
- package/lib/joinPath-B7kNnUX4.js +0 -8
- package/lib/joinPath-B7kNnUX4.js.map +0 -1
- package/lib/ui/Note.js +0 -51
- package/lib/ui/Note.js.map +0 -1
- package/lib/urql-core-KJnLL26g.js.map +0 -1
- package/lib/utils-B2yoT99j.js.map +0 -1
- package/src/lib/plugins/markdown/generateRoutes.tsx +0 -38
- package/src/lib/ui/Note.tsx +0 -58
|
@@ -15,7 +15,7 @@ var Sn = (t, e, n, i) => ({
|
|
|
15
15
|
});
|
|
16
16
|
import { a as $l } from "./index-LNp6rxyU.js";
|
|
17
17
|
import { g as jl } from "./_commonjsHelpers-BkfeUUK-.js";
|
|
18
|
-
import { C as Qa, b as Wa, m as Ha, f as Ya } from "./urql-core-
|
|
18
|
+
import { C as Qa, b as Wa, m as Ha, f as Ya } from "./urql-core-CqTI9H6N.js";
|
|
19
19
|
function Pl(t, e) {
|
|
20
20
|
for (var n = 0; n < e.length; n++) {
|
|
21
21
|
const i = e[n];
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { j as e } from "./jsx-runtime-B6kdoens.js";
|
|
2
|
-
import { S as m, R as
|
|
2
|
+
import { S as m, R as g } from "./SlotletProvider-4Naek_5M.js";
|
|
3
3
|
import { i as c } from "./invariant-Caa8-XvF.js";
|
|
4
|
-
import { u as d, S as
|
|
4
|
+
import { u as d, S as f, a as j, b as v, c as w, d as b, e as x } from "./Select-Bagt3Bme.js";
|
|
5
5
|
import { a as k } from "./index.esm-C5mr_sKO.js";
|
|
6
6
|
import { a as K, L as u, O as N } from "./index-CRo94sKK.js";
|
|
7
|
-
import { u as h,
|
|
7
|
+
import { u as h, d as I, g as S } from "./ZudokuContext-BKXGJTmu.js";
|
|
8
8
|
import { Button as l } from "./ui/Button.js";
|
|
9
9
|
import { Input as A } from "./ui/Input.js";
|
|
10
|
-
import { u as C } from "./hook-
|
|
10
|
+
import { u as C } from "./hook-sn0zMTkE.js";
|
|
11
11
|
import { D as E } from "./DeveloperHint-DHdLXGHA.js";
|
|
12
12
|
import { RotateCwIcon as P, TrashIcon as D, EyeOffIcon as R, EyeIcon as q, CheckIcon as O, CopyIcon as z } from "lucide-react";
|
|
13
13
|
import { useState as p } from "react";
|
|
@@ -40,7 +40,7 @@ const F = ({ service: t }) => {
|
|
|
40
40
|
/* @__PURE__ */ e.jsx(A, { ...n.register("description") }),
|
|
41
41
|
"Expiration",
|
|
42
42
|
/* @__PURE__ */ e.jsxs(
|
|
43
|
-
|
|
43
|
+
f,
|
|
44
44
|
{
|
|
45
45
|
onValueChange: (a) => n.setValue("expiresOn", a),
|
|
46
46
|
defaultValue: n.getValues("expiresOn"),
|
|
@@ -259,7 +259,7 @@ const F = ({ service: t }) => {
|
|
|
259
259
|
getRoutes: () => [
|
|
260
260
|
{
|
|
261
261
|
element: /* @__PURE__ */ e.jsx(V, {}),
|
|
262
|
-
errorElement: /* @__PURE__ */ e.jsx(
|
|
262
|
+
errorElement: /* @__PURE__ */ e.jsx(g, {}),
|
|
263
263
|
children: [
|
|
264
264
|
{
|
|
265
265
|
path: "/settings/api-keys",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { j as e } from "./jsx-runtime-B6kdoens.js";
|
|
2
2
|
import a from "react";
|
|
3
|
-
import { P as n } from "./Markdown-
|
|
3
|
+
import { P as n } from "./Markdown-BDcCAWwm.js";
|
|
4
4
|
import { c } from "./cn-BmFQLtkS.js";
|
|
5
5
|
import { u } from "./useExposedProps-B9K-9GTc.js";
|
|
6
6
|
const l = ({
|
|
@@ -1,32 +1,98 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
var d = Object.defineProperty;
|
|
2
|
+
var m = (n, t, o) => t in n ? d(n, t, { enumerable: !0, configurable: !0, writable: !0, value: o }) : n[t] = o;
|
|
3
|
+
var f = (n, t, o) => m(n, typeof t != "symbol" ? t + "" : t, o);
|
|
4
|
+
import { j as P } from "./jsx-runtime-B6kdoens.js";
|
|
5
|
+
import { f as u } from "./__vite-browser-external-BYRIRx8p.js";
|
|
6
|
+
const x = "/pages/**/*.{md,mdx}", D = [".md", ".mdx"];
|
|
7
|
+
class c {
|
|
8
|
+
constructor(t) {
|
|
9
|
+
f(this, "fileMap", /* @__PURE__ */ new Map());
|
|
10
|
+
this.config = t;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Gets the default docs config from the zudoku config
|
|
14
|
+
*/
|
|
15
|
+
getDocsConfigs() {
|
|
16
|
+
return this.config.docs ? Array.isArray(this.config.docs) ? this.config.docs : [this.config.docs] : [{ files: x }];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Resolves the first matching file system path for a given docId
|
|
20
|
+
* @param docId - The docId to resolve
|
|
21
|
+
* @returns
|
|
22
|
+
*/
|
|
23
|
+
resolveFilePath(t) {
|
|
24
|
+
const o = this.getDocsConfigs();
|
|
25
|
+
let s;
|
|
26
|
+
return o.forEach(({ files: i }) => {
|
|
27
|
+
if (s)
|
|
28
|
+
return;
|
|
29
|
+
const e = c.getRootDir(i);
|
|
30
|
+
for (const a of D) {
|
|
31
|
+
if (s)
|
|
32
|
+
return;
|
|
33
|
+
const r = u.join(e, `${t}${a}`);
|
|
34
|
+
u.existsSync(r) && (s = r);
|
|
35
|
+
}
|
|
36
|
+
}), s;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Gets the root directory from a files glob
|
|
40
|
+
*/
|
|
41
|
+
static getRootDir(t) {
|
|
42
|
+
let o = t.split("**")[0];
|
|
43
|
+
if (!o)
|
|
44
|
+
throw new Error("Invalid files glob. Must have '**' in the path.");
|
|
45
|
+
return o = o.replace("/**", "/"), o;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Resolves the route path for a given file system path
|
|
49
|
+
* @param options - The options to resolve the route path
|
|
50
|
+
* @returns The string route path
|
|
51
|
+
*/
|
|
52
|
+
static resolveRoutePath({
|
|
53
|
+
filesGlob: t,
|
|
54
|
+
fsPath: o
|
|
55
|
+
}) {
|
|
56
|
+
const s = this.getRootDir(t), i = new RegExp(`^${s}(.*).mdx?`), e = o.match(i);
|
|
57
|
+
return e == null ? void 0 : e.at(1);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const C = (n) => ({
|
|
61
|
+
getRoutes: () => {
|
|
62
|
+
const t = /* @__PURE__ */ new Map();
|
|
63
|
+
return n.forEach(
|
|
64
|
+
({ fileImports: o, files: s, defaultOptions: i }) => Object.entries(o).flatMap(([e, a]) => {
|
|
65
|
+
const r = c.resolveRoutePath({
|
|
66
|
+
filesGlob: s,
|
|
67
|
+
fsPath: e
|
|
68
|
+
});
|
|
69
|
+
if (!r) return [];
|
|
70
|
+
if (t.has(r))
|
|
71
|
+
return console.warn(
|
|
72
|
+
`Duplicate route path found for ${r}. Skipping file at '${e}'.`
|
|
73
|
+
), [];
|
|
74
|
+
const h = {
|
|
75
|
+
path: r,
|
|
76
|
+
lazy: async () => {
|
|
77
|
+
const { MdxPage: l } = await import("./MdxPage-DKMH_t0f.js"), { default: p, ...g } = await a();
|
|
78
|
+
return {
|
|
79
|
+
element: /* @__PURE__ */ P.jsx(
|
|
80
|
+
l,
|
|
81
|
+
{
|
|
82
|
+
mdxComponent: p,
|
|
83
|
+
...g,
|
|
84
|
+
defaultOptions: i
|
|
85
|
+
}
|
|
86
|
+
)
|
|
87
|
+
};
|
|
17
88
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
markdownFiles: t,
|
|
24
|
-
defaultOptions: e,
|
|
25
|
-
filesPath: n
|
|
26
|
-
}) => ({
|
|
27
|
-
getRoutes: () => x(t, n, e)
|
|
89
|
+
};
|
|
90
|
+
t.set(r, h);
|
|
91
|
+
})
|
|
92
|
+
), [...t.values()];
|
|
93
|
+
}
|
|
28
94
|
});
|
|
29
95
|
export {
|
|
30
|
-
|
|
96
|
+
C as markdownPlugin
|
|
31
97
|
};
|
|
32
98
|
//# sourceMappingURL=zudoku.plugin-markdown.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zudoku.plugin-markdown.js","sources":["../src/lib/plugins/markdown/
|
|
1
|
+
{"version":3,"file":"zudoku.plugin-markdown.js","sources":["../src/lib/plugins/markdown/resolver.ts","../src/lib/plugins/markdown/index.tsx"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport {\n ZudokuConfig,\n ZudokuDocsConfig,\n} from \"../../../config/validators/validate.js\";\n\nconst DEFAULT_DOCS_FILES = \"/pages/**/*.{md,mdx}\";\n\n// TODO: This should be dynamic based on the glob selector\nconst SUPPORTED_EXTENSIONS = [\".md\", \".mdx\"];\n\n/**\n * Utilities for resolving markdown file paths and routes\n */\nexport class DocResolver {\n constructor(private config: ZudokuConfig) {}\n\n fileMap = new Map<string, string>();\n\n /**\n * Gets the default docs config from the zudoku config\n */\n getDocsConfigs() {\n const docsConfigs: ZudokuDocsConfig[] = this.config.docs\n ? Array.isArray(this.config.docs)\n ? this.config.docs\n : [this.config.docs]\n : [{ files: DEFAULT_DOCS_FILES }];\n\n return docsConfigs;\n }\n\n /**\n * Resolves the first matching file system path for a given docId\n * @param docId - The docId to resolve\n * @returns\n */\n resolveFilePath(docId: string) {\n const docsConfigs = this.getDocsConfigs();\n let fsPath: string | undefined;\n\n docsConfigs.forEach(({ files: fileGlob }) => {\n if (fsPath) {\n return;\n }\n const rootDir = DocResolver.getRootDir(fileGlob);\n for (const ext of SUPPORTED_EXTENSIONS) {\n if (fsPath) {\n return;\n }\n const checkPath = path.join(rootDir, `${docId}${ext}`);\n if (fs.existsSync(checkPath)) {\n fsPath = checkPath;\n }\n }\n });\n\n return fsPath;\n }\n\n /**\n * Gets the root directory from a files glob\n */\n private static getRootDir(filesGlob: string) {\n let rootDir = filesGlob.split(\"**\")[0];\n if (!rootDir) {\n throw new Error(\"Invalid files glob. Must have '**' in the path.\");\n }\n rootDir = rootDir.replace(\"/**\", \"/\");\n return rootDir;\n }\n\n /**\n * Resolves the route path for a given file system path\n * @param options - The options to resolve the route path\n * @returns The string route path\n */\n static resolveRoutePath({\n filesGlob,\n fsPath,\n }: {\n filesGlob: string;\n fsPath: string;\n }) {\n const rootDir = this.getRootDir(filesGlob);\n const re = new RegExp(`^${rootDir}(.*).mdx?`);\n const match = fsPath.match(re);\n const routePath = match?.at(1);\n return routePath;\n }\n}\n","import type { Toc } from \"@stefanprobst/rehype-extract-toc\";\nimport type { MDXProps } from \"mdx/types.js\";\nimport { RouteObject } from \"react-router-dom\";\nimport { ZudokuDocsConfig } from \"../../../config/validators/validate.js\";\nimport type { DevPortalPlugin } from \"../../core/plugins.js\";\nimport { DocResolver } from \"./resolver.js\";\n\nexport interface MarkdownPluginOptions extends ZudokuDocsConfig {\n fileImports: Record<string, () => Promise<MDXImport>>;\n}\nexport type MarkdownPluginDefaultOptions = Pick<\n Frontmatter,\n \"toc\" | \"disablePager\"\n>;\n\nexport type Frontmatter = {\n title?: string;\n description?: string;\n category?: string;\n toc?: boolean;\n disablePager?: boolean;\n};\n\nexport type MDXImport = {\n tableOfContents: Toc;\n frontmatter: Frontmatter;\n default: (props: MDXProps) => JSX.Element;\n};\n\nexport const markdownPlugin = (\n options: MarkdownPluginOptions[],\n): DevPortalPlugin => ({\n getRoutes: () => {\n const routeMap = new Map<string, RouteObject>();\n options.forEach(({ fileImports, files, defaultOptions }) =>\n Object.entries(fileImports).flatMap(([file, importPromise]) => {\n const routePath = DocResolver.resolveRoutePath({\n filesGlob: files,\n fsPath: file,\n });\n\n if (!routePath) return [];\n\n if (routeMap.has(routePath)) {\n // eslint-disable-next-line no-console\n console.warn(\n `Duplicate route path found for ${routePath}. Skipping file at '${file}'.`,\n );\n return [];\n }\n\n const route: RouteObject = {\n path: routePath,\n lazy: async () => {\n const { MdxPage } = await import(\"./MdxPage.js\");\n const { default: Component, ...props } = await importPromise();\n return {\n element: (\n <MdxPage\n mdxComponent={Component}\n {...props}\n defaultOptions={defaultOptions}\n />\n ),\n };\n },\n };\n routeMap.set(routePath, route);\n }),\n );\n return [...routeMap.values()];\n },\n});\n"],"names":["DEFAULT_DOCS_FILES","SUPPORTED_EXTENSIONS","DocResolver","config","__publicField","docId","docsConfigs","fsPath","fileGlob","rootDir","ext","checkPath","path","fs","filesGlob","re","match","markdownPlugin","options","routeMap","fileImports","files","defaultOptions","file","importPromise","routePath","route","MdxPage","Component","props","jsx"],"mappings":";;;;;AAOA,MAAMA,IAAqB,wBAGrBC,IAAuB,CAAC,OAAO,MAAM;AAKpC,MAAMC,EAAY;AAAA,EACvB,YAAoBC,GAAsB;AAE1C,IAAAC,EAAA,qCAAc;AAFM,SAAA,SAAAD;AAAA,EAAuB;AAAA;AAAA;AAAA;AAAA,EAO3C,iBAAiB;AAOR,WANiC,KAAK,OAAO,OAChD,MAAM,QAAQ,KAAK,OAAO,IAAI,IAC5B,KAAK,OAAO,OACZ,CAAC,KAAK,OAAO,IAAI,IACnB,CAAC,EAAE,OAAOH,EAAA,CAAoB;AAAA,EAGpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,gBAAgBK,GAAe;AACvB,UAAAC,IAAc,KAAK;AACrB,QAAAC;AAEJ,WAAAD,EAAY,QAAQ,CAAC,EAAE,OAAOE,QAAe;AAC3C,UAAID;AACF;AAEI,YAAAE,IAAUP,EAAY,WAAWM,CAAQ;AAC/C,iBAAWE,KAAOT,GAAsB;AACtC,YAAIM;AACF;AAEI,cAAAI,IAAYC,EAAK,KAAKH,GAAS,GAAGJ,CAAK,GAAGK,CAAG,EAAE;AACjD,QAAAG,EAAG,WAAWF,CAAS,MAChBJ,IAAAI;AAAA,MAEb;AAAA,IAAA,CACD,GAEMJ;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,WAAWO,GAAmB;AAC3C,QAAIL,IAAUK,EAAU,MAAM,IAAI,EAAE,CAAC;AACrC,QAAI,CAACL;AACG,YAAA,IAAI,MAAM,iDAAiD;AAEzD,WAAAA,IAAAA,EAAQ,QAAQ,OAAO,GAAG,GAC7BA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,iBAAiB;AAAA,IACtB,WAAAK;AAAA,IACA,QAAAP;AAAA,EAAA,GAIC;AACK,UAAAE,IAAU,KAAK,WAAWK,CAAS,GACnCC,IAAK,IAAI,OAAO,IAAIN,CAAO,WAAW,GACtCO,IAAQT,EAAO,MAAMQ,CAAE;AAEtB,WADWC,KAAA,gBAAAA,EAAO,GAAG;AAAA,EAE9B;AACF;AC9Da,MAAAC,IAAiB,CAC5BC,OACqB;AAAA,EACrB,WAAW,MAAM;AACT,UAAAC,wBAAe;AACb,WAAAD,EAAA;AAAA,MAAQ,CAAC,EAAE,aAAAE,GAAa,OAAAC,GAAO,gBAAAC,QACrC,OAAO,QAAQF,CAAW,EAAE,QAAQ,CAAC,CAACG,GAAMC,CAAa,MAAM;AACvD,cAAAC,IAAYvB,EAAY,iBAAiB;AAAA,UAC7C,WAAWmB;AAAA,UACX,QAAQE;AAAA,QAAA,CACT;AAEG,YAAA,CAACE,EAAW,QAAO;AAEnB,YAAAN,EAAS,IAAIM,CAAS;AAEhB,yBAAA;AAAA,YACN,kCAAkCA,CAAS,uBAAuBF,CAAI;AAAA,UAAA,GAEjE;AAGT,cAAMG,IAAqB;AAAA,UACzB,MAAMD;AAAA,UACN,MAAM,YAAY;AAChB,kBAAM,EAAE,SAAAE,EAAA,IAAY,MAAM,OAAO,uBAAc,GACzC,EAAE,SAASC,GAAW,GAAGC,EAAM,IAAI,MAAML;AACxC,mBAAA;AAAA,cACL,SACEM,gBAAAA,EAAA;AAAA,gBAACH;AAAA,gBAAA;AAAA,kBACC,cAAcC;AAAA,kBACb,GAAGC;AAAA,kBACJ,gBAAAP;AAAA,gBAAA;AAAA,cACF;AAAA,YAAA;AAAA,UAGN;AAAA,QAAA;AAEO,QAAAH,EAAA,IAAIM,GAAWC,CAAK;AAAA,MAAA,CAC9B;AAAA,IAAA,GAEI,CAAC,GAAGP,EAAS,OAAA,CAAQ;AAAA,EAC9B;AACF;"}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import "./jsx-runtime-B6kdoens.js";
|
|
2
|
-
import { o as
|
|
3
|
-
import "./ZudokuContext-
|
|
2
|
+
import { o as s } from "./index-B3F9d8oi.js";
|
|
3
|
+
import "./ZudokuContext-BKXGJTmu.js";
|
|
4
4
|
import "lucide-react";
|
|
5
5
|
import "zudoku/openapi-worker";
|
|
6
|
-
import "./hook-
|
|
7
|
-
import "./Markdown-
|
|
6
|
+
import "./hook-sn0zMTkE.js";
|
|
7
|
+
import "./Markdown-BDcCAWwm.js";
|
|
8
8
|
import "./ui/Button.js";
|
|
9
|
-
import "./
|
|
10
|
-
import "./urql-core-KJnLL26g.js";
|
|
9
|
+
import "./urql-core-CqTI9H6N.js";
|
|
11
10
|
import "./router-BsfSoK2j.js";
|
|
12
11
|
import "./index-CRo94sKK.js";
|
|
13
12
|
export {
|
|
14
|
-
|
|
13
|
+
s as openApiPlugin
|
|
15
14
|
};
|
|
16
15
|
//# sourceMappingURL=zudoku.plugin-openapi.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zudoku.plugin-openapi.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"zudoku.plugin-openapi.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zudoku",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"homepage": "https://zudoku.dev",
|
|
6
6
|
"repository": {
|
|
@@ -167,7 +167,7 @@
|
|
|
167
167
|
"posthog-node": "4.2.1",
|
|
168
168
|
"prism-react-renderer": "2.4.0",
|
|
169
169
|
"prismjs": "1.29.0",
|
|
170
|
-
"react-error-boundary": "4.
|
|
170
|
+
"react-error-boundary": "4.1.2",
|
|
171
171
|
"react-hook-form": "7.53.0",
|
|
172
172
|
"react-is": "18.3.1",
|
|
173
173
|
"react-markdown": "9.0.1",
|
|
@@ -199,7 +199,7 @@
|
|
|
199
199
|
"zustand": "5.0.0"
|
|
200
200
|
},
|
|
201
201
|
"devDependencies": {
|
|
202
|
-
"@types/express": "
|
|
202
|
+
"@types/express": "5.0.0",
|
|
203
203
|
"@types/har-format": "1.2.15",
|
|
204
204
|
"@types/json-schema": "7.0.15",
|
|
205
205
|
"@types/mdx": "2.0.13",
|
package/src/app/entry.client.tsx
CHANGED
|
@@ -20,8 +20,10 @@ if (root.childElementCount > 0) {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
async function hydrateLazyRoutes(routes: RouteObject[]) {
|
|
23
|
-
const path = window.location.pathname
|
|
24
|
-
const lazyMatches = matchRoutes(routes, path)?.filter(
|
|
23
|
+
const path = window.location.pathname;
|
|
24
|
+
const lazyMatches = matchRoutes(routes, path, config.basePath)?.filter(
|
|
25
|
+
(m) => m.route.lazy,
|
|
26
|
+
);
|
|
25
27
|
|
|
26
28
|
if (lazyMatches?.length) {
|
|
27
29
|
await Promise.all(
|
package/src/app/entry.server.tsx
CHANGED
|
@@ -96,6 +96,10 @@ export const render = async ({
|
|
|
96
96
|
|
|
97
97
|
const [htmlStart, htmlEnd] = template.split("<!--app-html-->");
|
|
98
98
|
|
|
99
|
+
if (!htmlStart) {
|
|
100
|
+
throw new Error("No <!--app-html--> found in template");
|
|
101
|
+
}
|
|
102
|
+
|
|
99
103
|
response.write(
|
|
100
104
|
htmlStart.replace(
|
|
101
105
|
"<!--app-helmet-->",
|
package/src/app/main.css
CHANGED
package/src/app/main.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type RouteObject } from "react-router-dom";
|
|
2
2
|
import { configuredApiKeysPlugin } from "virtual:zudoku-api-keys-plugin";
|
|
3
3
|
import { configuredApiPlugins } from "virtual:zudoku-api-plugins";
|
|
4
4
|
import { configuredAuthProvider } from "virtual:zudoku-auth";
|
|
@@ -10,10 +10,8 @@ import { configuredSidebar } from "virtual:zudoku-sidebar";
|
|
|
10
10
|
import "virtual:zudoku-theme.css";
|
|
11
11
|
import { DevPortal, Layout, RouterError } from "zudoku/components";
|
|
12
12
|
import type { ZudokuConfig } from "../config/config.js";
|
|
13
|
-
import { traverseSidebar } from "../lib/components/navigation/utils.js";
|
|
14
13
|
import type { ZudokuContextOptions } from "../lib/core/DevPortalContext.js";
|
|
15
14
|
import { isNavigationPlugin } from "../lib/core/plugins.js";
|
|
16
|
-
import { joinPath } from "../lib/util/joinPath.js";
|
|
17
15
|
|
|
18
16
|
export const convertZudokuConfigToOptions = (
|
|
19
17
|
config: ZudokuConfig,
|
|
@@ -67,9 +65,7 @@ export const convertZudokuConfigToOptions = (
|
|
|
67
65
|
};
|
|
68
66
|
};
|
|
69
67
|
|
|
70
|
-
export const
|
|
71
|
-
const options = convertZudokuConfigToOptions(config);
|
|
72
|
-
|
|
68
|
+
export const getRoutesByOptions = (options: ZudokuContextOptions) => {
|
|
73
69
|
const allPlugins = [
|
|
74
70
|
...(options.plugins ? options.plugins : []),
|
|
75
71
|
...(options.authentication?.getAuthenticationPlugin
|
|
@@ -77,27 +73,8 @@ export const getRoutesByConfig = (config: ZudokuConfig): RouteObject[] => {
|
|
|
77
73
|
: []),
|
|
78
74
|
];
|
|
79
75
|
|
|
80
|
-
const topNavRedirects =
|
|
81
|
-
options.topNavigation?.flatMap((topNavItem) => {
|
|
82
|
-
if (!options.sidebars?.[topNavItem.id]) return [];
|
|
83
|
-
|
|
84
|
-
const first =
|
|
85
|
-
topNavItem.default ??
|
|
86
|
-
traverseSidebar(options.sidebars[topNavItem.id], (item) => {
|
|
87
|
-
if (item.type === "doc") return joinPath(topNavItem.id, item.id);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
if (!first) return [];
|
|
91
|
-
|
|
92
|
-
return {
|
|
93
|
-
path: topNavItem.id,
|
|
94
|
-
loader: () => redirect(joinPath(first)),
|
|
95
|
-
} satisfies RouteObject;
|
|
96
|
-
}) ?? [];
|
|
97
|
-
|
|
98
76
|
const routes = allPlugins
|
|
99
77
|
.flatMap((plugin) => (isNavigationPlugin(plugin) ? plugin.getRoutes() : []))
|
|
100
|
-
.concat(topNavRedirects)
|
|
101
78
|
.concat({
|
|
102
79
|
path: "*",
|
|
103
80
|
loader: () => {
|
|
@@ -105,6 +82,13 @@ export const getRoutesByConfig = (config: ZudokuConfig): RouteObject[] => {
|
|
|
105
82
|
},
|
|
106
83
|
});
|
|
107
84
|
|
|
85
|
+
return routes;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const getRoutesByConfig = (config: ZudokuConfig): RouteObject[] => {
|
|
89
|
+
const options = convertZudokuConfigToOptions(config);
|
|
90
|
+
const routes = getRoutesByOptions(options);
|
|
91
|
+
|
|
108
92
|
return [
|
|
109
93
|
{
|
|
110
94
|
element: (
|
package/src/app/standalone.tsx
CHANGED
|
@@ -16,7 +16,7 @@ if (!root) {
|
|
|
16
16
|
themeToggle();
|
|
17
17
|
|
|
18
18
|
const apiUrl = root.getAttribute("data-api-url");
|
|
19
|
-
const pageTitle = document.getElementsByTagName("title")[0]
|
|
19
|
+
const pageTitle = document.getElementsByTagName("title")[0]!.innerText;
|
|
20
20
|
const logoUrl = root.getAttribute("data-logo-url");
|
|
21
21
|
|
|
22
22
|
// IMPORTANT: This component must not contain tailwind classes
|
|
@@ -70,14 +70,22 @@ export const Header = memo(function HeaderInner() {
|
|
|
70
70
|
{page?.logo && (
|
|
71
71
|
<>
|
|
72
72
|
<img
|
|
73
|
-
src={
|
|
73
|
+
src={
|
|
74
|
+
/https?:\/\//.test(page.logo.src.light)
|
|
75
|
+
? page.logo.src.light
|
|
76
|
+
: import.meta.env.BASE_URL + page.logo.src.light
|
|
77
|
+
}
|
|
74
78
|
alt={page.logo.alt ?? page.pageTitle}
|
|
75
79
|
style={{ width: page.logo.width }}
|
|
76
80
|
className={cn("h-10", isDark && "hidden")}
|
|
77
81
|
loading="lazy"
|
|
78
82
|
/>
|
|
79
83
|
<img
|
|
80
|
-
src={
|
|
84
|
+
src={
|
|
85
|
+
/https?:\/\//.test(page.logo.src.dark)
|
|
86
|
+
? page.logo.src.dark
|
|
87
|
+
: import.meta.env.BASE_URL + page.logo.src.dark
|
|
88
|
+
}
|
|
81
89
|
alt={page.logo.alt ?? page.pageTitle}
|
|
82
90
|
style={{ width: page.logo.width }}
|
|
83
91
|
className={cn("h-10", !isDark && "hidden")}
|
|
@@ -46,6 +46,10 @@ type SyntaxHighlightProps = {
|
|
|
46
46
|
language?: string;
|
|
47
47
|
} & Omit<HighlightProps, "children" | "language">;
|
|
48
48
|
|
|
49
|
+
const remapLang = {
|
|
50
|
+
mdx: "md",
|
|
51
|
+
} as Record<string, string>;
|
|
52
|
+
|
|
49
53
|
export const SyntaxHighlight = ({
|
|
50
54
|
copyable = true,
|
|
51
55
|
language = "plain",
|
|
@@ -61,7 +65,7 @@ export const SyntaxHighlight = ({
|
|
|
61
65
|
return (
|
|
62
66
|
<Highlight
|
|
63
67
|
theme={isDark ? themes.vsDark : themes.github}
|
|
64
|
-
language={language}
|
|
68
|
+
language={remapLang[language] ?? language}
|
|
65
69
|
{...props}
|
|
66
70
|
>
|
|
67
71
|
{({ className, style, tokens, getLineProps, getTokenProps }) => (
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { cx } from "class-variance-authority";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { Suspense } from "react";
|
|
3
|
+
import { Link } from "react-router-dom";
|
|
4
4
|
import { useAuth } from "../authentication/hook.js";
|
|
5
|
-
import {
|
|
5
|
+
import { TopNavigationItem } from "../../config/validators/validate.js";
|
|
6
|
+
import { joinPath } from "../util/joinPath.js";
|
|
7
|
+
import { useCurrentNavigation, useZudoku } from "./context/ZudokuContext.js";
|
|
8
|
+
import { traverseSidebar } from "./navigation/utils.js";
|
|
6
9
|
|
|
7
10
|
export const isHiddenItem =
|
|
8
11
|
(isAuthenticated?: boolean) =>
|
|
@@ -25,26 +28,57 @@ export const TopNavigation = () => {
|
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
return (
|
|
28
|
-
<
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
31
|
+
<Suspense>
|
|
32
|
+
<nav className="hidden lg:block border-b text-sm px-12 h-[--top-nav-height]">
|
|
33
|
+
<ul className="flex flex-row items-center gap-8">
|
|
34
|
+
{topNavigation.filter(isHiddenItem(isAuthenticated)).map((item) => (
|
|
35
|
+
<li key={item.id}>
|
|
36
|
+
<TopNavItem {...item} />
|
|
37
|
+
</li>
|
|
38
|
+
))}
|
|
39
|
+
</ul>
|
|
40
|
+
</nav>
|
|
41
|
+
</Suspense>
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const TopNavItem = ({ id, label, default: defaultLink }: TopNavigationItem) => {
|
|
46
|
+
const { sidebars } = useZudoku();
|
|
47
|
+
const nav = useCurrentNavigation();
|
|
48
|
+
const currentSidebar = sidebars[id];
|
|
49
|
+
|
|
50
|
+
// TODO: This is a bit of a hack to get the first link in the sidebar
|
|
51
|
+
// We should really process this when we load the config so we can validate
|
|
52
|
+
// that the sidebar is actually set. In this case we just fall back to linking
|
|
53
|
+
// to the id if we can't resolve a sidebar.
|
|
54
|
+
const first =
|
|
55
|
+
defaultLink ??
|
|
56
|
+
(currentSidebar
|
|
57
|
+
? traverseSidebar(currentSidebar, (item) => {
|
|
58
|
+
if (item.type === "doc") return joinPath(item.id);
|
|
59
|
+
})
|
|
60
|
+
: joinPath(id));
|
|
61
|
+
|
|
62
|
+
if (!first) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`No links found in top navigation for top navigation '${id}'. Check that the sidebar isn't empty or that a default link set.`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Manually set the active sidebar based on our logic of what is active
|
|
69
|
+
const isActive = nav.data.topNavItem?.id === id;
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<Link
|
|
73
|
+
className={cx(
|
|
74
|
+
"block py-3.5 font-medium -mb-px border-b-2",
|
|
75
|
+
isActive
|
|
76
|
+
? "border-primary text-foreground"
|
|
77
|
+
: "border-transparent text-foreground/75 hover:text-foreground hover:border-accent-foreground/25",
|
|
78
|
+
)}
|
|
79
|
+
to={first}
|
|
80
|
+
>
|
|
81
|
+
{label}
|
|
82
|
+
</Link>
|
|
49
83
|
);
|
|
50
84
|
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { useQuery, useSuspenseQuery } from "@tanstack/react-query";
|
|
2
2
|
import { createContext, useContext } from "react";
|
|
3
|
-
import { useLocation } from "react-router-dom";
|
|
3
|
+
import { matchPath, useLocation } from "react-router-dom";
|
|
4
4
|
import { DevPortalContext } from "../../core/DevPortalContext.js";
|
|
5
|
+
import { joinPath } from "../../util/joinPath.js";
|
|
6
|
+
import { traverseSidebar } from "../navigation/utils.js";
|
|
5
7
|
|
|
6
8
|
export const ZudokuReactContext = createContext<DevPortalContext | undefined>(
|
|
7
9
|
undefined,
|
|
@@ -25,34 +27,40 @@ export const useApiIdentities = () => {
|
|
|
25
27
|
});
|
|
26
28
|
};
|
|
27
29
|
|
|
28
|
-
export const
|
|
29
|
-
const { topNavigation } = useZudoku();
|
|
30
|
+
export const useCurrentNavigation = () => {
|
|
31
|
+
const { getPluginSidebar, sidebars, topNavigation } = useZudoku();
|
|
30
32
|
const location = useLocation();
|
|
31
33
|
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
+
const currentSidebarItem = Object.entries(sidebars).find(([, sidebar]) => {
|
|
35
|
+
return traverseSidebar(sidebar, (item) => {
|
|
36
|
+
const itemId =
|
|
37
|
+
item.type === "doc"
|
|
38
|
+
? joinPath(item.id)
|
|
39
|
+
: item.type === "category" && item.link
|
|
40
|
+
? joinPath(item.link.id)
|
|
41
|
+
: undefined;
|
|
34
42
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const location = useLocation();
|
|
43
|
+
if (itemId === location.pathname) {
|
|
44
|
+
return item;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
const currentTopNavItem =
|
|
49
|
+
topNavigation.find((t) => t.id === currentSidebarItem?.[0]) ??
|
|
50
|
+
topNavigation.find((item) => matchPath(item.id, location.pathname));
|
|
44
51
|
|
|
45
52
|
return useSuspenseQuery({
|
|
46
53
|
queryFn: async () => {
|
|
47
|
-
const pluginSidebar =
|
|
48
|
-
? await getPluginSidebar(path)
|
|
49
|
-
: await getPluginSidebar(location.pathname);
|
|
54
|
+
const pluginSidebar = await getPluginSidebar(location.pathname);
|
|
50
55
|
|
|
51
56
|
return {
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
sidebar: [
|
|
58
|
+
...(currentSidebarItem ? currentSidebarItem[1] : []),
|
|
59
|
+
...pluginSidebar,
|
|
60
|
+
],
|
|
61
|
+
topNavItem: currentTopNavItem,
|
|
54
62
|
};
|
|
55
63
|
},
|
|
56
|
-
queryKey: ["navigation",
|
|
64
|
+
queryKey: ["navigation", location.pathname],
|
|
57
65
|
});
|
|
58
66
|
};
|
|
@@ -2,23 +2,23 @@ import { useRef } from "react";
|
|
|
2
2
|
|
|
3
3
|
import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
|
|
4
4
|
import { DrawerContent, DrawerTitle } from "../../ui/Drawer.js";
|
|
5
|
-
import {
|
|
5
|
+
import { useCurrentNavigation } from "../context/ZudokuContext.js";
|
|
6
6
|
import { Slotlet } from "../SlotletProvider.js";
|
|
7
7
|
import { SidebarItem } from "./SidebarItem.js";
|
|
8
8
|
import { SidebarWrapper } from "./SidebarWrapper.js";
|
|
9
9
|
|
|
10
10
|
export const Sidebar = () => {
|
|
11
11
|
const navRef = useRef<HTMLDivElement | null>(null);
|
|
12
|
-
const navigation =
|
|
12
|
+
const navigation = useCurrentNavigation();
|
|
13
13
|
|
|
14
14
|
return (
|
|
15
15
|
<>
|
|
16
16
|
<SidebarWrapper
|
|
17
17
|
ref={navRef}
|
|
18
|
-
pushMainContent={navigation.data.
|
|
18
|
+
pushMainContent={navigation.data.sidebar.length > 0}
|
|
19
19
|
>
|
|
20
20
|
<Slotlet name="zudoku-before-navigation" />
|
|
21
|
-
{navigation.data.
|
|
21
|
+
{navigation.data.sidebar.map((item) => (
|
|
22
22
|
<SidebarItem key={item.label} item={item} />
|
|
23
23
|
))}
|
|
24
24
|
<Slotlet name="zudoku-after-navigation" />
|
|
@@ -30,7 +30,7 @@ export const Sidebar = () => {
|
|
|
30
30
|
<VisuallyHidden>
|
|
31
31
|
<DrawerTitle>Sidebar</DrawerTitle>
|
|
32
32
|
</VisuallyHidden>
|
|
33
|
-
{navigation.data.
|
|
33
|
+
{navigation.data.sidebar.map((item) => (
|
|
34
34
|
<SidebarItem key={item.label} item={item} />
|
|
35
35
|
))}
|
|
36
36
|
</DrawerContent>
|