Skip to content

Commit 3f04fae

Browse files
committed
Stop relying on Nextra's MenuProvider
1 parent b4f1a6d commit 3f04fae

File tree

12 files changed

+93
-48
lines changed

12 files changed

+93
-48
lines changed

patches/nextra-theme-docs.patch

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ index 71f87bcd1dde49d7c19ad49fc098e715a76c5c10..a0b8143b6b7ef89513c2199b956f5f87
3636
+ flatDocsDirectories: Item[]
3737
+}
3838
diff --git a/dist/index.js b/dist/index.js
39-
index 56201641fd965dcc5ab7c5df53e444c41293c00e..71f4d353b5bd6c0fcab630330f578b5593f8596e 100644
39+
index 56201641fd965dcc5ab7c5df53e444c41293c00e..cb6682bf947351f5757f51b43ff85237f16f1096 100644
4040
--- a/dist/index.js
4141
+++ b/dist/index.js
4242
@@ -100,10 +100,10 @@ IntersectionObserverContext.displayName = "IntersectionObserver";
@@ -125,3 +125,12 @@ index 56201641fd965dcc5ab7c5df53e444c41293c00e..71f4d353b5bd6c0fcab630330f578b55
125125
body
126126
] })
127127
}
128+
@@ -2524,7 +2485,7 @@ function getComponents({
129+
components
130+
}) {
131+
if (isRawLayout) {
132+
- return { a: A, wrapper: DEFAULT_COMPONENTS.wrapper };
133+
+ return { a: A, wrapper: components.wrapper };
134+
}
135+
const context = { index: 0 };
136+
return __spreadValues(__spreadProps(__spreadValues({}, DEFAULT_COMPONENTS), {

patches/nextra.patch

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,22 @@ index 9d05118d3d10e746cd2c020785a0f34465bb8570..218107600d7efed1b5f9d49f0a696b16
2020
Playground,
2121
Popup,
2222
Pre,
23+
diff --git a/dist/client/hooks/use-fs-route.js b/dist/client/hooks/use-fs-route.js
24+
index 7948959d9c044d66e241864789454e0ea637c659..46e352a845c3776965f3f1957e5d93b946444a3a 100644
25+
--- a/dist/client/hooks/use-fs-route.js
26+
+++ b/dist/client/hooks/use-fs-route.js
27+
@@ -1,9 +1,9 @@
28+
-import { useRouter } from "next/router";
29+
+import { useRouter } from "next/compat/router";
30+
import { useMemo } from "react";
31+
import { DEFAULT_LOCALE, ERROR_ROUTES } from "../../constants.js";
32+
const template = "https://nextra.site";
33+
const useFSRoute = () => {
34+
- const { locale = DEFAULT_LOCALE, asPath, route } = useRouter();
35+
+ const { locale = DEFAULT_LOCALE, asPath, route } = useRouter() || {};
36+
return useMemo(() => {
37+
const clientRoute = ERROR_ROUTES.has(route) ? route : asPath;
38+
const { pathname } = new URL(clientRoute, template);
2339
diff --git a/dist/client/normalize-pages.js b/dist/client/normalize-pages.js
2440
index 15afee0c1de26f47d781f423e5ec32e33ad925d3..fefd01736bd2b778df275bf50ac48384d5f63845 100644
2541
--- a/dist/client/normalize-pages.js

pnpm-lock.yaml

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/(main)/layout.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ import { ThemeProvider } from "next-themes"
44
import { Footer } from "../../components/footer"
55
import { NewFontsStyleTag } from "../fonts"
66
import { Navbar } from "../../components/navbar/navbar"
7-
import { topLevelNavbarItems } from "../../components/navbar/top-level-items"
8-
import { MenuProvider } from "./menu-provider"
7+
import {
8+
directories,
9+
docsDirectories,
10+
topLevelNavbarItems,
11+
} from "../../components/navbar/top-level-items"
12+
import { Sidebar } from "../../components/sidebar"
913

1014
export default function MainLayout({
1115
children,
@@ -16,13 +20,17 @@ export default function MainLayout({
1620
<>
1721
<NewFontsStyleTag />
1822
<ThemeProvider attribute="class">
19-
<MenuProvider>
2023
<Navbar items={topLevelNavbarItems} />
24+
<Sidebar
25+
includePlaceholder={false}
26+
toc={[]}
27+
docsDirectories={docsDirectories}
28+
fullDirectories={directories}
29+
/>
2130
<div className="isolate bg-neu-0 text-neu-900 antialiased">
2231
{children}
2332
</div>
2433
<Footer />
25-
</MenuProvider>
2634
</ThemeProvider>
2735
</>
2836
)

src/app/(main)/menu-provider.tsx

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/components/navbar/navbar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import NextLink from "next/link"
88
import { Button } from "nextra/components"
99
import type * as normalizePages from "nextra/normalize-pages"
1010
import React, { useEffect, type ReactElement, type ReactNode } from "react"
11-
import { useMenu } from "nextra-theme-docs"
1211
import { Anchor } from "@/app/conf/_design-system/anchor"
1312

1413
import MenuIcon from "@/app/conf/_design-system/pixelarticons/menu.svg?svgr"
@@ -17,6 +16,7 @@ import { GraphQLWordmarkLogo } from "../../icons"
1716
import { ThemeSwitch } from "../theme-switch"
1817
import { Flexsearch } from "../flexsearch"
1918
import { NavLink, navLinkClasses } from "./nav-link"
19+
import { useMenu } from "../use-menu"
2020

2121
type Item = normalizePages.PageItem | normalizePages.MenuItem
2222
export interface NavBarProps {

src/components/navbar/top-level-items.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,4 @@ export function normalizeMetaToItems(meta: Record<string, any>, parent = "/") {
4747
return result
4848
}
4949

50-
export const { topLevelNavbarItems } = normalizeMetaToItems(meta)
50+
export const { topLevelNavbarItems, docsDirectories, directories } = normalizeMetaToItems(meta)

src/components/nextra-mdx-wrapper.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export function NextraMdxWrapper({
4949
<TableOfContents toc={toc} filePath={config.filePath} />
5050
</nav>
5151
)
52+
5253
return (
5354
<div
5455
className={clsx(

src/components/sidebar.tsx renamed to src/components/sidebar/index.tsx

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,15 @@ import {
2222
useState,
2323
} from "react"
2424
import scrollIntoView from "scroll-into-view-if-needed"
25-
import {
26-
useActiveAnchor,
27-
useMenu,
28-
useThemeConfig,
29-
Collapse,
30-
LocaleSwitch,
31-
} from "nextra-theme-docs"
25+
import { useActiveAnchor, useThemeConfig, Collapse } from "nextra-theme-docs"
3226

3327
import ArrowBarLeft from "@/app/conf/_design-system/pixelarticons/arrow-bar-left.svg?svgr"
3428
import { Anchor } from "@/app/conf/_design-system/anchor"
3529

36-
import { renderComponent } from "./utils/render-component"
37-
import { ThemeSwitch } from "./theme-switch"
38-
import { Flexsearch } from "./flexsearch"
30+
import { renderComponent } from "../utils/render-component"
31+
import { ThemeSwitch } from "../theme-switch"
32+
import { Flexsearch } from "../flexsearch"
33+
import { useMenu } from "../use-menu"
3934

4035
const TreeState: Record<string, boolean> = Object.create(null)
4136

@@ -229,7 +224,7 @@ function Separator({ title }: { title: string }): ReactElement {
229224
className={cn(
230225
"[word-break:break-word]",
231226
title
232-
? "typography-body-sm mb-2 px-2 py-1.5 font-semibold text-neu-800 [&:not(:first-child)]:mt-5"
227+
? "typography-body-sm mb-2 px-2 py-1.5 font-semibold text-neu-800 max-md:first:hidden [&:not(:first-child)]:mt-5"
233228
: "my-4",
234229
)}
235230
>
@@ -370,7 +365,6 @@ export function Sidebar({
370365
const { menu, setMenu } = useMenu()
371366
const [focused, setFocused] = useState("")
372367
const [showSidebar, setSidebar] = useState(true)
373-
const [showToggleAnimation, setToggleAnimation] = useState(false)
374368

375369
const anchors = useMemo(() => toc.filter(v => v.depth === 2), [toc])
376370
const sidebarRef = useRef<HTMLDivElement>(null!)
@@ -480,7 +474,6 @@ export function Sidebar({
480474
<SidebarFooter
481475
showSidebar={showSidebar}
482476
setSidebar={setSidebar}
483-
showToggleAnimation={showToggleAnimation}
484477
hasI18n={hasI18n}
485478
/>
486479
)}
@@ -492,17 +485,13 @@ export function Sidebar({
492485
export function SidebarFooter({
493486
showSidebar,
494487
setSidebar,
495-
showToggleAnimation = false,
496488
hasI18n = false,
497-
setToggleAnimation,
498489
className,
499490
hiddenOnMobile = true,
500491
}: {
501492
showSidebar: boolean
502493
setSidebar: (show: boolean) => void
503-
showToggleAnimation?: boolean
504494
hasI18n?: boolean
505-
setToggleAnimation?: (show: boolean) => void
506495
className?: string
507496
hiddenOnMobile?: boolean
508497
}) {
@@ -519,14 +508,7 @@ export function SidebarFooter({
519508
: "flex-col flex-wrap justify-center py-4",
520509
className,
521510
)}
522-
data-toggle-animation={
523-
showToggleAnimation ? (showSidebar ? "show" : "hide") : "off"
524-
}
525511
>
526-
<LocaleSwitch
527-
lite={!showSidebar}
528-
className={showSidebar ? "_grow" : "max-md:_grow"}
529-
/>
530512
<div className={showSidebar && !hasI18n ? "_grow _flex _flex-col" : ""}>
531513
<ThemeSwitch lite={!showSidebar} />
532514
</div>
@@ -539,7 +521,6 @@ export function SidebarFooter({
539521
)}
540522
onClick={() => {
541523
setSidebar(!showSidebar)
542-
setToggleAnimation?.(true)
543524
}}
544525
>
545526
<ArrowBarLeft

src/components/use-menu.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { useSyncExternalStore } from "react"
2+
3+
const createStore = () => {
4+
let state = false
5+
const listeners = new Set<() => void>()
6+
return {
7+
get: () => state,
8+
sub: (l: () => void) => (listeners.add(l), () => listeners.delete(l)),
9+
set: (action: boolean | ((prev: boolean) => boolean)) => {
10+
const val = typeof action === "function" ? action(state) : action
11+
if (val !== state) {
12+
state = val
13+
listeners.forEach(l => l())
14+
}
15+
},
16+
}
17+
}
18+
19+
const store = createStore()
20+
21+
export const useMenu = () => ({
22+
menu: useSyncExternalStore(store.sub, store.get, store.get),
23+
setMenu: store.set,
24+
})

0 commit comments

Comments
 (0)