active nav link style
This commit is contained in:
@@ -11,13 +11,13 @@ export function AppFooter() {
|
||||
</address>
|
||||
<p>
|
||||
Coded with <HeartIcon className="inline w-4 align-sub" /> using{" "}
|
||||
<ExternalLink className={linkClass} href="https://remix.run">
|
||||
<ExternalLink className={linkClass()} href="https://remix.run">
|
||||
Remix
|
||||
</ExternalLink>
|
||||
</p>
|
||||
<p>
|
||||
Uses{" "}
|
||||
<ExternalLink className={linkClass} href="https://umami.is/">
|
||||
<ExternalLink className={linkClass()} href="https://umami.is/">
|
||||
umami
|
||||
</ExternalLink>{" "}
|
||||
for simple, non-identifying analytics.
|
||||
|
||||
14
packages/website/app/modules/navigation/active-link.tsx
Normal file
14
packages/website/app/modules/navigation/active-link.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import type { ReactNode } from "react"
|
||||
import type { PathPattern } from "react-router"
|
||||
import { useMatch } from "react-router"
|
||||
|
||||
export function ActiveLink({
|
||||
to,
|
||||
children,
|
||||
}: {
|
||||
to: string | PathPattern
|
||||
children: (props: { active: boolean }) => ReactNode
|
||||
}) {
|
||||
const match = useMatch(to)
|
||||
return <>{children({ active: match != undefined })}</>
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Menu, Transition } from "@headlessui/react"
|
||||
import { MenuAlt4Icon } from "@heroicons/react/outline"
|
||||
import clsx from "clsx"
|
||||
import { ActiveLink } from "~/modules/navigation/active-link"
|
||||
import { useGuideLinksContext } from "~/modules/navigation/guide-links-context"
|
||||
import { Popper } from "~/modules/ui/popper"
|
||||
import { AppLink } from "./app-link"
|
||||
@@ -39,8 +40,17 @@ export function MainNavigationMenu() {
|
||||
</Menu.Item>
|
||||
{guideLinks.map(({ link }) => (
|
||||
<Menu.Item key={link.to}>
|
||||
{({ active }) => (
|
||||
<AppLink {...link} className={menuItemClass({ active })} />
|
||||
{(menuItem) => (
|
||||
<ActiveLink to={link.to}>
|
||||
{(activeLink) => (
|
||||
<AppLink
|
||||
{...link}
|
||||
className={menuItemClass({
|
||||
active: activeLink.active || menuItem.active,
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
</ActiveLink>
|
||||
)}
|
||||
</Menu.Item>
|
||||
))}
|
||||
|
||||
@@ -12,7 +12,7 @@ export function MainNavigation() {
|
||||
</a>
|
||||
<div className="hidden md:flex gap-4">
|
||||
{mainLinks.map((link) => (
|
||||
<AppLink {...link} key={link.to} className={linkClass} />
|
||||
<AppLink {...link} key={link.to} className={linkClass()} />
|
||||
))}
|
||||
</div>
|
||||
<div className="md:hidden">
|
||||
|
||||
@@ -4,12 +4,16 @@ export const maxWidthContainer = clsx`mx-auto w-full max-w-screen-lg px-4`
|
||||
|
||||
export const inlineIconClass = clsx`inline w-5 align-sub`
|
||||
|
||||
export const linkClass = clsx`
|
||||
font-medium inline-block relative
|
||||
opacity-60 hover:opacity-100 transition-opacity
|
||||
after:absolute after:block after:w-full after:h-px after:bg-white/50 after:translate-y-[3px] after:opacity-0 after:transition
|
||||
hover:after:translate-y-[-1px] hover:after:opacity-100
|
||||
`
|
||||
export const linkClass = ({ active = false } = {}) =>
|
||||
clsx(
|
||||
clsx`font-medium inline-block relative`,
|
||||
clsx`opacity-60 hover:opacity-100 transition-opacity`,
|
||||
clsx`after:absolute after:block after:w-full after:h-px after:bg-white/50 after:translate-y-[3px] after:opacity-0 after:transition`,
|
||||
clsx`hover:after:translate-y-[-1px] hover:after:opacity-100`,
|
||||
active
|
||||
? clsx`text-emerald-500 after:bg-emerald-500`
|
||||
: clsx`after:bg-white/50`,
|
||||
)
|
||||
|
||||
export const docsProseClass = clsx`
|
||||
prose prose-invert
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import clsx from "clsx"
|
||||
import { Outlet } from "remix"
|
||||
import { ActiveLink } from "~/modules/navigation/active-link"
|
||||
import { AppLink } from "~/modules/navigation/app-link"
|
||||
import { useGuideLinksContext } from "~/modules/navigation/guide-links-context"
|
||||
import { MainNavigation } from "~/modules/navigation/main-navigation"
|
||||
@@ -24,7 +25,11 @@ export default function GuidePage() {
|
||||
<ul className="mt-3 flex flex-col gap-2 items-start">
|
||||
{guideLinks.map(({ link }) => (
|
||||
<li key={link.to}>
|
||||
<AppLink {...link} className={linkClass} />
|
||||
<ActiveLink to={link.to}>
|
||||
{({ active }) => (
|
||||
<AppLink {...link} className={linkClass({ active })} />
|
||||
)}
|
||||
</ActiveLink>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-focus-on": "^3.5.4",
|
||||
"react-router": "^6.2.1",
|
||||
"react-router-dom": "^6.2.1",
|
||||
"remix": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
Reference in New Issue
Block a user