new main nav menu, remove alpine

This commit is contained in:
MapleLeaf
2022-01-13 11:16:09 -06:00
parent 2765b4fda4
commit e06bfa490f
8 changed files with 156 additions and 58 deletions

View File

@@ -0,0 +1,59 @@
import { Menu, Transition } from "@headlessui/react"
import { MenuAlt4Icon } from "@heroicons/react/outline"
import clsx from "clsx"
import { useGuideLinksContext } from "~/modules/navigation/guide-links-context"
import { Popper } from "~/modules/ui/popper"
import { AppLink } from "./app-link"
import { mainLinks } from "./main-links"
export function MainNavigationMenu() {
const guideLinks = useGuideLinksContext()
return (
<Menu>
<Popper
renderReference={(reference) => (
<Menu.Button {...reference}>
<MenuAlt4Icon className="w-6" />
<span className="sr-only">Menu</span>
</Menu.Button>
)}
renderPopover={() => (
<Transition
enter="transition"
enterFrom="translate-y-4 opacity-0"
enterTo="translate-y-0 opacity-100"
leave="transition"
leaveFrom="translate-y-0 opacity-100"
leaveTo="translate-y-4 opacity-0"
>
<Menu.Items className="w-48 max-h-[calc(100vh-5rem)] bg-slate-800 shadow rounded-lg overflow-hidden overflow-y-auto focus:outline-none">
{mainLinks.map((link) => (
<Menu.Item key={link.to}>
{({ active }) => (
<AppLink {...link} className={menuItemClass({ active })} />
)}
</Menu.Item>
))}
<Menu.Item disabled>
<hr className="border-0 h-[2px] bg-black/50" />
</Menu.Item>
{guideLinks.map(({ link }) => (
<Menu.Item key={link.to}>
{({ active }) => (
<AppLink {...link} className={menuItemClass({ active })} />
)}
</Menu.Item>
))}
</Menu.Items>
</Transition>
)}
/>
</Menu>
)
}
const menuItemClass = ({ active = false }) =>
clsx(
clsx`px-3 py-2 transition text-left font-medium block opacity-50`,
active && clsx`opacity-100 bg-black/75 text-emerald-400`,
)

View File

@@ -1,12 +1,10 @@
import { AppLogo } from "~/modules/app/app-logo"
import { useGuideLinksContext } from "~/modules/navigation/guide-links-context"
import { linkClass } from "../ui/components"
import { PopoverMenu } from "../ui/popover-menu"
import { AppLink } from "./app-link"
import { mainLinks } from "./main-links"
import { MainNavigationMenu } from "./main-navigation-menu"
export function MainNavigation() {
const guideLinks = useGuideLinksContext()
return (
<nav className="flex justify-between items-center h-16">
<a href="/">
@@ -18,25 +16,7 @@ export function MainNavigation() {
))}
</div>
<div className="md:hidden">
<PopoverMenu>
{mainLinks.map((link) => (
<AppLink
{...link}
role="menuitem"
key={link.to}
className={PopoverMenu.itemClass}
/>
))}
<hr className="border-0 h-[2px] bg-black/50" />
{guideLinks.map(({ link }) => (
<AppLink
{...link}
role="menuitem"
key={link.to}
className={PopoverMenu.itemClass}
/>
))}
</PopoverMenu>
<MainNavigationMenu />
</div>
</nav>
)

View File

@@ -1,32 +0,0 @@
import { MenuAlt4Icon } from "@heroicons/react/outline"
import clsx from "clsx"
import React from "react"
import { linkClass } from "./components"
export function PopoverMenu({ children }: { children: React.ReactNode }) {
return (
<div className="relative" x-data="{ open: false }">
<button title="Menu" className={linkClass} x-on:click="open = !open">
<MenuAlt4Icon className="w-6" />
</button>
<div
role="menu"
className={`
w-48 max-h-[calc(100vh-4rem)]
absolute right-0 top-[calc(100%+8px)]
bg-slate-800 shadow rounded-lg
overflow-hidden overflow-y-auto
transition-all
`}
x-bind:class="open ? 'visible opacity-100' : 'invisible opacity-0 translate-y-3'"
>
{children}
</div>
</div>
)
}
PopoverMenu.itemClass = clsx`
px-3 py-2 transition text-left font-medium block
opacity-50 hover:opacity-100 hover:bg-black/30
`

View File

@@ -0,0 +1,41 @@
import { useRect } from "@reach/rect"
import * as React from "react"
import { Portal } from "~/modules/dom/portal"
export function Popper({
renderReference,
renderPopover,
}: {
renderReference: (referenceProps: {
ref: (element: HTMLElement | null | undefined) => void
}) => React.ReactNode
renderPopover: () => React.ReactNode
}) {
const [reference, referenceRef] = React.useState<HTMLElement | null>()
const referenceRect = useRect(useValueAsRefObject(reference))
return (
<>
{renderReference({ ref: referenceRef })}
<Portal>
{referenceRect && (
<div
className="fixed -translate-x-full"
style={{
left: referenceRect.right,
top: referenceRect.bottom + 16,
}}
>
{renderPopover()}
</div>
)}
</Portal>
</>
)
}
function useValueAsRefObject<Value>(value: Value): { readonly current: Value } {
const ref = React.useRef<Value>(value)
ref.current = value
return ref
}

View File

@@ -73,11 +73,9 @@ export default function App() {
<meta name="viewport" content="width=device-width,initial-scale=1" />
<Meta />
<Links />
<script defer src="https://unpkg.com/alpinejs@3.7.1/dist/cdn.min.js" />
{process.env.NODE_ENV === "production" && (
<script
async
defer
data-website-id="49c69ade-5593-4853-9686-c9ca9d519a18"
src="https://maple-umami.fly.dev/umami.js"
/>

View File

@@ -12,7 +12,7 @@ import {
export default function GuidePage() {
const guideLinks = useGuideLinksContext()
return (
<>
<div className="isolate">
<header className="bg-slate-700/30 shadow sticky top-0 backdrop-blur-sm transition z-10 flex">
<div className={maxWidthContainer}>
<MainNavigation />
@@ -33,6 +33,6 @@ export default function GuidePage() {
<Outlet />
</section>
</main>
</>
</div>
)
}