diff --git a/src/App.tsx b/src/App.tsx
index 10bad3f3b..6806aef6e 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -213,6 +213,11 @@ const Routing = () => {
const renderPageComponent = (PageComponent: PageComponent) => {
if (!PageComponent.route.isPageEnabled) return null
+ const { parentPathBase: parentPathBaseFromRoute } = PageComponent.route
+ const parentPathBase = parentPathBaseFromRoute || ""
+ const updatedParentPathBase = PageComponent.route.path
+ ? `${parentPathBase}/${PageComponent.route.path}`
+ : parentPathBase
return (
@@ -224,9 +229,17 @@ const renderPageComponent = (PageComponent: PageComponent) => {
)}
}
+ element={
+
+ }
>
- {PageComponent.route.pages?.map(renderPageComponent)}
+ {PageComponent.route.pages?.map((page) => {
+ page.route.parentPathBase = updatedParentPathBase
+ return renderPageComponent(page)
+ })}
)
diff --git a/src/components/SubNavigationPills/index.tsx b/src/components/SubNavigationPills/index.tsx
index b8117efbe..8621ed21f 100644
--- a/src/components/SubNavigationPills/index.tsx
+++ b/src/components/SubNavigationPills/index.tsx
@@ -7,16 +7,29 @@ import {
Stack,
useColorModeValue,
} from "@threshold-network/components"
-import { useMatch, useResolvedPath } from "react-router-dom"
+import { matchPath, resolvePath, useLocation } from "react-router-dom"
import { RouteProps } from "../../types"
import Link from "../Link"
-interface Props {
+interface SubNavigationPillsProps {
links: RouteProps[]
}
-const SubNavigationPills: FC = ({ links }) => {
+interface PathMatchResult {
+ index: number
+ path: string
+ pathOverride?: string
+ resolvedPath: string
+ match: any
+}
+interface NavPill extends RouteProps {
+ isActive?: boolean
+}
+
+const SubNavigationPills: FC = ({ links }) => {
+ const { pathname } = useLocation()
const linksWithTitle = links.filter((link) => !!link.title)
+ const activePillIndex = getActivePillIndex(linksWithTitle, pathname)
const wrapperBorderColor = useColorModeValue("gray.100", "gray.700")
return (
@@ -38,16 +51,17 @@ const SubNavigationPills: FC = ({ links }) => {
height="28px"
as="ul"
>
- {linksWithTitle.map(renderPill)}
+ {linksWithTitle.map((linkWithTitle, index) => {
+ const isActive = index === activePillIndex
+ return renderPill(linkWithTitle, isActive)
+ })}
>
)
}
-const NavPill: FC = ({ path, pathOverride, title }) => {
- const resolved = useResolvedPath(pathOverride || path)
- const isActive = useMatch({ path: resolved.pathname, end: true })
+const NavPill: FC = ({ path, title, isActive = false }) => {
const activeColor = useColorModeValue("brand.500", "gray.100")
const underlineColor = useColorModeValue("brand.500", "white")
@@ -81,6 +95,70 @@ const NavPill: FC = ({ path, pathOverride, title }) => {
)
}
-const renderPill = (pill: RouteProps) =>
+const renderPill = (pill: RouteProps, isActive = false) => (
+
+)
+
+const getPathMatches = (pills: RouteProps[], locationPathname: string) => {
+ const pathMatches: PathMatchResult[] = []
+ for (let i = 0; i < pills.length; i++) {
+ const { path, pathOverride, parentPathBase } = pills[i]
+ // This is a workaround for preview links. We have to remove the branch name
+ // from the pathname so first we check if `parentPathBase` is not an
+ // undefined. If it is then it means that this is the main page without any
+ // additional paths so we can just use an empty string here. If it's not
+ // undefined then we have to remove all the characters (if there are any)
+ // that are before the occurrence of the `parentPathBase`. If this is a
+ // preview then those removed characters should be a name of the branch. In
+ // other cases there should not be any character before the occurrence of
+ // the `parentPathBase` so nothing happens.
+ const currentPathname = parentPathBase
+ ? locationPathname.includes(parentPathBase) &&
+ locationPathname.indexOf(parentPathBase) !== 0
+ ? locationPathname.substring(
+ locationPathname.indexOf(parentPathBase),
+ locationPathname.length
+ )
+ : locationPathname
+ : ""
+ const resolved = resolvePath(
+ pathOverride
+ ? `${parentPathBase}/${pathOverride}`
+ : `${parentPathBase}/${path}`
+ )
+ const match = matchPath(
+ { path: resolved.pathname, end: true },
+ currentPathname
+ )
+ pathMatches.push({
+ index: i,
+ path,
+ pathOverride,
+ resolvedPath: resolved.pathname,
+ match,
+ })
+ }
+ return pathMatches
+}
+
+const getActivePillIndex = (pills: RouteProps[], locationPathname: string) => {
+ const pathMatches = getPathMatches(pills, locationPathname)
+ const matchedPaths = pathMatches.filter((_) => {
+ return !!_.match
+ })
+ if (matchedPaths.length === 0) return undefined
+ if (matchedPaths.length === 1) return matchedPaths[0].index
+
+ const matchedElementWithLongestPathnameBase = matchedPaths.reduce(
+ (maxElement, currentElement) => {
+ return currentElement.match.pathnameBase.length >
+ maxElement.match.pathnameBase.length
+ ? currentElement
+ : maxElement
+ }
+ )
+
+ return matchedElementWithLongestPathnameBase.index
+}
export default SubNavigationPills
diff --git a/src/pages/Staking/index.tsx b/src/pages/Staking/index.tsx
index 4e0bf489a..2d2d58793 100644
--- a/src/pages/Staking/index.tsx
+++ b/src/pages/Staking/index.tsx
@@ -212,6 +212,7 @@ Auth.route = {
StakingPage.route = {
path: "",
index: false,
+ pathOverride: "*",
title: "Staking",
isPageEnabled: true,
}
diff --git a/src/pages/tBTC/Bridge/index.tsx b/src/pages/tBTC/Bridge/index.tsx
index 6b1614358..cfe2ba51b 100644
--- a/src/pages/tBTC/Bridge/index.tsx
+++ b/src/pages/tBTC/Bridge/index.tsx
@@ -1,5 +1,5 @@
import { useEffect } from "react"
-import { Grid, Box, Skeleton, Stack } from "@threshold-network/components"
+import { Grid, Box } from "@threshold-network/components"
import { PageComponent } from "../../../types"
import { TbtcBalanceCard } from "./TbtcBalanceCard"
import { MintUnmintNav } from "./MintUnmintNav"
@@ -70,7 +70,7 @@ const TBTCBridge: PageComponent = (props) => {
TBTCBridge.route = {
path: "",
index: false,
- pathOverride: "/tBTC/*",
+ pathOverride: "*",
pages: [MintPage, UnmintPage],
title: "Bridge",
isPageEnabled: true,
diff --git a/src/types/page.ts b/src/types/page.ts
index 00cbc8458..c549758d8 100644
--- a/src/types/page.ts
+++ b/src/types/page.ts
@@ -8,6 +8,10 @@ export type RouteProps = {
pages?: PageComponent[]
hideFromMenu?: boolean
isPageEnabled: boolean
+ // Paths combined from all Route parents of the current Route
+ parentPathBase?: string
}
-export type PageComponent = FC & { route: RouteProps }
+export type PageComponent = FC & {
+ route: RouteProps
+}