Skip to content

fix(mobile): stop bottom-nav labels breaking mid-word - #6464

Merged
iscekic merged 4 commits into
mainfrom
kwf/explorer-app-updates-the-bottom-nav-labels-break-mid-word-f8f9d-dcd1
Sep 22, 2026
Merged

iscekic merged 4 commits into
mainfrom
kwf/explorer-app-updates-the-bottom-nav-labels-break-mid-word-f8f9d-dcd1

Conversation

@iscekic

@iscekic iscekic commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

Changelog for users

  • The bottom navigation no longer breaks tab labels into mid-word fragments on narrow screens.
  • On a 160dp-wide window the tab bar shows icons only, so no label is clipped or split.
  • Labels return in full on wider windows, such as 360dp.
  • The icon-only bar still announces each tab's name and position to screen readers.
  • Tapping an icon in the icon-only bar opens that screen on the first tap.

Changelog for maintainers

  • apps/mobile/src/lib/tab-bar-layout.ts:164 — accepted: the renderer breaks a label only on an explicit \n (apps/mobile/src/components/tab-bar-label.tsx:21), so tabLabelWidth now splits on \n instead of /\s+/ and measures a space-separated label as its one rendered line; the unit tests cover the space case.
  • Tab-label visibility now also depends on the window width: if any label is wider than its tab, all labels are hidden.
  • The bar-height calculation accepts the label decision, so the compact height and the content clearance stay in step.
  • Label width is estimated from the label style: 11px at 0.6em per glyph plus 0.2px tracking, minus 10dp of tab-item padding.
  • CJK, Kana, Hangul and fullwidth glyphs count as one em; the class over-estimates, so labels hide early rather than render clipped.
  • The width rule cannot override the existing font-scale rule.
  • No dependency or configuration changes; keep the mirrored label metrics in step when the tab label style changes.
  • Review hint: the earlier "not proved live" claims for the 160dp icon-only bar, the 160→360dp resize and a long-label locale are replaced by the captures kept below (e4, e7 and e8, with e6 for TalkBack), re-verified on the Android emulators on 2026-09-22; the space-separated label-fit check at a set window width is skipped, pending owner verification, because it needs a display-size/density override and no harness verb provides one (papercut obstacle:device-display-size).

E2E proof

happy - default phone geometry: the bottom nav still shows its three labelled tabs with every word intact (the label-fit rule must not drop labels where they fit) — e1.png

[e1] ux-check: At 480x1000 px / density 480 (160dp) in dark mode, open the app to kiloapp://home with the bottom nav visible: no tab label text renders at all and no label is split across two lines (no… — e2e-mobile-app/e1.png

[e2] ux-check: Resizing/rotating from 160dp to 360dp makes the one-line labels appear without overlapping the bar background or the content above, and no label row is left blank. — e2e-mobile-app/e2.png

e2

edge - supported small phone 320x640 @ 160dpi (320dp wide): the labels stay visible and unbroken, proving the width rule does not drop them where they fit.320x640@160 - set it with `adb shell wm size… — e3.png

[e3] edge - supported small phone 320x640 @ 160dpi (320dp wide): the labels stay visible and unbroken, proving the width rule does not drop them where they fit.320x640@160 - set it with `adb shell wm size… — scripted-shard2/e3.png

[e4] ux-check: 480x1000 @ 480dpi (160dp), dark, kiloapp://home — icons only, no split label — e4.png

ux-check: On the 160dp icon-only bar, tapping each icon navigates to the matching screen on the first tap and the focused icon is tinted with the foreground token. — e5-agents-160dp.png

[e5] ux-check: On the 160dp icon-only bar, tapping each icon navigates to the matching screen on the first tap and the focused icon is tinted with the foreground token. — prior/e5-profile-160dp.png

e5-home-160dp

[e6] ux-check - TalkBack on the 160dp icon-only bar announces each tab's name and position — prior/e6-talkback.png

[e7] ux-check: resizing from 160dp to 360dp shows one-line labels without overlap and no blank label row — e7-narrow160.png

[e8] ux-check: long-label locale (Italian) on a 360dp phone — one-line labels or icons only — e8.png

Owner request

Explorer finding: app-updates: The bottom-nav labels break mid-word into two lines ('Upda tes', 'Settin gs', 'Hom e'), so the primary navigation text does not fit its tab.

The user-agent explorer found this while using the app like a user.
One finding per item; the explorer never edits product code.

Flow: app-updates
Found on revision: f2181ae

Repro:

  1. set this state first: uimode night; battery 9 discharging; size 480x1000; density 480; relaunch; back; deeplink kiloapp://home; the device in dark mode
  2. open the app on emulator-5554
  3. reach app-updates
  4. the capture shows the defect named below

Observed: The bottom-nav labels break mid-word into two lines ('Upda tes', 'Settin gs', 'Hom e'), so the primary navigation text does not fit its tab.
Expected: the screen renders without this defect

Evidence (from the device run):

E2E proof — log excerpts

[e1] ux-check: At 480x1000 px / density 480 (160dp) in dark mode, open the app t -> pass :: android emulator-5554: setup confirms 'size: Physical size: 1080x2400 Override size: 480x1000' and 'night mode: Night mode: yes' (e1-dark-confirm.log), then kiloapp://home; e1-live.log shows 'SCENE e1 OK' with root 'android.widget.LinearLayout com.kilocode.kiloapp:id/action_bar_root tappable [0,0][480,1000]' and the bar carrying only three content-desc View nodes — 'android.view.View Home, tab, 1 of 3 tappable [0,766][160,928]' and 'android.view.View Profile, tab, 3 of 3 tappable [320,766][480,928]' — with 0 label TextViews in the live tree e1-scene.xml, and the icon geometry ('bounds="[48,790][114,856]"' in e2-iconforward.txt) is identical to the pre-existing icon-forward state, so no new b
[e2] ux-check: Resizing/rotating from 160dp to 360dp makes the one-line labels a -> pass :: android emulator-5554: resize to 360dp ('Physical size: 1080x2400' with 'Override density: 480', e2-wide-setup.log) then home+relaunch; e2-live.log shows 'SCENE e2 OK' with 'android.view.View Home, tab, 1 of 3 tappable [0,2166][360,2328]' and one label per tab — 'android.widget.TextView HOME tappable [15,2265][345,2309]', 'android.widget.TextView AGENTS tappable [375,2265][705,2309]', 'android.widget.TextView PROFILE tappable [735,2265][1065,2309]' — each 44 px tall (single line) inside its tab item, the content above ends at 'bounds="[195,1519][933,1561]"' (e2-scene.xml), clear of the bar top 2166, and all three tabs carry a label (no blank row); screenshot e2.png for the visual reviewer; n

Comment thread apps/mobile/src/lib/tab-bar-layout.ts
@kilo-code-bot

kilo-code-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

This incremental pass covers comment-only test edits plus the removal of the duplicated AppState/Keyboard/Platform keys the previous review flagged; the product code is unchanged at this HEAD and no new defects were found on the changed lines.

Files Reviewed (4 files)
  • apps/mobile/plugins/branded-splash.test.ts - no issues
  • apps/mobile/src/components/agents/new-session-configure-form.test.ts - no issues (comment rewrite only)
  • apps/mobile/src/components/code-reviewer/manual-review-screen.mounted.test.tsx - no issues (previous duplicate-key WARNING resolved)
  • apps/mobile/src/components/profile-screen.signout.mounted.test.tsx - no issues (comment-only)
Previous Review Summaries (6 snapshots, latest commit 2404584)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 2404584)

Status: 2 Issues Found | Recommendation: Address before merge

Executive Summary

The width rule now measures the same single line the renderer paints and the tab screens share the layout's label decision, but a duplicated key block in a mounted-test mock fails no-dupe-keys/TS1117 lint and typecheck.

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 1
Issue Details (click to expand)

WARNING

File Line Issue
apps/mobile/src/components/code-reviewer/manual-review-screen.mounted.test.tsx 35 The added AppState/Keyboard/Platform keys duplicate lines 38-40; the later keys win, and repeated property names fail no-dupe-keys/TS1117.

SUGGESTION

File Line Issue
apps/mobile/src/components/app-root-providers.tsx 151 The toast bottom offset still calls getEffectiveTabBarHeight without the width-based label decision, so on narrow windows it reserves the label-inclusive height while the bar renders compact. Unchanged file - no inline target.
Files Reviewed (21 files)
  • apps/mobile/plugins/branded-splash.test.ts
  • apps/mobile/src/app/(app)/(tabs)/_layout.tsx
  • apps/mobile/src/app/(app)/agent-chat/[session-id].mounted.test.tsx
  • apps/mobile/src/components/account-settings-screen.arabic.mounted.test.tsx
  • apps/mobile/src/components/agents/new-session-configure-form.test.ts
  • apps/mobile/src/components/agents/session-detail-content.test.ts
  • apps/mobile/src/components/agents/session-list-content.tsx
  • apps/mobile/src/components/agents/session-list-screen.tsx
  • apps/mobile/src/components/agents/session-list-search-header.mounted.test.tsx
  • apps/mobile/src/components/agents/session-list-search-header.tsx
  • apps/mobile/src/components/code-reviewer/manual-review-screen.mounted.test.tsx - 1 issue
  • apps/mobile/src/components/kilo-chat/conversation-list-screen.tsx
  • apps/mobile/src/components/profile-screen.signout.mounted.test.tsx
  • apps/mobile/src/components/screen-header.mounted.test.tsx
  • apps/mobile/src/components/screen-header.tsx
  • apps/mobile/src/components/security-agent/finding-detail-screen.mounted.test.tsx
  • apps/mobile/src/components/tab-screen.mounted.test.tsx
  • apps/mobile/src/components/tab-screen.tsx
  • apps/mobile/src/lib/tab-bar-clearance.ts
  • apps/mobile/src/lib/tab-bar-layout.test.ts
  • apps/mobile/src/lib/tab-bar-layout.ts

Fix these issues in Kilo Cloud

Previous review (commit b7c2dc2)

Status: 2 Issues Found | Recommendation: Address before merge

Executive Summary

tabLabelWidth measures the widest whitespace-separated token instead of the single line the renderer paints, so multi-word tab labels in several locales can be kept and then truncated; a separate clearance caller (the toast offset) is not width-aware.

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 1
Issue Details (click to expand)

WARNING

File Line Issue
apps/mobile/src/lib/tab-bar-layout.ts 164 tabLabelWidth splits on /\s+/ while a label without \n renders on one line, so space-separated labels (so Bogga shakhsiga, fr Agents IA, vi Trò chuyện) are under-measured and kept even though they overflow and truncate. Split on \n to match tabLabelNumberOfLines.

SUGGESTION

File Line Issue
apps/mobile/src/components/app-root-providers.tsx 151 The toast bottom offset calls getEffectiveTabBarHeight without the new width-aware label decision, so on narrow windows it reserves the label-inclusive height while the bar renders compact. Unchanged file - no inline target.
Files Reviewed (21 files)
  • apps/mobile/plugins/branded-splash.test.ts
  • apps/mobile/src/app/(app)/(tabs)/_layout.tsx
  • apps/mobile/src/app/(app)/agent-chat/[session-id].mounted.test.tsx
  • apps/mobile/src/components/account-settings-screen.arabic.mounted.test.tsx
  • apps/mobile/src/components/agents/new-session-configure-form.test.ts
  • apps/mobile/src/components/agents/session-detail-content.test.ts
  • apps/mobile/src/components/agents/session-list-content.tsx
  • apps/mobile/src/components/agents/session-list-screen.tsx
  • apps/mobile/src/components/agents/session-list-search-header.mounted.test.tsx
  • apps/mobile/src/components/agents/session-list-search-header.tsx
  • apps/mobile/src/components/code-reviewer/manual-review-screen.mounted.test.tsx
  • apps/mobile/src/components/kilo-chat/conversation-list-screen.tsx
  • apps/mobile/src/components/profile-screen.signout.mounted.test.tsx
  • apps/mobile/src/components/screen-header.mounted.test.tsx
  • apps/mobile/src/components/screen-header.tsx
  • apps/mobile/src/components/security-agent/finding-detail-screen.mounted.test.tsx
  • apps/mobile/src/components/tab-screen.mounted.test.tsx
  • apps/mobile/src/components/tab-screen.tsx
  • apps/mobile/src/lib/tab-bar-clearance.ts
  • apps/mobile/src/lib/tab-bar-layout.test.ts
  • apps/mobile/src/lib/tab-bar-layout.ts

Fix these issues in Kilo Cloud

Previous review (commit e81af0b)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental commit only hardens a splash test and adds mirrored-metric parity tests plus the corrected comment; the previously reported stale TabLabel reference is resolved at this HEAD and no new defects were found on the changed lines.

Files Reviewed (3 files)
  • apps/mobile/plugins/branded-splash.test.ts - no issues
  • apps/mobile/src/lib/tab-bar-layout.test.ts - no issues
  • apps/mobile/src/lib/tab-bar-layout.ts - no issues (previous mirrored-metrics pointer finding resolved: the comment and tabLabelWidth doc now name TabBarLabel and the new parity test guards the 11px/0.2px metrics)

Previous review (commit f00fa61)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
apps/mobile/src/lib/tab-bar-layout.ts 20 The mirrored-label-metrics comment points at a nonexistent TabLabel component in _layout.tsx; the style lives in TabBarLabel at components/tab-bar-label.tsx, and that component does not wrap at whitespace (numberOfLines is 1 for normal labels, 2 only for the pre-wrapped copy).
Files Reviewed (22 files)
  • apps/mobile/src/app/(app)/(tabs)/_layout.tsx - no issues
  • apps/mobile/src/app/(app)/agent-chat/[session-id].mounted.test.tsx - no issues
  • apps/mobile/src/components/account-settings-screen.arabic.mounted.test.tsx - no issues
  • apps/mobile/src/components/agents/new-session-configure-form.test.ts - no issues
  • apps/mobile/src/components/agents/session-detail-content.test.ts - no issues
  • apps/mobile/src/components/agents/session-list-content.tsx - no issues
  • apps/mobile/src/components/agents/session-list-screen.tsx - no issues
  • apps/mobile/src/components/agents/session-list-search-header.mounted.test.tsx - no issues
  • apps/mobile/src/components/agents/session-list-search-header.tsx - no issues
  • apps/mobile/src/components/code-reviewer/manual-review-screen.mounted.test.tsx - no issues
  • apps/mobile/src/components/kilo-chat/conversation-list-screen.tsx - no issues
  • apps/mobile/src/components/profile-screen.signout.mounted.test.tsx - no issues
  • apps/mobile/src/components/screen-header.mounted.test.tsx - no issues
  • apps/mobile/src/components/screen-header.tsx - no issues
  • apps/mobile/src/components/security-agent/finding-detail-screen.mounted.test.tsx - no issues
  • apps/mobile/src/components/tab-screen.mounted.test.tsx - no issues
  • apps/mobile/src/components/tab-screen.tsx - no issues
  • apps/mobile/src/components/ui/segmented-control.tsx - no issues
  • apps/mobile/src/components/ui/text.rtl-tracking.mounted.test.tsx - no issues
  • apps/mobile/src/lib/tab-bar-clearance.ts - no issues
  • apps/mobile/src/lib/tab-bar-layout.test.ts - no issues
  • apps/mobile/src/lib/tab-bar-layout.ts - 1 issue

Fix these issues in Kilo Cloud

Previous review (commit 9ffe127)

Status: No Issues Found | Recommendation: Merge

The previously reported content-clearance gap is resolved at this HEAD: apps/mobile/src/lib/tab-bar-clearance.ts publishes the tabs layout's width-aware label decision through TabBarLabelContext, and all four clearance callers now route through useEffectiveTabBarHeight. The rest of the changed code (width-based label fit, header action reflow, single-line search field) showed no new defects.

Files Reviewed (17 files)
  • apps/mobile/src/app/(app)/(tabs)/_layout.tsx
  • apps/mobile/src/app/(app)/agent-chat/[session-id].mounted.test.tsx
  • apps/mobile/src/components/account-settings-screen.arabic.mounted.test.tsx
  • apps/mobile/src/components/agents/session-detail-content.test.ts
  • apps/mobile/src/components/agents/session-list-content.tsx
  • apps/mobile/src/components/agents/session-list-screen.tsx
  • apps/mobile/src/components/agents/session-list-search-header.mounted.test.tsx
  • apps/mobile/src/components/agents/session-list-search-header.tsx
  • apps/mobile/src/components/kilo-chat/conversation-list-screen.tsx
  • apps/mobile/src/components/screen-header.mounted.test.tsx
  • apps/mobile/src/components/screen-header.tsx
  • apps/mobile/src/components/security-agent/finding-detail-screen.mounted.test.tsx
  • apps/mobile/src/components/tab-screen.mounted.test.tsx
  • apps/mobile/src/components/tab-screen.tsx
  • apps/mobile/src/lib/tab-bar-clearance.ts
  • apps/mobile/src/lib/tab-bar-layout.test.ts
  • apps/mobile/src/lib/tab-bar-layout.ts

Previous review (commit 47cc12a)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The mobile tab-label fit change is well-tested, but the width-based label decision is only threaded into the tab bar itself, so the content-clearance callers of getEffectiveTabBarHeight can reserve a taller bar than is rendered on narrow windows with an enlarged font scale.

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
apps/mobile/src/lib/tab-bar-layout.ts 85 showLabel defaults to the font-scale-only decision, so the four content-clearance callers still reserve the taller overlay height when the width rule hides labels.
Files Reviewed (3 files)
  • apps/mobile/src/app/(app)/(tabs)/_layout.tsx - no issues (label strings hoisted and the width decision is passed to the bar)
  • apps/mobile/src/lib/tab-bar-layout.ts - 1 issue
  • apps/mobile/src/lib/tab-bar-layout.test.ts - no issues (all new expectations match the implementation; no memory leaks or subscription changes in this diff)

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

@iscekic
iscekic marked this pull request as draft September 21, 2026 07:39
@iscekic
iscekic force-pushed the kwf/explorer-app-updates-the-bottom-nav-labels-break-mid-word-f8f9d-dcd1 branch from 2bd16a1 to 9ffe127 Compare September 21, 2026 12:19
@iscekic
iscekic marked this pull request as ready for review September 21, 2026 12:40
@iscekic

iscekic commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator Author

This description names a scenario the proof did not capture:

  • not proved live: edge - reported state 480x1000 @ 480dpi (160dp wide, dark): the bar drops the visible labels and renders icon-forward, so no nav label is split across two lines.480x1000@480 - before the run set the display with adb shell wm size 480x1000 and adb shell wm density 480, then relaunch; restore with wm size reset and wm density reset (no capture cited it)

A repeated proof run rebuilds the same evidence, so no proof run is dispatched for a named gap. Merging with this gap open is your decision.

@iscekic
iscekic requested a review from eshurakov September 21, 2026 13:03
@iscekic iscekic added the human-ready The PR is ready for human review. label Sep 21, 2026
@iscekic
iscekic requested a review from pandemicsyn September 21, 2026 13:03
@iscekic iscekic self-assigned this Sep 21, 2026
@iscekic
iscekic force-pushed the kwf/explorer-app-updates-the-bottom-nav-labels-break-mid-word-f8f9d-dcd1 branch from c297341 to f00fa61 Compare September 22, 2026 03:36
Comment thread apps/mobile/src/lib/tab-bar-layout.ts Outdated
@iscekic
iscekic force-pushed the kwf/explorer-app-updates-the-bottom-nav-labels-break-mid-word-f8f9d-dcd1 branch from 574f5f3 to b7c2dc2 Compare September 22, 2026 15:25
Comment thread apps/mobile/src/lib/tab-bar-layout.ts Outdated
@iscekic
iscekic force-pushed the kwf/explorer-app-updates-the-bottom-nav-labels-break-mid-word-f8f9d-dcd1 branch from 0b78318 to 2404584 Compare September 22, 2026 16:28
Comment thread apps/mobile/src/components/code-reviewer/manual-review-screen.mounted.test.tsx Outdated
@iscekic
iscekic force-pushed the kwf/explorer-app-updates-the-bottom-nav-labels-break-mid-word-f8f9d-dcd1 branch from 06aba80 to f316d34 Compare September 22, 2026 17:09
…tom-nav-labels-break-mid-word-f8f9d-dcd1' into HEAD

# Conflicts:
#	apps/mobile/src/components/profile-screen.signout.mounted.test.tsx
@iscekic
iscekic merged commit abce818 into main Sep 22, 2026
28 checks passed
@iscekic
iscekic deleted the kwf/explorer-app-updates-the-bottom-nav-labels-break-mid-word-f8f9d-dcd1 branch September 22, 2026 17:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

human-ready The PR is ready for human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants