feat(nav): add extraPaths to NavItem — Einstellungen active on /household/staples
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -56,5 +56,35 @@ describe('nav config', () => {
|
|||||||
it('does not match unrelated route', () => {
|
it('does not match unrelated route', () => {
|
||||||
expect(isActiveRoute('/planner', '/recipes')).toBe(false);
|
expect(isActiveRoute('/planner', '/recipes')).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('matches when pathname is in extraPaths', () => {
|
||||||
|
expect(isActiveRoute('/settings', '/household/staples', ['/household/staples'])).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('matches sub-route of extraPath', () => {
|
||||||
|
expect(isActiveRoute('/settings', '/household/staples/edit', ['/household/staples'])).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not match extraPath with similar prefix', () => {
|
||||||
|
expect(isActiveRoute('/settings', '/household/staples-old', ['/household/staples'])).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false when extraPaths provided but no match', () => {
|
||||||
|
expect(isActiveRoute('/settings', '/members', ['/household/staples'])).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('NavItem extraPaths', () => {
|
||||||
|
it('Einstellungen desktop nav item includes /household/staples in extraPaths', () => {
|
||||||
|
const einstellungen = desktopNavSections
|
||||||
|
.flatMap((s) => s.items)
|
||||||
|
.find((i) => i.href === '/settings');
|
||||||
|
expect(einstellungen?.extraPaths).toContain('/household/staples');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Einstellungen mobile nav item includes /household/staples in extraPaths', () => {
|
||||||
|
const einstellungen = mobileNavItems.find((i) => i.href === '/settings');
|
||||||
|
expect(einstellungen?.extraPaths).toContain('/household/staples');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ export interface NavItem {
|
|||||||
href: string;
|
href: string;
|
||||||
label: string;
|
label: string;
|
||||||
icon: string;
|
icon: string;
|
||||||
|
extraPaths?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NavSection {
|
export interface NavSection {
|
||||||
@@ -13,11 +14,15 @@ export const mobileNavItems: NavItem[] = [
|
|||||||
{ href: '/planner', label: 'Planer', icon: '📅' },
|
{ href: '/planner', label: 'Planer', icon: '📅' },
|
||||||
{ href: '/recipes', label: 'Rezepte', icon: '📖' },
|
{ href: '/recipes', label: 'Rezepte', icon: '📖' },
|
||||||
{ href: '/shopping', label: 'Einkauf', icon: '🛒' },
|
{ href: '/shopping', label: 'Einkauf', icon: '🛒' },
|
||||||
{ href: '/settings', label: 'Einstellungen', icon: '⚙️' }
|
{ href: '/settings', label: 'Einstellungen', icon: '⚙️', extraPaths: ['/household/staples'] }
|
||||||
];
|
];
|
||||||
|
|
||||||
export function isActiveRoute(href: string, pathname: string): boolean {
|
export function isActiveRoute(href: string, pathname: string, extraPaths?: string[]): boolean {
|
||||||
return pathname === href || pathname.startsWith(href + '/');
|
if (pathname === href || pathname.startsWith(href + '/')) return true;
|
||||||
|
if (extraPaths) {
|
||||||
|
return extraPaths.some((p) => pathname === p || pathname.startsWith(p + '/'));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const desktopNavSections: NavSection[] = [
|
export const desktopNavSections: NavSection[] = [
|
||||||
@@ -33,7 +38,7 @@ export const desktopNavSections: NavSection[] = [
|
|||||||
title: 'Haushalt',
|
title: 'Haushalt',
|
||||||
items: [
|
items: [
|
||||||
{ href: '/members', label: 'Mitglieder', icon: '👥' },
|
{ href: '/members', label: 'Mitglieder', icon: '👥' },
|
||||||
{ href: '/settings', label: 'Einstellungen', icon: '⚙️' }
|
{ href: '/settings', label: 'Einstellungen', icon: '⚙️', extraPaths: ['/household/staples'] }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user