Skip to content

Commit 1e06a64

Browse files
Merge pull request #4 from guardiafinance/feat/add-navbar-route-prefix
feat: add route prefix for navbar navigate links
2 parents a891ede + 78ec61e commit 1e06a64

4 files changed

Lines changed: 58 additions & 11 deletions

File tree

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@guardiafinance/design-system",
3-
"version": "0.0.5",
3+
"version": "0.0.6",
44
"type": "module",
55
"exports": {
66
".": {
@@ -80,8 +80,8 @@
8080
"typescript": "^5.7.2"
8181
},
8282
"peerDependencies": {
83-
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
84-
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
83+
"react": "^19.0.0",
84+
"react-dom": "^19.0.0",
8585
"react-router": "^7.9.1",
8686
"zod": "^4.1.8"
8787
}

src/components/navbar/navbar.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import {
1818
NavigationItem,
1919
getActiveStatesFromPath,
2020
getDefaultActiveArea,
21-
getNavigationItems
21+
getNavigationItems,
22+
addRoutePrefix
2223
} from "./utils";
2324
import { DynamicMenuSections } from "./dynamic-section";
2425
import { When } from "../../lib/when";
@@ -64,7 +65,8 @@ function NavbarInternal({
6465
if (item.onClick) {
6566
item.onClick();
6667
} else if (item.path) {
67-
navigate(item.path);
68+
const pathWithPrefix = addRoutePrefix(item.path, settings.routePrefix);
69+
navigate(pathWithPrefix);
6870
}
6971

7072
onItemClick?.(item);

src/components/navbar/utils.tsx

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export interface NavbarConfiguration {
5353
areas: NavigationArea[];
5454
defaultActiveArea?: string;
5555
allowDefaultPathBehavior?: boolean;
56+
routePrefix?: string;
5657
organization?: NavbarOrganization;
5758
generalArea?: GeneralArea;
5859
user?: NavbarUser;
@@ -64,6 +65,48 @@ export interface NavbarConfiguration {
6465
};
6566
}
6667

68+
export const stripRoutePrefix = (pathname: string, prefix?: string): string => {
69+
if (!prefix) {
70+
return pathname;
71+
}
72+
73+
const normalizedPrefix = prefix.startsWith('/') ? prefix : `/${prefix}`;
74+
const normalizedPathname = pathname.startsWith('/') ? pathname : `/${pathname}`;
75+
76+
if (normalizedPathname.startsWith(normalizedPrefix)) {
77+
const stripped = normalizedPathname.slice(normalizedPrefix.length);
78+
if (stripped === '') {
79+
return '/';
80+
}
81+
return stripped.startsWith('/') ? stripped : `/${stripped}`;
82+
}
83+
84+
return pathname;
85+
};
86+
87+
export const addRoutePrefix = (path: string, prefix?: string): string => {
88+
if (!prefix || !path) {
89+
return path;
90+
}
91+
92+
let normalizedPrefix = prefix.startsWith('/') ? prefix : `/${prefix}`;
93+
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
94+
95+
if (normalizedPath === '/') {
96+
return normalizedPrefix;
97+
}
98+
99+
if (normalizedPrefix === '/') {
100+
return normalizedPath;
101+
}
102+
103+
if (normalizedPrefix.endsWith('/')) {
104+
normalizedPrefix = normalizedPrefix.slice(0, -1);
105+
}
106+
107+
return `${normalizedPrefix}${normalizedPath}`;
108+
};
109+
67110
export const getDefaultActiveArea = (config: NavbarConfiguration): string => {
68111
if (config.defaultActiveArea) {
69112
return config.defaultActiveArea;
@@ -113,10 +156,11 @@ export const matchesNavigationItem = (pathname: string, item: NavigationItem): b
113156
};
114157

115158
export const findNavigationItemByPath = (config: NavbarConfiguration, path: string): NavigationItem | null => {
159+
const strippedPath = stripRoutePrefix(path, config.routePrefix);
116160
for (const area of config.areas) {
117161
for (const section of area.sections) {
118162
for (const item of section.items) {
119-
if (matchesNavigationItem(path, item)) {
163+
if (matchesNavigationItem(strippedPath, item)) {
120164
return item;
121165
}
122166
}
@@ -146,9 +190,10 @@ export const getActiveStatesFromPath = (config: NavbarConfiguration, pathname: s
146190

147191
const foundItem = findNavigationItemByPath(config, pathname);
148192
if (foundItem) {
193+
const strippedPath = stripRoutePrefix(pathname, config.routePrefix);
149194
for (const area of config.areas) {
150195
for (const section of area.sections) {
151-
if (section.items.some(item => matchesNavigationItem(pathname, item))) {
196+
if (section.items.some(item => matchesNavigationItem(strippedPath, item))) {
152197
activeArea = area.title;
153198
activeItem = foundItem.title;
154199
return { activeArea, activeItem };

0 commit comments

Comments
 (0)