@@ -5,6 +5,59 @@ function normalize(url: string) {
55 return url ;
66}
77
8+ // Products that have versioned paths like /product/X.Y.x/...
9+ const VERSIONED_PRODUCTS = [ "/relayer" , "/monitor" ] ;
10+
11+ // Version pattern: matches patterns like "1.3.x", "1.0.x", "2.1.x"
12+ const VERSION_PATTERN = / ^ ( \d + \. \d + \. x ) $ / ;
13+
14+ interface ParsedPath {
15+ base : string ;
16+ version : string | null ; // null means development/unversioned
17+ subpath : string ;
18+ }
19+
20+ /**
21+ * Parses a path for versioned products.
22+ * For "/relayer/1.3.x/quickstart" returns { base: "/relayer", version: "1.3.x", subpath: "/quickstart" }
23+ * For "/relayer/quickstart" (development) returns { base: "/relayer", version: null, subpath: "/quickstart" }
24+ * For "/relayer" (development root) returns { base: "/relayer", version: null, subpath: "" }
25+ * For non-product paths, returns null.
26+ */
27+ function parseProductPath ( path : string ) : ParsedPath | null {
28+ const normalizedPath = normalize ( path ) ;
29+
30+ for ( const product of VERSIONED_PRODUCTS ) {
31+ if ( normalizedPath === product ) {
32+ // Exact match to product root (development version)
33+ return { base : product , version : null , subpath : "" } ;
34+ }
35+
36+ if ( normalizedPath . startsWith ( `${ product } /` ) ) {
37+ const remainder = normalizedPath . slice ( product . length + 1 ) ; // +1 for the slash
38+ const segments = remainder . split ( "/" ) ;
39+ const firstSegment = segments [ 0 ] ;
40+
41+ if ( firstSegment && VERSION_PATTERN . test ( firstSegment ) ) {
42+ // Versioned path: /relayer/1.3.x or /relayer/1.3.x/quickstart
43+ return {
44+ base : product ,
45+ version : firstSegment ,
46+ subpath : segments . length > 1 ? `/${ segments . slice ( 1 ) . join ( "/" ) } ` : "" ,
47+ } ;
48+ }
49+ // Development path with subpath: /relayer/quickstart
50+ return {
51+ base : product ,
52+ version : null ,
53+ subpath : `/${ remainder } ` ,
54+ } ;
55+ }
56+ }
57+
58+ return null ;
59+ }
60+
861export function isActive (
962 url : string ,
1063 pathname : string ,
@@ -13,7 +66,39 @@ export function isActive(
1366 url = normalize ( url ) ;
1467 pathname = normalize ( pathname ) ;
1568
16- return url === pathname || ( nested && pathname . startsWith ( `${ url } /` ) ) ;
69+ // Standard exact match or nested match
70+ if ( url === pathname || ( nested && pathname . startsWith ( `${ url } /` ) ) ) {
71+ return true ;
72+ }
73+
74+ // Check for versioned/development path matching
75+ const urlParsed = parseProductPath ( url ) ;
76+ const pathnameParsed = parseProductPath ( pathname ) ;
77+
78+ if ( urlParsed && pathnameParsed ) {
79+ // Both are paths for the same product
80+ if ( urlParsed . base === pathnameParsed . base ) {
81+ // Same subpath means it's the same "page" just different version
82+ if ( urlParsed . subpath === pathnameParsed . subpath ) {
83+ return true ;
84+ }
85+
86+ // Check if pathname is nested under url's subpath
87+ if (
88+ nested &&
89+ pathnameParsed . subpath . startsWith ( `${ urlParsed . subpath } /` )
90+ ) {
91+ return true ;
92+ }
93+
94+ // Handle root match: /relayer/1.3.x should match any /relayer/* when nested
95+ if ( nested && urlParsed . subpath === "" ) {
96+ return true ;
97+ }
98+ }
99+ }
100+
101+ return false ;
17102}
18103
19104export function isTabActive ( tab : SidebarTab , pathname : string ) {
0 commit comments