From 120bc93f96fa7096a64f21f8d30b0390b1e32e0f Mon Sep 17 00:00:00 2001 From: Till-JS <101404291+Till-JS@users.noreply.github.com> Date: Sun, 30 Nov 2025 01:00:43 +0100 Subject: [PATCH] feat(shared-ui): add nested language submenu in PillNavigation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Move language selector into nested submenu within user dropdown - Show full language name instead of code (e.g., "🇩🇪 Deutsch" vs "🇩🇪 DE") - Align submenu items with parent pill styling (same padding, font-size, gap) - Left-align submenu content - Add extra spacing between flag emoji and text 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- packages/shared-i18n/src/utils.ts | 6 +++--- .../shared-ui/src/navigation/PillDropdown.svelte | 13 +++++++------ .../shared-ui/src/navigation/PillNavigation.svelte | 12 ++++++++---- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/packages/shared-i18n/src/utils.ts b/packages/shared-i18n/src/utils.ts index 3b9c454b3..c9a8a952b 100644 --- a/packages/shared-i18n/src/utils.ts +++ b/packages/shared-i18n/src/utils.ts @@ -269,7 +269,7 @@ export function getLanguageDropdownItems( const info = getLanguageInfo(locale); return { id: locale, - label: info ? `${info.emoji} ${info.nativeName}` : locale.toUpperCase(), + label: info ? `${info.emoji} ${info.nativeName}` : locale.toUpperCase(), onClick: () => onLocaleChange(locale), active: currentLocale === locale, }; @@ -279,12 +279,12 @@ export function getLanguageDropdownItems( /** * Get current language label for PillDropdown trigger * @param currentLocale - Currently selected locale - * @returns Label with flag emoji and language code (e.g., "🇩🇪 DE") + * @returns Label with flag emoji and native name (e.g., "🇩🇪 Deutsch") */ export function getCurrentLanguageLabel(currentLocale: string): string { const info = getLanguageInfo(currentLocale); if (info) { - return `${info.emoji} ${currentLocale.toUpperCase()}`; + return `${info.emoji} ${info.nativeName}`; } return currentLocale.toUpperCase(); } diff --git a/packages/shared-ui/src/navigation/PillDropdown.svelte b/packages/shared-ui/src/navigation/PillDropdown.svelte index c32ef8533..0fc560ced 100644 --- a/packages/shared-ui/src/navigation/PillDropdown.svelte +++ b/packages/shared-ui/src/navigation/PillDropdown.svelte @@ -453,20 +453,21 @@ .submenu-container { display: flex; flex-direction: column; - gap: 0.25rem; - padding-left: 1rem; - margin-top: -0.25rem; - margin-bottom: 0.25rem; + gap: 0.5rem; + margin-top: 0; + margin-bottom: 0; } .submenu-item { - padding: 0.375rem 0.75rem; - font-size: 0.8125rem; + padding: 0.5rem 0.875rem; + font-size: 0.875rem; animation: fanIn 0.15s ease-out forwards; opacity: 0; + justify-content: flex-start; } .submenu-item .pill-label { flex: 1; + text-align: left; } diff --git a/packages/shared-ui/src/navigation/PillNavigation.svelte b/packages/shared-ui/src/navigation/PillNavigation.svelte index 216dba871..6ca62b864 100644 --- a/packages/shared-ui/src/navigation/PillNavigation.svelte +++ b/packages/shared-ui/src/navigation/PillNavigation.svelte @@ -457,10 +457,14 @@ ...(showLanguageSwitcher && languageItems.length > 0 ? [ { id: 'language-divider', label: '', divider: true }, - ...languageItems.map((item) => ({ - ...item, - id: `lang-${item.id}`, - })), + { + id: 'language', + label: currentLanguageLabel, + submenu: languageItems.map((item) => ({ + ...item, + id: `lang-${item.id}`, + })), + }, ] : []), { id: 'logout-divider', label: '', divider: true },