Skip to content

MenuItem decomposition Phase 4 — style-prop remnants #100159

Description

@MelvinBot

Phase 4 — style-related remnants

Part of the MenuItem decomposition rollout plan. Phase 1 landed in #97339 (MenuItemNavigation / MenuItemAction); Phase 2 is tracked in #99408. This is the style-prop phase.

Scope

Most of the remaining call sites differ from a preset by nothing but a style prop — style, wrapperStyle, outerWrapperStyle, innerContainerStyle, containerStyle and their siblings. Migrate them by deciding, per prop, whether the style can move outside MenuItem or needs a named variant on the subcomponent that owns that box.

The decision this phase has to make first

The new primitives currently expose no style prop at all — MenuItemRoot.tsx:77-86 hardcodes its style array, and MenuItemRow / MenuItemContent do the same. That's the right default: a generic style passthrough on every subcomponent rebuilds the monolith one prop at a time.

So before migrating anything, settle the escape-hatch policy. For each style prop, one of:

  1. Move it to the caller — wrap the row in the caller's own View (preferred).
  2. Add a named variant to the subcomponent that owns that box.
  3. Delete it — the style is dead, or a no-op under the new layout.

Per the plan's cross-cutting rule: no preset grows a prop for a minority need.

Verified inventory

Counts are MenuItem-scoped call sites at 3a621ed, excluding the shared wrappers (Phase 5).

Prop Sites Finding
outerWrapperStyle 13 Every one is the identical expression shouldUseNarrowLayout ? styles.mhn5 : styles.mhn8. A single MenuItem.Root variant covers the whole cluster.
iconStyles ~15 Two clean clusters: [styles.ml3, styles.mr2] ×4 and the trip-reservation icon container. Rest are one-offs (styles.h7, styles.mr0, styles.wAuto).
titleContainerStyle 3 TripDetailsView, TripRoomPreview, DynamicReportDetailsPage — all gap/alignment. → MenuItem.Content variant.
titleWrapperStyle 2 DynamicSplitExpensePage, DynamicSplitExpenseEditPage — both styles.flex1.
rightIconWrapperStyle 2 DiscoverSection, UpcomingTravelItem — both styles.pl2.
innerContainerStyle 1 Only IndividualExpenseRulesSectionRevamp.tsx:237 (styles.gap5). The other 34 innerContainerStyle= hits in src are Modal/Popover, not MenuItem. Migrate the one, then drop the prop.
rootWrapperStyle 0 Declared at MenuItem.tsx:458 and threaded to :845, but no call site passes it. Straight deletion.
style / wrapperStyle / containerStyle long tail Not yet separated from non-MenuItem consumers — raw src counts (~358 wrapperStyle=, ~173 containerStyle=) are dominated by other components. The first PR should enumerate the MenuItem-scoped subset and group it; expect the same "one repeated expression per cluster" shape as outerWrapperStyle.

The full MenuItem style surface is declared at MenuItem.tsx:120-138.

All 13 outerWrapperStyle sites, for reference:

  • ReimbursementAccount/VerifiedBankAccountFlowEntryPoint ×5 — e.g. :299
  • ReimbursementAccount/USD/ConnectBankAccount/components/FinishChatCard ×3
  • ReimbursementAccount/ConnectedVerifiedBankAccount ×2
  • settings/Wallet/InternationalDepositAccount/subPages/AccountFlowEntryPoint ×2
  • ReimbursementAccount/NonUSD/Finish ×1

Work

  • Write down the escape-hatch policy (the three options above) so later phases and reviewers apply it consistently.
  • Delete rootWrapperStyle — dead prop, no consumers.
  • Migrate the single innerContainerStyle site, then remove the prop.
  • Add the MenuItem.Root bleed/full-width variant and migrate all 13 outerWrapperStyle sites in one PR — they share one expression, so it's one decision reviewed once.
  • One PR per remaining style prop, grouped by prop rather than by page, so each diff is a single repeated expression across its call sites.
  • For each migrated row: confirm the style can be applied outside MenuItem with no visual change. If it can't, add the variant and handle it inside the owning subcomponent.
  • Extend the Storybook MenuItemComparison gallery with a section per variant introduced — old config API vs. new composition side by side.

Out of scope

  • FocusableMenuItem, HighlightableMenuItem, HighlightableMenuItemWithTopDescription, MenuItemList, and the PopoverMenu v2 rows are Phase 5 — even though 2 of the 15 outerWrapperStyle= occurrences and both additionalIconStyles occurrences live in them.
  • Text-level style props (titleStyle, descriptionTextStyle, labelStyle, helperTextStyle, errorTextStyle) belong with the label/error/hint surface in Phase 3, unless one blocks a Phase 4 migration.

Notes

  • Incremental and opt-in — the legacy <MenuItem … /> config API stays untouched.
  • Pure refactor: every migrated row must render identically to its old output. No behavioral or visual change.

Parent: #96202

Issue OwnerCurrent Issue Owner: @Pujan92

Activity

  1. added
    ReviewingHas a PR in review
    and removed
    ReviewingHas a PR in review
    on Sep 2, 2026
  2. changed the title [-]MenuItem decomposition Phase 4 — style-prop remnants[/-] [+][Due for payment 2026-09-15] MenuItem decomposition Phase 4 — style-prop remnants[/+] on Sep 8, 2026
  3. melvin-bot commented on Sep 8, 2026

    @melvin-bot

    @Pujan92

    The solution for this issue has been 🚀 deployed to production 🚀 in version 9.4.73-3 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:

    If no regressions arise, payment will be issued on 2026-09-15. 🎊

    The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the Contributor+ Checklist from here into a new comment on this GH and complete it. If you have the K2 extension, you can simply click: [this button]. If no checklist is needed for this issue, you can click: [no checklist button]

  4. roryabraham commented on Sep 8, 2026

    @roryabraham
    Contributor

    @MelvinBot provide a status update on this issue. Is there more code work needed, or are we just in a waiting-for-payment holding pattern?

  5. MelvinBot commented on Sep 8, 2026

    @MelvinBot
    ContributorAuthor

    More code work is needed — this isn't a pure payment hold. #99915 delivered one of the eight items in the Work list (the 13-site outerWrapperStyle cluster). Every other style prop in the inventory is still on main untouched.

    The payment automation has already run ahead of the scope, though: the title carries [Due for payment 2026-09-15] and Pujan92's C+ checklist is still outstanding. So you have two things to reconcile.

    What's still open, verified at bc098e0

    Work item Status
    outerWrapperStyle × 13 ✅ Done in #99915 — moved to caller-owned Views, no new variant needed
    Delete rootWrapperStyle (dead prop) ❌ Still declared at MenuItem.tsx:396 and threaded to :780
    Migrate the one innerContainerStyle site, drop the prop ❌ Still at IndividualExpenseRulesSectionRevamp.tsx:258
    titleContainerStyle × 3 ❌ TripRoomPreview:105, TripDetailsView:160, DynamicReportDetailsPage:928 — plus a 4th the inventory missed, WorkspaceReceiptPartnersPage:260
    titleWrapperStyle × 2 ❌ DynamicSplitExpensePage:578, DynamicSplitExpenseEditPage:411
    rightIconWrapperStyle × 2 ❌ DiscoverSection:98, UpcomingTravelItem:133
    iconStyles (~15) ❌ 25 iconStyles= sites remain, including both target clusters — [styles.ml3, styles.mr2] at BankAccountPurpose:37 / CardTypeStep:92 and the trip-reservation container
    style / wrapperStyle / containerStyle long tail ❌ Never enumerated. #100585 (wrapperStyle) was opened and closed empty on Sep 8, so there's intent but no live PR
    Write down the escape-hatch policy ❌ Not in the repo — nothing under src/components/MenuItem/ or contributingGuides/ records the three options
    Extend the Storybook MenuItemComparison gallery ❌ #99915 didn't touch MenuItemComparison.stories.tsx

    Recommendation

    Pay this one out and split the remainder into Phase 4b. The title already has a payment date, so melvin-bot will close it on the 15th regardless — fighting that is more friction than filing a follow-up. This also matches how Phases 1 and 2 were handled: one issue per reviewable PR chunk rather than one issue per phase.

    Concretely:

    1. Pujan92 posts the C+ checklist so the Sep 15 payment isn't blocked. Nothing else is in the way — the last open item, m-natarajan's Test 3 / Step 6 question, was answered by war-in on Sep 8, and the PR shipped to production in 9.4.73-3.
    2. Open Phase 4b for the nine remaining items, with the escape-hatch policy write-up as the first deliverable — it gates the rest, and the outerWrapperStyle PR already established the precedent (option 1, move to caller) that the policy should codify.

    Reply with @MelvinBot create the Phase 4b issue and I'll file it against the parent, carrying the verified inventory above.

  6. war-in commented on Sep 9, 2026

    @war-in
    Contributor

    @roryabraham I'm going to take care of the other parts of that issue (enumerated by Melvin) in a future PRs. However, I'd rather wait for #100191 and the next MenuItemWithTopDescription-related PRs because they'll add more required leaves

  7. 42 remaining items

  8. changed the title [-][Due for payment 2026-10-05] MenuItem decomposition Phase 4 — style-prop remnants[/-] [+][Due for payment 2026-10-12] MenuItem decomposition Phase 4 — style-prop remnants[/+] on Oct 5, 2026
  9. melvin-bot commented on Oct 5, 2026

    @melvin-bot

    @Pujan92 @mallenexpensify

    The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.1-9 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:

    If no regressions arise, payment will be issued on 2026-10-12. 🎊

    The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the Contributor+ Checklist from here into a new comment on this GH and complete it. If you have the K2 extension, you can simply click: [this button]. If no checklist is needed for this issue, you can click: [no checklist button]

  10. added
    ReviewingHas a PR in review
    and removed on Oct 5, 2026
  11. added
    Skip PaymentSkips all the payment process steps for an issue. Use it for fixed-price projects.
    on Oct 6, 2026
  12. changed the title [-][Due for payment 2026-10-12] MenuItem decomposition Phase 4 — style-prop remnants[/-] [+]MenuItem decomposition Phase 4 — style-prop remnants[/+] on Oct 6, 2026
  13. removed their assignment
    on Oct 6, 2026
  14. mallenexpensify commented on Oct 6, 2026

    @mallenexpensify
    Contributor

    Please comment and tag me if/when payment is due, thx

  15. added and removed
    ReviewingHas a PR in review
    on Oct 9, 2026
  16. melvin-bot commented on Oct 9, 2026

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

Metadata

Metadata

Labels

DailyKSv2OverdueSkip PaymentSkips all the payment process steps for an issue. Use it for fixed-price projects.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions