zudoku 0.38.0 → 0.39.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/entry.server.d.ts +5 -4
- package/dist/app/entry.server.js +2 -2
- package/dist/app/entry.server.js.map +1 -1
- package/dist/app/tailwind.js +14 -0
- package/dist/app/tailwind.js.map +1 -1
- package/dist/cli/cmds/dev.js +1 -7
- package/dist/cli/cmds/dev.js.map +1 -1
- package/dist/config/validators/common.d.ts +17 -0
- package/dist/config/validators/common.js +1 -0
- package/dist/config/validators/common.js.map +1 -1
- package/dist/config/validators/validate.d.ts +7 -0
- package/dist/lib/components/Bootstrap.d.ts +2 -1
- package/dist/lib/components/Bootstrap.js +3 -2
- package/dist/lib/components/Bootstrap.js.map +1 -1
- package/dist/lib/components/Header.js +2 -2
- 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 -9
- package/dist/lib/components/Layout.js.map +1 -1
- package/dist/lib/components/Main.js +3 -1
- package/dist/lib/components/Main.js.map +1 -1
- package/dist/lib/components/MobileTopNavigation.js +6 -3
- package/dist/lib/components/MobileTopNavigation.js.map +1 -1
- package/dist/lib/components/Pagination.d.ts +10 -0
- package/dist/lib/components/Pagination.js +10 -0
- package/dist/lib/components/Pagination.js.map +1 -0
- package/dist/lib/components/TopNavigation.d.ts +1 -0
- package/dist/lib/components/TopNavigation.js +18 -2
- package/dist/lib/components/TopNavigation.js.map +1 -1
- package/dist/lib/components/Zudoku.js +4 -1
- package/dist/lib/components/Zudoku.js.map +1 -1
- package/dist/lib/components/context/BypassProtectedRoutesContext.d.ts +1 -0
- package/dist/lib/components/context/BypassProtectedRoutesContext.js +3 -0
- package/dist/lib/components/context/BypassProtectedRoutesContext.js.map +1 -0
- package/dist/lib/components/index.d.ts +2 -1
- package/dist/lib/components/navigation/PoweredByZudoku.d.ts +3 -0
- package/dist/lib/components/navigation/PoweredByZudoku.js +6 -0
- package/dist/lib/components/navigation/PoweredByZudoku.js.map +1 -0
- package/dist/lib/components/navigation/SidebarItem.d.ts +1 -0
- package/dist/lib/components/navigation/SidebarItem.js +7 -3
- package/dist/lib/components/navigation/SidebarItem.js.map +1 -1
- package/dist/lib/components/navigation/SidebarWrapper.js +9 -2
- package/dist/lib/components/navigation/SidebarWrapper.js.map +1 -1
- package/dist/lib/{plugins/markdown → components/navigation}/Toc.js +5 -7
- package/dist/lib/components/navigation/Toc.js.map +1 -0
- package/dist/lib/components/navigation/ZudokuLogo.d.ts +6 -0
- package/dist/lib/components/navigation/ZudokuLogo.js +5 -0
- package/dist/lib/components/navigation/ZudokuLogo.js.map +1 -0
- package/dist/lib/core/RouteGuard.d.ts +1 -0
- package/dist/lib/core/RouteGuard.js +9 -3
- package/dist/lib/core/RouteGuard.js.map +1 -1
- package/dist/lib/core/ZudokuContext.d.ts +1 -0
- package/dist/lib/core/ZudokuContext.js.map +1 -1
- package/dist/lib/oas/graphql/index.d.ts +2 -1
- package/dist/lib/oas/graphql/index.js +74 -14
- package/dist/lib/oas/graphql/index.js.map +1 -1
- package/dist/lib/oas/parser/dereference/index.js +2 -0
- package/dist/lib/oas/parser/dereference/index.js.map +1 -1
- package/dist/lib/oas/parser/index.d.ts +5 -3
- package/dist/lib/oas/parser/index.js +0 -22
- package/dist/lib/oas/parser/index.js.map +1 -1
- package/dist/lib/plugins/api-catalog/index.js +19 -17
- package/dist/lib/plugins/api-catalog/index.js.map +1 -1
- package/dist/lib/plugins/markdown/MdxPage.js +3 -3
- package/dist/lib/plugins/markdown/MdxPage.js.map +1 -1
- package/dist/lib/plugins/openapi/ColorizedParam.js +1 -1
- package/dist/lib/plugins/openapi/ColorizedParam.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationList.d.ts +1 -1
- package/dist/lib/plugins/openapi/OperationList.js +28 -8
- package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationListItem.js +1 -1
- package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
- package/dist/lib/plugins/openapi/ParameterListItem.js +2 -1
- package/dist/lib/plugins/openapi/ParameterListItem.js.map +1 -1
- package/dist/lib/plugins/openapi/SchemaList.d.ts +1 -0
- package/dist/lib/plugins/openapi/SchemaList.js +52 -0
- package/dist/lib/plugins/openapi/SchemaList.js.map +1 -0
- package/dist/lib/plugins/openapi/client/GraphQLClient.d.ts +1 -1
- package/dist/lib/plugins/openapi/client/GraphQLClient.js +1 -1
- package/dist/lib/plugins/openapi/client/GraphQLClient.js.map +1 -1
- package/dist/lib/plugins/openapi/client/useCreateQuery.d.ts +6 -2
- package/dist/lib/plugins/openapi/client/useCreateQuery.js +5 -5
- package/dist/lib/plugins/openapi/client/useCreateQuery.js.map +1 -1
- package/dist/lib/plugins/openapi/components/EnumValues.js +1 -1
- package/dist/lib/plugins/openapi/components/EnumValues.js.map +1 -1
- package/dist/lib/plugins/openapi/graphql/gql.d.ts +6 -2
- package/dist/lib/plugins/openapi/graphql/gql.js +3 -2
- package/dist/lib/plugins/openapi/graphql/gql.js.map +1 -1
- package/dist/lib/plugins/openapi/graphql/graphql.d.ts +67 -11
- package/dist/lib/plugins/openapi/graphql/graphql.js +34 -5
- package/dist/lib/plugins/openapi/graphql/graphql.js.map +1 -1
- package/dist/lib/plugins/openapi/index.js +12 -0
- package/dist/lib/plugins/openapi/index.js.map +1 -1
- package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroup.d.ts +1 -2
- package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroup.js +2 -2
- package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroup.js.map +1 -1
- package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupConnector.d.ts +2 -1
- package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupConnector.js +2 -2
- package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupConnector.js.map +1 -1
- package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupItem.d.ts +0 -1
- package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupItem.js +1 -1
- package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupItem.js.map +1 -1
- package/dist/lib/plugins/openapi/schema/SchemaExampleAndDefault.d.ts +4 -0
- package/dist/lib/plugins/openapi/schema/SchemaExampleAndDefault.js +12 -0
- package/dist/lib/plugins/openapi/schema/SchemaExampleAndDefault.js.map +1 -0
- package/dist/lib/plugins/openapi/schema/SchemaPropertyItem.d.ts +2 -4
- package/dist/lib/plugins/openapi/schema/SchemaPropertyItem.js +12 -9
- package/dist/lib/plugins/openapi/schema/SchemaPropertyItem.js.map +1 -1
- package/dist/lib/plugins/openapi/schema/SchemaView.d.ts +1 -2
- package/dist/lib/plugins/openapi/schema/SchemaView.js +30 -52
- package/dist/lib/plugins/openapi/schema/SchemaView.js.map +1 -1
- package/dist/lib/plugins/openapi/schema/utils.d.ts +1 -0
- package/dist/lib/plugins/openapi/schema/utils.js +3 -1
- package/dist/lib/plugins/openapi/schema/utils.js.map +1 -1
- package/dist/lib/plugins/openapi/util/getRoutes.js +9 -3
- package/dist/lib/plugins/openapi/util/getRoutes.js.map +1 -1
- package/dist/lib/plugins/search-pagefind/PagefindSearch.js +9 -4
- package/dist/lib/plugins/search-pagefind/PagefindSearch.js.map +1 -1
- package/dist/lib/plugins/search-pagefind/ResultList.d.ts +1 -1
- package/dist/lib/plugins/search-pagefind/ResultList.js +6 -12
- package/dist/lib/plugins/search-pagefind/ResultList.js.map +1 -1
- package/dist/lib/plugins/search-pagefind/index.d.ts +1 -3
- package/dist/lib/util/useOnScreen.d.ts +3 -2
- package/dist/lib/util/useOnScreen.js +3 -3
- package/dist/lib/util/useOnScreen.js.map +1 -1
- package/dist/vite/api/schema-codegen.js +2 -2
- package/dist/vite/api/schema-codegen.js.map +1 -1
- package/dist/vite/api/schema-codegen.test.js +5 -0
- package/dist/vite/api/schema-codegen.test.js.map +1 -1
- package/dist/vite/build.js +1 -9
- package/dist/vite/build.js.map +1 -1
- package/dist/vite/plugin-api.js +8 -7
- package/dist/vite/plugin-api.js.map +1 -1
- package/dist/vite/plugin-search.js +1 -1
- package/dist/vite/plugin-search.js.map +1 -1
- package/dist/vite/prerender/FileWritingResponse.d.ts +9 -5
- package/dist/vite/prerender/FileWritingResponse.js +5 -5
- package/dist/vite/prerender/FileWritingResponse.js.map +1 -1
- package/dist/vite/prerender/InMemoryResponse.d.ts +16 -0
- package/dist/vite/prerender/InMemoryResponse.js +32 -0
- package/dist/vite/prerender/InMemoryResponse.js.map +1 -0
- package/dist/vite/prerender/PrerenderResponse.d.ts +10 -0
- package/dist/vite/prerender/PrerenderResponse.js +2 -0
- package/dist/vite/prerender/PrerenderResponse.js.map +1 -0
- package/dist/vite/prerender/prerender.d.ts +1 -0
- package/dist/vite/prerender/prerender.js +18 -0
- package/dist/vite/prerender/prerender.js.map +1 -1
- package/dist/vite/prerender/worker.js +36 -8
- package/dist/vite/prerender/worker.js.map +1 -1
- package/dist/zuplo/with-zuplo.js +4 -0
- package/dist/zuplo/with-zuplo.js.map +1 -1
- package/lib/{AuthenticationPlugin-Duy_R1TU.js → AuthenticationPlugin-foqdvvkf.js} +2 -2
- package/lib/{AuthenticationPlugin-Duy_R1TU.js.map → AuthenticationPlugin-foqdvvkf.js.map} +1 -1
- package/lib/{Markdown-DIZ8nBVC.js → Markdown-aF5FdsNi.js} +1339 -1335
- package/lib/{Markdown-DIZ8nBVC.js.map → Markdown-aF5FdsNi.js.map} +1 -1
- package/lib/MdxPage-JscVnWM8.js +84 -0
- package/lib/MdxPage-JscVnWM8.js.map +1 -0
- package/lib/{OasProvider-D1A10JeA.js → OasProvider-C7Y53snX.js} +3 -3
- package/lib/{OasProvider-D1A10JeA.js.map → OasProvider-C7Y53snX.js.map} +1 -1
- package/lib/OperationList-_M8wg22T.js +5066 -0
- package/lib/OperationList-_M8wg22T.js.map +1 -0
- package/lib/Pagination-DCCvGq0m.js +46 -0
- package/lib/Pagination-DCCvGq0m.js.map +1 -0
- package/lib/RouteGuard-CqZPoZYJ.js +744 -0
- package/lib/RouteGuard-CqZPoZYJ.js.map +1 -0
- package/lib/SchemaList-CrKZdUyo.js +148 -0
- package/lib/SchemaList-CrKZdUyo.js.map +1 -0
- package/lib/SchemaView-B4JHn-BX.js +354 -0
- package/lib/SchemaView-B4JHn-BX.js.map +1 -0
- package/lib/{Select-fAYcJ0OU.js → Select-DVFRKf1R.js} +3 -3
- package/lib/{Select-fAYcJ0OU.js.map → Select-DVFRKf1R.js.map} +1 -1
- package/lib/{SlotletProvider-BEwNY8q0.js → SlotletProvider-DXvc0aY6.js} +2 -2
- package/lib/{SlotletProvider-BEwNY8q0.js.map → SlotletProvider-DXvc0aY6.js.map} +1 -1
- package/lib/Toc-YBsgI72s.js +92 -0
- package/lib/Toc-YBsgI72s.js.map +1 -0
- package/lib/{createServer-DjgKDpGV.js → createServer-mYvGvmc0.js} +2596 -2502
- package/lib/createServer-mYvGvmc0.js.map +1 -0
- package/lib/{hook-Cge6LiTK.js → hook-CqpVYDqN.js} +28 -28
- package/lib/{hook-Cge6LiTK.js.map → hook-CqpVYDqN.js.map} +1 -1
- package/lib/{index-B0y3fTg-.js → index-C8-tlf_X.js} +771 -729
- package/lib/index-C8-tlf_X.js.map +1 -0
- package/lib/index-D6ktNq4i.js +1863 -0
- package/lib/index-D6ktNq4i.js.map +1 -0
- package/lib/{mutation-EChriCeF.js → mutation-8LjrN7uz.js} +2 -2
- package/lib/{mutation-EChriCeF.js.map → mutation-8LjrN7uz.js.map} +1 -1
- package/lib/objectEntries-yMIkr2mI.js +5 -0
- package/lib/objectEntries-yMIkr2mI.js.map +1 -0
- package/lib/useLatest-hmRS46UF.js +11 -0
- package/lib/useLatest-hmRS46UF.js.map +1 -0
- package/lib/zudoku.auth-auth0.js +1 -1
- package/lib/zudoku.auth-clerk.js +2 -2
- package/lib/zudoku.auth-openid.js +2 -2
- package/lib/zudoku.components.js +32 -1454
- package/lib/zudoku.components.js.map +1 -1
- package/lib/zudoku.hooks.js +1 -1
- package/lib/zudoku.plugin-api-catalog.js +80 -76
- package/lib/zudoku.plugin-api-catalog.js.map +1 -1
- package/lib/zudoku.plugin-api-keys.js +3 -3
- package/lib/zudoku.plugin-custom-pages.js +1 -1
- package/lib/zudoku.plugin-markdown.js +1 -1
- package/lib/zudoku.plugin-openapi.js +2 -2
- package/lib/zudoku.plugin-search-pagefind.js +132 -137
- package/lib/zudoku.plugin-search-pagefind.js.map +1 -1
- package/package.json +6 -5
- package/src/app/entry.server.tsx +6 -3
- package/src/app/tailwind.ts +14 -0
- package/src/lib/components/Bootstrap.tsx +13 -6
- package/src/lib/components/Header.tsx +2 -2
- package/src/lib/components/Layout.tsx +5 -17
- package/src/lib/components/Main.tsx +6 -3
- package/src/lib/components/MobileTopNavigation.tsx +27 -18
- package/src/lib/components/Pagination.tsx +47 -0
- package/src/lib/components/TopNavigation.tsx +29 -2
- package/src/lib/components/Zudoku.tsx +5 -3
- package/src/lib/components/context/BypassProtectedRoutesContext.ts +3 -0
- package/src/lib/components/navigation/PoweredByZudoku.tsx +23 -0
- package/src/lib/components/navigation/SidebarItem.tsx +10 -4
- package/src/lib/components/navigation/SidebarWrapper.tsx +27 -13
- package/src/lib/{plugins/markdown → components/navigation}/Toc.tsx +5 -14
- package/src/lib/components/navigation/ZudokuLogo.tsx +25 -0
- package/src/lib/core/RouteGuard.tsx +26 -4
- package/src/lib/core/ZudokuContext.ts +1 -0
- package/src/lib/oas/graphql/index.ts +118 -45
- package/src/lib/oas/parser/dereference/index.ts +2 -0
- package/src/lib/oas/parser/index.ts +7 -29
- package/src/lib/plugins/api-catalog/index.tsx +40 -35
- package/src/lib/plugins/markdown/MdxPage.tsx +6 -36
- package/src/lib/plugins/openapi/ColorizedParam.tsx +1 -1
- package/src/lib/plugins/openapi/OperationList.tsx +36 -15
- package/src/lib/plugins/openapi/OperationListItem.tsx +7 -2
- package/src/lib/plugins/openapi/ParameterListItem.tsx +2 -0
- package/src/lib/plugins/openapi/SchemaList.tsx +151 -0
- package/src/lib/plugins/openapi/client/GraphQLClient.tsx +1 -1
- package/src/lib/plugins/openapi/client/useCreateQuery.ts +12 -5
- package/src/lib/plugins/openapi/components/EnumValues.tsx +1 -1
- package/src/lib/plugins/openapi/graphql/gql.ts +15 -6
- package/src/lib/plugins/openapi/graphql/graphql.ts +104 -15
- package/src/lib/plugins/openapi/index.tsx +13 -0
- package/src/lib/plugins/openapi/schema/LogicalGroup/LogicalGroup.tsx +1 -8
- package/src/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupConnector.tsx +3 -0
- package/src/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupItem.tsx +6 -3
- package/src/lib/plugins/openapi/schema/SchemaExampleAndDefault.tsx +36 -0
- package/src/lib/plugins/openapi/schema/SchemaPropertyItem.tsx +20 -21
- package/src/lib/plugins/openapi/schema/SchemaView.tsx +69 -141
- package/src/lib/plugins/openapi/schema/utils.ts +7 -1
- package/src/lib/plugins/openapi/util/getRoutes.tsx +9 -6
- package/src/lib/plugins/search-pagefind/PagefindSearch.tsx +11 -4
- package/src/lib/plugins/search-pagefind/ResultList.tsx +5 -16
- package/src/lib/plugins/search-pagefind/index.tsx +1 -1
- package/src/lib/util/useOnScreen.ts +6 -4
- package/dist/cli/dev/pagefind-command.d.ts +0 -3
- package/dist/cli/dev/pagefind-command.js +0 -59
- package/dist/cli/dev/pagefind-command.js.map +0 -1
- package/dist/lib/components/context/PluginSystem.d.ts +0 -1
- package/dist/lib/components/context/PluginSystem.js +0 -2
- package/dist/lib/components/context/PluginSystem.js.map +0 -1
- package/dist/lib/plugins/markdown/Toc.js.map +0 -1
- package/lib/MdxPage-JEdbfW-f.js +0 -195
- package/lib/MdxPage-JEdbfW-f.js.map +0 -1
- package/lib/OperationList-yOmYzMIp.js +0 -5379
- package/lib/OperationList-yOmYzMIp.js.map +0 -1
- package/lib/createServer-DjgKDpGV.js.map +0 -1
- package/lib/index-B0y3fTg-.js.map +0 -1
- package/lib/index.esm-CltAN0Tf.js +0 -711
- package/lib/index.esm-CltAN0Tf.js.map +0 -1
- package/lib/objectEntries-BS7aAgOm.js +0 -12
- package/lib/objectEntries-BS7aAgOm.js.map +0 -1
- package/src/lib/components/context/PluginSystem.ts +0 -0
- /package/dist/lib/{plugins/markdown → components/navigation}/Toc.d.ts +0 -0
package/src/app/entry.server.tsx
CHANGED
|
@@ -14,7 +14,7 @@ import "virtual:zudoku-theme.css";
|
|
|
14
14
|
import "vite/modulepreload-polyfill";
|
|
15
15
|
import { BootstrapStatic, ServerError } from "zudoku/components";
|
|
16
16
|
import { NO_DEHYDRATE } from "../lib/components/cache.js";
|
|
17
|
-
import type {
|
|
17
|
+
import type { PrerenderResponse } from "../vite/prerender/PrerenderResponse.js";
|
|
18
18
|
import "./main.css";
|
|
19
19
|
import { getRoutesByConfig } from "./main.js";
|
|
20
20
|
export { getRoutesByConfig };
|
|
@@ -25,12 +25,14 @@ export const render = async ({
|
|
|
25
25
|
response,
|
|
26
26
|
routes,
|
|
27
27
|
basePath,
|
|
28
|
+
bypassProtection,
|
|
28
29
|
}: {
|
|
29
30
|
template: string;
|
|
30
31
|
request: express.Request | Request;
|
|
31
|
-
response: express.Response |
|
|
32
|
+
response: express.Response | PrerenderResponse;
|
|
32
33
|
routes: RouteObject[];
|
|
33
34
|
basePath?: string;
|
|
35
|
+
bypassProtection?: boolean;
|
|
34
36
|
}) => {
|
|
35
37
|
const { query, dataRoutes } = createStaticHandler(routes, {
|
|
36
38
|
basename: basePath,
|
|
@@ -73,6 +75,7 @@ export const render = async ({
|
|
|
73
75
|
context={context}
|
|
74
76
|
queryClient={queryClient}
|
|
75
77
|
helmetContext={helmetContext}
|
|
78
|
+
bypassProtection={bypassProtection}
|
|
76
79
|
/>
|
|
77
80
|
);
|
|
78
81
|
|
|
@@ -143,7 +146,7 @@ export const render = async ({
|
|
|
143
146
|
|
|
144
147
|
export function createFetchRequest(
|
|
145
148
|
req: express.Request,
|
|
146
|
-
res: express.Response |
|
|
149
|
+
res: express.Response | PrerenderResponse,
|
|
147
150
|
): Request {
|
|
148
151
|
const origin = `${req.protocol}://${req.get("host")}`;
|
|
149
152
|
// Note: This had to take originalUrl into account for presumably vite's proxying
|
package/src/app/tailwind.ts
CHANGED
|
@@ -28,6 +28,20 @@ const config = (zudokuConfig?: LoadedConfig): Omit<Config, "content"> => {
|
|
|
28
28
|
content,
|
|
29
29
|
theme: {
|
|
30
30
|
extend: {
|
|
31
|
+
keyframes: {
|
|
32
|
+
"bounce-x-start": {
|
|
33
|
+
"0%, 100%": { transform: "translateX(0)" },
|
|
34
|
+
"50%": { transform: "translateX(-25%)" },
|
|
35
|
+
},
|
|
36
|
+
"bounce-x-end": {
|
|
37
|
+
"0%, 100%": { transform: "translateX(0)" },
|
|
38
|
+
"50%": { transform: "translateX(25%)" },
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
animation: {
|
|
42
|
+
"bounce-x-start": "bounce-x-start 1s infinite",
|
|
43
|
+
"bounce-x-end": "bounce-x-end 1s infinite",
|
|
44
|
+
},
|
|
31
45
|
fontFamily: {
|
|
32
46
|
sans,
|
|
33
47
|
mono,
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
} from "react-router";
|
|
14
14
|
import { RouterProvider } from "react-router/dom";
|
|
15
15
|
import { StaggeredRenderContext } from "../plugins/openapi/StaggeredRender.js";
|
|
16
|
+
import { BypassProtectedRoutesContext } from "./context/BypassProtectedRoutesContext.js";
|
|
16
17
|
|
|
17
18
|
const queryClient = new QueryClient({
|
|
18
19
|
defaultOptions: {
|
|
@@ -32,11 +33,13 @@ const Bootstrap = ({
|
|
|
32
33
|
<StrictMode>
|
|
33
34
|
<QueryClientProvider client={queryClient}>
|
|
34
35
|
<HydrationBoundary state={hydrate ? (window as any).DATA : undefined}>
|
|
35
|
-
<
|
|
36
|
-
<
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
<BypassProtectedRoutesContext value={false}>
|
|
37
|
+
<HelmetProvider>
|
|
38
|
+
<StaggeredRenderContext.Provider value={{ stagger: !hydrate }}>
|
|
39
|
+
<RouterProvider router={router} />
|
|
40
|
+
</StaggeredRenderContext.Provider>
|
|
41
|
+
</HelmetProvider>
|
|
42
|
+
</BypassProtectedRoutesContext>
|
|
40
43
|
</HydrationBoundary>
|
|
41
44
|
</QueryClientProvider>
|
|
42
45
|
</StrictMode>
|
|
@@ -47,16 +50,20 @@ const BootstrapStatic = ({
|
|
|
47
50
|
context,
|
|
48
51
|
queryClient,
|
|
49
52
|
helmetContext,
|
|
53
|
+
bypassProtection = false,
|
|
50
54
|
}: {
|
|
51
55
|
helmetContext: HelmetData["context"];
|
|
52
56
|
context: StaticHandlerContext;
|
|
53
57
|
queryClient: QueryClient;
|
|
54
58
|
router: ReturnType<typeof createStaticRouter>;
|
|
59
|
+
bypassProtection?: boolean;
|
|
55
60
|
}) => (
|
|
56
61
|
<StrictMode>
|
|
57
62
|
<QueryClientProvider client={queryClient}>
|
|
58
63
|
<HelmetProvider context={helmetContext}>
|
|
59
|
-
<
|
|
64
|
+
<BypassProtectedRoutesContext value={bypassProtection}>
|
|
65
|
+
<StaticRouterProvider router={router} context={context} />
|
|
66
|
+
</BypassProtectedRoutesContext>
|
|
60
67
|
</HelmetProvider>
|
|
61
68
|
</QueryClientProvider>
|
|
62
69
|
</StrictMode>
|
|
@@ -69,7 +69,7 @@ export const Header = memo(function HeaderInner() {
|
|
|
69
69
|
<header className="sticky lg:top-0 z-10 bg-background/80 backdrop-blur w-full">
|
|
70
70
|
<Banner />
|
|
71
71
|
<div className="border-b">
|
|
72
|
-
<div className="max-w-screen-2xl
|
|
72
|
+
<div className="max-w-screen-2xl mx-auto flex relative items-center justify-between px-4 lg:px-8 h-[--top-header-height] border-transparent">
|
|
73
73
|
<div className="flex">
|
|
74
74
|
<Link to="/">
|
|
75
75
|
<div className="flex items-center gap-3.5">
|
|
@@ -182,7 +182,7 @@ export const Header = memo(function HeaderInner() {
|
|
|
182
182
|
</div>
|
|
183
183
|
</div>
|
|
184
184
|
<div className="border-b hidden lg:block">
|
|
185
|
-
<div className="max-w-screen-2xl mx-auto
|
|
185
|
+
<div className="max-w-screen-2xl mx-auto border-transparent">
|
|
186
186
|
<Slotlet name="top-navigation-before" />
|
|
187
187
|
<TopNavigation />
|
|
188
188
|
<Slotlet name="top-navigation-after" />
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Helmet } from "@zudoku/react-helmet-async";
|
|
2
2
|
import { Suspense, useEffect, type ReactNode } from "react";
|
|
3
|
-
import { Outlet, useLocation
|
|
4
|
-
import { useSpinDelay } from "spin-delay";
|
|
3
|
+
import { Outlet, useLocation } from "react-router";
|
|
5
4
|
import { joinUrl } from "../util/joinUrl.js";
|
|
6
5
|
import { useScrollToAnchor } from "../util/useScrollToAnchor.js";
|
|
7
6
|
import { useScrollToTop } from "../util/useScrollToTop.js";
|
|
@@ -29,13 +28,6 @@ export const Layout = ({ children }: { children?: ReactNode }) => {
|
|
|
29
28
|
authentication?.onPageLoad?.();
|
|
30
29
|
}, [authentication]);
|
|
31
30
|
|
|
32
|
-
// Page transition is happening: https://reactrouter.com/start/framework/pending-navigation
|
|
33
|
-
const isNavigating = Boolean(useNavigation().location);
|
|
34
|
-
const showSpinner = useSpinDelay(isNavigating, {
|
|
35
|
-
delay: 300,
|
|
36
|
-
minDuration: 500,
|
|
37
|
-
});
|
|
38
|
-
|
|
39
31
|
return (
|
|
40
32
|
<>
|
|
41
33
|
{import.meta.env.MODE === "standalone" && (
|
|
@@ -61,14 +53,10 @@ export const Layout = ({ children }: { children?: ReactNode }) => {
|
|
|
61
53
|
<Header />
|
|
62
54
|
<Slotlet name="layout-after-head" />
|
|
63
55
|
|
|
64
|
-
<div className="grid grid-cols-1 grid-rows-[min-content_1fr] lg:grid-cols-[var(--side-nav-width)_1fr] max-w-screen-2xl w-full lg:mx-auto
|
|
65
|
-
{
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
<Suspense fallback={<LoadingFallback />}>
|
|
69
|
-
<Main>{children ?? <Outlet />}</Main>
|
|
70
|
-
</Suspense>
|
|
71
|
-
)}
|
|
56
|
+
<div className="grid grid-cols-1 grid-rows-[0_min-content_1fr] lg:grid-rows-[min-content_1fr] lg:grid-cols-[var(--side-nav-width)_1fr] max-w-screen-2xl w-full lg:mx-auto">
|
|
57
|
+
<Suspense fallback={<LoadingFallback />}>
|
|
58
|
+
<Main>{children ?? <Outlet />}</Main>
|
|
59
|
+
</Suspense>
|
|
72
60
|
</div>
|
|
73
61
|
</>
|
|
74
62
|
);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PanelLeftIcon } from "lucide-react";
|
|
2
2
|
import { type PropsWithChildren, useState } from "react";
|
|
3
|
+
import { useNavigation } from "react-router";
|
|
3
4
|
import { Drawer, DrawerTrigger } from "zudoku/ui/Drawer.js";
|
|
4
5
|
import { cn } from "../util/cn.js";
|
|
5
6
|
import { useCurrentNavigation } from "./context/ZudokuContext.js";
|
|
@@ -10,6 +11,7 @@ export const Main = ({ children }: PropsWithChildren) => {
|
|
|
10
11
|
const [isDrawerOpen, setDrawerOpen] = useState(false);
|
|
11
12
|
const { sidebar } = useCurrentNavigation();
|
|
12
13
|
const hasSidebar = sidebar.length > 0;
|
|
14
|
+
const isNavigating = useNavigation().state === "loading";
|
|
13
15
|
|
|
14
16
|
return (
|
|
15
17
|
<Drawer
|
|
@@ -25,7 +27,7 @@ export const Main = ({ children }: PropsWithChildren) => {
|
|
|
25
27
|
)}
|
|
26
28
|
{hasSidebar && (
|
|
27
29
|
<div className="lg:hidden -mx-4 px-4 py-2 sticky bg-background/80 backdrop-blur z-10 top-0 left-0 right-0 border-b">
|
|
28
|
-
<DrawerTrigger className="flex items-center gap-2">
|
|
30
|
+
<DrawerTrigger className="flex items-center gap-2 px-4">
|
|
29
31
|
<PanelLeftIcon size={16} strokeWidth={1.5} />
|
|
30
32
|
<span className="text-sm">Menu</span>
|
|
31
33
|
</DrawerTrigger>
|
|
@@ -34,8 +36,9 @@ export const Main = ({ children }: PropsWithChildren) => {
|
|
|
34
36
|
<main
|
|
35
37
|
data-pagefind-body
|
|
36
38
|
className={cn(
|
|
37
|
-
"
|
|
38
|
-
hasSidebar
|
|
39
|
+
"px-4 lg:pe-8 lg:px-8",
|
|
40
|
+
!hasSidebar && "col-span-full",
|
|
41
|
+
isNavigating && "animate-pulse",
|
|
39
42
|
)}
|
|
40
43
|
>
|
|
41
44
|
<Slotlet name="zudoku-before-content" />
|
|
@@ -9,12 +9,13 @@ import {
|
|
|
9
9
|
DrawerTrigger,
|
|
10
10
|
} from "../ui/Drawer.js";
|
|
11
11
|
import { useZudoku } from "./context/ZudokuContext.js";
|
|
12
|
+
import { PoweredByZudoku } from "./navigation/PoweredByZudoku.js";
|
|
12
13
|
import { Search } from "./Search.js";
|
|
13
14
|
import { ThemeSwitch } from "./ThemeSwitch.js";
|
|
14
|
-
import { isHiddenItem, TopNavItem } from "./TopNavigation.js";
|
|
15
|
+
import { isHiddenItem, PageProgress, TopNavItem } from "./TopNavigation.js";
|
|
15
16
|
|
|
16
17
|
export const MobileTopNavigation = () => {
|
|
17
|
-
const { topNavigation } = useZudoku();
|
|
18
|
+
const { topNavigation, options } = useZudoku();
|
|
18
19
|
const { isAuthenticated } = useAuth();
|
|
19
20
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
20
21
|
|
|
@@ -28,28 +29,36 @@ export const MobileTopNavigation = () => {
|
|
|
28
29
|
<DrawerTrigger className="lg:hidden">
|
|
29
30
|
<MenuIcon size={22} />
|
|
30
31
|
</DrawerTrigger>
|
|
32
|
+
<PageProgress />
|
|
31
33
|
</div>
|
|
32
34
|
<DrawerContent
|
|
33
35
|
className="lg:hidden h-[100dvh] right-0 left-auto w-[320px] rounded-none"
|
|
34
36
|
aria-describedby={undefined}
|
|
35
37
|
>
|
|
36
|
-
<div className="p-4 overflow-y-auto overscroll-none">
|
|
37
|
-
<
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
<
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
{topNavigation.filter(isHiddenItem(isAuthenticated)).map((item) => (
|
|
46
|
-
<li key={item.label}>
|
|
47
|
-
<button type="button" onClick={() => setDrawerOpen(false)}>
|
|
48
|
-
<TopNavItem {...item} />
|
|
49
|
-
</button>
|
|
38
|
+
<div className="p-4 overflow-y-auto overscroll-none h-full flex flex-col justify-between">
|
|
39
|
+
<div>
|
|
40
|
+
<VisuallyHidden>
|
|
41
|
+
<DrawerTitle>Navigation</DrawerTitle>
|
|
42
|
+
</VisuallyHidden>
|
|
43
|
+
<Search className="flex p-4" />
|
|
44
|
+
<ul className="flex flex-col items-center gap-4 p-4">
|
|
45
|
+
<li>
|
|
46
|
+
<ThemeSwitch />
|
|
50
47
|
</li>
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
{topNavigation
|
|
49
|
+
.filter(isHiddenItem(isAuthenticated))
|
|
50
|
+
.map((item) => (
|
|
51
|
+
<li key={item.label}>
|
|
52
|
+
<button type="button" onClick={() => setDrawerOpen(false)}>
|
|
53
|
+
<TopNavItem {...item} />
|
|
54
|
+
</button>
|
|
55
|
+
</li>
|
|
56
|
+
))}
|
|
57
|
+
</ul>
|
|
58
|
+
</div>
|
|
59
|
+
{options.page?.showPoweredBy !== false && (
|
|
60
|
+
<PoweredByZudoku className="flex-grow-0 justify-center gap-1" />
|
|
61
|
+
)}
|
|
53
62
|
</div>
|
|
54
63
|
</DrawerContent>
|
|
55
64
|
</Drawer>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ArrowLeftIcon, ArrowRightIcon } from "lucide-react";
|
|
2
|
+
import { Link } from "react-router";
|
|
3
|
+
import { cn } from "../util/cn.js";
|
|
4
|
+
import { Button } from "./index.js";
|
|
5
|
+
|
|
6
|
+
export const Pagination = ({
|
|
7
|
+
prev,
|
|
8
|
+
next,
|
|
9
|
+
}: {
|
|
10
|
+
prev: { to: string; label: string } | undefined;
|
|
11
|
+
next: { to: string; label: string } | undefined;
|
|
12
|
+
}) => {
|
|
13
|
+
const linkClass =
|
|
14
|
+
"group transition-all p-5 space-x-1 transition-all hover:text-foreground";
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div
|
|
18
|
+
className={cn(
|
|
19
|
+
"flex my-8 -mx-4 text-muted-foreground font-semibold",
|
|
20
|
+
prev ? "justify-between" : "justify-end",
|
|
21
|
+
)}
|
|
22
|
+
>
|
|
23
|
+
{prev && (
|
|
24
|
+
<Button variant="ghost" asChild>
|
|
25
|
+
<Link to={prev.to} relative="path" className={linkClass}>
|
|
26
|
+
<ArrowLeftIcon
|
|
27
|
+
className="group-hover:motion-safe:animate-bounce-x-start"
|
|
28
|
+
size={12}
|
|
29
|
+
/>
|
|
30
|
+
<span className="truncate">{prev.label}</span>
|
|
31
|
+
</Link>
|
|
32
|
+
</Button>
|
|
33
|
+
)}
|
|
34
|
+
{next && (
|
|
35
|
+
<Button variant="ghost" asChild>
|
|
36
|
+
<Link to={next.to} relative="path" className={linkClass}>
|
|
37
|
+
<span className="truncate ">{next.label}</span>
|
|
38
|
+
<ArrowRightIcon
|
|
39
|
+
className="group-hover:motion-safe:animate-bounce-x-end"
|
|
40
|
+
size={12}
|
|
41
|
+
/>
|
|
42
|
+
</Link>
|
|
43
|
+
</Button>
|
|
44
|
+
)}
|
|
45
|
+
</div>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { useNProgress } from "@tanem/react-nprogress";
|
|
1
2
|
import { cx } from "class-variance-authority";
|
|
2
|
-
import { Suspense } from "react";
|
|
3
|
+
import { Suspense, useEffect, useState } from "react";
|
|
3
4
|
import { NavLink, useNavigation } from "react-router";
|
|
4
5
|
import type { TopNavigationItem } from "../../config/validators/common.js";
|
|
5
6
|
import { useAuth } from "../authentication/hook.js";
|
|
@@ -20,6 +21,31 @@ export const isHiddenItem =
|
|
|
20
21
|
);
|
|
21
22
|
};
|
|
22
23
|
|
|
24
|
+
export const PageProgress = () => {
|
|
25
|
+
const navigation = useNavigation();
|
|
26
|
+
const isNavigating = navigation.state === "loading";
|
|
27
|
+
// delay the animation to avoid flickering
|
|
28
|
+
const [isAnimating, setIsAnimating] = useState(false);
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
const timer = setTimeout(() => setIsAnimating(isNavigating), 100);
|
|
32
|
+
|
|
33
|
+
return () => clearTimeout(timer);
|
|
34
|
+
}, [isNavigating]);
|
|
35
|
+
|
|
36
|
+
const { isFinished, progress } = useNProgress({ isAnimating });
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<div
|
|
40
|
+
className="absolute w-0 left-0 right-0 bottom-[-1px] h-[2px] bg-primary transition-all duration-300 ease-in-out"
|
|
41
|
+
style={{
|
|
42
|
+
opacity: isFinished ? 0 : 1,
|
|
43
|
+
width: isFinished ? 0 : `${progress * 100}%`,
|
|
44
|
+
}}
|
|
45
|
+
/>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
|
|
23
49
|
export const TopNavigation = () => {
|
|
24
50
|
const { topNavigation } = useZudoku();
|
|
25
51
|
const { isAuthenticated } = useAuth();
|
|
@@ -32,7 +58,7 @@ export const TopNavigation = () => {
|
|
|
32
58
|
|
|
33
59
|
return (
|
|
34
60
|
<Suspense>
|
|
35
|
-
<div className="items-center justify-between px-8 h-[--top-nav-height] hidden lg:flex text-sm">
|
|
61
|
+
<div className="items-center justify-between px-8 h-[--top-nav-height] hidden lg:flex text-sm relative">
|
|
36
62
|
<nav className="text-sm">
|
|
37
63
|
<ul className="flex flex-row items-center gap-8">
|
|
38
64
|
{filteredItems.map((item) => (
|
|
@@ -44,6 +70,7 @@ export const TopNavigation = () => {
|
|
|
44
70
|
</nav>
|
|
45
71
|
<Slotlet name="top-navigation-side" />
|
|
46
72
|
</div>
|
|
73
|
+
<PageProgress />
|
|
47
74
|
</Suspense>
|
|
48
75
|
);
|
|
49
76
|
};
|
|
@@ -30,6 +30,8 @@ import { ViewportAnchorProvider } from "./context/ViewportAnchorContext.js";
|
|
|
30
30
|
import { ZudokuProvider } from "./context/ZudokuProvider.js";
|
|
31
31
|
import { SlotletProvider } from "./SlotletProvider.js";
|
|
32
32
|
|
|
33
|
+
let zudokuContext: ZudokuContext | undefined;
|
|
34
|
+
|
|
33
35
|
const ZudokoInner = memo(
|
|
34
36
|
({ children, ...props }: PropsWithChildren<ZudokuContextOptions>) => {
|
|
35
37
|
const components = useMemo(
|
|
@@ -70,9 +72,9 @@ const ZudokoInner = memo(
|
|
|
70
72
|
setDidNavigate(true);
|
|
71
73
|
}, [didNavigate, navigation.location]);
|
|
72
74
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
if (!zudokuContext) {
|
|
76
|
+
zudokuContext = new ZudokuContext(props, queryClient);
|
|
77
|
+
}
|
|
76
78
|
|
|
77
79
|
const heads = props.plugins
|
|
78
80
|
?.flatMap((plugin) =>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ChevronRightIcon } from "lucide-react";
|
|
2
|
+
import { cn } from "../../util/cn.js";
|
|
3
|
+
import ZudokuLogo from "./ZudokuLogo.js";
|
|
4
|
+
|
|
5
|
+
export const PoweredByZudoku = ({ className }: { className?: string }) => (
|
|
6
|
+
<a
|
|
7
|
+
href="https://zudoku.dev"
|
|
8
|
+
target="_blank"
|
|
9
|
+
rel="noopener noreferrer"
|
|
10
|
+
className={cn(
|
|
11
|
+
"flex justify-between items-center w-full border border-transparent hover:border-border rounded-full hover:shadow-sm h-7 px-3 text-nowrap hover:bg-muted/80 transition-all",
|
|
12
|
+
className,
|
|
13
|
+
)}
|
|
14
|
+
>
|
|
15
|
+
<div className="opacity-70 hover:opacity-100 transition-opacity gap-1.5 text-[11px] font-medium rounded-full h-7 flex items-center text-nowrap">
|
|
16
|
+
<ZudokuLogo className="w-3.5 h-3.5 dark:fill-white" />
|
|
17
|
+
powered by Zudoku
|
|
18
|
+
</div>
|
|
19
|
+
<div className="text-xs font-medium opacity-70 hover:text-foreground transition-colors cursor-pointer">
|
|
20
|
+
<ChevronRightIcon size={12} absoluteStrokeWidth strokeWidth={1.5} />
|
|
21
|
+
</div>
|
|
22
|
+
</a>
|
|
23
|
+
);
|
|
@@ -3,14 +3,14 @@ import { ExternalLinkIcon } from "lucide-react";
|
|
|
3
3
|
import { NavLink, useLocation, useSearchParams } from "react-router";
|
|
4
4
|
|
|
5
5
|
import type { SidebarItem as SidebarItemType } from "../../../config/validators/SidebarSchema.js";
|
|
6
|
-
import {
|
|
6
|
+
import { joinUrl } from "../../util/joinUrl.js";
|
|
7
7
|
import { AnchorLink } from "../AnchorLink.js";
|
|
8
8
|
import { useViewportAnchor } from "../context/ViewportAnchorContext.js";
|
|
9
9
|
import { SidebarBadge } from "./SidebarBadge.js";
|
|
10
10
|
import { SidebarCategory } from "./SidebarCategory.js";
|
|
11
11
|
|
|
12
12
|
export const navigationListItem = cva(
|
|
13
|
-
"flex items-center gap-2 px-[--padding-nav-item] my-0.5 py-1.5 rounded-lg hover:bg-accent",
|
|
13
|
+
"flex items-center gap-2 px-[--padding-nav-item] my-0.5 py-1.5 rounded-lg hover:bg-accent tabular-nums",
|
|
14
14
|
{
|
|
15
15
|
variants: {
|
|
16
16
|
isActive: {
|
|
@@ -21,6 +21,10 @@ export const navigationListItem = cva(
|
|
|
21
21
|
true: "text-foreground/30",
|
|
22
22
|
false: "",
|
|
23
23
|
},
|
|
24
|
+
isPending: {
|
|
25
|
+
true: "bg-accent animate-pulse",
|
|
26
|
+
false: "",
|
|
27
|
+
},
|
|
24
28
|
},
|
|
25
29
|
defaultVariants: {
|
|
26
30
|
isActive: false,
|
|
@@ -49,8 +53,10 @@ export const SidebarItem = ({
|
|
|
49
53
|
case "doc":
|
|
50
54
|
return (
|
|
51
55
|
<NavLink
|
|
52
|
-
className={({ isActive }) =>
|
|
53
|
-
|
|
56
|
+
className={({ isActive, isPending }) =>
|
|
57
|
+
navigationListItem({ isActive, isPending })
|
|
58
|
+
}
|
|
59
|
+
to={joinUrl(item.id)}
|
|
54
60
|
onClick={onRequestClose}
|
|
55
61
|
end
|
|
56
62
|
>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type PropsWithChildren, type Ref } from "react";
|
|
2
2
|
import { cn } from "../../util/cn.js";
|
|
3
|
+
import { useZudoku } from "../context/ZudokuContext.js";
|
|
4
|
+
import { PoweredByZudoku } from "./PoweredByZudoku.js";
|
|
3
5
|
|
|
4
6
|
export const SidebarWrapper = ({
|
|
5
7
|
children,
|
|
@@ -8,18 +10,30 @@ export const SidebarWrapper = ({
|
|
|
8
10
|
}: PropsWithChildren<{
|
|
9
11
|
className?: string;
|
|
10
12
|
ref?: Ref<HTMLDivElement>;
|
|
11
|
-
}>) =>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
)
|
|
13
|
+
}>) => {
|
|
14
|
+
const { options } = useZudoku();
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div className="grid sticky top-[--header-height] lg:h-[calc(100vh-var(--header-height))] grid-rows-[1fr_min-content] border-r">
|
|
18
|
+
<nav
|
|
19
|
+
className={cn(
|
|
20
|
+
"hidden max-w-[calc(var(--side-nav-width)+var(--padding-nav-item))] lg:flex scrollbar flex-col overflow-y-auto shrink-0 text-sm pe-3 ps-4 lg:ps-8",
|
|
21
|
+
"-mx-[--padding-nav-item] pb-6 pt-[--padding-content-top] scroll-pt-2 gap-1",
|
|
22
|
+
className,
|
|
23
|
+
)}
|
|
24
|
+
style={{
|
|
25
|
+
maskImage: `linear-gradient(180deg, transparent 1%, rgba(0, 0, 0, 1) 20px, rgba(0, 0, 0, 1) 90%, transparent 99%)`,
|
|
26
|
+
}}
|
|
27
|
+
ref={ref}
|
|
28
|
+
>
|
|
29
|
+
{children}
|
|
30
|
+
</nav>
|
|
31
|
+
|
|
32
|
+
<div className="bg-background border-t p-2 mx-5 gap-2 items-center mt-2 drop-shadow-[0_-3px_1px_rgba(0,0,0,0.015)] hidden lg:[&:has(>_:nth-child(1):last-child)]:flex">
|
|
33
|
+
{options.page?.showPoweredBy !== false && <PoweredByZudoku />}
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
24
38
|
|
|
25
39
|
SidebarWrapper.displayName = "SidebarWrapper";
|
|
@@ -7,9 +7,9 @@ import {
|
|
|
7
7
|
type CSSProperties,
|
|
8
8
|
type PropsWithChildren,
|
|
9
9
|
} from "react";
|
|
10
|
-
import { AnchorLink } from "../../components/AnchorLink.js";
|
|
11
|
-
import { useViewportAnchor } from "../../components/context/ViewportAnchorContext.js";
|
|
12
10
|
import { cn } from "../../util/cn.js";
|
|
11
|
+
import { AnchorLink } from "../AnchorLink.js";
|
|
12
|
+
import { useViewportAnchor } from "../context/ViewportAnchorContext.js";
|
|
13
13
|
|
|
14
14
|
const DATA_ANCHOR_ATTR = "data-active";
|
|
15
15
|
|
|
@@ -24,23 +24,14 @@ const TocItem = ({
|
|
|
24
24
|
className?: string;
|
|
25
25
|
}>) => {
|
|
26
26
|
return (
|
|
27
|
-
<li
|
|
28
|
-
className={cn(
|
|
29
|
-
"truncate",
|
|
30
|
-
isActive
|
|
31
|
-
? "text-primary"
|
|
32
|
-
: "text-foreground/65 dark:text-foreground/75",
|
|
33
|
-
className,
|
|
34
|
-
)}
|
|
35
|
-
title={item.value}
|
|
36
|
-
>
|
|
27
|
+
<li className={cn("truncate", className)} title={item.value}>
|
|
37
28
|
<AnchorLink
|
|
38
29
|
to={`#${item.id}`}
|
|
39
30
|
{...{ [DATA_ANCHOR_ATTR]: item.id }}
|
|
40
31
|
className={cn(
|
|
41
32
|
isActive
|
|
42
33
|
? "text-primary"
|
|
43
|
-
: "
|
|
34
|
+
: "hover:text-accent-foreground text-muted-foreground",
|
|
44
35
|
)}
|
|
45
36
|
>
|
|
46
37
|
{item.value}
|
|
@@ -89,7 +80,7 @@ export const Toc = ({ entries }: { entries: TocEntry[] }) => {
|
|
|
89
80
|
}, [activeAnchor]);
|
|
90
81
|
|
|
91
82
|
return (
|
|
92
|
-
<aside className="sticky scrollbar top-[--header-height] h-[calc(100vh-var(--header-height))] pt-[--padding-content-top] pb-[--padding-content-bottom] overflow-y-auto ps-1 text-sm">
|
|
83
|
+
<aside className="sticky scrollbar top-8 lg:top-[--header-height] h-[calc(100vh-var(--header-height))] pt-[--padding-content-top] pb-[--padding-content-bottom] overflow-y-auto ps-1 text-sm">
|
|
93
84
|
<div className="flex items-center gap-2 font-medium mb-2">
|
|
94
85
|
<ListTreeIcon size={16} />
|
|
95
86
|
On this page
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
const ZudokuLogo = (props: React.SVGProps<SVGSVGElement>) => (
|
|
4
|
+
<svg
|
|
5
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
6
|
+
viewBox="0 0 132 100"
|
|
7
|
+
fill="none"
|
|
8
|
+
{...props}
|
|
9
|
+
>
|
|
10
|
+
<path
|
|
11
|
+
fill="currentColor"
|
|
12
|
+
fillRule="evenodd"
|
|
13
|
+
d="M80.092 2.963A4.66 4.66 0 0 1 84.449 0h34.049c6.325 0 10.835 6.135 8.948 12.172L116.653 46.71a4.688 4.688 0 0 1-4.474 3.29H75c-5.178 0-7.813 4.687-9.375 9.374-1.288 3.864-11.07 28.963-14.467 37.662A4.66 4.66 0 0 1 46.801 100H12.75c-6.324 0-10.834-6.134-8.947-12.171l10.793-34.54A4.688 4.688 0 0 1 19.071 50H56.25c5.178 0 7.813-4.687 9.375-9.375 1.288-3.864 11.07-28.962 14.467-37.662Z"
|
|
14
|
+
clipRule="evenodd"
|
|
15
|
+
/>
|
|
16
|
+
<path
|
|
17
|
+
fill="currentColor"
|
|
18
|
+
d="M83.54 57.813a7.813 7.813 0 0 0-7.316 5.07L63.888 95.777c-.766 2.043.744 4.222 2.926 4.222h36.828c5.211 0 9.875-3.232 11.704-8.11l8.821-23.522c1.915-5.107-1.861-10.555-7.315-10.555H83.539ZM29.17 0a12.5 12.5 0 0 0-11.704 8.111l-8.82 23.521c-1.915 5.107 1.86 10.556 7.315 10.556h33.312a7.813 7.813 0 0 0 7.316-5.07L68.924 4.223C69.691 2.18 68.18 0 65.998 0H29.17Z"
|
|
19
|
+
/>
|
|
20
|
+
</svg>
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
ZudokuLogo.displayName = "ZudokuLogo";
|
|
24
|
+
|
|
25
|
+
export default ZudokuLogo;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { useQuery } from "@tanstack/react-query";
|
|
2
|
+
import { Helmet } from "@zudoku/react-helmet-async";
|
|
3
|
+
import { use } from "react";
|
|
2
4
|
import { matchPath, Outlet, useLocation, useNavigate } from "react-router";
|
|
3
5
|
import {
|
|
4
6
|
Dialog,
|
|
@@ -8,21 +10,28 @@ import {
|
|
|
8
10
|
DialogTitle,
|
|
9
11
|
} from "zudoku/ui/Dialog.js";
|
|
10
12
|
import { useAuth } from "../authentication/hook.js";
|
|
13
|
+
import { BypassProtectedRoutesContext } from "../components/context/BypassProtectedRoutesContext.js";
|
|
11
14
|
import { useZudoku } from "../components/context/ZudokuContext.js";
|
|
12
15
|
import { ZudokuError } from "../util/invariant.js";
|
|
13
16
|
import { useLatest } from "../util/useLatest.js";
|
|
14
17
|
|
|
18
|
+
export const SEARCH_PROTECTED_SECTION = "protected";
|
|
19
|
+
|
|
15
20
|
export const RouteGuard = () => {
|
|
16
21
|
const auth = useAuth();
|
|
17
22
|
const zudoku = useZudoku();
|
|
18
23
|
const navigate = useNavigate();
|
|
19
24
|
const location = useLocation();
|
|
20
25
|
const latestPath = useLatest(location.pathname);
|
|
26
|
+
const shouldBypass = use(BypassProtectedRoutesContext);
|
|
27
|
+
|
|
21
28
|
const { protectedRoutes = [] } = zudoku.options;
|
|
22
29
|
|
|
23
|
-
const isProtected =
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
const isProtected =
|
|
31
|
+
!shouldBypass &&
|
|
32
|
+
protectedRoutes.some((path) =>
|
|
33
|
+
matchPath({ path, end: true }, location.pathname),
|
|
34
|
+
);
|
|
26
35
|
|
|
27
36
|
useQuery({
|
|
28
37
|
queryKey: ["login-redirect"],
|
|
@@ -70,5 +79,18 @@ export const RouteGuard = () => {
|
|
|
70
79
|
});
|
|
71
80
|
}
|
|
72
81
|
|
|
73
|
-
return
|
|
82
|
+
return (
|
|
83
|
+
<>
|
|
84
|
+
{shouldBypass && (
|
|
85
|
+
<Helmet>
|
|
86
|
+
<meta
|
|
87
|
+
name="pagefind"
|
|
88
|
+
data-pagefind-filter={`section:${SEARCH_PROTECTED_SECTION}`}
|
|
89
|
+
content="true"
|
|
90
|
+
/>
|
|
91
|
+
</Helmet>
|
|
92
|
+
)}
|
|
93
|
+
<Outlet />
|
|
94
|
+
</>
|
|
95
|
+
);
|
|
74
96
|
};
|