Repository navigation
[No QA] Add a collapsing flat navigation bar - #102023
shawnborton wants to merge 61 commits into
Conversation
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… to the top bar Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
# Conflicts: # src/components/AccountSwitcher.tsx # src/pages/Search/SearchPageWide.tsx # src/pages/inbox/sidebar/InboxTabSelector.tsx # src/pages/inbox/sidebar/ProfileAvatarWithIndicator.tsx
…e Spend tabs Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ation Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…n rows Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
# Conflicts: # src/styles/variables.ts
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…youts Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…dius Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
🚧 shawnborton has triggered a test Expensify/App build. You can view the workflow run here. |
This comment has been minimized.
This comment has been minimized.
|
🚧 shawnborton has triggered a test Expensify/App build. You can view the workflow run here. |
This comment has been minimized.
This comment has been minimized.
|
🚧 shawnborton has triggered a test Expensify/App build. You can view the workflow run here. |
This comment has been minimized.
This comment has been minimized.
|
🚧 shawnborton has triggered a test Expensify/App build. You can view the workflow run here. |
|
🚧 shawnborton has triggered a test Expensify/App build. You can view the workflow run here. |
This comment has been minimized.
This comment has been minimized.
|
🚧 shawnborton has triggered a test Expensify/App build. You can view the workflow run here. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
🚧 shawnborton has triggered a test Expensify/App build. You can view the workflow run here. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
🚧 shawnborton has triggered a test Expensify/App build. You can view the workflow run here. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
🚧 shawnborton has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
🦜 Polyglot Parrot! 🦜Squawk! Looks like you added some shiny new English strings. Allow me to parrot them back to you in other tongues: View the translation diffdiff --git a/src/languages/de.ts b/src/languages/de.ts
index 784ff40d..dcc11818 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -2477,7 +2477,7 @@ const translations: TranslationDeepObject<typeof en> = {
profileTrace: 'Profil-Trace',
results: 'Ergebnisse',
testingPreferences: 'Testeinstellungen',
- showExtraNavItems: 'Zusätzliche Navigationselemente anzeigen',
+ showExtraNavItems: 'Zusätzliche Navigationspunkte anzeigen',
server: 'Server',
servers: {
production: {label: 'Produktion', description: 'Die Live-Umgebung, die echte Nutzer sehen'},
@@ -3729,9 +3729,9 @@ ${amount} für ${merchant} – ${date}`,
`Behalten Sie den Überblick, indem Sie nur ungelesene Chats oder Chats sehen, die Ihre Aufmerksamkeit erfordern. Keine Sorge, Sie können dies jederzeit in den <a href="${priorityModePageUrl}">Einstellungen</a> ändern.`,
},
morePage: {
- accountingDescription: 'Exporte, Abgrenzungen, Abrechnungen und Abstimmung',
- savedSearchesDescription: 'Zurück zu einer gespeicherten Suche',
- insightsDescription: 'Sehen Sie, wohin Ihre Ausgaben fließen',
+ accountingDescription: 'Exporte, Rückstellungen, Abrechnungen und Abstimmung',
+ savedSearchesDescription: 'Zu einer gespeicherten Suche zurückspringen',
+ insightsDescription: 'Sehen Sie, wofür Sie Ihr Geld ausgeben',
workspacesDescription: 'Verwalten Sie Ihre Arbeitsbereiche und Domains',
},
inboxTabs: {
diff --git a/src/languages/el.ts b/src/languages/el.ts
index 5d1d6999..9bdd4570 100644
--- a/src/languages/el.ts
+++ b/src/languages/el.ts
@@ -3782,10 +3782,10 @@ ${amount} για ${merchant} - ${date}`,
`Μείνετε οργανωμένοι βλέποντας μόνο μη αναγνωσμένες συνομιλίες ή συνομιλίες που χρειάζονται την προσοχή σας. Μη σας ανησυχεί, μπορείτε να το αλλάξετε οποιαδήποτε στιγμή από τις <a href="${priorityModePageUrl}">ρυθμίσεις</a>.`,
},
morePage: {
- accountingDescription: 'Εξαγωγές, δεδουλευμένα, καταστάσεις και συμφωνία',
- savedSearchesDescription: 'Επιστρέψτε σε μια αποθηκευμένη αναζήτηση',
- insightsDescription: 'Δείτε πού πηγαίνουν οι δαπάνες σας',
- workspacesDescription: 'Διαχειριστείτε τους χώρους εργασίας και τους τομείς σας',
+ accountingDescription: 'Εξαγωγές, δεδουλευμένα, καταστάσεις και συμφιλίωση',
+ savedSearchesDescription: 'Επιστρέψτε σε μια αναζήτηση που αποθηκεύσατε',
+ insightsDescription: 'Δείτε πού κατευθύνεται η δαπάνη σας',
+ workspacesDescription: 'Διαχειριστείτε τους χώρους εργασίας και τα domains σας',
},
inboxTabs: {
all: 'Όλα',
@@ -11065,10 +11065,10 @@ ${reportName}`,
tabs: {
expenseReports: 'Αναφορές εξόδων',
reports: 'Αναφορές',
- allExpenses: 'Όλα τα έξοδα',
+ allExpenses: 'Όλες οι δαπάνες',
allReports: 'Όλες οι αναφορές',
myReports: 'Οι αναφορές μου',
- myExpenses: 'Τα έξοδά μου',
+ myExpenses: 'Οι δαπάνες μου',
expenses: 'Έξοδα',
submit: 'Πρόχειρα',
approve: 'Χρειάζεται έγκριση',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 196bb304..49f69ef8 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -3696,7 +3696,7 @@ ${amount} para ${merchant} - ${date}`,
morePage: {
accountingDescription: 'Exportaciones, devengos, extractos y conciliación',
savedSearchesDescription: 'Vuelve a una búsqueda que guardaste',
- insightsDescription: 'Descubre a dónde va tu gasto',
+ insightsDescription: 'Descubre en qué se va tu gasto',
workspacesDescription: 'Gestiona tus espacios de trabajo y dominios',
},
inboxTabs: {
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index a6563ea4..f5c29ace 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -2485,7 +2485,7 @@ const translations: TranslationDeepObject<typeof en> = {
profileTrace: 'Profil de trace',
results: 'Résultats',
testingPreferences: 'Préférences de test',
- showExtraNavItems: 'Afficher les éléments de navigation supplémentaires',
+ showExtraNavItems: 'Afficher des éléments de navigation supplémentaires',
server: 'Serveur',
servers: {
production: {label: 'Production', description: "L'environnement en direct que voient les vrais utilisateurs"},
@@ -3739,10 +3739,10 @@ ${amount} pour ${merchant} - ${date}`,
`Gardez le contrôle en n’affichant que les discussions non lues ou celles qui nécessitent votre attention. Ne vous inquiétez pas, vous pouvez modifier ce réglage à tout moment dans les <a href="${priorityModePageUrl}">paramètres</a>.`,
},
morePage: {
- accountingDescription: 'Exports, charges à payer, relevés et rapprochement',
- savedSearchesDescription: 'Revenez à une recherche enregistrée',
- insightsDescription: 'Voyez où passent vos dépenses',
- workspacesDescription: 'Gérez vos espaces de travail et domaines',
+ accountingDescription: 'Exports, écritures d’engagement, relevés et rapprochement',
+ savedSearchesDescription: 'Revenir à une recherche que vous avez enregistrée',
+ insightsDescription: 'Visualisez où vont vos dépenses',
+ workspacesDescription: 'Gérer vos espaces de travail et domaines',
},
inboxTabs: {
all: 'Tout',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 8032d589..97fe7076 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -2471,7 +2471,7 @@ const translations: TranslationDeepObject<typeof en> = {
profileTrace: 'Traccia profilo',
results: 'Risultati',
testingPreferences: 'Preferenze di test',
- showExtraNavItems: 'Mostra voci di navigazione extra',
+ showExtraNavItems: 'Mostra elementi di navigazione extra',
server: 'Server',
servers: {
production: {label: 'Produzione', description: "L'ambiente live che vedono gli utenti reali"},
@@ -3716,7 +3716,7 @@ ${amount} per ${merchant} - ${date}`,
},
morePage: {
accountingDescription: 'Esportazioni, ratei, estratti conto e riconciliazione',
- savedSearchesDescription: 'Torna a una ricerca salvata',
+ savedSearchesDescription: 'Torna a una ricerca che hai salvato',
insightsDescription: 'Scopri dove vanno le tue spese',
workspacesDescription: 'Gestisci i tuoi spazi di lavoro e domini',
},
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 05645ccd..900b37dd 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -2450,7 +2450,7 @@ const translations: TranslationDeepObject<typeof en> = {
profileTrace: 'プロファイルトレース',
results: '結果',
testingPreferences: 'テスト設定',
- showExtraNavItems: '追加のナビゲーション項目を表示',
+ showExtraNavItems: '追加のナビ項目を表示',
server: 'サーバー',
servers: {
production: {label: '本番', description: '実際のユーザーが利用している環境'},
@@ -3673,10 +3673,10 @@ ${date} の ${merchant} への ${amount}`,
`未読のチャットや対応が必要なチャットだけを表示して、状況を常に把握できるようにしましょう。いつでも<a href="${priorityModePageUrl}">設定</a>で変更できます。`,
},
morePage: {
- accountingDescription: 'エクスポート、未払計上、明細、消込',
+ accountingDescription: 'エクスポート、発生主義、明細書と照合',
savedSearchesDescription: '保存した検索に戻る',
- insightsDescription: '支出の行き先を確認',
- workspacesDescription: 'ワークスペースとドメインを管理',
+ insightsDescription: '支出がどこに向かっているかを確認する',
+ workspacesDescription: 'ワークスペースとドメインを管理する',
},
inboxTabs: {
all: 'すべて',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index 1f1aa116..d656cbae 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -3715,8 +3715,8 @@ ${amount} voor ${merchant} - ${date}`,
`Blijf op de hoogte door alleen ongelezen chats of chats te zien die je aandacht nodig hebben. Geen zorgen, je kunt dit op elk moment wijzigen in de <a href="${priorityModePageUrl}">instellingen</a>.`,
},
morePage: {
- accountingDescription: 'Exports, overlopende posten, afschriften en reconciliatie',
- savedSearchesDescription: 'Ga terug naar een opgeslagen zoekopdracht',
+ accountingDescription: 'Exporten, overlopende posten, afschriften en afstemming',
+ savedSearchesDescription: 'Ga terug naar een zoekopdracht die je hebt opgeslagen',
insightsDescription: 'Zie waar je uitgaven naartoe gaan',
workspacesDescription: 'Beheer je werkruimtes en domeinen',
},
@@ -11126,10 +11126,10 @@ er bestedingsregels toe om de kasstroom van het bedrijf te beschermen.`,
tabs: {
expenseReports: 'Declaraties',
reports: 'Rapporten',
- allExpenses: 'Alle declaraties',
+ allExpenses: 'Alle uitgaven',
allReports: 'Alle rapporten',
myReports: 'Mijn rapporten',
- myExpenses: 'Mijn declaraties',
+ myExpenses: 'Mijn uitgaven',
expenses: 'Declaraties',
submit: 'Concepten',
approve: 'Moet worden goedgekeurd',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index 0f3bdbab..3e3a46f8 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -3751,10 +3751,10 @@ ${amount} dla ${merchant} - ${date}`,
`Bądź na bieżąco, widząc tylko nieprzeczytane czaty lub czaty wymagające twojej uwagi. Spokojnie, możesz to zmienić w dowolnym momencie w <a href="${priorityModePageUrl}">ustawieniach</a>.`,
},
morePage: {
- accountingDescription: 'Eksporty, rozliczenia międzyokresowe, wyciągi i uzgodnienia',
- savedSearchesDescription: 'Wróć do zapisanego wyszukiwania',
- insightsDescription: 'Zobacz, na co idą Twoje wydatki',
- workspacesDescription: 'Zarządzaj przestrzeniami roboczymi i domenami',
+ accountingDescription: 'Eksporty, rozliczenia memoriałowe, wyciągi i uzgadnianie',
+ savedSearchesDescription: 'Wróć do zapisanej wyszukiwarki',
+ insightsDescription: 'Zobacz, na co wydajesz',
+ workspacesDescription: 'Zarządzaj swoimi przestrzeniami roboczymi i domenami',
},
inboxTabs: {
all: 'Wszystko',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 568e136b..1aad7d6a 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -2470,7 +2470,7 @@ const translations: TranslationDeepObject<typeof en> = {
profileTrace: 'Rastreamento de perfil',
results: 'Resultados',
testingPreferences: 'Preferências de teste',
- showExtraNavItems: 'Mostrar itens de navegação extras',
+ showExtraNavItems: 'Mostrar itens extras de navegação',
server: 'Servidor',
servers: {
production: {label: 'Produção', description: 'O ambiente ativo que os usuários reais veem'},
@@ -3717,9 +3717,9 @@ ${amount} para ${merchant} - ${date}`,
`Fique no controle vendo apenas chats não lidos ou que precisam da sua atenção. Não se preocupe, você pode mudar isso a qualquer momento em <a href="${priorityModePageUrl}">configurações</a>.`,
},
morePage: {
- accountingDescription: 'Exportações, provisões, extratos e conciliação',
- savedSearchesDescription: 'Volte para uma busca que você salvou',
- insightsDescription: 'Veja para onde vão seus gastos',
+ accountingDescription: 'Exportações, provisões, extratos e conciliações',
+ savedSearchesDescription: 'Voltar para uma pesquisa que você salvou',
+ insightsDescription: 'Veja para onde vai o seu gasto',
workspacesDescription: 'Gerencie seus espaços de trabalho e domínios',
},
inboxTabs: {
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 8c34a34d..32250f7d 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -2377,7 +2377,7 @@ const translations: TranslationDeepObject<typeof en> = {
profileTrace: '性能追踪',
results: '结果',
testingPreferences: '测试偏好',
- showExtraNavItems: '显示额外的导航项',
+ showExtraNavItems: '显示更多导航项目',
server: '服务器',
servers: {
production: {label: '生产', description: '真实用户所使用的线上环境'},
@@ -3575,10 +3575,10 @@ ${amount},商户:${merchant} - 日期:${date}`,
prompt: (priorityModePageUrl: string) => `通过只查看未读聊天或需要你关注的聊天,随时掌握最新进展。别担心,你可以随时在<a href="${priorityModePageUrl}">设置</a>中更改此项。`,
},
morePage: {
- accountingDescription: '导出、应计、对账单和对账',
- savedSearchesDescription: '返回已保存的搜索',
- insightsDescription: '查看支出去向',
- workspacesDescription: '管理您的工作区和域',
+ accountingDescription: '导出、应计项目、报表和对账',
+ savedSearchesDescription: '返回到你保存的搜索',
+ insightsDescription: '查看您的支出流向',
+ workspacesDescription: '管理你的工作区和域',
},
inboxTabs: {
all: '全部',
@@ -10679,10 +10679,10 @@ ${reportName}`,
tabs: {
expenseReports: '报销报告',
reports: '报表',
- allExpenses: '所有报销费用',
+ allExpenses: '所有报销',
allReports: '所有报表',
myReports: '我的报表',
- myExpenses: '我的报销费用',
+ myExpenses: '我的报销',
expenses: '报销费用',
submit: '草稿',
approve: '待审批',
Note You can apply these changes to your branch by copying the patch to your clipboard, then running |
Explanation of Change
This builds on the flat navigation bar and adds a collapsing left bar on wide layouts. It is opened as a separate pull request so that the other one keeps its own test build to compare against.
This replaces the 72px skinny left bar on web and desktop with a 220px flat navigation bar, and reworks the narrow layout's bottom bar to match.
Wide layout
Every destination is a full-width row with a horizontal icon and label. The Spend pages no longer render a second left nav — their searches move into the main nav as child rows, so there is one navigation surface instead of two.
The nav lists Home, Inbox, Expenses, Reports, Accounting, Saved, Insights (behind the
insightsPagebeta) and Workspaces, then an account row with your avatar and name. Reports, Accounting and Saved reveal their searches as child rows only while that group is the active destination. A collapsed group carries its children's combined count as a badge; expanding it drops that badge so the children's own counts do not double-report the same work.At the top sit the Expensify wordmark and a small green create button that opens the global create menu.
Narrow layout
The bottom bar is Home, Inbox, Expenses, Reports and More. The Spend tab row shows only the group you are in — Reports shows its four searches, Accounting its five — and hides entirely for Expenses, which is a group of one. The page title names the group, so it holds still while you tab within it.
More opens a page of navigation rows: Accounting, Saved, Insights and Workspaces. Each row returns you to where you last were inside that destination rather than to its first page, and each of those pages gets a back arrow to the More list. Tapping More while you are inside one of its destinations climbs back to the list.
Collapsing the bar
A toggle in the bar's header narrows it from 220px to a 60px icon rail, and the central pane follows. Every row keeps its normal padding while collapsed, so the icons stay on the same column and none of them move as the bar animates; the labels, badges, group children and hover menus simply go away.
Hovering a collapsed bar peeks it back open over the content rather than pushing the page around, and moving the pointer away closes it again.
The collapsed state reuses the store the Spend sidebar already had,
SearchSidebarCollapseStore. That sidebar is the surface this navigation replaced, so sharing one persisted flag and one peek state avoids two that can disagree. The flat navigation bar adds its own width hooks alongside the existing ones.Three places assumed the bar was a fixed 220px and now read its live width: the navigator's own container, which is what slides the central pane;
DebugTabView's absolute positioning; andSearchRowSkeleton, which right-aligns against the left pane.Shared changes
navigationRowSelected(product-300) andnavigationRowHovered(product-200). They apply to the flat nav, the Inbox LHN, and the Workspace, Domain and Account editor menus. The editor menus opt in through a newshouldUseNavigationRowColorsprop onMenuItem, so popover and context menus that also usefocusedkeep their current colors.getSplitNavigatorSidebarWidthresolves the width from the navigator's sidebar route so the sidebar and the central pane offset always agree.Two fixes that reach beyond the new navigation
WORKSPACES_TAB_SETdid not listSCREENS.DOMAINS_LIST, so the Workspaces tab could not restore onto its Domains tab and always fell back to Workspaces. This is reproducible onmaintoday: open Workspaces, switch to Domains, leave the tab, and come back.SearchRowSkeletonpositioned its trailing elements against a left pane that included the Spend sidebar this PR removes, leaving a gap on the right of every skeleton row.Fixed Issues
$
PROPOSAL:
Tests
Wide layout
Narrow layout
Collapsing the bar
Failure and edge scenarios
insightsPagebeta. Verify no Insights row appears in either place, and that Account is still reachable from the top right.Offline tests
QA Steps
Same as tests.
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
🤖 Generated with Claude Code