From 5c066d33ef484ee81b4fcfb997217967175a76d5 Mon Sep 17 00:00:00 2001 From: Marcel Raddatz Date: Thu, 2 Apr 2026 14:03:53 +0200 Subject: [PATCH] feat(nav): add emoji icons to all nav components Renders emoji icons in MobileTabBar (stacked above label), TabletNavBar (inline), and DesktopSidebar (16px, 20px column). Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/lib/nav/DesktopSidebar.svelte | 1 + .../src/lib/nav/MobileTabBar.routes.test.ts | 4 ++-- frontend/src/lib/nav/MobileTabBar.svelte | 1 + frontend/src/lib/nav/MobileTabBar.test.ts | 8 ++++++++ frontend/src/lib/nav/TabletNavBar.svelte | 1 + frontend/src/lib/nav/nav.ts | 18 +++++++++--------- 6 files changed, 22 insertions(+), 11 deletions(-) diff --git a/frontend/src/lib/nav/DesktopSidebar.svelte b/frontend/src/lib/nav/DesktopSidebar.svelte index ec7aa95..d7a7453 100644 --- a/frontend/src/lib/nav/DesktopSidebar.svelte +++ b/frontend/src/lib/nav/DesktopSidebar.svelte @@ -32,6 +32,7 @@ ? 'bg-[var(--green-tint)] text-[var(--green-dark)] font-medium' : ''}" > + {item.icon} {item.label} {/each} diff --git a/frontend/src/lib/nav/MobileTabBar.routes.test.ts b/frontend/src/lib/nav/MobileTabBar.routes.test.ts index ef30c4d..36b73a7 100644 --- a/frontend/src/lib/nav/MobileTabBar.routes.test.ts +++ b/frontend/src/lib/nav/MobileTabBar.routes.test.ts @@ -23,11 +23,11 @@ describe('MobileTabBar active state per route', () => { pageStore.set({ url: new URL(`http://localhost${route}`) }); const { unmount } = render(MobileTabBar); - const activeLink = screen.getByRole('link', { name: expectedActiveLabel }); + const activeLink = screen.getByRole('link', { name: new RegExp(expectedActiveLabel) }); expect(activeLink).toHaveAttribute('aria-current', 'page'); const allLinks = screen.getAllByRole('link'); - const inactiveLinks = allLinks.filter((link) => link.textContent?.trim() !== expectedActiveLabel); + const inactiveLinks = allLinks.filter((link) => !link.textContent?.includes(expectedActiveLabel)); for (const link of inactiveLinks) { expect(link).not.toHaveAttribute('aria-current'); } diff --git a/frontend/src/lib/nav/MobileTabBar.svelte b/frontend/src/lib/nav/MobileTabBar.svelte index 9482191..d0b336a 100644 --- a/frontend/src/lib/nav/MobileTabBar.svelte +++ b/frontend/src/lib/nav/MobileTabBar.svelte @@ -16,6 +16,7 @@ ? 'bg-[var(--green-tint)] text-[var(--green-dark)] font-medium' : ''}" > + {item.icon} {item.label} {/each} diff --git a/frontend/src/lib/nav/MobileTabBar.test.ts b/frontend/src/lib/nav/MobileTabBar.test.ts index a830119..3e7f023 100644 --- a/frontend/src/lib/nav/MobileTabBar.test.ts +++ b/frontend/src/lib/nav/MobileTabBar.test.ts @@ -39,6 +39,14 @@ describe('MobileTabBar', () => { expect(plannerLink).toHaveAttribute('aria-current', 'page'); }); + it('renders icons for each nav item', () => { + render(MobileTabBar); + expect(screen.getByText('📅')).toBeInTheDocument(); + expect(screen.getByText('📖')).toBeInTheDocument(); + expect(screen.getByText('🛒')).toBeInTheDocument(); + expect(screen.getByText('⚙️')).toBeInTheDocument(); + }); + it('non-active items do not have aria-current', () => { render(MobileTabBar); const recipesLink = screen.getByRole('link', { name: /rezepte/i }); diff --git a/frontend/src/lib/nav/TabletNavBar.svelte b/frontend/src/lib/nav/TabletNavBar.svelte index ecf7f88..2daa707 100644 --- a/frontend/src/lib/nav/TabletNavBar.svelte +++ b/frontend/src/lib/nav/TabletNavBar.svelte @@ -16,6 +16,7 @@ ? 'bg-[var(--green-tint)] text-[var(--green-dark)] font-medium' : ''}" > + {item.icon} {item.label} {/each} diff --git a/frontend/src/lib/nav/nav.ts b/frontend/src/lib/nav/nav.ts index 3770035..883bdcb 100644 --- a/frontend/src/lib/nav/nav.ts +++ b/frontend/src/lib/nav/nav.ts @@ -10,10 +10,10 @@ export interface NavSection { } export const mobileNavItems: NavItem[] = [ - { href: '/planner', label: 'Planer', icon: 'calendar' }, - { href: '/recipes', label: 'Rezepte', icon: 'book' }, - { href: '/shopping', label: 'Einkauf', icon: 'shopping-cart' }, - { href: '/settings', label: 'Einstellungen', icon: 'settings' } + { href: '/planner', label: 'Planer', icon: '📅' }, + { href: '/recipes', label: 'Rezepte', icon: '📖' }, + { href: '/shopping', label: 'Einkauf', icon: '🛒' }, + { href: '/settings', label: 'Einstellungen', icon: '⚙️' } ]; export function isActiveRoute(href: string, pathname: string): boolean { @@ -24,16 +24,16 @@ export const desktopNavSections: NavSection[] = [ { title: 'Plan', items: [ - { href: '/planner', label: 'Planer', icon: 'calendar' }, - { href: '/recipes', label: 'Rezepte', icon: 'book' }, - { href: '/shopping', label: 'Einkauf', icon: 'shopping-cart' } + { href: '/planner', label: 'Planer', icon: '📅' }, + { href: '/recipes', label: 'Rezepte', icon: '📖' }, + { href: '/shopping', label: 'Einkauf', icon: '🛒' } ] }, { title: 'Haushalt', items: [ - { href: '/members', label: 'Mitglieder', icon: 'users' }, - { href: '/settings', label: 'Einstellungen', icon: 'settings' } + { href: '/members', label: 'Mitglieder', icon: '👥' }, + { href: '/settings', label: 'Einstellungen', icon: '⚙️' } ] } ];