Skip to content

Make Concierge suggested followup buttons wrap horizontally - #94923

Draft
MelvinBot wants to merge 3 commits into
mainfrom
claude-conciergeFollowupsHorizontalWrap
Draft

Make Concierge suggested followup buttons wrap horizontally#94923
MelvinBot wants to merge 3 commits into
mainfrom
claude-conciergeFollowupsHorizontalWrap

Conversation

@MelvinBot

Copy link
Copy Markdown
Contributor

Explanation of Change

Currently the Concierge AI suggested followup (suggested response) buttons are stacked vertically, one per line, taking up a lot of vertical space.

This change makes those buttons "float" in a wrapping horizontal layout, as agreed in the issue discussion:

  • Buttons sit side-by-side on the same line with an 8px horizontal gap.
  • When there isn't enough width, buttons wrap to the next line, all aligned to the left, with an 8px vertical gap between rows.

How it works:

  • ActionableItemButtons.tsx: the horizontal layout now applies flexWrap in addition to flexRow, so buttons wrap instead of overflowing. The existing gap2 (8px) style already applies to both axes in React Native, giving the 8px horizontal and vertical gaps. Left alignment is the flexbox default (justifyContent: flex-start).
  • ChatActionableButtons.tsx: suggested followups now use the horizontal layout. The layout decision was changed from isPhrasalConciergeOptions to isConciergeOptions, so numbered Concierge category/description option lists stay vertical while only the suggested followups switch to the new wrapping layout. The pill styling/text props remain tied to isPhrasalConciergeOptions, so the followup buttons keep their chip appearance.
  • FollowupListSkeleton.tsx: the loading skeleton now matches the new wrapping horizontal layout.

This is purely a presentation/styling change — the underlying suggestion data model is unchanged.

Fixed Issues

$ #92441
PROPOSAL: #92441 (comment)

Tests

// TODO: The human co-author must fill out the tests you ran before marking this PR as "ready for review".
// Please describe what tests you performed that validate your changes worked.

  1. Open a Concierge AI chat that returns suggested followup buttons.
  2. Verify the suggested followup buttons display horizontally on the same line with an 8px gap between them.
  3. Narrow the window (or use a small/mobile viewport) and verify the buttons wrap to the next line, left-aligned, with an 8px vertical gap between rows.
  4. Verify numbered Concierge category/description option lists still display vertically (unchanged).
  • Verify that no errors appear in the JS console

Offline tests

Same as Tests.

QA Steps

// TODO: The human co-author must fill out the QA tests you ran before marking this PR as "ready for review".

  1. Open a Concierge AI chat that returns suggested followup buttons.
  2. Verify the suggested followup buttons display horizontally on the same line with an 8px gap between them.
  3. Resize to a narrow/mobile viewport and verify the buttons wrap to the next line, left-aligned, with an 8px vertical gap between rows.
  • Verify that no errors appear in the JS console

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

Screenshots/Videos

Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari

Co-authored-by: Shawn Borton <shawnborton@users.noreply.github.com>
@MelvinBot
MelvinBot requested a review from a team June 30, 2026 03:06
@github-actions

Copy link
Copy Markdown
Contributor

🚧 shawnborton has triggered a test Expensify/App build. You can view the workflow run here.

@github-actions

This comment has been minimized.

@shawnborton

Copy link
Copy Markdown
Contributor

@MelvinBot we should still allow the buttons to wrap to multiple lines if they are wider than the viewport, like main currently does. The rest of the changes look good though.

Co-authored-by: Shawn Borton <shawnborton@users.noreply.github.com>
@MelvinBot

Copy link
Copy Markdown
Contributor Author

Done — pushed 91ecb56.

The horizontal wrapping layout let buttons wrap to new lines, but a single button wider than the viewport would still overflow off-screen, because React Native flex items default to flexShrink: 0 (unlike main's vertical layout, where each button could wrap its text). I added flexShrink1 + mw100 to the button wrapper, but only in the horizontal layout, so an over-wide button now shrinks to the viewport width and wraps its text to multiple lines — matching main's behavior — while normal-width buttons still sit side-by-side and wrap row-to-row.

ActionableItemButtons.tsx:41-42

Ran prettier, lint-changed, and typecheck-tsgo — all clean. Worth a quick visual check on a narrow viewport with a long suggested-followup label to confirm the wrap looks right.

@github-actions

Copy link
Copy Markdown
Contributor

🚧 shawnborton has triggered a test Expensify/App build. You can view the workflow run here.

@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🚧 shawnborton has triggered a test Expensify/App build. You can view the workflow run here.

@github-actions

This comment has been minimized.

@shawnborton

Copy link
Copy Markdown
Contributor

@MelvinBot this still isn't working as expected. I need button labels to break to multiple lines when the button is wider than the viewport width.

Co-authored-by: Shawn Borton <shawnborton@users.noreply.github.com>
@codecov

codecov Bot commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ Changes either increased or maintained existing code coverage, great job!

Files with missing lines Coverage Δ
...ponents/ReportActionItem/ActionableItemButtons.tsx 100.00% <100.00%> (ø)
...ox/report/actionContents/ChatActionableButtons.tsx 78.94% <100.00%> (ø)
...mponents/ReportActionItem/FollowupListSkeleton.tsx 25.00% <0.00%> (ø)
... and 211 files with indirect coverage changes

@shawnborton

Copy link
Copy Markdown
Contributor

@MelvinBot this still isn't working as expected. I need button labels to break to multiple lines when the button is wider than the viewport width.

@MelvinBot

Copy link
Copy Markdown
Contributor Author

Before I push another change, I want to flag something about the build you're likely testing, because I think the wrap fix may not actually be in it.

The fix that makes an over-wide label wrap is in 3f189c8, and there's no adhoc build for that commit yet. Here's the timeline:

  • 91ecb56 added flexShrink1 + mw100 — this clamps the button's width, but the label still stays content-sized on a single line and overflows, because the inner content isn't stretched to the clamped width.
  • 3f189c8 added alignItemsStretch (ActionableItemButtons.tsx:43-46) — this is the piece that reflows the label to the clamped width so it breaks to multiple lines.

Both adhoc builds posted above were compiled from 91ecb56 (see the Adhoc-91ecb56ab13-... artifact names) — i.e. before the wrap fix. So if you retested on the iOS/Android adhoc build, you were on the pre-fix build, which still overflows exactly as you're describing.

Could you retest on the latest?

If it still doesn't wrap on the latest, drop a screenshot + which platform you're on. The width chain is bounded all the way down (the message column uses flexBasis: 0, flexGrow: 1), so on web this should already clamp the button and wrap the label — if it isn't, I'll want to see whether the button is overflowing or the label is truncating, since the fix differs between the two (and between web and native), and I'd rather target the real failure than guess a third time.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🚧 shawnborton has triggered a test Expensify/App build. You can view the workflow run here.

@dubielzyk-expensify

Copy link
Copy Markdown
Contributor

Just came back, but are we still wanting to test it? If so, I might just do a local Claude riff. Looks like the original issue was closed

@shawnborton

Copy link
Copy Markdown
Contributor

We tested it with the adhoc builds above! And I think we all generally felt kinda "meh" - don't hate it, don't love it. How are you feeling?

@dubielzyk-expensify

Copy link
Copy Markdown
Contributor

Getting this so can't test, but if y'all don't love it, then lets leave it. I don't feel strongly from the mocks. Didn't feel much when I made them either. What we have kinda works.

@dubielzyk-expensify

Copy link
Copy Markdown
Contributor

Forgot screenie. Looks like the PR needs to merge main:

CleanShot 2026-07-14 at 10 08 56@2x

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants