[NoQA] HeaderWithBackButton migration - primitives introduction - #98160
Open
Guccio163 wants to merge 50 commits into
Open
[NoQA] HeaderWithBackButton migration - primitives introduction#98160Guccio163 wants to merge 50 commits into
Guccio163 wants to merge 50 commits into
Conversation
…-fork into Guccio163/header/headerComposedImplementation
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
…-fork into Guccio163/header/headerComposedImplementation
…-fork into Guccio163/header/headerComposedImplementation
…-fork into Guccio163/header/headerComposedImplementation
Same profile as HeaderReportAvatar/HeaderSearchRouter/HeaderHelpButton — zero added logic beyond forwarding to Avatar. policyAvatar prop stays, only the primitive-file indirection goes.
…mplementation' into Guccio163/header/headerComposedImplementation # Conflicts: # src/components/HeaderWithBackButtonComposed/index.tsx # src/components/HeaderWithBackButtonComposed/primitives/HeaderDownloadButton.tsx # src/components/HeaderWithBackButtonComposed/primitives/HeaderMenuItemButtonTooltip.tsx
…-fork into Guccio163/header/headerComposedImplementation
|
@gijoe0295 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] |
melvin-bot
Bot
requested review from
garrettmknight
and removed request for
a team
August 17, 2026 19:04
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cb2f654f4f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…WithBackButtonComposed
- Composed policy avatar block dropped the policyAvatarSize prop entirely, hardcoding
CONST.AVATAR_SIZE.DEFAULT; WorkspaceInitialPage's policyAvatarSize={SMALL} would have
silently grown the workspace header avatar from 28px to 40px once migrated.
- Dedupe the anchorAlignment default between index.tsx and HeaderThreeDotsMenu into one
shared constant.
- Add missing prop JSDoc, eslint-disable justifications, and drop em-dash comments per
coding-standards review.
- Rename styles/index.ts to styles/useHeaderStyles.ts per file-naming convention.
The em-dash pass missed that the rule also flags semicolons joining two clauses; split those into separate sentences in HeaderTooltipIconButton, HeaderMenuItemButtonTooltip, and HeaderRight.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Explanation of Change
First step of the HeaderWithBackButton
composition over configurationmigration; This branch is the "build the replacement" phase; swapping real callers over is a later PR.Current
HeaderWithBackButtonComposed/index.tsxform is not the end goal — it's scaffolding. It reassembles the legacy render from small named primitives while keeping the exact same flat prop API as the original, so:Header.Left/Header.Right+ block children) can be designed with minimal wrapper overhead.Introduced primitives:
HeaderBackButton,HeaderIcon,HeaderTitle,HeaderThreeDotsMenu,HeaderCloseButtonTooltip,HeaderDownloadButton,HeaderMenuItemButtonTooltip.HeaderTooltipIconButton— Back/Download/Close/MenuItem were all Tooltip+Pressable+Icon differing only in onPress-wrapping, fill, and ref logic, so the shared skeleton got extracted and the four now delegate to it.zones/HeaderRight+zones/HeaderActionswrap the right-side cluster: outer separates it from the center content, inner packs custom children + download together and applies its padding unconditionally so the gap to whatever follows never needs to know what that is.Parts kept inline, not extracted:
AvatarWithDisplayName(report avatar),Avatar(policy avatar),SearchButton,SidePanelButtonare rendered directly inindex.tsx, not through dedicated primitives, because extracting them into separate primitives would be either a no-op wrapper or they are used only once so it's redundant to create a separate primitive wrapper just for this.Parts removed entirely (confirmed via census across all 531 real legacy call sites that these never actually render/apply, then deleted along with their plumbing):
HeaderRotateButton/shouldShowRotateButton/isRotating/onRotateButtonPress— the one real caller passes it as a prop that always resolves tofalse.HeaderPinButton/shouldShowPinButton— always explicitfalseor absent, nevertrue.shouldOverlay,shouldNavigateToTopMostReport,shouldDisableThreeDotsButton,threeDotsMenuIcon/threeDotsMenuIconFill— each 100% unused across every call site.progressBarPercentage,stepCounter-driven bar,HeaderProgressBar) — already removed upstream onmainwhile this PR was being developed.Parts restructured (ensuring unchanged behavior):
pl2on the outer header container (a leftover from when the progress bar also needed container-level padding logic). Now that the progress bar is gone, it's a negative margin (mln3) onHeaderBackButtonitself — self-contained, doesn't need the container to coordinate with anything.SearchButton/SidePanelButtonmoved from being siblings outside the right-side wrapper View to siblings inside it. Verified with DOM measurements and screenshots: zero visual difference either way, because the gap between them and whatever precedes them comes from padding on the actions-wrapper regardless of where they sit. Moved purely so the whole right side is one visibly single group in the tree, instead of "half of it is wrapped, half isn't" — easier to explain and reason about, not a rendering change.Tooling accommodation:
knip.jsongotindex.tsxadded as an entry point, since nothing imports this folder yet — without it, Knip would flag the whole thing as dead code.Fixed Issues
$ #96611
PROPOSAL:
Tests
NoQA PR, so tests are code-wise: check if the whole HeaderWithBackButton component's pieces are swapped correctly with primitive components in the new HeaderWithBackButtonComposed/index.tsx file.
Offline tests
QA Steps
Same as tests
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, 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.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari