zudoku 0.3.0-dev.83 → 0.3.0-dev.85
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 +5 -1
- package/dist/app/demo.js +5 -4
- package/dist/app/demo.js.map +1 -1
- package/dist/app/main.js +3 -1
- package/dist/app/main.js.map +1 -1
- package/dist/app/standalone.js +5 -4
- package/dist/app/standalone.js.map +1 -1
- package/dist/config/validators/ResolvedSidebarSchema.d.ts +18 -0
- package/dist/config/validators/ResolvedSidebarSchema.js +76 -0
- package/dist/config/validators/ResolvedSidebarSchema.js.map +1 -0
- package/dist/config/validators/SidebarSchema.d.ts +177 -0
- package/dist/config/validators/SidebarSchema.js +71 -0
- package/dist/config/validators/SidebarSchema.js.map +1 -0
- package/dist/config/validators/validate.d.ts +411 -59
- package/dist/config/validators/validate.js +22 -4
- package/dist/config/validators/validate.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/lib/components/DevPortal.js +1 -1
- package/dist/lib/components/DevPortal.js.map +1 -1
- package/dist/lib/components/Header.js +5 -4
- package/dist/lib/components/Header.js.map +1 -1
- package/dist/lib/components/Heading.d.ts +1 -1
- package/dist/lib/components/Layout.js +2 -2
- package/dist/lib/components/Layout.js.map +1 -1
- package/dist/lib/components/TopNavigation.js +5 -5
- package/dist/lib/components/TopNavigation.js.map +1 -1
- package/dist/lib/components/context/DevPortalProvider.d.ts +9 -3
- package/dist/lib/components/context/DevPortalProvider.js +11 -23
- package/dist/lib/components/context/DevPortalProvider.js.map +1 -1
- package/dist/lib/components/context/ThemeContext.d.ts +1 -4
- package/dist/lib/components/context/ThemeContext.js +3 -29
- package/dist/lib/components/context/ThemeContext.js.map +1 -1
- package/dist/lib/components/context/ThemeProvider.d.ts +4 -0
- package/dist/lib/components/context/ThemeProvider.js +23 -0
- package/dist/lib/components/context/ThemeProvider.js.map +1 -0
- package/dist/lib/components/navigation/Sidebar.d.ts +1 -0
- package/dist/lib/components/navigation/Sidebar.js +12 -0
- package/dist/lib/components/navigation/Sidebar.js.map +1 -0
- package/dist/lib/components/navigation/SidebarBadge.d.ts +22 -0
- package/dist/lib/components/navigation/SidebarBadge.js +24 -0
- package/dist/lib/components/navigation/SidebarBadge.js.map +1 -0
- package/dist/lib/components/navigation/SidebarCategory.d.ts +5 -0
- package/dist/lib/components/navigation/SidebarCategory.js +33 -0
- package/dist/lib/components/navigation/SidebarCategory.js.map +1 -0
- package/dist/lib/components/navigation/SidebarItem.d.ts +12 -0
- package/dist/lib/components/navigation/SidebarItem.js +42 -0
- package/dist/lib/components/navigation/SidebarItem.js.map +1 -0
- package/dist/lib/components/navigation/{SideNavigationWrapper.d.ts → SidebarWrapper.d.ts} +1 -1
- package/dist/lib/components/navigation/{SideNavigationWrapper.js → SidebarWrapper.js} +2 -2
- package/dist/lib/components/navigation/SidebarWrapper.js.map +1 -0
- package/dist/lib/components/navigation/utils.d.ts +16 -0
- package/dist/lib/components/navigation/utils.js +85 -0
- package/dist/lib/components/navigation/utils.js.map +1 -0
- package/dist/lib/core/DevPortalContext.d.ts +9 -32
- package/dist/lib/core/DevPortalContext.js +8 -5
- package/dist/lib/core/DevPortalContext.js.map +1 -1
- package/dist/lib/core/plugins.d.ts +6 -8
- package/dist/lib/core/plugins.js.map +1 -1
- package/dist/lib/plugins/markdown/MdxPage.js +5 -36
- package/dist/lib/plugins/markdown/MdxPage.js.map +1 -1
- package/dist/lib/plugins/markdown/generateRoutes.js +20 -43
- package/dist/lib/plugins/markdown/generateRoutes.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationListItem.js +4 -3
- package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
- package/dist/lib/plugins/openapi/ParameterList.js +2 -1
- package/dist/lib/plugins/openapi/ParameterList.js.map +1 -1
- package/dist/lib/plugins/openapi/SchemaListView.js +6 -1
- package/dist/lib/plugins/openapi/SchemaListView.js.map +1 -1
- package/dist/lib/plugins/openapi/SchemaListViewItem.d.ts +3 -2
- package/dist/lib/plugins/openapi/SchemaListViewItem.js +6 -3
- package/dist/lib/plugins/openapi/SchemaListViewItem.js.map +1 -1
- package/dist/lib/plugins/openapi/Sidecar.js +12 -2
- package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
- package/dist/lib/plugins/openapi/index.js +14 -11
- package/dist/lib/plugins/openapi/index.js.map +1 -1
- package/dist/lib/plugins/openapi/interfaces.d.ts +1 -1
- package/dist/lib/plugins/openapi/playground/Headers.js +1 -1
- package/dist/lib/plugins/openapi/playground/Headers.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/Playground.js +1 -1
- package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
- package/dist/lib/util/useScrollToAnchor.js +31 -17
- package/dist/lib/util/useScrollToAnchor.js.map +1 -1
- package/dist/vite/plugin-sidebar.d.ts +3 -0
- package/dist/vite/plugin-sidebar.js +23 -0
- package/dist/vite/plugin-sidebar.js.map +1 -0
- package/dist/vite/plugin.js +2 -0
- package/dist/vite/plugin.js.map +1 -1
- package/lib/{AuthenticationPlugin-XS0DoAhE.js → AuthenticationPlugin-DgwV0hVu.js} +7 -7
- package/lib/{AuthenticationPlugin-XS0DoAhE.js.map → AuthenticationPlugin-DgwV0hVu.js.map} +1 -1
- package/lib/{CategoryHeading-DCmchnA1.js → CategoryHeading-BWq12Bfa.js} +3 -3
- package/lib/{CategoryHeading-DCmchnA1.js.map → CategoryHeading-BWq12Bfa.js.map} +1 -1
- package/lib/{Combination-C442XfGG.js → Combination-DkycFHkm.js} +4 -4
- package/lib/{Combination-C442XfGG.js.map → Combination-DkycFHkm.js.map} +1 -1
- package/lib/{DevPortalProvider-BWeAysxF.js → DevPortalProvider-CTxoCHIT.js} +375 -417
- package/lib/DevPortalProvider-CTxoCHIT.js.map +1 -0
- package/lib/DeveloperHint-BQSFXH01.js +10 -0
- package/lib/{DeveloperHint-DQVwIery.js.map → DeveloperHint-BQSFXH01.js.map} +1 -1
- package/lib/{Input-3IEt27jb.js → Input-BclXSY0g.js} +5 -5
- package/lib/{Input-3IEt27jb.js.map → Input-BclXSY0g.js.map} +1 -1
- package/lib/{Markdown-QsZ-PHET.js → Markdown-B_Gax7at.js} +1136 -1152
- package/lib/{Markdown-QsZ-PHET.js.map → Markdown-B_Gax7at.js.map} +1 -1
- package/lib/{MdxPage-CA1WmW14.js → MdxPage-Crlr0GmN.js} +67 -81
- package/lib/MdxPage-Crlr0GmN.js.map +1 -0
- package/lib/{OperationList-CHK_erYP.js → OperationList-CMH3DPpj.js} +145 -129
- package/lib/OperationList-CMH3DPpj.js.map +1 -0
- package/lib/Route-CwXfyIUw.js +14 -0
- package/lib/{Route-D70pGn9n.js.map → Route-CwXfyIUw.js.map} +1 -1
- package/lib/{SlotletProvider-B71hNEUL.js → SlotletProvider-CzMAO73_.js} +12 -12
- package/lib/{SlotletProvider-B71hNEUL.js.map → SlotletProvider-CzMAO73_.js.map} +1 -1
- package/lib/Spinner-fF-Xv-gw.js +274 -0
- package/lib/Spinner-fF-Xv-gw.js.map +1 -0
- package/lib/index-7kcHaXD6.js +1771 -0
- package/lib/index-7kcHaXD6.js.map +1 -0
- package/lib/{index-Bl6YeerK.js → index-DUrF63A6.js} +1028 -1044
- package/lib/index-DUrF63A6.js.map +1 -0
- package/lib/{index-BH-Ub36F.js → index-DkuZvRNP.js} +4 -4
- package/lib/{index-BH-Ub36F.js.map → index-DkuZvRNP.js.map} +1 -1
- package/lib/joinPath-VeNuJa7y.js +8 -0
- package/lib/joinPath-VeNuJa7y.js.map +1 -0
- package/lib/jsx-runtime-B6kdoens.js +635 -0
- package/lib/jsx-runtime-B6kdoens.js.map +1 -0
- package/lib/{AnchorLink-BZcpTwOs.js → utils-CzT_9Tsn.js} +258 -214
- package/lib/utils-CzT_9Tsn.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 +1229 -1227
- package/lib/zudoku.components.js.map +1 -1
- package/lib/zudoku.plugin-api-keys.js +19 -19
- package/lib/zudoku.plugin-custom-page.js +2 -2
- package/lib/zudoku.plugin-markdown.js +21 -38
- package/lib/zudoku.plugin-markdown.js.map +1 -1
- package/lib/zudoku.plugin-openapi.js +8 -6
- package/lib/zudoku.plugin-openapi.js.map +1 -1
- package/package.json +4 -1
- package/src/app/demo.tsx +5 -4
- package/src/app/main.css +2 -2
- package/src/app/main.tsx +3 -1
- package/src/app/standalone.tsx +5 -4
- package/src/lib/components/DevPortal.tsx +1 -1
- package/src/lib/components/Header.tsx +21 -19
- package/src/lib/components/Layout.tsx +2 -2
- package/src/lib/components/TopNavigation.tsx +5 -5
- package/src/lib/components/context/DevPortalProvider.ts +11 -28
- package/src/lib/components/context/ThemeContext.tsx +3 -41
- package/src/lib/components/context/ThemeProvider.tsx +27 -0
- package/src/lib/components/navigation/{SideNavigation.tsx → Sidebar.tsx} +7 -7
- package/src/lib/components/navigation/SidebarBadge.tsx +40 -0
- package/src/lib/components/navigation/SidebarCategory.tsx +105 -0
- package/src/lib/components/navigation/SidebarItem.tsx +96 -0
- package/src/lib/components/navigation/{SideNavigationWrapper.tsx → SidebarWrapper.tsx} +1 -1
- package/src/lib/components/navigation/utils.ts +120 -0
- package/src/lib/core/DevPortalContext.ts +12 -44
- package/src/lib/core/plugins.ts +6 -13
- package/src/lib/plugins/markdown/MdxPage.tsx +14 -50
- package/src/lib/plugins/markdown/generateRoutes.tsx +29 -57
- package/src/lib/plugins/openapi/OperationListItem.tsx +5 -6
- package/src/lib/plugins/openapi/ParameterList.tsx +13 -10
- package/src/lib/plugins/openapi/SchemaListView.tsx +18 -2
- package/src/lib/plugins/openapi/SchemaListViewItem.tsx +16 -7
- package/src/lib/plugins/openapi/Sidecar.tsx +15 -2
- package/src/lib/plugins/openapi/index.tsx +17 -23
- package/src/lib/plugins/openapi/interfaces.ts +1 -1
- package/src/lib/plugins/openapi/playground/Headers.tsx +1 -1
- package/src/lib/plugins/openapi/playground/Playground.tsx +1 -1
- package/src/lib/util/useScrollToAnchor.ts +39 -18
- package/dist/lib/components/navigation/SideNavigation.d.ts +0 -1
- package/dist/lib/components/navigation/SideNavigation.js +0 -12
- package/dist/lib/components/navigation/SideNavigation.js.map +0 -1
- package/dist/lib/components/navigation/SideNavigationCategory.d.ts +0 -4
- package/dist/lib/components/navigation/SideNavigationCategory.js +0 -26
- package/dist/lib/components/navigation/SideNavigationCategory.js.map +0 -1
- package/dist/lib/components/navigation/SideNavigationItem.d.ts +0 -9
- package/dist/lib/components/navigation/SideNavigationItem.js +0 -44
- package/dist/lib/components/navigation/SideNavigationItem.js.map +0 -1
- package/dist/lib/components/navigation/SideNavigationWrapper.js.map +0 -1
- package/dist/lib/components/navigation/useNavigationCollapsibleState.d.ts +0 -9
- package/dist/lib/components/navigation/useNavigationCollapsibleState.js +0 -28
- package/dist/lib/components/navigation/useNavigationCollapsibleState.js.map +0 -1
- package/dist/lib/components/navigation/util.d.ts +0 -8
- package/dist/lib/components/navigation/util.js +0 -15
- package/dist/lib/components/navigation/util.js.map +0 -1
- package/dist/lib/plugins/openapi/MethodBadge.d.ts +0 -13
- package/dist/lib/plugins/openapi/MethodBadge.js +0 -26
- package/dist/lib/plugins/openapi/MethodBadge.js.map +0 -1
- package/dist/lib/util/traverseNavigation.d.ts +0 -6
- package/dist/lib/util/traverseNavigation.js +0 -30
- package/dist/lib/util/traverseNavigation.js.map +0 -1
- package/lib/AnchorLink-BZcpTwOs.js.map +0 -1
- package/lib/DevPortalProvider-BWeAysxF.js.map +0 -1
- package/lib/DeveloperHint-DQVwIery.js +0 -10
- package/lib/MdxPage-CA1WmW14.js.map +0 -1
- package/lib/OperationList-CHK_erYP.js.map +0 -1
- package/lib/Route-D70pGn9n.js +0 -13
- package/lib/Spinner-Coi7ORUV.js +0 -244
- package/lib/Spinner-Coi7ORUV.js.map +0 -1
- package/lib/index-Bl6YeerK.js.map +0 -1
- package/lib/index-Dt-pU7Vu.js +0 -916
- package/lib/index-Dt-pU7Vu.js.map +0 -1
- package/lib/jsx-runtime-CJBdjYYx.js +0 -1526
- package/lib/jsx-runtime-CJBdjYYx.js.map +0 -1
- package/src/lib/components/navigation/SideNavigationCategory.tsx +0 -72
- package/src/lib/components/navigation/SideNavigationItem.tsx +0 -148
- package/src/lib/components/navigation/useNavigationCollapsibleState.ts +0 -42
- package/src/lib/components/navigation/util.ts +0 -38
- package/src/lib/plugins/openapi/MethodBadge.tsx +0 -36
- package/src/lib/util/traverseNavigation.ts +0 -55
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as p, R as
|
|
3
|
-
import { u as
|
|
4
|
-
import { L as x } from "./index-
|
|
5
|
-
import { u as h,
|
|
6
|
-
import { B as l, p as I } from "./Combination-
|
|
7
|
-
import { D as P } from "./DeveloperHint-
|
|
1
|
+
import { j as e } from "./jsx-runtime-B6kdoens.js";
|
|
2
|
+
import { a as p, R as f } from "./SlotletProvider-CzMAO73_.js";
|
|
3
|
+
import { u as g, a as u, I as j, S as v, b as k, c as w, d as b, e as K, f as y } from "./Input-BclXSY0g.js";
|
|
4
|
+
import { b as N, L as x, O as E } from "./index-7kcHaXD6.js";
|
|
5
|
+
import { u as h, q as A, t as S } from "./DevPortalProvider-CTxoCHIT.js";
|
|
6
|
+
import { B as l, p as I } from "./Combination-DkycFHkm.js";
|
|
7
|
+
import { D as P } from "./DeveloperHint-BQSFXH01.js";
|
|
8
8
|
import { useState as D } from "react";
|
|
9
|
-
import { c as d, a as
|
|
9
|
+
import { c as d, a as q } from "./Markdown-B_Gax7at.js";
|
|
10
10
|
/**
|
|
11
11
|
* @license lucide-react v0.378.0 - ISC
|
|
12
12
|
*
|
|
13
13
|
* This source code is licensed under the ISC license.
|
|
14
14
|
* See the LICENSE file in the root directory of this source tree.
|
|
15
15
|
*/
|
|
16
|
-
const
|
|
16
|
+
const C = d("EyeOff", [
|
|
17
17
|
["path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24", key: "1jxqfv" }],
|
|
18
18
|
[
|
|
19
19
|
"path",
|
|
@@ -34,7 +34,7 @@ const R = d("EyeOff", [
|
|
|
34
34
|
* This source code is licensed under the ISC license.
|
|
35
35
|
* See the LICENSE file in the root directory of this source tree.
|
|
36
36
|
*/
|
|
37
|
-
const
|
|
37
|
+
const R = d("Eye", [
|
|
38
38
|
["path", { d: "M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z", key: "rwhkz3" }],
|
|
39
39
|
["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
|
|
40
40
|
]);
|
|
@@ -71,7 +71,7 @@ class z extends Error {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
const F = ({ service: t }) => {
|
|
74
|
-
const s = h(), r =
|
|
74
|
+
const s = h(), r = N(), n = g({
|
|
75
75
|
defaultValues: {
|
|
76
76
|
expiresOn: "30"
|
|
77
77
|
}
|
|
@@ -95,16 +95,16 @@ const F = ({ service: t }) => {
|
|
|
95
95
|
onSubmit: n.handleSubmit((i) => o.mutate(i)),
|
|
96
96
|
children: /* @__PURE__ */ e.jsxs("div", { className: "flex gap-2 flex-col", children: [
|
|
97
97
|
"Note",
|
|
98
|
-
/* @__PURE__ */ e.jsx(
|
|
98
|
+
/* @__PURE__ */ e.jsx(j, { ...n.register("description") }),
|
|
99
99
|
"Expiration",
|
|
100
100
|
/* @__PURE__ */ e.jsxs(
|
|
101
|
-
|
|
101
|
+
v,
|
|
102
102
|
{
|
|
103
103
|
onValueChange: (i) => n.setValue("expiresOn", i),
|
|
104
104
|
defaultValue: n.getValues("expiresOn"),
|
|
105
105
|
children: [
|
|
106
|
-
/* @__PURE__ */ e.jsx(
|
|
107
|
-
/* @__PURE__ */ e.jsx(
|
|
106
|
+
/* @__PURE__ */ e.jsx(k, { children: /* @__PURE__ */ e.jsx(w, {}) }),
|
|
107
|
+
/* @__PURE__ */ e.jsx(b, { children: /* @__PURE__ */ e.jsxs(K, { children: [
|
|
108
108
|
[7, 30, 60, 90].map((i) => /* @__PURE__ */ e.jsxs(y, { value: String(i), children: [
|
|
109
109
|
i,
|
|
110
110
|
" days"
|
|
@@ -127,7 +127,7 @@ const F = ({ service: t }) => {
|
|
|
127
127
|
return s.setDate(s.getDate() + t), s.toISOString();
|
|
128
128
|
}, T = () => {
|
|
129
129
|
const t = I();
|
|
130
|
-
return t.isAuthEnabled && t.isPending ? null : t.isAuthenticated ? /* @__PURE__ */ e.jsx(
|
|
130
|
+
return t.isAuthEnabled && t.isPending ? null : t.isAuthenticated ? /* @__PURE__ */ e.jsx(E, {}) : t.isAuthEnabled ? /* @__PURE__ */ e.jsxs("div", { className: "flex flex-col justify-center gap-2 items-center h-1/2", children: [
|
|
131
131
|
"Please login first to view this page",
|
|
132
132
|
/* @__PURE__ */ e.jsx(l, { onClick: () => t.login(), children: "Login" })
|
|
133
133
|
] }) : /* @__PURE__ */ e.jsx("div", { className: "flex flex-col justify-center gap-2 items-center h-1/2", children: /* @__PURE__ */ e.jsxs(P, { className: "max-w-[600px]", children: [
|
|
@@ -174,7 +174,7 @@ const F = ({ service: t }) => {
|
|
|
174
174
|
] }) : /* @__PURE__ */ e.jsx(
|
|
175
175
|
"ul",
|
|
176
176
|
{
|
|
177
|
-
className:
|
|
177
|
+
className: q(
|
|
178
178
|
"grid grid-cols-1 rounded border",
|
|
179
179
|
"lg:grid-cols-[minmax(250px,min-content)_1fr_min-content]"
|
|
180
180
|
),
|
|
@@ -240,7 +240,7 @@ const F = ({ service: t }) => {
|
|
|
240
240
|
variant: "outline",
|
|
241
241
|
onClick: () => r((n) => !n),
|
|
242
242
|
size: "icon",
|
|
243
|
-
children: s ? /* @__PURE__ */ e.jsx(
|
|
243
|
+
children: s ? /* @__PURE__ */ e.jsx(C, { size: 16 }) : /* @__PURE__ */ e.jsx(R, { size: 16 })
|
|
244
244
|
}
|
|
245
245
|
)
|
|
246
246
|
] });
|
|
@@ -304,7 +304,7 @@ const F = ({ service: t }) => {
|
|
|
304
304
|
getRoutes: () => [
|
|
305
305
|
{
|
|
306
306
|
element: /* @__PURE__ */ e.jsx(T, {}),
|
|
307
|
-
errorElement: /* @__PURE__ */ e.jsx(
|
|
307
|
+
errorElement: /* @__PURE__ */ e.jsx(f, {}),
|
|
308
308
|
children: [
|
|
309
309
|
{
|
|
310
310
|
path: "/settings/api-keys",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { j as m } from "./jsx-runtime-
|
|
2
|
-
import { P as o } from "./Markdown-
|
|
1
|
+
import { j as m } from "./jsx-runtime-B6kdoens.js";
|
|
2
|
+
import { P as o } from "./Markdown-B_Gax7at.js";
|
|
3
3
|
const l = (s) => ({
|
|
4
4
|
getRoutes: () => s.map(({ path: e, element: t }) => ({
|
|
5
5
|
path: e,
|
|
@@ -1,48 +1,31 @@
|
|
|
1
|
-
import { j as
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { j as m } from "./jsx-runtime-B6kdoens.js";
|
|
2
|
+
const u = (t, e) => Object.entries(t).flatMap(([a, r]) => {
|
|
3
|
+
const n = a.match(/pages\/(.*).mdx?$/), o = n == null ? void 0 : n.at(1);
|
|
4
|
+
if (!o) return [];
|
|
5
|
+
const s = o.split("/");
|
|
6
|
+
return {
|
|
7
|
+
path: s.at(-1) === "index" ? s.slice(0, -1).join("/") : o,
|
|
8
|
+
lazy: async () => {
|
|
9
|
+
const { MdxPage: i } = await import("./MdxPage-Crlr0GmN.js"), { default: p, ...c } = await r();
|
|
9
10
|
return {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
...l,
|
|
19
|
-
defaultOptions: e
|
|
20
|
-
}
|
|
21
|
-
)
|
|
22
|
-
};
|
|
23
|
-
}
|
|
11
|
+
element: /* @__PURE__ */ m.jsx(
|
|
12
|
+
i,
|
|
13
|
+
{
|
|
14
|
+
mdxComponent: p,
|
|
15
|
+
...c,
|
|
16
|
+
defaultOptions: e
|
|
17
|
+
}
|
|
18
|
+
)
|
|
24
19
|
};
|
|
25
20
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
).map((n) => ({
|
|
29
|
-
path: `/${n}`,
|
|
30
|
-
element: /* @__PURE__ */ o.jsx(j, {})
|
|
31
|
-
}));
|
|
32
|
-
return [...a, ...p];
|
|
33
|
-
}, j = () => {
|
|
34
|
-
const t = d();
|
|
35
|
-
return t ? g(t, (e, a) => {
|
|
36
|
-
if (!("children" in e || !h(e)))
|
|
37
|
-
return /* @__PURE__ */ o.jsx(x, { to: a, replace: !0 });
|
|
38
|
-
}) : null;
|
|
39
|
-
}, w = ({
|
|
21
|
+
};
|
|
22
|
+
}), g = ({
|
|
40
23
|
markdownFiles: t,
|
|
41
24
|
defaultOptions: e
|
|
42
25
|
}) => ({
|
|
43
|
-
getRoutes: () =>
|
|
26
|
+
getRoutes: () => u(t, e)
|
|
44
27
|
});
|
|
45
28
|
export {
|
|
46
|
-
|
|
29
|
+
g as markdownPlugin
|
|
47
30
|
};
|
|
48
31
|
//# sourceMappingURL=zudoku.plugin-markdown.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zudoku.plugin-markdown.js","sources":["../src/lib/plugins/markdown/generateRoutes.tsx","../src/lib/plugins/markdown/index.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"zudoku.plugin-markdown.js","sources":["../src/lib/plugins/markdown/generateRoutes.tsx","../src/lib/plugins/markdown/index.tsx"],"sourcesContent":["import { type RouteObject } from \"react-router-dom\";\n\nimport {\n MarkdownPluginDefaultOptions,\n MarkdownPluginOptions,\n} from \"./index.js\";\n\nexport const generateRoutes = (\n markdownFiles: MarkdownPluginOptions[\"markdownFiles\"],\n defaultOptions?: MarkdownPluginDefaultOptions,\n): RouteObject[] =>\n Object.entries(markdownFiles).flatMap(([file, importPromise]) => {\n // @todo we can pass in the folder name and then filter the markdown files based on that path\n const match = file.match(/pages\\/(.*).mdx?$/);\n const path = match?.at(1);\n\n if (!path) return [];\n\n const pathSegments = path.split(\"/\");\n const isIndexFile = pathSegments.at(-1) === \"index\";\n const routePath = isIndexFile ? pathSegments.slice(0, -1).join(\"/\") : path;\n\n return {\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 } satisfies RouteObject;\n });\n","import type { Toc } from \"@stefanprobst/rehype-extract-toc\";\nimport type { MDXProps } from \"mdx/types.js\";\nimport type { DevPortalPlugin } from \"../../core/plugins.js\";\nimport { generateRoutes } from \"./generateRoutes.js\";\n\nexport type MarkdownPluginOptions = {\n markdownFiles: Record<string, () => Promise<MDXImport>>;\n defaultOptions?: MarkdownPluginDefaultOptions;\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 markdownFiles,\n defaultOptions,\n}: MarkdownPluginOptions): DevPortalPlugin => ({\n getRoutes: () => generateRoutes(markdownFiles, defaultOptions),\n});\n"],"names":["generateRoutes","markdownFiles","defaultOptions","file","importPromise","match","path","pathSegments","MdxPage","Component","props","jsx","markdownPlugin"],"mappings":";AAOO,MAAMA,IAAiB,CAC5BC,GACAC,MAEA,OAAO,QAAQD,CAAa,EAAE,QAAQ,CAAC,CAACE,GAAMC,CAAa,MAAM;AAEzD,QAAAC,IAAQF,EAAK,MAAM,mBAAmB,GACtCG,IAAOD,KAAA,gBAAAA,EAAO,GAAG;AAEnB,MAAA,CAACC,EAAM,QAAO;AAEZ,QAAAC,IAAeD,EAAK,MAAM,GAAG;AAI5B,SAAA;AAAA,IACL,MAJkBC,EAAa,GAAG,EAAE,MAAM,UACZA,EAAa,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,IAAID;AAAA,IAIpE,MAAM,YAAY;AAChB,YAAM,EAAE,SAAAE,EAAA,IAAY,MAAM,OAAO,uBAAc,GACzC,EAAE,SAASC,GAAW,GAAGC,EAAM,IAAI,MAAMN;AACxC,aAAA;AAAA,QACL,SACEO,gBAAAA,EAAA;AAAA,UAACH;AAAA,UAAA;AAAA,YACC,cAAcC;AAAA,YACb,GAAGC;AAAA,YACJ,gBAAAR;AAAA,UAAA;AAAA,QACF;AAAA,MAAA;AAAA,IAGN;AAAA,EAAA;AAEJ,CAAC,GCVUU,IAAiB,CAAC;AAAA,EAC7B,eAAAX;AAAA,EACA,gBAAAC;AACF,OAA+C;AAAA,EAC7C,WAAW,MAAMF,EAAeC,GAAeC,CAAc;AAC/D;"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import "./jsx-runtime-
|
|
2
|
-
import { o as
|
|
1
|
+
import "./jsx-runtime-B6kdoens.js";
|
|
2
|
+
import { o as l } from "./index-DUrF63A6.js";
|
|
3
3
|
import "./urql-DrBfkb92.js";
|
|
4
|
-
import "./DevPortalProvider-
|
|
4
|
+
import "./DevPortalProvider-CTxoCHIT.js";
|
|
5
5
|
import "zudoku/openapi-worker";
|
|
6
|
-
import "./Combination-
|
|
7
|
-
import "./Markdown-
|
|
6
|
+
import "./Combination-DkycFHkm.js";
|
|
7
|
+
import "./Markdown-B_Gax7at.js";
|
|
8
|
+
import "./joinPath-VeNuJa7y.js";
|
|
8
9
|
import "./router-BiRCp01d.js";
|
|
10
|
+
import "./index-7kcHaXD6.js";
|
|
9
11
|
export {
|
|
10
|
-
|
|
12
|
+
l as openApiPlugin
|
|
11
13
|
};
|
|
12
14
|
//# 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.0-dev.
|
|
3
|
+
"version": "0.3.0-dev.85",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -102,9 +102,11 @@
|
|
|
102
102
|
"class-variance-authority": "0.7.0",
|
|
103
103
|
"dotenv": "16.4.5",
|
|
104
104
|
"express": "4.19.2",
|
|
105
|
+
"glob": "^11.0.0",
|
|
105
106
|
"graphql": "16.9.0",
|
|
106
107
|
"graphql-type-json": "0.3.2",
|
|
107
108
|
"graphql-yoga": "5.2.0",
|
|
109
|
+
"gray-matter": "^4.0.3",
|
|
108
110
|
"loglevel": "^1.9.1",
|
|
109
111
|
"lru-cache": "10.2.0",
|
|
110
112
|
"mdx": "0.3.1",
|
|
@@ -170,6 +172,7 @@
|
|
|
170
172
|
"react-markdown": "9.0.1",
|
|
171
173
|
"react-router-dom": "6.25.1",
|
|
172
174
|
"rollup-plugin-visualizer": "^5.12.0",
|
|
175
|
+
"tsx": "4.16.5",
|
|
173
176
|
"typescript": "5.5.3"
|
|
174
177
|
},
|
|
175
178
|
"peerDependencies": {
|
package/src/app/demo.tsx
CHANGED
|
@@ -32,14 +32,15 @@ createRoot(document.getElementById("root")!).render(
|
|
|
32
32
|
},
|
|
33
33
|
pageTitle: "Developer Portal",
|
|
34
34
|
}}
|
|
35
|
-
|
|
35
|
+
topNavigation={[
|
|
36
36
|
{
|
|
37
|
+
id: "demo",
|
|
37
38
|
label: "API Reference",
|
|
38
|
-
path: "/demo",
|
|
39
|
-
categories: [],
|
|
40
39
|
},
|
|
41
40
|
]}
|
|
42
|
-
plugins={[
|
|
41
|
+
plugins={[
|
|
42
|
+
openApiPlugin({ type: "url", input: apiUrl!, navigationId: "demo" }),
|
|
43
|
+
]}
|
|
43
44
|
/>
|
|
44
45
|
</StrictMode>,
|
|
45
46
|
);
|
package/src/app/main.css
CHANGED
|
@@ -137,10 +137,10 @@
|
|
|
137
137
|
--slide-offset: -0.75rem;
|
|
138
138
|
@apply overflow-hidden;
|
|
139
139
|
}
|
|
140
|
-
|
|
140
|
+
.CollapsibleContent[data-state="open"] {
|
|
141
141
|
animation: slideDown 300ms var(--easing);
|
|
142
142
|
}
|
|
143
|
-
|
|
143
|
+
.CollapsibleContent[data-state="closed"] {
|
|
144
144
|
animation: slideUp 300ms var(--easing);
|
|
145
145
|
}
|
|
146
146
|
|
package/src/app/main.tsx
CHANGED
|
@@ -4,6 +4,7 @@ import { configuredApiPlugins } from "virtual:zudoku-api-plugins";
|
|
|
4
4
|
import { configuredAuthProvider } from "virtual:zudoku-auth";
|
|
5
5
|
import { configuredDocsPlugins } from "virtual:zudoku-docs-plugins";
|
|
6
6
|
import { configuredRedirectPlugin } from "virtual:zudoku-redirect-plugin";
|
|
7
|
+
import { configuredSidebar } from "virtual:zudoku-sidebar";
|
|
7
8
|
import "virtual:zudoku-theme.css";
|
|
8
9
|
import { DevPortal, Layout, RouterError } from "zudoku/components";
|
|
9
10
|
import { isNavigationPlugin } from "zudoku/internal";
|
|
@@ -35,8 +36,9 @@ export const convertZudokuConfigToOptions = (
|
|
|
35
36
|
title: "%s | Developer Portal",
|
|
36
37
|
...config.metadata,
|
|
37
38
|
},
|
|
39
|
+
sidebars: configuredSidebar,
|
|
40
|
+
topNavigation: config.topNavigation,
|
|
38
41
|
mdx: config.mdx,
|
|
39
|
-
navigation: config.navigation ?? [],
|
|
40
42
|
authentication: configuredAuthProvider,
|
|
41
43
|
plugins: [
|
|
42
44
|
...configuredDocsPlugins,
|
package/src/app/standalone.tsx
CHANGED
|
@@ -38,14 +38,15 @@ createRoot(root).render(
|
|
|
38
38
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
39
39
|
pageTitle: pageTitle ?? "Developer Portal",
|
|
40
40
|
}}
|
|
41
|
-
|
|
41
|
+
topNavigation={[
|
|
42
42
|
{
|
|
43
|
+
id: "demo",
|
|
43
44
|
label: "API Reference",
|
|
44
|
-
path: "/",
|
|
45
|
-
categories: [],
|
|
46
45
|
},
|
|
47
46
|
]}
|
|
48
|
-
plugins={[
|
|
47
|
+
plugins={[
|
|
48
|
+
openApiPlugin({ type: "url", input: apiUrl!, navigationId: "/" }),
|
|
49
|
+
]}
|
|
49
50
|
/>
|
|
50
51
|
</StrictMode>,
|
|
51
52
|
);
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
DEFAULT_COMPONENTS,
|
|
29
29
|
} from "./context/ComponentsContext.js";
|
|
30
30
|
import { DevPortalProvider } from "./context/DevPortalProvider.js";
|
|
31
|
-
import { ThemeProvider } from "./context/
|
|
31
|
+
import { ThemeProvider } from "./context/ThemeProvider.js";
|
|
32
32
|
import { ViewportAnchorProvider } from "./context/ViewportAnchorContext.js";
|
|
33
33
|
import { SlotletProvider } from "./SlotletProvider.js";
|
|
34
34
|
|
|
@@ -3,7 +3,7 @@ import { memo } from "react";
|
|
|
3
3
|
|
|
4
4
|
import { Link, useLocation } from "react-router-dom";
|
|
5
5
|
import { useAuth } from "../authentication/hook.js";
|
|
6
|
-
import { isProfileMenuPlugin,
|
|
6
|
+
import { isProfileMenuPlugin, ProfileNavigationItem } from "../core/plugins.js";
|
|
7
7
|
import { Button } from "../ui/Button.js";
|
|
8
8
|
import {
|
|
9
9
|
DropdownMenu,
|
|
@@ -22,7 +22,7 @@ import { TopNavigation } from "./TopNavigation.js";
|
|
|
22
22
|
import { useDevPortal } from "./context/DevPortalProvider.js";
|
|
23
23
|
import { useTheme } from "./context/ThemeContext.js";
|
|
24
24
|
|
|
25
|
-
const RecursiveMenu = ({ item }: { item:
|
|
25
|
+
const RecursiveMenu = ({ item }: { item: ProfileNavigationItem }) => {
|
|
26
26
|
return item.children ? (
|
|
27
27
|
<DropdownMenuSub key={item.label}>
|
|
28
28
|
<DropdownMenuSubTrigger>{item.label}</DropdownMenuSubTrigger>
|
|
@@ -49,6 +49,11 @@ export const Header = memo(function HeaderInner() {
|
|
|
49
49
|
const context = useDevPortal();
|
|
50
50
|
const { page, plugins } = context;
|
|
51
51
|
|
|
52
|
+
const accountItems = plugins
|
|
53
|
+
.filter((p) => isProfileMenuPlugin(p))
|
|
54
|
+
.flatMap((p) => p.getProfileMenuItems(context))
|
|
55
|
+
.map((i) => <RecursiveMenu key={i.label} item={i} />);
|
|
56
|
+
|
|
52
57
|
const ThemeIcon = isDark ? MoonStarIcon : SunIcon;
|
|
53
58
|
|
|
54
59
|
return (
|
|
@@ -108,23 +113,20 @@ export const Header = memo(function HeaderInner() {
|
|
|
108
113
|
</Link>
|
|
109
114
|
</Button>
|
|
110
115
|
) : (
|
|
111
|
-
|
|
112
|
-
<
|
|
113
|
-
<
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
))}
|
|
126
|
-
</DropdownMenuContent>
|
|
127
|
-
</DropdownMenu>
|
|
116
|
+
accountItems.length > 0 && (
|
|
117
|
+
<DropdownMenu>
|
|
118
|
+
<DropdownMenuTrigger asChild>
|
|
119
|
+
<Button variant="ghost">
|
|
120
|
+
{profile?.email ? `${profile.email}` : "My Account"}
|
|
121
|
+
</Button>
|
|
122
|
+
</DropdownMenuTrigger>
|
|
123
|
+
<DropdownMenuContent className="w-56">
|
|
124
|
+
<DropdownMenuLabel>My Account</DropdownMenuLabel>
|
|
125
|
+
<DropdownMenuSeparator />
|
|
126
|
+
{accountItems}
|
|
127
|
+
</DropdownMenuContent>
|
|
128
|
+
</DropdownMenu>
|
|
129
|
+
)
|
|
128
130
|
)}
|
|
129
131
|
|
|
130
132
|
<button
|
|
@@ -7,7 +7,7 @@ import { useScrollToTop } from "../util/useScrollToTop.js";
|
|
|
7
7
|
import { useDevPortal } from "./context/DevPortalProvider.js";
|
|
8
8
|
import { useViewportAnchor } from "./context/ViewportAnchorContext.js";
|
|
9
9
|
import { Header } from "./Header.js";
|
|
10
|
-
import {
|
|
10
|
+
import { Sidebar } from "./navigation/Sidebar.js";
|
|
11
11
|
import { Slotlet } from "./SlotletProvider.js";
|
|
12
12
|
import { Spinner } from "./Spinner.js";
|
|
13
13
|
|
|
@@ -47,7 +47,7 @@ export const Layout = ({ children }: { children?: ReactNode }) => {
|
|
|
47
47
|
</div>
|
|
48
48
|
}
|
|
49
49
|
>
|
|
50
|
-
<
|
|
50
|
+
<Sidebar />
|
|
51
51
|
<main
|
|
52
52
|
className={cn(
|
|
53
53
|
"dark:border-white/10 translate-x-0 h-full",
|
|
@@ -4,17 +4,17 @@ import { NavLink } from "react-router-dom";
|
|
|
4
4
|
import { useDevPortal } from "./context/DevPortalProvider.js";
|
|
5
5
|
|
|
6
6
|
export const TopNavigation = () => {
|
|
7
|
-
const {
|
|
7
|
+
const { topNavigation } = useDevPortal();
|
|
8
8
|
|
|
9
|
-
// Hide
|
|
10
|
-
if (
|
|
9
|
+
// Hide top nav if there is only one item
|
|
10
|
+
if (topNavigation.length <= 1) {
|
|
11
11
|
return null;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
return (
|
|
15
15
|
<nav className="border-b text-sm px-12 h-[--top-nav-height]">
|
|
16
16
|
<ul className="flex flex-row items-center gap-8">
|
|
17
|
-
{
|
|
17
|
+
{topNavigation.map((item) => (
|
|
18
18
|
<li key={item.label}>
|
|
19
19
|
<NavLink
|
|
20
20
|
className={({ isActive }) =>
|
|
@@ -25,7 +25,7 @@ export const TopNavigation = () => {
|
|
|
25
25
|
: "border-transparent text-foreground/75 hover:text-foreground hover:border-accent-foreground/25",
|
|
26
26
|
)
|
|
27
27
|
}
|
|
28
|
-
to={item.
|
|
28
|
+
to={item.id}
|
|
29
29
|
>
|
|
30
30
|
{item.label}
|
|
31
31
|
</NavLink>
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { useQuery, useSuspenseQuery } from "@tanstack/react-query";
|
|
2
2
|
import { createContext, useContext } from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { useLocation } from "react-router-dom";
|
|
4
4
|
import { DevPortalContext } from "../../core/DevPortalContext.js";
|
|
5
|
-
import { traverseNavigation } from "../../util/traverseNavigation.js";
|
|
6
5
|
|
|
7
6
|
const DevPortalReactContext = createContext<DevPortalContext | undefined>(
|
|
8
7
|
undefined,
|
|
@@ -29,43 +28,27 @@ export const useApiIdentities = () => {
|
|
|
29
28
|
};
|
|
30
29
|
|
|
31
30
|
export const useTopNavigationItem = () => {
|
|
32
|
-
const {
|
|
31
|
+
const { topNavigation } = useDevPortal();
|
|
33
32
|
const location = useLocation();
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
for (const item of navigation) {
|
|
38
|
-
const foundNavItem = traverseNavigation(item, (_node, fullPath) => {
|
|
39
|
-
if (location.pathname === fullPath) {
|
|
40
|
-
return item;
|
|
41
|
-
}
|
|
42
|
-
});
|
|
34
|
+
const firstPart = location.pathname.split("/").at(1);
|
|
35
|
+
if (!firstPart) return;
|
|
43
36
|
|
|
44
|
-
|
|
45
|
-
return foundNavItem;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
if (location.pathname === "/") {
|
|
49
|
-
return navigation.find((item) => item.path === "/");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return navigation.find(
|
|
53
|
-
(item) =>
|
|
54
|
-
item.path !== "/" &&
|
|
55
|
-
matchPath({ path: item.path, end: false }, location.pathname),
|
|
56
|
-
);
|
|
37
|
+
return topNavigation.find((item) => item.id === firstPart);
|
|
57
38
|
};
|
|
58
39
|
|
|
59
40
|
export const useNavigation = () => {
|
|
60
|
-
const {
|
|
41
|
+
const { getPluginNavigation, sidebars } = useDevPortal();
|
|
61
42
|
const navItem = useTopNavigationItem();
|
|
62
|
-
|
|
63
|
-
const
|
|
43
|
+
const path = navItem?.id;
|
|
44
|
+
const currentSidebar = path ? sidebars[path] ?? [] : [];
|
|
64
45
|
|
|
65
46
|
return useSuspenseQuery({
|
|
66
47
|
queryFn: async () => {
|
|
48
|
+
const pluginSidebar = path ? await getPluginNavigation(path) : [];
|
|
49
|
+
|
|
67
50
|
return {
|
|
68
|
-
items: [...
|
|
51
|
+
items: [...currentSidebar, ...pluginSidebar],
|
|
69
52
|
currentTopNavItem: navItem,
|
|
70
53
|
};
|
|
71
54
|
},
|
|
@@ -1,46 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createContext,
|
|
3
|
-
type ReactNode,
|
|
4
|
-
useCallback,
|
|
5
|
-
useContext,
|
|
6
|
-
useEffect,
|
|
7
|
-
useState,
|
|
8
|
-
} from "react";
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
9
2
|
|
|
10
|
-
const ThemeContext = createContext<readonly [boolean, () => void]>([
|
|
3
|
+
export const ThemeContext = createContext<readonly [boolean, () => void]>([
|
|
11
4
|
false,
|
|
12
5
|
() => {},
|
|
13
6
|
]);
|
|
14
7
|
|
|
15
|
-
export const useTheme = () =>
|
|
16
|
-
const context = useContext(ThemeContext);
|
|
17
|
-
if (!context) {
|
|
18
|
-
throw new Error("useTheme must be used within a ThemeProvider");
|
|
19
|
-
}
|
|
20
|
-
return context;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export const ThemeProvider = (props: { children: ReactNode }) => {
|
|
24
|
-
const [dark, setDark] = useState(false);
|
|
25
|
-
|
|
26
|
-
// On mount, read the preferred theme from the persistence
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
const theme = localStorage.getItem("theme");
|
|
29
|
-
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)");
|
|
30
|
-
const isDark = theme === "dark" || (!theme && prefersDark.matches);
|
|
31
|
-
|
|
32
|
-
setDark(isDark);
|
|
33
|
-
}, [dark]);
|
|
34
|
-
|
|
35
|
-
// To toggle between dark and light modes
|
|
36
|
-
const toggle = useCallback(() => {
|
|
37
|
-
const toggled = !dark;
|
|
38
|
-
document.documentElement.classList.toggle("dark", toggled);
|
|
39
|
-
localStorage.setItem("theme", toggled ? "dark" : "light");
|
|
40
|
-
setDark(toggled);
|
|
41
|
-
}, [dark]);
|
|
42
|
-
|
|
43
|
-
const value = [dark, toggle] as const;
|
|
44
|
-
|
|
45
|
-
return <ThemeContext.Provider value={value} {...props} />;
|
|
46
|
-
};
|
|
8
|
+
export const useTheme = () => useContext(ThemeContext);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ReactNode, useCallback, useEffect, useState } from "react";
|
|
2
|
+
import { ThemeContext } from "./ThemeContext.js";
|
|
3
|
+
|
|
4
|
+
export const ThemeProvider = (props: { children: ReactNode }) => {
|
|
5
|
+
const [dark, setDark] = useState(false);
|
|
6
|
+
|
|
7
|
+
// On mount, read the preferred theme from the persistence
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const theme = localStorage.getItem("theme");
|
|
10
|
+
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)");
|
|
11
|
+
const isDark = theme === "dark" || (!theme && prefersDark.matches);
|
|
12
|
+
|
|
13
|
+
setDark(isDark);
|
|
14
|
+
}, [dark]);
|
|
15
|
+
|
|
16
|
+
// To toggle between dark and light modes
|
|
17
|
+
const toggle = useCallback(() => {
|
|
18
|
+
const toggled = !dark;
|
|
19
|
+
document.documentElement.classList.toggle("dark", toggled);
|
|
20
|
+
localStorage.setItem("theme", toggled ? "dark" : "light");
|
|
21
|
+
setDark(toggled);
|
|
22
|
+
}, [dark]);
|
|
23
|
+
|
|
24
|
+
const value = [dark, toggle] as const;
|
|
25
|
+
|
|
26
|
+
return <ThemeContext.Provider value={value} {...props} />;
|
|
27
|
+
};
|
|
@@ -2,23 +2,23 @@ import { useRef } from "react";
|
|
|
2
2
|
|
|
3
3
|
import { useNavigation } from "../context/DevPortalProvider.js";
|
|
4
4
|
import { Slotlet } from "../SlotletProvider.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { SidebarItem } from "./SidebarItem.js";
|
|
6
|
+
import { SidebarWrapper } from "./SidebarWrapper.js";
|
|
7
7
|
|
|
8
|
-
export const
|
|
8
|
+
export const Sidebar = () => {
|
|
9
9
|
const navRef = useRef<HTMLDivElement | null>(null);
|
|
10
10
|
const navigation = useNavigation();
|
|
11
11
|
|
|
12
12
|
return (
|
|
13
|
-
<
|
|
13
|
+
<SidebarWrapper
|
|
14
14
|
ref={navRef}
|
|
15
15
|
pushMainContent={navigation.data.items.length > 0}
|
|
16
16
|
>
|
|
17
17
|
<Slotlet name="zudoku-before-navigation" />
|
|
18
|
-
{navigation.data.items.map((
|
|
19
|
-
<
|
|
18
|
+
{navigation.data.items.map((item) => (
|
|
19
|
+
<SidebarItem key={item.label} item={item} />
|
|
20
20
|
))}
|
|
21
21
|
<Slotlet name="zudoku-after-navigation" />
|
|
22
|
-
</
|
|
22
|
+
</SidebarWrapper>
|
|
23
23
|
);
|
|
24
24
|
};
|