Mobile Navbar #75
|
@ -54,7 +54,7 @@ const menu: Menu = [
|
|||
},
|
||||
{
|
||||
name: "Resources",
|
||||
route: "/resources",
|
||||
route: "/resources/services",
|
||||
submenu: [
|
||||
{
|
||||
name: "Services",
|
||||
|
@ -72,15 +72,18 @@ const menu: Menu = [
|
|||
},
|
||||
];
|
||||
|
||||
function getMainRoute(route: string) {
|
||||
if (route === "/") {
|
||||
return "/";
|
||||
} else if (route.startsWith("http://") || route.startsWith("https://")) {
|
||||
return route;
|
||||
}
|
||||
return "/" + route.split("/")[1];
|
||||
}
|
||||
|
||||
export function Navbar() {
|
||||
const router = useRouter();
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
const parentPath =
|
||||
router.pathname === "/"
|
||||
? "/"
|
||||
: menu.find(
|
||||
(item) => item.route !== "/" && router.pathname.startsWith(item.route)
|
||||
)?.route;
|
||||
|
||||
return (
|
||||
<nav className={styles.navbar}>
|
||||
|
@ -92,7 +95,7 @@ export function Navbar() {
|
|||
</Link>
|
||||
<button
|
||||
className={styles.hamburger}
|
||||
onClick={() => dispatch({ type: "open", route: parentPath ?? "" })}
|
||||
onClick={() => dispatch({ type: "open", route: router.pathname })}
|
||||
>
|
||||
<Image src="/images/hamburger.svg" alt="Menu" />
|
||||
</button>
|
||||
|
@ -125,7 +128,7 @@ export function Navbar() {
|
|||
route={item.route}
|
||||
submenu={item.submenu}
|
||||
activeSubmenus={state.activeSubmenus}
|
||||
onClick={(type) => dispatch({ type, route: item.route })}
|
||||
dispatch={dispatch}
|
||||
/>
|
||||
</li>
|
||||
);
|
||||
|
@ -158,14 +161,14 @@ function reducer(state: MobileState, action: MobileAction): MobileState {
|
|||
case "open":
|
||||
return {
|
||||
isNavOpen: true,
|
||||
activeSubmenus: new Set([action.route]),
|
||||
activeSubmenus: new Set([getMainRoute(action.route)]),
|
||||
};
|
||||
case "toggle":
|
||||
const newSet = new Set(state.activeSubmenus);
|
||||
if (state.activeSubmenus.has(action.route)) {
|
||||
newSet.delete(action.route);
|
||||
if (state.activeSubmenus.has(getMainRoute(action.route))) {
|
||||
newSet.delete(getMainRoute(action.route));
|
||||
} else {
|
||||
newSet.add(action.route);
|
||||
newSet.add(getMainRoute(action.route));
|
||||
}
|
||||
return {
|
||||
isNavOpen: state.isNavOpen,
|
||||
|
@ -184,14 +187,15 @@ interface NavItemProps {
|
|||
route: string;
|
||||
}[];
|
||||
activeSubmenus: Set<string>;
|
||||
onClick: (type: MobileAction["type"]) => void;
|
||||
dispatch: React.Dispatch<MobileAction>;
|
||||
}
|
||||
|
||||
function NavItem(props: NavItemProps) {
|
||||
const router = useRouter();
|
||||
const isCurrentPage =
|
||||
router.pathname === props.route ||
|
||||
(props.submenu != null && router.pathname.startsWith(props.route));
|
||||
(props.submenu != null &&
|
||||
router.pathname.startsWith(getMainRoute(props.route)));
|
||||
const isExternalLink =
|
||||
props.route.includes("http://") || props.route.includes("https://");
|
||||
|
||||
|
@ -199,7 +203,7 @@ function NavItem(props: NavItemProps) {
|
|||
if (document.activeElement instanceof HTMLElement) {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
props.onClick("close");
|
||||
props.dispatch({ type: "close" });
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -228,17 +232,19 @@ function NavItem(props: NavItemProps) {
|
|||
<>
|
||||
<button
|
||||
className={
|
||||
props.activeSubmenus.has(props.route)
|
||||
props.activeSubmenus.has(getMainRoute(props.route))
|
||||
? `${styles.dropdownIcon} ${styles.rotate}`
|
||||
: styles.dropdownIcon
|
||||
}
|
||||
onClick={() => props.onClick("toggle")}
|
||||
onClick={() =>
|
||||
props.dispatch({ type: "toggle", route: props.route })
|
||||
}
|
||||
>
|
||||
<Image src="/images/dropdown-icon.svg" alt="Dropdown Icon" />
|
||||
</button>
|
||||
<ul
|
||||
className={
|
||||
props.activeSubmenus.has(props.route)
|
||||
props.activeSubmenus.has(getMainRoute(props.route))
|
||||
? `${styles.dropdown} ${styles.show}`
|
||||
: styles.dropdown
|
||||
}
|
||||
|
@ -250,7 +256,7 @@ function NavItem(props: NavItemProps) {
|
|||
name={item.name}
|
||||
route={item.route}
|
||||
activeSubmenus={props.activeSubmenus}
|
||||
onClick={props.onClick}
|
||||
dispatch={props.dispatch}
|
||||
/>
|
||||
</li>
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue