fix: Keep teleported item in sync with collapsed content - #595
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
MatiPl01
force-pushed
the
fix/portal-collapsible-teleport-size
branch
2 times, most recently
from
July 8, 2026 10:39
090ea23 to
29cc4b1
Compare
The portal teleport pushed a one-shot snapshot of the item cell and relied on a first-update setTimeout to re-push it, which raced the collapse re-render and could leave the teleported active item stuck at its pre-collapse size. Drive teleportation from a React state flag instead: one effect hides the source item while teleported (and clears the outlet on teardown), and a separate effect keeps the outlet in sync with the current cell whenever the item node changes. Keeping the source-hiding independent of the content re-push is deliberate - it means a collapsible item shrinks its teleported copy without ever revealing the source item underneath. Also drop the now-unused isTeleported from the portal context.
MatiPl01
force-pushed
the
fix/portal-collapsible-teleport-size
branch
from
July 8, 2026 10:55
29cc4b1 to
763aa48
Compare
The mounted source cell of a teleported item is hidden with `left: 9999`. On Fabric that layout offset is transiently defeated during auto-scroll's per-frame commits, so the source card shows behind the teleported copy and the two separate as the list auto-scrolls. Add a static `opacity: 0` alongside the offset (a non-layout prop that survives the commit timing; `left` still covers the Old Architecture), plus a render test that drives a teleport and asserts the hidden source is marked hidden and carries the opacity.
Drop the memoized renderTeleportedItemCell, the manual push effect, and the context-provider nesting from ActiveItemPortal. A small declarative Teleport component pushes the cell into the outlet (re-pushing on change, so a collapsing item stays in sync), and TeleportedItemCell now owns the CommonValues/Item context wrappers it renders under. ActiveItemPortal goes from 8 hooks to 6 and reads top to bottom; behaviour is unchanged - the source-hide stays keyed on the teleported flag and the teardown state updates batch into one commit.
MatiPl01
pushed a commit
that referenced
this pull request
Jul 23, 2026
# [1.10.0](v1.9.4...v1.10.0) (2026-07-23) ### Bug Fixes * Add item zIndex preserving based on the order of items ([#534](#534)) ([fb0be4e](fb0be4e)), closes [#36877](https://github.com/MatiPl01/react-native-sortables/issues/36877) * allow scrolling the ScrollView from draggable items on web ([#574](#574)) ([74879ed](74879ed)), closes [#545](#545) * Balance onTouchesUp on Sortable.Touchable long press ([#594](#594)) ([f977567](f977567)) * Deduplicate expo example native modules for expo-doctor ([#590](#590)) ([e5af169](e5af169)), closes [#589](#589) * disable dragging for fixed-order and non-draggable handles ([#598](#598)) ([8ed2e81](8ed2e81)) * dragging stops after a screen is detached and re-attached (gesture-handler v3) ([#573](#573)) ([c70a14f](c70a14f)), closes [#349](#349) [react-native-gesture-handler#3560](https://github.com/react-native-gesture-handler/issues/3560) [#349](#349) [#349](#349) * Item can settle on another item's slot after a rapid re-order ([#591](#591)) ([9d63817](9d63817)), closes [#586](#586) * Item position drift on slow web container resize ([#562](#562)) ([8973115](8973115)) * Keep npm version from walking yarn workspaces during release ([#609](#609)) ([0d8d869](0d8d869)) * Keep Sortable.Grid measurements when revealed after react-freeze ([#572](#572)) ([609c73c](609c73c)), closes [#519](#519) [#36877](https://github.com/MatiPl01/react-native-sortables/issues/36877) * keep Sortable.Touchable onTouchesUp firing on web ([#596](#596)) ([8529fa8](8529fa8)), closes [#594](#594) * Keep Sortable.Touchable tap and long press working on teleported items ([#602](#602)) ([3efb111](3efb111)) * Keep teleported item in sync with collapsed content ([#595](#595)) ([1fbcf9e](1fbcf9e)) * New-Arch grid mount crash in the example and unrunnable expo example ([#589](#589)) ([01aa1a8](01aa1a8)) * Respect Sortable.Flex alignItems before items are measured ([#560](#560)) ([5c84117](5c84117)), closes [#258](#258) * Restore tap and long press on teleported items ([#599](#599)) ([e73117b](e73117b)) * Sortable.Touchable crash on gesture-handler v3 (onActivate not a worklet) ([#587](#587)) ([4b3007e](4b3007e)) * Support react-native-gesture-handler 3.x types ([#553](#553)) ([83754e0](83754e0)) * Support react-native-reanimated 4.5 / worklets 0.10 ([#566](#566)) ([828c6d6](828c6d6)), closes [/github.com//issues/552#issuecomment-4634261543](https://github.com//github.com/MatiPl01/react-native-sortables/issues/552/issues/issuecomment-4634261543) [#552](#552) ### Features * Add react-native-pulsar as a top-priority haptics adapter ([#568](#568)) ([642e734](642e734)) * Auto-detect expo-haptics when available ([#558](#558)) ([a0d7602](a0d7602)), closes [#554](#554) * Reverse items stacking order ([#535](#535)) ([14c7d82](14c7d82)), closes [#36877](https://github.com/MatiPl01/react-native-sortables/issues/36877) ### Performance Improvements * Drive active item position from a single reaction ([#586](#586)) ([c498091](c498091)), closes [#584](#584)
Owner
Author
|
馃帀 This PR is included in version 1.10.0 馃帀 The release is available on: Your semantic-release bot 馃摝馃殌 |
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.
Description
When a grid is wrapped in
Sortable.PortalProviderand its items collapse on drag (e.g.onDragStartshrinks them), the teleported active item stayed at its pre-collapse (large) size instead of shrinking with the rest.The portal pushed a one-shot snapshot of the item cell into the outlet and relied on a first-update
setTimeoutto re-push it. That deferred re-push raced the collapse re-render, so the teleported copy could keep rendering the pre-collapse content.This drives teleportation from a React state flag instead, with two effects that are intentionally kept separate:
Keeping the source-hiding independent of the content re-push matters: because the rendered cell changes identity when the item collapses, folding both into a single effect would toggle the source item's hidden state on every re-push and leave the underlying item visible under the teleported copy. Split, the teleported copy tracks the live (collapsed) content while the source stays hidden, with no timer.
The now-unused
isTeleportedwas also dropped from the portal context (this rework was its only consumer).Testing
Verified on the iOS fabric example (New Arch) with the built-in Collapsible Items example under
Sortable.PortalProvider(enabled via the bottom-bar settings) and a dedicated portal + collapsible screen:typecheck,lint, andtestpass; a store regression test is included.