Skip to content

Give a horizontal pager a header that scrolls with the page showing (re-land #139) - #154

Merged
simonhamp merged 1 commit into
mainfrom
fix/reland-pager-header
Oct 22, 2026
Merged

simonhamp merged 1 commit into
mainfrom
fix/reland-pager-header

Conversation

@simonhamp

@simonhamp simonhamp commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

This re-lands #139, the pager header, on main.

#139 shows as merged, but its code never reached main. It was based on feat/pager-tabs and merged into that branch at 11:06 UTC. #136 had already merged feat/pager-tabs into feat/pager-report-on-settle at 11:04, and that went to main as #135. So main has the native tabs but not <native:pager-header> or <native:pager-overlay>.

This is #139's commit (8475c3d) cherry-picked onto main and rebased onto #119, with no other changes. See #139 for what it does and how it was tested.

Two conflicts, both in NativeUIListRenderer.swift.

First, since #139 was written, #144 replaced the rows' end-reached closures with Self.endReachedAction(...), so a row scrolled out of view no longer keeps a copy of the whole list. #139 had moved that code into a new branch for lists under a pager header. I kept #139's structure and used Self.endReachedAction in all three places, including the header's rows. The combined dev-null-app branch, which the app already runs, resolved it the same way.

Second, #118 added the list's minimum row height (defaultMinListRowHeight) on the same line where #139 adds the pager header environment value. The list keeps both. The header row isn't a rowView row, so #118's row sizing doesn't touch it.

Everything else merged cleanly, including with #131. The pager files (NativeUIPagerRenderer.swift, PagerRenderer.kt, Pager.php, PagerHeader.php, PagerOverlay.php) come out identical to the ones on combined/dev-null-app.

Checked: Pest (367 passing), Pint, and swiftc -parse on every Swift file. I didn't build it into an app. The pager files match what the dev-null app ships, but the list renderer now has #118 alongside the header, which the app hasn't run yet.

Once this merges, feat/pager-tabs can be deleted. Until then it's the only copy of #139's commit apart from the combined branch.

🤖 Generated with Claude Code

A profile has a header (avatar, bio, counts) above its tabs. Native apps
scroll the header up with the page you're on, pin the tabs under the nav
bar, and swipe the pages sideways under them while the header stays put.
EDGE couldn't do that: the pager's tabs sat above the pages, and anything
above the pager never scrolled away.

<native:pager-header> goes inside a horizontal pager beside the pages. The
pager hands it to each page, and the page's list draws it as its first row
with the tabs as a pinned section header (iOS) or sticky header (Android)
under it. So the header scrolls with the list, pull to refresh pulls it
down, and a drag that starts on it scrolls. While the pager swipes, the
header and tabs are moved against the page so they stay still, and the
two halves on screen meet as one.

That only works if the pages beside each other are level. The pager keeps
every page's list at the same offset while any of the header shows. Once
it has gone, each list keeps its own place, and one higher than the header
is brought down to where it pins the tabs. A list too short to scroll the
header away gets room at its end. iOS moves the lists through their
UIScrollView, since SwiftUI can't set a List's offset.

<native:pager-overlay> hangs something under the tabs over the pages, a
"3 new posts" pill say, and follows the tabs as the header scrolls.

Every page needs a list for the header to show on it.

This re-lands #139. That PR was merged into feat/pager-tabs a minute after #136 had already merged that branch, so it never reached main. Two conflicts, both in the iOS list renderer. #144 replaced the rows' end-reached closures with Self.endReachedAction, and the header's rows use that too. #118 added the list's minimum row height next to where this adds the pager header, and the list keeps both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@simonhamp
simonhamp force-pushed the fix/reland-pager-header branch from 96b18fe to 85fd537 Compare October 22, 2026 12:07
@simonhamp
simonhamp merged commit ec5eef9 into main Oct 22, 2026
4 checks passed
@simonhamp
simonhamp deleted the fix/reland-pager-header branch October 22, 2026 12:44
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.

1 participant