Skip to content

fix(mobile): render full segmented-control option labels - #8522

Merged
iscekic merged 1 commit into
mainfrom
drain/segmented-control-label-wrap
Oct 22, 2026
Merged

iscekic merged 1 commit into
mainfrom
drain/segmented-control-label-wrap

Conversation

@iscekic

@iscekic iscekic commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Evidence

Evidence: partially demonstrated — the fixed rendering was observed on the Android emulator at the default display size and one density step up, and on the iOS simulator through the lane, where the Hindi period control shows 24 घंटे, 7 दिन and 30 दिन in full; the previous one-line clamp was observed through the component tests, which fail against the base version of the control.

What changed

apps/mobile/src/components/ui/segmented-control.tsx clamped every option label to one line with numberOfLines={1} and adjustsFontSizeToFit. The label sat in a content-sized Text inside a centre-aligned segment, so a label wider than its equal-width segment had no width constraint to shrink into and was cut at the segment edge with no ellipsis. The Hindi period option 7 दिन on the spend-alerts screen rendered as 7.

The shared control now:

  • leaves each label uncapped and unshrunk, so it always renders in full;
  • fills the segment width (justify-center without items-center), so a long label wraps inside the pill instead of overflowing it;
  • keeps every segment at the tallest height (the row's default stretch), so a wrapped choice never looks uneven next to a short one — the earlier complaint that motivated the single-line clamp;
  • adds py-2, so a one-line segment stays 44dp and a two-line segment gets balanced insets.

Every caller renders the same control, so the fix covers all of them: appearance switcher, New Session "Changes", MCP auth pickers, model catalog tabs, profile owner picker, part-detail text mode, spend alerts.

Tests now assert the invariant instead of the clamp: no line cap, no font shrink, no content-sized label box that would clip a long label.

No schema, API, or native change. JavaScript only; no new dev client is needed.

End-to-end evidence

Unit and component tests (apps/mobile):

  • vitest run src/components/ui/segmented-control.test.ts src/components/ui/segmented-control.mounted.test.tsx — 3 tests pass on the branch. With the base version of segmented-control.tsx planted back, all 3 fail (numberOfLines is 1), so the assertions cover the old defect.
  • Caller-adjacent suites (settings-screens-a11y, new-session-configure-form, part-detail-sheet, part-detail-images, chat/, profiles/, spend-alerts-screen, preferences-screen, organization/): 40 files, 468 tests pass.
  • oxlint on the changed files: 0 warnings, 0 errors. tsc --noEmit: clean.

Android (emulator omp36, API 36, local dev stack, app language Hindi, personal spend-alerts scope, owned fake account):

  • Open Profile → Preferences → Spend alerts, turn the alerts on, look at the अवधि selector under सीमा पार होना.
  • Default display size (density 420): 24 घंटे, 7 दिन, 30 दिन each render in full, all three on one line, same segment height.
  • One Display size step up (density 480): same three labels in full, still one line each.
  • uiautomator bounds confirm the label text fills its segment (stretched, not content-sized), and OCR of the captures reads all three labels whole.

iOS (simulator through the lane, cached branch dev client, same Hindi personal spend-alerts screen):

  • अवधि shows 24 घंटे, 7 दिन, 30 दिन in full, one line each, equal segment heights.

Limitation stated plainly: on this AVD and simulator image the pre-fix control happened to fit the three Hindi labels, so the device captures show the label shrinking/centring mechanism is gone and the full text renders, while the reported clip itself is proven by the failing-before component tests rather than by a device screenshot of the old code.

Screenshots

Attached in a follow-up comment: Android at the default display size, Android one Display size step up, and the iOS simulator, all on the same Hindi spend-alerts period control.

Proxy answers

The owner's proxy gave these answers in the owner's place.

  1. Question: Label fitting: The shared segmented control forces every label onto one shrunken line (numberOfLines=1 + adjustsFontSizeToFit). On Android RN 0.86 that combination also disables the ellipsis, so a label the autosize cannot fit is cut with no '…' — the reported "7" with the word gone. How should labels fit?
    Answer: Allow two lines, no autosize
    Confidence: 0.75 · Precedent: UX and design quality: best-in-class, consistent elements, no silent cuts; the brief asks segments to "fit their content or wrap"
  2. Question: Blast radius: The control is shared by 8 callers (appearance switcher, New Session "Changes" control, MCP auth pickers, model catalog tabs, profile owner picker, part-detail text mode, spend alerts). Applying two-line labels to all of them lets "Commit and push" wrap again at narrow widths — the earlier explorer complaint was that a wrapped option looked uneven. Equal-height segments remove the unevenness. Scope?
    Answer: Fix shared control for every caller
    Confidence: 0.85 · Precedent: Fix the root cause and the class — "fix this for all shared services model pickers on all surfaces"
  3. Question: iOS proof: The change alters text truncation and line breaks, which the session rules treat as iOS-specific. Verify it on the iOS simulator through the ios_lane tool as well as on Android?
    Answer: Yes, lease the iOS lane
    Confidence: 0.70 · Precedent: Verify on both iOS and Android — "Both iOS and Android need to be verified"; the iOS lane opens when the agent asks
  4. Question: Line cap: two lines fixes the reported Hindi case, but an English label like "Commit and push" in a third-width segment needs a third line at a large display size / font scale. What should the shared control do past two lines?
    Answer: No cap: wrap as far as needed
    Confidence: 0.45 · Precedent: UX and design quality: fix the whole class of each defect; the brief asks for full labels that fit or wrap, and an ellipsis would still cut the label at large scale.
  5. Question: Padding: today the segment is min-h-11 (44dp) with the label centered, so a two-line label sits 2dp from the edges. Add vertical padding so two-line segments get balanced insets while single-line segments stay 44dp?
    Answer: Add py-2 (44dp single line, 56dp two lines)
    Confidence: 0.75 · Precedent: UX and design quality: consistent, right-sized padding and vertically centered text.
  6. Question: Proof scope: The period control is shared and the report steps go Profile → organization hub → Spend alerts (org scope). The same control and the same three Hindi labels render in the personal scope (Profile → Preferences → spend-alert row), which needs no organization fixture. Which surface do I prove on the emulator?
    Answer: Personal scope only
    Confidence: 0.60 · Precedent: Do the least work possible with no drop in quality; the fix is in the shared control, which renders the same labels and widths in personal scope.
  7. Question: Large size: Android has two independent knobs: font scale and display density (Settings "Display size"). Which do I capture?
    Answer: Density step only
    Confidence: 0.55 · Precedent: Never change font scaling — always use the default; the brief's "large display size" maps to Android's Display size, which is the density setting.

The shared segmented control clamped every option to a single line and let
the platform shrink the font. The label sat in a content-sized Text inside a
centre-aligned segment, so when a label was wider than its equal-width
segment the shrink found no width to fit into and the text was cut at the
segment edge with no ellipsis. Hindi "7 दिन" in the spend-alert period
control showed up as "7".

The label now fills the segment width and wraps onto as many lines as it
needs, and the row keeps every segment at the tallest height so a wrapped
choice never looks uneven. Segments gain vertical padding so two-line labels
keep balanced insets.

Tests cover the invariant instead of the old clamp: no line cap, no font
shrink, and no content-sized label box.
@iscekic iscekic added drain Work item from the findings drain explorer:android Finding surfaced by the Android explorer labels Oct 22, 2026
@kilo-code-bot

kilo-code-bot Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The shared segmented control now lets each option label stretch to its segment width and wrap without a line cap or font shrink, with py-2 keeping vertical insets; both unit and mounted tests assert the new invariant, and every caller I checked sits in a flexible container so the taller two-line row cannot be clipped.

Assumptions: [INFERENCE] I did not run the test suites or verify device rendering (read-only review); the claim that the row's default alignItems: stretch equalizes segment heights and that Android's adjustsFontSizeToFit combo suppressed the ellipsis is taken from the RN behavior described in the PR rather than measured here.

Files Reviewed (3 files)
  • apps/mobile/src/components/ui/segmented-control.tsx
  • apps/mobile/src/components/ui/segmented-control.test.ts
  • apps/mobile/src/components/ui/segmented-control.mounted.test.tsx

No memory-leak surface was introduced: the change only edits class names, removes two text props, and rewrites test assertions, with no new effects, listeners, timers, or subscriptions. No markdown documentation files are touched.


Reviewed by deepseek-flash-latest · Input: 50.6K · Output: 6.3K · Cached: 329.5K

Review guidance: REVIEW.md from base branch main

@iscekic

iscekic commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Spend-alerts period control in Hindi on the branch, personal scope, owned fake account on the local dev stack.

  • Android emulator, default display size: the अवधि selector renders 24 घंटे, 7 दिन and 30 दिन in full, one line each, equal segment heights.
  • Android emulator, one Display size step up: the same three labels stay whole.
  • iOS simulator through the lane, same screen: all three labels in full.

The control no longer clamps a label to one shrunken line; a label that does not fit its segment wraps inside it instead of being cut.

Android period selector with full Hindi option labels at the default display size

Android period selector with full Hindi option labels one display size step up

iOS simulator period selector with full Hindi option labels

@iscekic iscekic added the merge:bot Bot-owned review; merge when ready once readiness passes and a review approves. label Oct 22, 2026
@iscekic
iscekic enabled auto-merge October 22, 2026 02:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

drain Work item from the findings drain explorer:android Finding surfaced by the Android explorer merge:bot Bot-owned review; merge when ready once readiness passes and a review approves.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants