hydrate mobile popover menu
This commit is contained in:
21
packages/docs-new/src/components/main-navigation.client.tsx
Normal file
21
packages/docs-new/src/components/main-navigation.client.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import { createRoot } from "react-dom"
|
||||||
|
import { mainLinks } from "../data/main-links"
|
||||||
|
import { AppLink } from "./app-link"
|
||||||
|
import type { MainNavigationClientData } from "./main-navigation"
|
||||||
|
import { PopoverMenu } from "./popover-menu"
|
||||||
|
|
||||||
|
const dataScript = document.querySelector("#main-navigation-popover-data")!
|
||||||
|
const data: MainNavigationClientData = JSON.parse(dataScript.innerHTML)
|
||||||
|
|
||||||
|
createRoot(document.querySelector("#main-navigation-popover")!).render(
|
||||||
|
<PopoverMenu>
|
||||||
|
{mainLinks.map((link) => (
|
||||||
|
<AppLink {...link} key={link.to} className={PopoverMenu.itemClass} />
|
||||||
|
))}
|
||||||
|
<hr className="border-0 h-[2px] bg-black/50" />
|
||||||
|
{data.guideLinks.map((link) => (
|
||||||
|
<AppLink {...link} key={link.to} className={PopoverMenu.itemClass} />
|
||||||
|
))}
|
||||||
|
</PopoverMenu>,
|
||||||
|
)
|
||||||
@@ -1,9 +1,38 @@
|
|||||||
|
import { build } from "esbuild"
|
||||||
|
import { readFile } from "node:fs/promises"
|
||||||
|
import { dirname } from "node:path"
|
||||||
import React from "react"
|
import React from "react"
|
||||||
import { guideLinks } from "../data/guide-links"
|
import { guideLinks } from "../data/guide-links"
|
||||||
import { mainLinks } from "../data/main-links"
|
import { mainLinks } from "../data/main-links"
|
||||||
import { linkClass } from "../styles/components"
|
import { linkClass } from "../styles/components"
|
||||||
|
import type { AppLinkProps } from "./app-link"
|
||||||
import { AppLink } from "./app-link"
|
import { AppLink } from "./app-link"
|
||||||
import { PopoverMenu } from "./popover-menu"
|
import { PopoverMenu } from "./popover-menu"
|
||||||
|
import { Script } from "./script"
|
||||||
|
|
||||||
|
const clientSourcePath = new URL(
|
||||||
|
"./main-navigation.client.tsx",
|
||||||
|
import.meta.url,
|
||||||
|
).pathname
|
||||||
|
|
||||||
|
const clientOutput = await build({
|
||||||
|
bundle: true,
|
||||||
|
stdin: {
|
||||||
|
contents: await readFile(clientSourcePath, "utf-8"),
|
||||||
|
sourcefile: clientSourcePath,
|
||||||
|
loader: "tsx",
|
||||||
|
resolveDir: dirname(clientSourcePath),
|
||||||
|
},
|
||||||
|
target: ["chrome89", "firefox89"],
|
||||||
|
format: "esm",
|
||||||
|
write: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
export type MainNavigationClientData = {
|
||||||
|
guideLinks: AppLinkProps[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const data: MainNavigationClientData = { guideLinks }
|
||||||
|
|
||||||
export function MainNavigation() {
|
export function MainNavigation() {
|
||||||
return (
|
return (
|
||||||
@@ -16,7 +45,7 @@ export function MainNavigation() {
|
|||||||
<AppLink {...link} key={link.to} className={linkClass} />
|
<AppLink {...link} key={link.to} className={linkClass} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="md:hidden">
|
<div className="md:hidden" id="main-navigation-popover">
|
||||||
<PopoverMenu>
|
<PopoverMenu>
|
||||||
{mainLinks.map((link) => (
|
{mainLinks.map((link) => (
|
||||||
<AppLink
|
<AppLink
|
||||||
@@ -26,7 +55,7 @@ export function MainNavigation() {
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<hr className="border-0 h-[2px] bg-black/50" />
|
<hr className="border-0 h-[2px] bg-black/50" />
|
||||||
{guideLinks.map((link) => (
|
{data.guideLinks.map((link) => (
|
||||||
<AppLink
|
<AppLink
|
||||||
{...link}
|
{...link}
|
||||||
key={link.to}
|
key={link.to}
|
||||||
@@ -35,6 +64,10 @@ export function MainNavigation() {
|
|||||||
))}
|
))}
|
||||||
</PopoverMenu>
|
</PopoverMenu>
|
||||||
</div>
|
</div>
|
||||||
|
<Script id="main-navigation-popover-data" type="application/json">
|
||||||
|
{JSON.stringify(data)}
|
||||||
|
</Script>
|
||||||
|
<Script>{clientOutput.outputFiles[0]?.text!}</Script>
|
||||||
</nav>
|
</nav>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
16
packages/docs-new/src/components/script.tsx
Normal file
16
packages/docs-new/src/components/script.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import type { ComponentPropsWithoutRef } from "react"
|
||||||
|
import React from "react"
|
||||||
|
import type { Merge } from "type-fest"
|
||||||
|
|
||||||
|
export function Script({
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: Merge<ComponentPropsWithoutRef<"script">, { children: string }>) {
|
||||||
|
return (
|
||||||
|
<script
|
||||||
|
type="module"
|
||||||
|
dangerouslySetInnerHTML={{ __html: children }}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
10
packages/docs-new/src/react.d.ts
vendored
Normal file
10
packages/docs-new/src/react.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import "react"
|
||||||
|
declare module "react" {
|
||||||
|
export function createContext<Value>(): Context<Value | undefined>
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "react-dom" {
|
||||||
|
export function createRoot(element: Element): {
|
||||||
|
render(element: React.ReactNode): void
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user