hydrate mobile popover menu

This commit is contained in:
MapleLeaf
2022-01-03 03:11:00 -06:00
committed by Darius
parent 04e6a15b55
commit f9ab9ba7f5
4 changed files with 82 additions and 2 deletions

View 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>,
)

View File

@@ -1,9 +1,38 @@
import { build } from "esbuild"
import { readFile } from "node:fs/promises"
import { dirname } from "node:path"
import React from "react"
import { guideLinks } from "../data/guide-links"
import { mainLinks } from "../data/main-links"
import { linkClass } from "../styles/components"
import type { AppLinkProps } from "./app-link"
import { AppLink } from "./app-link"
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() {
return (
@@ -16,7 +45,7 @@ export function MainNavigation() {
<AppLink {...link} key={link.to} className={linkClass} />
))}
</div>
<div className="md:hidden">
<div className="md:hidden" id="main-navigation-popover">
<PopoverMenu>
{mainLinks.map((link) => (
<AppLink
@@ -26,7 +55,7 @@ export function MainNavigation() {
/>
))}
<hr className="border-0 h-[2px] bg-black/50" />
{guideLinks.map((link) => (
{data.guideLinks.map((link) => (
<AppLink
{...link}
key={link.to}
@@ -35,6 +64,10 @@ export function MainNavigation() {
))}
</PopoverMenu>
</div>
<Script id="main-navigation-popover-data" type="application/json">
{JSON.stringify(data)}
</Script>
<Script>{clientOutput.outputFiles[0]?.text!}</Script>
</nav>
)
}

View 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
View 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
}
}