From 3ce7c00d5bbe2f089a69db6c6a866ac2d0d161eb Mon Sep 17 00:00:00 2001
From: Remmy Cat Stock <3317423+remmycat@users.noreply.github.com>
Date: Fri, 21 Oct 2022 18:29:23 +0200
Subject: [PATCH] Detect active nav item via route handle instead of path
matching
---
app/components/layout/index.tsx | 34 ++++++++++++++++++++++++---------
app/routes/admin.tsx | 10 +++++++++-
app/routes/analyzer.tsx | 1 +
app/routes/badges.tsx | 1 +
app/routes/builds.tsx | 1 +
app/routes/calendar/index.tsx | 1 +
app/routes/maps.tsx | 1 +
app/routes/plus.tsx | 5 +++++
app/utils/remix.ts | 4 ++++
9 files changed, 48 insertions(+), 10 deletions(-)
diff --git a/app/components/layout/index.tsx b/app/components/layout/index.tsx
index b05710e8d..b04831c4d 100644
--- a/app/components/layout/index.tsx
+++ b/app/components/layout/index.tsx
@@ -1,7 +1,8 @@
-import { Link, useLocation } from "@remix-run/react";
+import { Link, useMatches } from "@remix-run/react";
import * as React from "react";
import { useTranslation } from "react-i18next";
import type { RootLoaderData } from "~/root";
+import { type SendouRouteHandle } from "~/utils/remix";
import { LOGO_PATH, navIconUrl } from "~/utils/urls";
import { Image } from "../Image";
import { ColorModeToggle } from "./ColorModeToggle";
@@ -12,6 +13,25 @@ import { Menu } from "./Menu";
import navItems from "./nav-items.json";
import { UserItem } from "./UserItem";
+function useActiveNavItem() {
+ const matches = useMatches();
+
+ return React.useMemo(() => {
+ let activeItem: { name: string; url: string } | undefined = undefined;
+
+ for (const match of matches.reverse()) {
+ const handle = match.handle as SendouRouteHandle | undefined;
+
+ if (handle?.navItemName) {
+ activeItem = navItems.find(({ name }) => name === handle.navItemName);
+ break;
+ }
+ }
+
+ return activeItem;
+ }, [matches]);
+}
+
export const Layout = React.memo(function Layout({
children,
patrons,
@@ -22,12 +42,8 @@ export const Layout = React.memo(function Layout({
isCatchBoundary?: boolean;
}) {
const { t } = useTranslation();
- const location = useLocation();
const [menuOpen, setMenuOpen] = React.useState(false);
-
- const currentPagesNavItem = navItems.find((navItem) =>
- location.pathname.includes(navItem.name)
- );
+ const activeNavItem = useActiveNavItem();
return (
@@ -51,15 +67,15 @@ export const Layout = React.memo(function Layout({