Fix Inbox filter tabs overlapping for long labels#95381
Conversation
|
@ahmedGaber93 Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
| const styles = useThemeStyles(); | ||
| return ( | ||
| <View style={{maxWidth: variables.tabSelectorMaxTabLabelWidth}}> | ||
| <View style={{maxWidth: variables.tabSelectorMaxTabLabelWidth, flexShrink: 1, minWidth: 0}}> |
There was a problem hiding this comment.
❌ UI-3 (docs)
This line passes an inline style object literal (style={{maxWidth: variables.tabSelectorMaxTabLabelWidth, flexShrink: 1, minWidth: 0}}) to a style-typed prop. Per STYLING.md, inline style objects are not allowed: they allocate a new object on every render (defeating memoization) and duplicate values that belong in the shared style system. This change compounds the issue by adding two more static values (flexShrink: 1, minWidth: 0) inline.
Move these static values into the shared styles object (e.g. a styles.tabSelectorLabelContainer entry combining maxWidth, flexShrink: 1, minWidth: 0) and reference it:
<View style={styles.tabSelectorLabelContainer}>Define the style once in src/styles/index.ts rather than inline in JSX.
Reviewed at: dbe1d9d | Please rate this suggestion with 👍 or 👎 to help us improve! Reactions are used to monitor reviewer efficiency.
There was a problem hiding this comment.
👍 Moved to shared styles
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
|
Can we see a video recording for when the tabs have the counter badges? Thanks! |
|
The badge counter is visible in the video recorded on macOS Safari. Have you had a chance to watch that video? |
|
Ah sorry I missed that, thanks! Let's get this into final review. |
|
@Abdulloh0109 The implemented fix isn't the approach we agreed to move forward with. Please take another look at the discussion here: #93975 (comment) Also please update the OP with all the required data
|
Per the design decision on Expensify#93975, the Inbox filter tabs should be content-sized and scroll horizontally (like Spend) instead of being squeezed into equal thirds. Dropping the equalWidth prop lets long-word locales (e.g. Polish) show full labels without overlap, and TabSelectorBase's existing horizontal ScrollView + 20px content padding handle the scroll and right margin.
ea8df06 to
9e0aab4
Compare
|
@ahmedGaber93 Could you please review the changes again? |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.2026-07-15.at.1.25.00.PM.movAndroid: mWeb ChromeScreen.Recording.2026-07-15.at.1.27.08.PM.moviOS: HybridAppScreen.Recording.2026-07-15.at.12.54.57.PM.moviOS: mWeb SafariScreen.Recording.2026-07-15.at.11.26.48.AM.movMacOS: Chrome / SafariScreen.Recording.2026-07-15.at.11.22.45.AM.movScreen.Recording.2026-07-15.at.11.23.45.AM.mov |
|
@shawnborton Here's the final result if you'd like to take a look. Screenshots/VideosAndroid: HybridAppScreen.Recording.2026-07-15.at.1.25.00.PM.movAndroid: mWeb ChromeScreen.Recording.2026-07-15.at.1.27.08.PM.moviOS: HybridAppScreen.Recording.2026-07-15.at.12.54.57.PM.moviOS: mWeb SafariScreen.Recording.2026-07-15.at.11.26.48.AM.movMacOS: Chrome / SafariScreen.Recording.2026-07-15.at.11.22.45.AM.movScreen.Recording.2026-07-15.at.11.23.45.AM.mov |
|
@Julesssss It's been a long time. Could we please merge this PR? |
|
@Abdulloh0109 could you please fix the git conflict? |
…-label-overflow # Conflicts: # src/pages/inbox/sidebar/InboxTabSelector.tsx
|
@ahmedGaber93 done |


In equalWidth mode each tab is constrained to a third of the row, but the TabLabel container only had a fixed maxWidth with no flexShrink/minWidth, so long-word locales (e.g. Polish) overflowed the pill into the neighbouring tab and the selection background stopped short of the label. Letting the label container shrink lets the existing numberOfLines={1} truncate within its tab.
Explanation of Change
The Inbox filter tabs (All / Unread / To-dos) were rendered with
equalWidth, which forces each tab into a third of the narrow LHN width. In long-word locales (e.g. Polish —Nieprzeczytane,Zadania do wykonania) the labels overflowed their third, overlapped the neighbouring tab, and the selected-tab pill didn't cover the full label.Per the design decision on the issue, the tab bar should be content-sized and scroll horizontally (like Spend) instead of being squeezed into equal thirds. This PR removes the
equalWidthprop fromInboxTabSelector, so each tab sizes to its label and the row scrolls horizontally when labels overflow — no truncation.TabSelectorBasealready wraps the tabs in a horizontalScrollView, and its content container's existingpaddingHorizontal: 20provides the 20px right margin when scrolled to the end.Fixed Issues
$ #93975
PROPOSAL: #93975 (comment)
Tests
Wszystko/Nieprzeczytane/Zadania do wykonania— each show their full label and do not overlap each other.TabSelectorBase(e.g. the narrow Search type menu) and verify it still renders correctly — no regression.Offline tests
The tab layout and filtering are entirely client-side (no API). Go offline, switch between All / Unread / To-dos in Polski, and verify the tabs still render, scroll, and don't overlap.
QA Steps
Same as tests.
Offline tests
QA Steps
// TODO: These must be filled out, or the issue title must include "[No QA]."
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)Avatar, 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
Windows: Chrome
78f6ee4f-3e87-4f63-96ac-fcf635b0286a.mp4
Android: App
REC-20260714141928.mp4
IOS: App
REC-20260714141549.mp4