react-native-screen-transitions 3.9.0-alpha.2 → 3.9.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (421) hide show
  1. package/lib/commonjs/shared/components/boundary/components/boundary-target.js +14 -9
  2. package/lib/commonjs/shared/components/boundary/components/boundary-target.js.map +1 -1
  3. package/lib/commonjs/shared/components/boundary/create-boundary-component.js +66 -28
  4. package/lib/commonjs/shared/components/boundary/create-boundary-component.js.map +1 -1
  5. package/lib/commonjs/shared/components/boundary/hooks/{use-boundary-presence.js → lifecycles/use-boundary-presence.js} +8 -4
  6. package/lib/commonjs/shared/components/boundary/hooks/lifecycles/use-boundary-presence.js.map +1 -0
  7. package/lib/commonjs/shared/components/boundary/hooks/{use-initial-destination-measurement.js → lifecycles/use-initial-destination-measurement.js} +27 -10
  8. package/lib/commonjs/shared/components/boundary/hooks/lifecycles/use-initial-destination-measurement.js.map +1 -0
  9. package/lib/commonjs/shared/components/boundary/hooks/{use-initial-source-measurement.js → lifecycles/use-initial-source-measurement.js} +5 -7
  10. package/lib/commonjs/shared/components/boundary/hooks/lifecycles/use-initial-source-measurement.js.map +1 -0
  11. package/lib/commonjs/shared/components/boundary/hooks/{use-refresh-boundary.js → lifecycles/use-refresh-boundary.js} +4 -4
  12. package/lib/commonjs/shared/components/boundary/hooks/lifecycles/use-refresh-boundary.js.map +1 -0
  13. package/lib/commonjs/shared/components/boundary/hooks/use-boundary-measurement.js +14 -35
  14. package/lib/commonjs/shared/components/boundary/hooks/use-boundary-measurement.js.map +1 -1
  15. package/lib/commonjs/shared/components/boundary/hooks/use-measurer.js +5 -6
  16. package/lib/commonjs/shared/components/boundary/hooks/use-measurer.js.map +1 -1
  17. package/lib/commonjs/shared/components/boundary/index.js +26 -29
  18. package/lib/commonjs/shared/components/boundary/index.js.map +1 -1
  19. package/lib/commonjs/shared/components/boundary/portal/components/boundary-local-portal-host.js +58 -0
  20. package/lib/commonjs/shared/components/boundary/portal/components/boundary-local-portal-host.js.map +1 -0
  21. package/lib/commonjs/shared/components/boundary/portal/components/host.js +20 -4
  22. package/lib/commonjs/shared/components/boundary/portal/components/host.js.map +1 -1
  23. package/lib/commonjs/shared/components/boundary/portal/components/portal-boundary-host.js +53 -32
  24. package/lib/commonjs/shared/components/boundary/portal/components/portal-boundary-host.js.map +1 -1
  25. package/lib/commonjs/shared/components/boundary/portal/components/portal.js +206 -96
  26. package/lib/commonjs/shared/components/boundary/portal/components/portal.js.map +1 -1
  27. package/lib/commonjs/shared/components/boundary/portal/hooks/use-host-measurement.js +14 -2
  28. package/lib/commonjs/shared/components/boundary/portal/hooks/use-host-measurement.js.map +1 -1
  29. package/lib/commonjs/shared/components/boundary/portal/stores/host-registry.store.js +5 -44
  30. package/lib/commonjs/shared/components/boundary/portal/stores/host-registry.store.js.map +1 -1
  31. package/lib/commonjs/shared/components/boundary/portal/stores/portal-boundary-host.store.js +37 -5
  32. package/lib/commonjs/shared/components/boundary/portal/stores/portal-boundary-host.store.js.map +1 -1
  33. package/lib/commonjs/shared/components/boundary/portal/teleport.js +15 -2
  34. package/lib/commonjs/shared/components/boundary/portal/teleport.js.map +1 -1
  35. package/lib/commonjs/shared/components/boundary/portal/utils/has-local-slot.js +18 -0
  36. package/lib/commonjs/shared/components/boundary/portal/utils/has-local-slot.js.map +1 -0
  37. package/lib/commonjs/shared/components/boundary/portal/utils/naming.js +10 -3
  38. package/lib/commonjs/shared/components/boundary/portal/utils/naming.js.map +1 -1
  39. package/lib/commonjs/shared/components/boundary/portal/utils/offset-style.js +28 -49
  40. package/lib/commonjs/shared/components/boundary/portal/utils/offset-style.js.map +1 -1
  41. package/lib/commonjs/shared/components/boundary/portal/utils/ownership.js +254 -0
  42. package/lib/commonjs/shared/components/boundary/portal/utils/ownership.js.map +1 -0
  43. package/lib/commonjs/shared/components/boundary/portal/utils/resolve-portal.js +38 -0
  44. package/lib/commonjs/shared/components/boundary/portal/utils/resolve-portal.js.map +1 -0
  45. package/lib/commonjs/shared/components/boundary/portal/utils/shallow-equal.js +29 -0
  46. package/lib/commonjs/shared/components/boundary/portal/utils/shallow-equal.js.map +1 -0
  47. package/lib/commonjs/shared/components/boundary/portal/utils/teleport-control.js +10 -1
  48. package/lib/commonjs/shared/components/boundary/portal/utils/teleport-control.js.map +1 -1
  49. package/lib/commonjs/shared/components/boundary/portal/utils/visible-host.js +25 -0
  50. package/lib/commonjs/shared/components/boundary/portal/utils/visible-host.js.map +1 -0
  51. package/lib/commonjs/shared/components/boundary/providers/boundary-root.provider.js +6 -7
  52. package/lib/commonjs/shared/components/boundary/providers/boundary-root.provider.js.map +1 -1
  53. package/lib/commonjs/shared/components/boundary/utils/destination-signals.js +1 -22
  54. package/lib/commonjs/shared/components/boundary/utils/destination-signals.js.map +1 -1
  55. package/lib/commonjs/shared/components/boundary/utils/refresh-signals.js +0 -21
  56. package/lib/commonjs/shared/components/boundary/utils/refresh-signals.js.map +1 -1
  57. package/lib/commonjs/shared/components/boundary/utils/source-signals.js +4 -9
  58. package/lib/commonjs/shared/components/boundary/utils/source-signals.js.map +1 -1
  59. package/lib/commonjs/shared/index.js.map +1 -1
  60. package/lib/commonjs/shared/providers/helpers/measured-bounds-writes.js +6 -3
  61. package/lib/commonjs/shared/providers/helpers/measured-bounds-writes.js.map +1 -1
  62. package/lib/commonjs/shared/providers/screen/animation/helpers/derivations.js +1 -0
  63. package/lib/commonjs/shared/providers/screen/animation/helpers/derivations.js.map +1 -1
  64. package/lib/commonjs/shared/providers/screen/animation/helpers/pipeline.js +1 -0
  65. package/lib/commonjs/shared/providers/screen/animation/helpers/pipeline.js.map +1 -1
  66. package/lib/commonjs/shared/providers/screen/styles/helpers/compose-slot-style.js +95 -0
  67. package/lib/commonjs/shared/providers/screen/styles/helpers/compose-slot-style.js.map +1 -0
  68. package/lib/commonjs/shared/providers/screen/styles/helpers/normalize-slots.js +30 -9
  69. package/lib/commonjs/shared/providers/screen/styles/helpers/normalize-slots.js.map +1 -1
  70. package/lib/commonjs/shared/providers/screen/styles/helpers/resolve-slot-styles/index.js +9 -3
  71. package/lib/commonjs/shared/providers/screen/styles/helpers/resolve-slot-styles/index.js.map +1 -1
  72. package/lib/commonjs/shared/providers/screen/styles/helpers/resolve-slot-styles/materialize-slot.js +2 -0
  73. package/lib/commonjs/shared/providers/screen/styles/helpers/resolve-slot-styles/materialize-slot.js.map +1 -1
  74. package/lib/commonjs/shared/providers/screen/styles/hooks/slot-resolvers.js +96 -0
  75. package/lib/commonjs/shared/providers/screen/styles/hooks/slot-resolvers.js.map +1 -0
  76. package/lib/commonjs/shared/providers/screen/styles/hooks/use-interpolated-style-maps.js +16 -3
  77. package/lib/commonjs/shared/providers/screen/styles/hooks/use-interpolated-style-maps.js.map +1 -1
  78. package/lib/commonjs/shared/providers/screen/styles/index.js +16 -3
  79. package/lib/commonjs/shared/providers/screen/styles/index.js.map +1 -1
  80. package/lib/commonjs/shared/providers/screen/styles/slot.provider.js +22 -51
  81. package/lib/commonjs/shared/providers/screen/styles/slot.provider.js.map +1 -1
  82. package/lib/commonjs/shared/providers/screen/styles/stores/slot-references.store.js +53 -0
  83. package/lib/commonjs/shared/providers/screen/styles/stores/slot-references.store.js.map +1 -0
  84. package/lib/commonjs/shared/stores/bounds/helpers/link-pairs.helpers.js +22 -2
  85. package/lib/commonjs/shared/stores/bounds/helpers/link-pairs.helpers.js.map +1 -1
  86. package/lib/commonjs/shared/stores/bounds/internals/entries.js +11 -4
  87. package/lib/commonjs/shared/stores/bounds/internals/entries.js.map +1 -1
  88. package/lib/commonjs/shared/stores/bounds/internals/links.js +134 -51
  89. package/lib/commonjs/shared/stores/bounds/internals/links.js.map +1 -1
  90. package/lib/commonjs/shared/stores/bounds/internals/resolver.js +1 -3
  91. package/lib/commonjs/shared/stores/bounds/internals/resolver.js.map +1 -1
  92. package/lib/commonjs/shared/stores/system.store.js +5 -0
  93. package/lib/commonjs/shared/stores/system.store.js.map +1 -1
  94. package/lib/commonjs/shared/utils/bounds/helpers/styles/compute.js +10 -69
  95. package/lib/commonjs/shared/utils/bounds/helpers/styles/compute.js.map +1 -1
  96. package/lib/commonjs/shared/utils/bounds/helpers/styles/local-transform.js +59 -0
  97. package/lib/commonjs/shared/utils/bounds/helpers/styles/local-transform.js.map +1 -0
  98. package/lib/module/shared/components/boundary/components/boundary-target.js +12 -7
  99. package/lib/module/shared/components/boundary/components/boundary-target.js.map +1 -1
  100. package/lib/module/shared/components/boundary/create-boundary-component.js +67 -29
  101. package/lib/module/shared/components/boundary/create-boundary-component.js.map +1 -1
  102. package/lib/module/shared/components/boundary/hooks/{use-boundary-presence.js → lifecycles/use-boundary-presence.js} +8 -4
  103. package/lib/module/shared/components/boundary/hooks/lifecycles/use-boundary-presence.js.map +1 -0
  104. package/lib/module/shared/components/boundary/hooks/{use-initial-destination-measurement.js → lifecycles/use-initial-destination-measurement.js} +27 -10
  105. package/lib/module/shared/components/boundary/hooks/lifecycles/use-initial-destination-measurement.js.map +1 -0
  106. package/lib/module/shared/components/boundary/hooks/{use-initial-source-measurement.js → lifecycles/use-initial-source-measurement.js} +5 -7
  107. package/lib/module/shared/components/boundary/hooks/lifecycles/use-initial-source-measurement.js.map +1 -0
  108. package/lib/module/shared/components/boundary/hooks/{use-refresh-boundary.js → lifecycles/use-refresh-boundary.js} +4 -4
  109. package/lib/module/shared/components/boundary/hooks/lifecycles/use-refresh-boundary.js.map +1 -0
  110. package/lib/module/shared/components/boundary/hooks/use-boundary-measurement.js +15 -36
  111. package/lib/module/shared/components/boundary/hooks/use-boundary-measurement.js.map +1 -1
  112. package/lib/module/shared/components/boundary/hooks/use-measurer.js +5 -6
  113. package/lib/module/shared/components/boundary/hooks/use-measurer.js.map +1 -1
  114. package/lib/module/shared/components/boundary/index.js +26 -29
  115. package/lib/module/shared/components/boundary/index.js.map +1 -1
  116. package/lib/module/shared/components/boundary/portal/components/boundary-local-portal-host.js +53 -0
  117. package/lib/module/shared/components/boundary/portal/components/boundary-local-portal-host.js.map +1 -0
  118. package/lib/module/shared/components/boundary/portal/components/host.js +21 -5
  119. package/lib/module/shared/components/boundary/portal/components/host.js.map +1 -1
  120. package/lib/module/shared/components/boundary/portal/components/portal-boundary-host.js +53 -32
  121. package/lib/module/shared/components/boundary/portal/components/portal-boundary-host.js.map +1 -1
  122. package/lib/module/shared/components/boundary/portal/components/portal.js +212 -102
  123. package/lib/module/shared/components/boundary/portal/components/portal.js.map +1 -1
  124. package/lib/module/shared/components/boundary/portal/hooks/use-host-measurement.js +15 -3
  125. package/lib/module/shared/components/boundary/portal/hooks/use-host-measurement.js.map +1 -1
  126. package/lib/module/shared/components/boundary/portal/stores/host-registry.store.js +4 -41
  127. package/lib/module/shared/components/boundary/portal/stores/host-registry.store.js.map +1 -1
  128. package/lib/module/shared/components/boundary/portal/stores/portal-boundary-host.store.js +35 -4
  129. package/lib/module/shared/components/boundary/portal/stores/portal-boundary-host.store.js.map +1 -1
  130. package/lib/module/shared/components/boundary/portal/teleport.js +16 -2
  131. package/lib/module/shared/components/boundary/portal/teleport.js.map +1 -1
  132. package/lib/module/shared/components/boundary/portal/utils/has-local-slot.js +13 -0
  133. package/lib/module/shared/components/boundary/portal/utils/has-local-slot.js.map +1 -0
  134. package/lib/module/shared/components/boundary/portal/utils/naming.js +8 -2
  135. package/lib/module/shared/components/boundary/portal/utils/naming.js.map +1 -1
  136. package/lib/module/shared/components/boundary/portal/utils/offset-style.js +29 -49
  137. package/lib/module/shared/components/boundary/portal/utils/offset-style.js.map +1 -1
  138. package/lib/module/shared/components/boundary/portal/utils/ownership.js +246 -0
  139. package/lib/module/shared/components/boundary/portal/utils/ownership.js.map +1 -0
  140. package/lib/module/shared/components/boundary/portal/utils/resolve-portal.js +33 -0
  141. package/lib/module/shared/components/boundary/portal/utils/resolve-portal.js.map +1 -0
  142. package/lib/module/shared/components/boundary/portal/utils/shallow-equal.js +24 -0
  143. package/lib/module/shared/components/boundary/portal/utils/shallow-equal.js.map +1 -0
  144. package/lib/module/shared/components/boundary/portal/utils/teleport-control.js +8 -0
  145. package/lib/module/shared/components/boundary/portal/utils/teleport-control.js.map +1 -1
  146. package/lib/module/shared/components/boundary/portal/utils/visible-host.js +20 -0
  147. package/lib/module/shared/components/boundary/portal/utils/visible-host.js.map +1 -0
  148. package/lib/module/shared/components/boundary/providers/boundary-root.provider.js +6 -7
  149. package/lib/module/shared/components/boundary/providers/boundary-root.provider.js.map +1 -1
  150. package/lib/module/shared/components/boundary/utils/destination-signals.js +2 -23
  151. package/lib/module/shared/components/boundary/utils/destination-signals.js.map +1 -1
  152. package/lib/module/shared/components/boundary/utils/refresh-signals.js +0 -21
  153. package/lib/module/shared/components/boundary/utils/refresh-signals.js.map +1 -1
  154. package/lib/module/shared/components/boundary/utils/source-signals.js +4 -9
  155. package/lib/module/shared/components/boundary/utils/source-signals.js.map +1 -1
  156. package/lib/module/shared/index.js.map +1 -1
  157. package/lib/module/shared/providers/helpers/measured-bounds-writes.js +6 -3
  158. package/lib/module/shared/providers/helpers/measured-bounds-writes.js.map +1 -1
  159. package/lib/module/shared/providers/screen/animation/helpers/derivations.js +1 -0
  160. package/lib/module/shared/providers/screen/animation/helpers/derivations.js.map +1 -1
  161. package/lib/module/shared/providers/screen/animation/helpers/pipeline.js +1 -0
  162. package/lib/module/shared/providers/screen/animation/helpers/pipeline.js.map +1 -1
  163. package/lib/module/shared/providers/screen/styles/helpers/compose-slot-style.js +89 -0
  164. package/lib/module/shared/providers/screen/styles/helpers/compose-slot-style.js.map +1 -0
  165. package/lib/module/shared/providers/screen/styles/helpers/normalize-slots.js +30 -9
  166. package/lib/module/shared/providers/screen/styles/helpers/normalize-slots.js.map +1 -1
  167. package/lib/module/shared/providers/screen/styles/helpers/resolve-slot-styles/index.js +9 -3
  168. package/lib/module/shared/providers/screen/styles/helpers/resolve-slot-styles/index.js.map +1 -1
  169. package/lib/module/shared/providers/screen/styles/helpers/resolve-slot-styles/materialize-slot.js +2 -0
  170. package/lib/module/shared/providers/screen/styles/helpers/resolve-slot-styles/materialize-slot.js.map +1 -1
  171. package/lib/module/shared/providers/screen/styles/hooks/slot-resolvers.js +87 -0
  172. package/lib/module/shared/providers/screen/styles/hooks/slot-resolvers.js.map +1 -0
  173. package/lib/module/shared/providers/screen/styles/hooks/use-interpolated-style-maps.js +16 -3
  174. package/lib/module/shared/providers/screen/styles/hooks/use-interpolated-style-maps.js.map +1 -1
  175. package/lib/module/shared/providers/screen/styles/index.js +2 -1
  176. package/lib/module/shared/providers/screen/styles/index.js.map +1 -1
  177. package/lib/module/shared/providers/screen/styles/slot.provider.js +22 -47
  178. package/lib/module/shared/providers/screen/styles/slot.provider.js.map +1 -1
  179. package/lib/module/shared/providers/screen/styles/stores/slot-references.store.js +47 -0
  180. package/lib/module/shared/providers/screen/styles/stores/slot-references.store.js.map +1 -0
  181. package/lib/module/shared/stores/bounds/helpers/link-pairs.helpers.js +19 -1
  182. package/lib/module/shared/stores/bounds/helpers/link-pairs.helpers.js.map +1 -1
  183. package/lib/module/shared/stores/bounds/internals/entries.js +11 -4
  184. package/lib/module/shared/stores/bounds/internals/entries.js.map +1 -1
  185. package/lib/module/shared/stores/bounds/internals/links.js +135 -53
  186. package/lib/module/shared/stores/bounds/internals/links.js.map +1 -1
  187. package/lib/module/shared/stores/bounds/internals/resolver.js +1 -3
  188. package/lib/module/shared/stores/bounds/internals/resolver.js.map +1 -1
  189. package/lib/module/shared/stores/system.store.js +5 -0
  190. package/lib/module/shared/stores/system.store.js.map +1 -1
  191. package/lib/module/shared/types/animation.types.js.map +1 -1
  192. package/lib/module/shared/utils/bounds/helpers/styles/compute.js +10 -69
  193. package/lib/module/shared/utils/bounds/helpers/styles/compute.js.map +1 -1
  194. package/lib/module/shared/utils/bounds/helpers/styles/local-transform.js +52 -0
  195. package/lib/module/shared/utils/bounds/helpers/styles/local-transform.js.map +1 -0
  196. package/lib/typescript/blank-stack/navigators/create-blank-stack-navigator.d.ts +1 -2
  197. package/lib/typescript/blank-stack/navigators/create-blank-stack-navigator.d.ts.map +1 -1
  198. package/lib/typescript/component-stack/components/component-screen.d.ts +1 -1
  199. package/lib/typescript/component-stack/components/component-screen.d.ts.map +1 -1
  200. package/lib/typescript/component-stack/navigators/create-component-stack-navigator.d.ts +1 -2
  201. package/lib/typescript/component-stack/navigators/create-component-stack-navigator.d.ts.map +1 -1
  202. package/lib/typescript/native-stack/navigators/createNativeStackNavigator.d.ts +1 -1
  203. package/lib/typescript/native-stack/navigators/createNativeStackNavigator.d.ts.map +1 -1
  204. package/lib/typescript/native-stack/views/NativeStackView.d.ts +1 -2
  205. package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
  206. package/lib/typescript/native-stack/views/useHeaderConfigProps.d.ts +2 -2
  207. package/lib/typescript/shared/adapters/with-screen-transitions/context.d.ts +1 -1
  208. package/lib/typescript/shared/adapters/with-screen-transitions/context.d.ts.map +1 -1
  209. package/lib/typescript/shared/adapters/with-screen-transitions/stack-layout.d.ts +1 -1
  210. package/lib/typescript/shared/adapters/with-screen-transitions/stack-layout.d.ts.map +1 -1
  211. package/lib/typescript/shared/components/activity/variants/activity-container.d.ts +1 -1
  212. package/lib/typescript/shared/components/activity/variants/activity-container.d.ts.map +1 -1
  213. package/lib/typescript/shared/components/activity/variants/activity-screen.d.ts +1 -1
  214. package/lib/typescript/shared/components/activity/variants/activity-screen.d.ts.map +1 -1
  215. package/lib/typescript/shared/components/boundary/components/boundary-target.d.ts +1 -1
  216. package/lib/typescript/shared/components/boundary/components/boundary-target.d.ts.map +1 -1
  217. package/lib/typescript/shared/components/boundary/create-boundary-component.d.ts +0 -1
  218. package/lib/typescript/shared/components/boundary/create-boundary-component.d.ts.map +1 -1
  219. package/lib/typescript/shared/components/boundary/hooks/lifecycles/use-boundary-presence.d.ts +11 -0
  220. package/lib/typescript/shared/components/boundary/hooks/lifecycles/use-boundary-presence.d.ts.map +1 -0
  221. package/lib/typescript/shared/components/boundary/hooks/{use-initial-destination-measurement.d.ts → lifecycles/use-initial-destination-measurement.d.ts} +2 -2
  222. package/lib/typescript/shared/components/boundary/hooks/lifecycles/use-initial-destination-measurement.d.ts.map +1 -0
  223. package/lib/typescript/shared/components/boundary/hooks/lifecycles/use-initial-source-measurement.d.ts +8 -0
  224. package/lib/typescript/shared/components/boundary/hooks/lifecycles/use-initial-source-measurement.d.ts.map +1 -0
  225. package/lib/typescript/shared/components/boundary/hooks/{use-refresh-boundary.d.ts → lifecycles/use-refresh-boundary.d.ts} +2 -2
  226. package/lib/typescript/shared/components/boundary/hooks/lifecycles/use-refresh-boundary.d.ts.map +1 -0
  227. package/lib/typescript/shared/components/boundary/hooks/use-boundary-measurement.d.ts +5 -9
  228. package/lib/typescript/shared/components/boundary/hooks/use-boundary-measurement.d.ts.map +1 -1
  229. package/lib/typescript/shared/components/boundary/hooks/use-measurer.d.ts +4 -3
  230. package/lib/typescript/shared/components/boundary/hooks/use-measurer.d.ts.map +1 -1
  231. package/lib/typescript/shared/components/boundary/index.d.ts +35 -24
  232. package/lib/typescript/shared/components/boundary/index.d.ts.map +1 -1
  233. package/lib/typescript/shared/components/boundary/portal/components/boundary-local-portal-host.d.ts +8 -0
  234. package/lib/typescript/shared/components/boundary/portal/components/boundary-local-portal-host.d.ts.map +1 -0
  235. package/lib/typescript/shared/components/boundary/portal/components/host.d.ts +2 -2
  236. package/lib/typescript/shared/components/boundary/portal/components/host.d.ts.map +1 -1
  237. package/lib/typescript/shared/components/boundary/portal/components/portal-boundary-host.d.ts +2 -2
  238. package/lib/typescript/shared/components/boundary/portal/components/portal-boundary-host.d.ts.map +1 -1
  239. package/lib/typescript/shared/components/boundary/portal/components/portal-provider.d.ts +1 -1
  240. package/lib/typescript/shared/components/boundary/portal/components/portal-provider.d.ts.map +1 -1
  241. package/lib/typescript/shared/components/boundary/portal/components/portal.d.ts +4 -3
  242. package/lib/typescript/shared/components/boundary/portal/components/portal.d.ts.map +1 -1
  243. package/lib/typescript/shared/components/boundary/portal/hooks/use-host-measurement.d.ts.map +1 -1
  244. package/lib/typescript/shared/components/boundary/portal/stores/host-registry.store.d.ts +0 -7
  245. package/lib/typescript/shared/components/boundary/portal/stores/host-registry.store.d.ts.map +1 -1
  246. package/lib/typescript/shared/components/boundary/portal/stores/portal-boundary-host.store.d.ts +16 -1
  247. package/lib/typescript/shared/components/boundary/portal/stores/portal-boundary-host.store.d.ts.map +1 -1
  248. package/lib/typescript/shared/components/boundary/portal/teleport.d.ts +1 -1
  249. package/lib/typescript/shared/components/boundary/portal/teleport.d.ts.map +1 -1
  250. package/lib/typescript/shared/components/boundary/portal/utils/has-local-slot.d.ts +3 -0
  251. package/lib/typescript/shared/components/boundary/portal/utils/has-local-slot.d.ts.map +1 -0
  252. package/lib/typescript/shared/components/boundary/portal/utils/naming.d.ts +2 -1
  253. package/lib/typescript/shared/components/boundary/portal/utils/naming.d.ts.map +1 -1
  254. package/lib/typescript/shared/components/boundary/portal/utils/offset-style.d.ts +16 -32
  255. package/lib/typescript/shared/components/boundary/portal/utils/offset-style.d.ts.map +1 -1
  256. package/lib/typescript/shared/components/boundary/portal/utils/ownership.d.ts +35 -0
  257. package/lib/typescript/shared/components/boundary/portal/utils/ownership.d.ts.map +1 -0
  258. package/lib/typescript/shared/components/boundary/portal/utils/resolve-portal.d.ts +12 -0
  259. package/lib/typescript/shared/components/boundary/portal/utils/resolve-portal.d.ts.map +1 -0
  260. package/lib/typescript/shared/components/boundary/portal/utils/shallow-equal.d.ts +8 -0
  261. package/lib/typescript/shared/components/boundary/portal/utils/shallow-equal.d.ts.map +1 -0
  262. package/lib/typescript/shared/components/boundary/portal/utils/teleport-control.d.ts +4 -0
  263. package/lib/typescript/shared/components/boundary/portal/utils/teleport-control.d.ts.map +1 -1
  264. package/lib/typescript/shared/components/boundary/portal/utils/visible-host.d.ts +8 -0
  265. package/lib/typescript/shared/components/boundary/portal/utils/visible-host.d.ts.map +1 -0
  266. package/lib/typescript/shared/components/boundary/providers/boundary-root.provider.d.ts +7 -12
  267. package/lib/typescript/shared/components/boundary/providers/boundary-root.provider.d.ts.map +1 -1
  268. package/lib/typescript/shared/components/boundary/types.d.ts +9 -36
  269. package/lib/typescript/shared/components/boundary/types.d.ts.map +1 -1
  270. package/lib/typescript/shared/components/boundary/utils/destination-signals.d.ts.map +1 -1
  271. package/lib/typescript/shared/components/boundary/utils/refresh-signals.d.ts.map +1 -1
  272. package/lib/typescript/shared/components/boundary/utils/source-signals.d.ts +0 -1
  273. package/lib/typescript/shared/components/boundary/utils/source-signals.d.ts.map +1 -1
  274. package/lib/typescript/shared/components/create-transition-aware-component.d.ts +6 -5
  275. package/lib/typescript/shared/components/create-transition-aware-component.d.ts.map +1 -1
  276. package/lib/typescript/shared/components/masked-view.d.ts +1 -1
  277. package/lib/typescript/shared/components/masked-view.d.ts.map +1 -1
  278. package/lib/typescript/shared/components/overlay/variations/float-overlay.d.ts +1 -1
  279. package/lib/typescript/shared/components/overlay/variations/float-overlay.d.ts.map +1 -1
  280. package/lib/typescript/shared/components/overlay/variations/overlay-host.d.ts +1 -1
  281. package/lib/typescript/shared/components/overlay/variations/overlay-host.d.ts.map +1 -1
  282. package/lib/typescript/shared/components/scene-view.d.ts +1 -1
  283. package/lib/typescript/shared/components/scene-view.d.ts.map +1 -1
  284. package/lib/typescript/shared/components/screen-container/index.d.ts +1 -1
  285. package/lib/typescript/shared/components/screen-container/index.d.ts.map +1 -1
  286. package/lib/typescript/shared/components/screen-container/layers/backdrop.d.ts +1 -1
  287. package/lib/typescript/shared/components/screen-container/layers/backdrop.d.ts.map +1 -1
  288. package/lib/typescript/shared/components/screen-container/layers/content.d.ts +1 -1
  289. package/lib/typescript/shared/components/screen-container/layers/content.d.ts.map +1 -1
  290. package/lib/typescript/shared/components/screen-container/layers/maybe-masked-navigation-container.d.ts +1 -1
  291. package/lib/typescript/shared/components/screen-container/layers/maybe-masked-navigation-container.d.ts.map +1 -1
  292. package/lib/typescript/shared/components/screen-container/layers/surface-container.d.ts +1 -1
  293. package/lib/typescript/shared/components/screen-container/layers/surface-container.d.ts.map +1 -1
  294. package/lib/typescript/shared/hooks/navigation/use-stack.d.ts +1 -1
  295. package/lib/typescript/shared/hooks/navigation/use-stack.d.ts.map +1 -1
  296. package/lib/typescript/shared/index.d.ts +711 -667
  297. package/lib/typescript/shared/index.d.ts.map +1 -1
  298. package/lib/typescript/shared/providers/helpers/measured-bounds-writes.d.ts +3 -3
  299. package/lib/typescript/shared/providers/helpers/measured-bounds-writes.d.ts.map +1 -1
  300. package/lib/typescript/shared/providers/screen/animation/helpers/derivations.d.ts +1 -0
  301. package/lib/typescript/shared/providers/screen/animation/helpers/derivations.d.ts.map +1 -1
  302. package/lib/typescript/shared/providers/screen/animation/helpers/pipeline.d.ts.map +1 -1
  303. package/lib/typescript/shared/providers/screen/descriptors/descriptors.provider.d.ts +1 -1
  304. package/lib/typescript/shared/providers/screen/descriptors/descriptors.provider.d.ts.map +1 -1
  305. package/lib/typescript/shared/providers/screen/screen-composer.d.ts +1 -1
  306. package/lib/typescript/shared/providers/screen/screen-composer.d.ts.map +1 -1
  307. package/lib/typescript/shared/providers/screen/styles/components/floating-overlay-layer.d.ts +1 -1
  308. package/lib/typescript/shared/providers/screen/styles/components/floating-overlay-layer.d.ts.map +1 -1
  309. package/lib/typescript/shared/providers/screen/styles/helpers/compose-slot-style.d.ts +4 -0
  310. package/lib/typescript/shared/providers/screen/styles/helpers/compose-slot-style.d.ts.map +1 -0
  311. package/lib/typescript/shared/providers/screen/styles/helpers/normalize-slots.d.ts.map +1 -1
  312. package/lib/typescript/shared/providers/screen/styles/helpers/resolve-slot-styles/index.d.ts.map +1 -1
  313. package/lib/typescript/shared/providers/screen/styles/helpers/resolve-slot-styles/materialize-slot.d.ts +2 -1
  314. package/lib/typescript/shared/providers/screen/styles/helpers/resolve-slot-styles/materialize-slot.d.ts.map +1 -1
  315. package/lib/typescript/shared/providers/screen/styles/hooks/slot-resolvers.d.ts +11 -0
  316. package/lib/typescript/shared/providers/screen/styles/hooks/slot-resolvers.d.ts.map +1 -0
  317. package/lib/typescript/shared/providers/screen/styles/hooks/use-interpolated-style-maps.d.ts +4 -1
  318. package/lib/typescript/shared/providers/screen/styles/hooks/use-interpolated-style-maps.d.ts.map +1 -1
  319. package/lib/typescript/shared/providers/screen/styles/hooks/use-maybe-block-visibility.d.ts +2 -2
  320. package/lib/typescript/shared/providers/screen/styles/index.d.ts +2 -1
  321. package/lib/typescript/shared/providers/screen/styles/index.d.ts.map +1 -1
  322. package/lib/typescript/shared/providers/screen/styles/slot.provider.d.ts +5 -10
  323. package/lib/typescript/shared/providers/screen/styles/slot.provider.d.ts.map +1 -1
  324. package/lib/typescript/shared/providers/screen/styles/stores/slot-references.store.d.ts +6 -0
  325. package/lib/typescript/shared/providers/screen/styles/stores/slot-references.store.d.ts.map +1 -0
  326. package/lib/typescript/shared/stores/bounds/helpers/link-pairs.helpers.d.ts +2 -0
  327. package/lib/typescript/shared/stores/bounds/helpers/link-pairs.helpers.d.ts.map +1 -1
  328. package/lib/typescript/shared/stores/bounds/internals/entries.d.ts.map +1 -1
  329. package/lib/typescript/shared/stores/bounds/internals/links.d.ts +4 -3
  330. package/lib/typescript/shared/stores/bounds/internals/links.d.ts.map +1 -1
  331. package/lib/typescript/shared/stores/bounds/internals/resolver.d.ts.map +1 -1
  332. package/lib/typescript/shared/stores/bounds/types.d.ts +9 -20
  333. package/lib/typescript/shared/stores/bounds/types.d.ts.map +1 -1
  334. package/lib/typescript/shared/stores/system.store.d.ts +1 -0
  335. package/lib/typescript/shared/stores/system.store.d.ts.map +1 -1
  336. package/lib/typescript/shared/types/animation.types.d.ts +7 -1
  337. package/lib/typescript/shared/types/animation.types.d.ts.map +1 -1
  338. package/lib/typescript/shared/utils/bounds/helpers/styles/compute.d.ts.map +1 -1
  339. package/lib/typescript/shared/utils/bounds/helpers/styles/local-transform.d.ts +6 -0
  340. package/lib/typescript/shared/utils/bounds/helpers/styles/local-transform.d.ts.map +1 -0
  341. package/package.json +1 -1
  342. package/src/shared/components/boundary/components/boundary-target.tsx +21 -7
  343. package/src/shared/components/boundary/create-boundary-component.tsx +92 -28
  344. package/src/shared/components/boundary/hooks/{use-boundary-presence.ts → lifecycles/use-boundary-presence.ts} +16 -5
  345. package/src/shared/components/boundary/hooks/{use-initial-destination-measurement.ts → lifecycles/use-initial-destination-measurement.ts} +40 -13
  346. package/src/shared/components/boundary/hooks/{use-initial-source-measurement.ts → lifecycles/use-initial-source-measurement.ts} +7 -9
  347. package/src/shared/components/boundary/hooks/{use-refresh-boundary.ts → lifecycles/use-refresh-boundary.ts} +6 -6
  348. package/src/shared/components/boundary/hooks/use-boundary-measurement.ts +15 -45
  349. package/src/shared/components/boundary/hooks/use-measurer.ts +9 -14
  350. package/src/shared/components/boundary/index.tsx +55 -29
  351. package/src/shared/components/boundary/portal/components/boundary-local-portal-host.tsx +66 -0
  352. package/src/shared/components/boundary/portal/components/host.tsx +20 -5
  353. package/src/shared/components/boundary/portal/components/portal-boundary-host.tsx +67 -52
  354. package/src/shared/components/boundary/portal/components/portal.tsx +280 -119
  355. package/src/shared/components/boundary/portal/hooks/use-host-measurement.ts +23 -2
  356. package/src/shared/components/boundary/portal/stores/host-registry.store.ts +4 -51
  357. package/src/shared/components/boundary/portal/stores/portal-boundary-host.store.ts +59 -6
  358. package/src/shared/components/boundary/portal/teleport.ts +28 -3
  359. package/src/shared/components/boundary/portal/utils/has-local-slot.ts +16 -0
  360. package/src/shared/components/boundary/portal/utils/naming.ts +11 -1
  361. package/src/shared/components/boundary/portal/utils/offset-style.ts +37 -139
  362. package/src/shared/components/boundary/portal/utils/ownership.ts +371 -0
  363. package/src/shared/components/boundary/portal/utils/resolve-portal.ts +50 -0
  364. package/src/shared/components/boundary/portal/utils/shallow-equal.ts +25 -0
  365. package/src/shared/components/boundary/portal/utils/teleport-control.ts +12 -0
  366. package/src/shared/components/boundary/portal/utils/visible-host.ts +24 -0
  367. package/src/shared/components/boundary/providers/boundary-root.provider.tsx +9 -18
  368. package/src/shared/components/boundary/types.ts +9 -39
  369. package/src/shared/components/boundary/utils/destination-signals.ts +1 -32
  370. package/src/shared/components/boundary/utils/refresh-signals.ts +0 -41
  371. package/src/shared/components/boundary/utils/source-signals.ts +5 -17
  372. package/src/shared/index.ts +0 -5
  373. package/src/shared/providers/helpers/measured-bounds-writes.ts +6 -11
  374. package/src/shared/providers/screen/animation/helpers/derivations.ts +3 -0
  375. package/src/shared/providers/screen/animation/helpers/pipeline.ts +1 -0
  376. package/src/shared/providers/screen/styles/helpers/compose-slot-style.ts +129 -0
  377. package/src/shared/providers/screen/styles/helpers/normalize-slots.ts +45 -8
  378. package/src/shared/providers/screen/styles/helpers/resolve-slot-styles/index.ts +14 -2
  379. package/src/shared/providers/screen/styles/helpers/resolve-slot-styles/materialize-slot.ts +3 -0
  380. package/src/shared/providers/screen/styles/hooks/slot-resolvers.tsx +111 -0
  381. package/src/shared/providers/screen/styles/hooks/use-interpolated-style-maps.tsx +21 -3
  382. package/src/shared/providers/screen/styles/index.tsx +8 -3
  383. package/src/shared/providers/screen/styles/slot.provider.tsx +36 -54
  384. package/src/shared/providers/screen/styles/stores/slot-references.store.ts +71 -0
  385. package/src/shared/stores/bounds/helpers/link-pairs.helpers.ts +24 -1
  386. package/src/shared/stores/bounds/internals/entries.ts +13 -5
  387. package/src/shared/stores/bounds/internals/links.ts +167 -85
  388. package/src/shared/stores/bounds/internals/resolver.ts +0 -2
  389. package/src/shared/stores/bounds/types.ts +10 -22
  390. package/src/shared/stores/system.store.ts +6 -0
  391. package/src/shared/types/animation.types.ts +8 -1
  392. package/src/shared/utils/bounds/helpers/styles/compute.ts +22 -124
  393. package/src/shared/utils/bounds/helpers/styles/local-transform.ts +86 -0
  394. package/lib/commonjs/shared/components/boundary/hooks/use-boundary-presence.js.map +0 -1
  395. package/lib/commonjs/shared/components/boundary/hooks/use-initial-destination-measurement.js.map +0 -1
  396. package/lib/commonjs/shared/components/boundary/hooks/use-initial-source-measurement.js.map +0 -1
  397. package/lib/commonjs/shared/components/boundary/hooks/use-refresh-boundary.js.map +0 -1
  398. package/lib/commonjs/shared/components/boundary/portal/resolve-portal.js +0 -36
  399. package/lib/commonjs/shared/components/boundary/portal/resolve-portal.js.map +0 -1
  400. package/lib/commonjs/shared/components/boundary/portal/utils/attachment.js +0 -40
  401. package/lib/commonjs/shared/components/boundary/portal/utils/attachment.js.map +0 -1
  402. package/lib/module/shared/components/boundary/hooks/use-boundary-presence.js.map +0 -1
  403. package/lib/module/shared/components/boundary/hooks/use-initial-destination-measurement.js.map +0 -1
  404. package/lib/module/shared/components/boundary/hooks/use-initial-source-measurement.js.map +0 -1
  405. package/lib/module/shared/components/boundary/hooks/use-refresh-boundary.js.map +0 -1
  406. package/lib/module/shared/components/boundary/portal/resolve-portal.js +0 -31
  407. package/lib/module/shared/components/boundary/portal/resolve-portal.js.map +0 -1
  408. package/lib/module/shared/components/boundary/portal/utils/attachment.js +0 -35
  409. package/lib/module/shared/components/boundary/portal/utils/attachment.js.map +0 -1
  410. package/lib/typescript/shared/components/boundary/hooks/use-boundary-presence.d.ts +0 -9
  411. package/lib/typescript/shared/components/boundary/hooks/use-boundary-presence.d.ts.map +0 -1
  412. package/lib/typescript/shared/components/boundary/hooks/use-initial-destination-measurement.d.ts.map +0 -1
  413. package/lib/typescript/shared/components/boundary/hooks/use-initial-source-measurement.d.ts +0 -9
  414. package/lib/typescript/shared/components/boundary/hooks/use-initial-source-measurement.d.ts.map +0 -1
  415. package/lib/typescript/shared/components/boundary/hooks/use-refresh-boundary.d.ts.map +0 -1
  416. package/lib/typescript/shared/components/boundary/portal/resolve-portal.d.ts +0 -14
  417. package/lib/typescript/shared/components/boundary/portal/resolve-portal.d.ts.map +0 -1
  418. package/lib/typescript/shared/components/boundary/portal/utils/attachment.d.ts +0 -21
  419. package/lib/typescript/shared/components/boundary/portal/utils/attachment.d.ts.map +0 -1
  420. package/src/shared/components/boundary/portal/resolve-portal.ts +0 -40
  421. package/src/shared/components/boundary/portal/utils/attachment.ts +0 -48
@@ -7,41 +7,43 @@ import {
7
7
  useLayoutEffect,
8
8
  useState,
9
9
  } from "react";
10
- import type { View } from "react-native";
10
+ import type { LayoutRectangle, View } from "react-native";
11
11
  import Animated, {
12
12
  type AnimatedRef,
13
13
  runOnJS,
14
+ runOnUI,
14
15
  useAnimatedProps,
15
16
  useAnimatedReaction,
16
17
  useAnimatedStyle,
17
18
  useSharedValue,
18
19
  } from "react-native-reanimated";
20
+ import { EPSILON } from "../../../../constants";
19
21
  import { useDescriptorsStore } from "../../../../providers/screen/descriptors";
20
22
  import { useScreenSlots } from "../../../../providers/screen/styles";
23
+ import { useRegisteredScreenSlots } from "../../../../providers/screen/styles/stores/slot-references.store";
21
24
  import { AnimationStore } from "../../../../stores/animation.store";
22
- import { getLinkKeyFromTag } from "../../../../stores/bounds/helpers/link-pairs.helpers";
23
- import { getLink } from "../../../../stores/bounds/internals/links";
24
25
  import { pairs } from "../../../../stores/bounds/internals/state";
25
- import { createTransitionAwareComponent } from "../../../create-transition-aware-component";
26
- import type { BoundaryPortal, BoundaryPortalAttachTarget } from "../../types";
27
- import {
28
- getHostCapturesScroll,
29
- useActiveHostKey,
30
- } from "../stores/host-registry.store";
26
+ import { logger } from "../../../../utils/logger";
27
+ import { useActiveHostKey } from "../stores/host-registry.store";
31
28
  import {
29
+ dropStalePortalBoundaryHosts,
32
30
  mountPortalBoundaryHost,
33
31
  unmountPortalBoundaryHost,
34
32
  } from "../stores/portal-boundary-host.store";
35
33
  import { isTeleportAvailable, NativePortal } from "../teleport";
36
34
  import {
37
- type PortalAttachment,
38
- resolvePortalAttachmentTargets,
39
- } from "../utils/attachment";
40
- import {
35
+ createBoundaryLocalPortalHostName,
41
36
  createPortalBoundaryHostName,
42
37
  PORTAL_HOST_NAME_RESET_VALUE,
43
38
  } from "../utils/naming";
44
- import { isTeleportEnabled } from "../utils/teleport-control";
39
+ import {
40
+ canSwitchBoundaryLocalHandoffImmediately,
41
+ type PortalOwnershipSignal,
42
+ resolveBoundaryPortalOwnership,
43
+ } from "../utils/ownership";
44
+ import { shallowEqual } from "../utils/shallow-equal";
45
+ import { shouldAttachBoundaryPortal } from "../utils/teleport-control";
46
+ import { resolveNextVisiblePortalHostName } from "../utils/visible-host";
45
47
 
46
48
  type NullableHostNamePortalProps = Omit<
47
49
  ComponentProps<NonNullable<typeof NativePortal>>,
@@ -50,8 +52,8 @@ type NullableHostNamePortalProps = Omit<
50
52
  hostName?: string | null;
51
53
  };
52
54
 
53
- const TransitionAwareTeleport = NativePortal
54
- ? createTransitionAwareComponent(
55
+ const AnimatedNativePortal = NativePortal
56
+ ? Animated.createAnimatedComponent(
55
57
  NativePortal as ComponentType<NullableHostNamePortalProps>,
56
58
  )
57
59
  : null;
@@ -59,7 +61,8 @@ const TransitionAwareTeleport = NativePortal
59
61
  interface PortalProps {
60
62
  id?: string;
61
63
  children: ReactNode;
62
- mode?: BoundaryPortal;
64
+ handoff?: boolean;
65
+ escapeClipping?: boolean;
63
66
  /**
64
67
  * Ref to the layout-preserving placeholder wrapper. Boundaries measure
65
68
  * this instead of teleported content — the placeholder keeps the source
@@ -67,178 +70,318 @@ interface PortalProps {
67
70
  * host.
68
71
  */
69
72
  placeholderRef?: AnimatedRef<View>;
73
+ placeholderChildren?: ReactNode;
70
74
  }
71
75
 
72
76
  export const Portal = memo(function Portal({
73
- id = "my-id",
77
+ id,
74
78
  children,
75
- mode = false,
79
+ handoff = false,
80
+ escapeClipping = false,
76
81
  placeholderRef,
82
+ placeholderChildren,
77
83
  }: PortalProps) {
78
- // Teleporting requires the optional `react-native-teleport` peer. Without it,
79
- // a portal-enabled boundary degrades to inline rendering (the `return
80
- // children` path below).
81
- const isPortalEnabled = !!mode && isTeleportAvailable;
82
- const portalAttachTarget: BoundaryPortalAttachTarget =
83
- !mode || mode === true
84
- ? "current-screen"
85
- : (mode.attachTo ?? "current-screen");
86
- const { slotsMap } = useScreenSlots();
84
+ // Teleporting requires the optional `react-native-teleport` peer and a stable
85
+ // `id` to name the boundary host. Missing either degrades to inline rendering
86
+ // (the `return children` path below).
87
+ const isPortalEnabled =
88
+ (handoff || escapeClipping) && isTeleportAvailable && id !== undefined;
89
+ if (__DEV__ && (handoff || escapeClipping) && id === undefined) {
90
+ logger.warnOnce(
91
+ "portal:missing-id",
92
+ "A handoff or escapeClipping boundary was rendered without an id; rendering inline.",
93
+ );
94
+ }
95
+ const boundaryId = id ?? "";
96
+ const ownScreenSlots = useScreenSlots();
87
97
  const sourcePairKey = useDescriptorsStore((s) => s.derivations.sourcePairKey);
88
98
  const currentScreenKey = useDescriptorsStore(
89
99
  (s) => s.derivations.currentScreenKey,
90
100
  );
91
101
 
92
- const nextScreenKey = useDescriptorsStore((s) => s.derivations.nextScreenKey);
93
-
94
- const [attachment, setAttachment] = useState<PortalAttachment | null>(
95
- PORTAL_HOST_NAME_RESET_VALUE,
96
- );
97
- const attachedHostName = useSharedValue<string | null>(
98
- PORTAL_HOST_NAME_RESET_VALUE,
99
- );
102
+ const [ownership, setOwnership] = useState<Extract<
103
+ PortalOwnershipSignal,
104
+ { status: "complete" }
105
+ > | null>(null);
106
+ const styleOwnerScreenKey = ownership?.ownerScreenKey ?? currentScreenKey;
107
+ const ownerScreenSlots = useRegisteredScreenSlots(styleOwnerScreenKey);
108
+ const activeScreenSlots = ownerScreenSlots ?? ownScreenSlots;
109
+ const {
110
+ localStylesMaps: activeLocalStylesMaps,
111
+ nextInterpolatorReady: activeNextInterpolatorReady,
112
+ slotsMap: activeSlotsMap,
113
+ } = activeScreenSlots;
114
+ const requestedPortalHostName = useSharedValue<string | null>(null);
115
+ const visiblePortalHostName = useSharedValue<string | null>(null);
116
+ const canSwitchPortalHostImmediately = useSharedValue(0);
100
117
  const placeholderWidth = useSharedValue(0);
101
118
  const placeholderHeight = useSharedValue(0);
102
119
 
103
- const { progressScreenKey, targetScreenKey } = resolvePortalAttachmentTargets(
104
- {
105
- attachment,
106
- currentScreenKey,
107
- nextScreenKey,
108
- portalAttachTarget,
109
- sourcePairKey,
110
- },
120
+ const targetScreenKey = ownership ? ownership.hostScreenKey : null;
121
+ const settledHostScreenKey = ownership?.hostScreenKey ?? null;
122
+ const settledHostProgress = AnimationStore.getValue(
123
+ settledHostScreenKey ?? currentScreenKey,
124
+ "progressSettled",
125
+ );
126
+ const settledHostAnimating = AnimationStore.getValue(
127
+ settledHostScreenKey ?? currentScreenKey,
128
+ "progressAnimating",
129
+ );
130
+ const settledHostClosing = AnimationStore.getValue(
131
+ settledHostScreenKey ?? currentScreenKey,
132
+ "closing",
111
133
  );
112
- const activeHostKey = useActiveHostKey(targetScreenKey);
113
- const activeHostCapturesScroll = activeHostKey
114
- ? getHostCapturesScroll(activeHostKey)
115
- : false;
116
- const progress = AnimationStore.getValue(
117
- progressScreenKey ?? "",
118
- "transitionProgress",
134
+ const settledHostVisualProgress = AnimationStore.getValue(
135
+ settledHostScreenKey ?? currentScreenKey,
136
+ "visualProgress",
119
137
  );
120
- const closing = AnimationStore.getValue(progressScreenKey ?? "", "closing");
121
138
 
122
- const updatePortalAttachment = useCallback(
123
- (matchedScreenKey: string | null, pairKey?: string) => {
124
- if (matchedScreenKey && pairKey) {
125
- setAttachment((current) => {
139
+ const activeHostKey = useActiveHostKey(
140
+ escapeClipping ? targetScreenKey : null,
141
+ );
142
+ const boundaryLocalHostName =
143
+ handoff && !escapeClipping && targetScreenKey
144
+ ? createBoundaryLocalPortalHostName(targetScreenKey, boundaryId)
145
+ : null;
146
+
147
+ const updatePortalOwnership = useCallback(
148
+ (
149
+ hostScreenKey: string | null,
150
+ ownerPairKey?: string,
151
+ ownerScreenKey?: string,
152
+ ) => {
153
+ if (hostScreenKey && ownerPairKey && ownerScreenKey) {
154
+ setOwnership((current) => {
126
155
  if (
127
- current?.matchedScreenKey === matchedScreenKey &&
128
- current.pairKey === pairKey
156
+ current?.hostScreenKey === hostScreenKey &&
157
+ current.ownerPairKey === ownerPairKey &&
158
+ current.ownerScreenKey === ownerScreenKey
129
159
  ) {
130
160
  return current;
131
161
  }
132
162
 
133
163
  return {
134
- matchedScreenKey,
135
- pairKey,
164
+ hostScreenKey,
165
+ ownerPairKey,
166
+ ownerScreenKey,
167
+ status: "complete",
136
168
  };
137
169
  });
138
170
  return;
139
171
  }
140
172
 
141
- setAttachment((current) => (current ? null : current));
173
+ setOwnership((current) => (current ? null : current));
142
174
  },
143
175
  [],
144
176
  );
145
177
 
146
178
  useLayoutEffect(() => {
147
- if (!isPortalEnabled || !attachment || !activeHostKey || !targetScreenKey) {
148
- attachedHostName.set(PORTAL_HOST_NAME_RESET_VALUE);
179
+ if (!isPortalEnabled || !ownership || !targetScreenKey) {
180
+ requestedPortalHostName.set(null);
181
+ visiblePortalHostName.set(null);
182
+ unmountPortalBoundaryHost(boundaryId);
149
183
  return;
150
184
  }
151
185
 
186
+ if (boundaryLocalHostName) {
187
+ requestedPortalHostName.set(boundaryLocalHostName);
188
+ unmountPortalBoundaryHost(boundaryId);
189
+ return;
190
+ }
191
+
192
+ if (!escapeClipping || !activeHostKey) {
193
+ requestedPortalHostName.set(null);
194
+ visiblePortalHostName.set(null);
195
+ unmountPortalBoundaryHost(boundaryId);
196
+ return;
197
+ }
198
+
199
+ const portalHostName = createPortalBoundaryHostName(
200
+ activeHostKey,
201
+ boundaryId,
202
+ ownership.ownerPairKey,
203
+ );
204
+
152
205
  mountPortalBoundaryHost({
153
- boundaryId: id,
154
- capturesScroll: activeHostCapturesScroll,
206
+ boundaryId,
207
+ escapeClipping,
155
208
  hostKey: activeHostKey,
156
- pairKey: attachment.pairKey,
209
+ localStylesMaps: activeLocalStylesMaps,
210
+ pairKey: ownership.ownerPairKey,
211
+ portalHostName,
157
212
  screenKey: targetScreenKey,
213
+ slotsMap: activeSlotsMap,
158
214
  });
159
215
 
160
- // The native registry parks portals whose host has not registered yet and
161
- // re-parents the moment it does, so the host name can be handed over
162
- // immediately ordering belongs to the registry, not to frame counting.
163
- // hostName rides animated props, so the handover needs no React commit.
164
- attachedHostName.set(createPortalBoundaryHostName(activeHostKey, id));
216
+ // Request the new receiver immediately, but keep the currently visible
217
+ // receiver until the new interpolator is ready. This avoids a no-host gap
218
+ // during A -> B(closing) -> C(opening) spam retargets.
219
+ requestedPortalHostName.set(portalHostName);
165
220
  }, [
166
221
  activeHostKey,
167
- activeHostCapturesScroll,
168
- attachedHostName,
169
- attachment,
170
- id,
222
+ boundaryId,
223
+ escapeClipping,
171
224
  isPortalEnabled,
225
+ activeLocalStylesMaps,
226
+ activeSlotsMap,
227
+ ownership,
228
+ boundaryLocalHostName,
229
+ requestedPortalHostName,
172
230
  targetScreenKey,
231
+ visiblePortalHostName,
173
232
  ]);
174
233
 
175
234
  useLayoutEffect(() => {
176
235
  return () => {
177
- attachedHostName.set(PORTAL_HOST_NAME_RESET_VALUE);
178
- unmountPortalBoundaryHost(id);
236
+ requestedPortalHostName.set(null);
237
+ visiblePortalHostName.set(null);
238
+ unmountPortalBoundaryHost(boundaryId);
179
239
  };
180
- }, [attachedHostName, id]);
240
+ }, [boundaryId, requestedPortalHostName, visiblePortalHostName]);
181
241
 
182
242
  useAnimatedReaction(
183
243
  () => {
184
244
  "worklet";
185
245
  if (!isPortalEnabled || !sourcePairKey) {
186
- return null;
246
+ return {
247
+ hostScreenKey: null,
248
+ ownerPairKey: sourcePairKey,
249
+ ownerScreenKey: null,
250
+ status: "clear",
251
+ };
187
252
  }
188
253
 
189
- pairs.get();
190
- // Strict per-member lookup: getResolvedLink's group fallback borrows
191
- // the initial member's link for style resolution, which would make
192
- // every inactive group member's portal see a "complete" link and
193
- // attach. A portal may only teleport on its OWN member's link.
194
- const link = getLink(sourcePairKey, id);
195
-
196
- if (link?.status !== "complete") {
197
- return null;
254
+ return resolveBoundaryPortalOwnership({
255
+ boundaryId,
256
+ currentScreenKey,
257
+ escapeClipping,
258
+ handoff,
259
+ isSettledHostClosingComplete:
260
+ !!settledHostClosing.get() &&
261
+ settledHostVisualProgress.get() <= EPSILON,
262
+ isSettledHostReady:
263
+ settledHostProgress.get() === 1 && settledHostAnimating.get() === 0,
264
+ pairsState: pairs.get(),
265
+ settledHostScreenKey,
266
+ sourcePairKey,
267
+ });
268
+ },
269
+ (signal, previousSignal) => {
270
+ "worklet";
271
+ if (shallowEqual(previousSignal, signal)) {
272
+ return;
198
273
  }
199
274
 
200
- // Grouped portals teleport only while their member is the group's
201
- // active id — retargeting detaches the previous member (its content
202
- // returns home) and attaches the new one. Exactly one grouped member
203
- // is teleported at a time.
204
- if (link.group) {
205
- const activeId =
206
- pairs.get()[sourcePairKey]?.groups?.[link.group]?.activeId;
275
+ if (!handoff || escapeClipping) {
276
+ canSwitchPortalHostImmediately.set(0);
277
+ } else if (signal.status === "pending") {
278
+ canSwitchPortalHostImmediately.set(0);
279
+ return;
280
+ } else {
281
+ const hostScreenKey =
282
+ signal.status === "complete" ? signal.hostScreenKey : null;
283
+ let previousOwnerPairKey: string | undefined;
207
284
 
208
- if (activeId && activeId !== getLinkKeyFromTag(id)) {
209
- return null;
285
+ if (previousSignal?.status === "complete") {
286
+ previousOwnerPairKey = previousSignal.ownerPairKey ?? undefined;
287
+ }
288
+ const canSwitchImmediately = canSwitchBoundaryLocalHandoffImmediately({
289
+ hostScreenKey,
290
+ ownerPairKey:
291
+ signal.status === "complete" ? signal.ownerPairKey : undefined,
292
+ previousOwnerPairKey,
293
+ });
294
+
295
+ canSwitchPortalHostImmediately.set(canSwitchImmediately ? 1 : 0);
296
+
297
+ if (canSwitchImmediately && hostScreenKey) {
298
+ const hostName = createBoundaryLocalPortalHostName(
299
+ hostScreenKey,
300
+ boundaryId,
301
+ );
302
+ requestedPortalHostName.set(hostName);
303
+ visiblePortalHostName.set(hostName);
210
304
  }
211
305
  }
212
306
 
213
- return link.destination.screenKey;
307
+ runOnJS(updatePortalOwnership)(
308
+ signal.hostScreenKey,
309
+ signal.ownerPairKey,
310
+ signal.ownerScreenKey ?? undefined,
311
+ );
214
312
  },
215
- (matchedScreenKey, previousMatchedScreenKey) => {
313
+ );
314
+
315
+ useAnimatedReaction(
316
+ () => {
216
317
  "worklet";
217
- if (matchedScreenKey === previousMatchedScreenKey) {
318
+ const slot = activeSlotsMap.get()[boundaryId];
319
+ const teleport = slot?.props?.teleport;
320
+ const shouldTeleport = shouldAttachBoundaryPortal({
321
+ enabled: isPortalEnabled,
322
+ teleport,
323
+ });
324
+ const requestedName = requestedPortalHostName.get();
325
+ const visibleName = visiblePortalHostName.get();
326
+ const isInterpolatorReady = activeNextInterpolatorReady.get();
327
+ const nextVisibleName = resolveNextVisiblePortalHostName({
328
+ canSwitchImmediately: canSwitchPortalHostImmediately.get() === 1,
329
+ isInterpolatorReady: isInterpolatorReady === 1,
330
+ requestedName,
331
+ shouldTeleport,
332
+ visibleName,
333
+ });
334
+
335
+ return {
336
+ isInterpolatorReady,
337
+ nextVisibleName,
338
+ requestedName,
339
+ shouldTeleport,
340
+ teleport,
341
+ visibleName,
342
+ };
343
+ },
344
+ (state, previousState) => {
345
+ "worklet";
346
+ if (shallowEqual(previousState, state)) {
347
+ return;
348
+ }
349
+
350
+ if (state.nextVisibleName !== state.visibleName) {
351
+ visiblePortalHostName.set(state.nextVisibleName);
218
352
  return;
219
353
  }
220
354
 
221
- runOnJS(updatePortalAttachment)(matchedScreenKey, sourcePairKey);
355
+ // Visible receiver has caught up to the request: GC the superseded hosts.
356
+ if (state.visibleName && state.visibleName === state.requestedName) {
357
+ runOnJS(dropStalePortalBoundaryHosts)({
358
+ boundaryId,
359
+ keepPortalHostName: state.visibleName,
360
+ });
361
+ }
222
362
  },
223
363
  );
224
364
 
225
365
  const teleportProps = useAnimatedProps(() => {
226
366
  "worklet";
227
367
 
228
- // Opening waits for the destination transition to start so content is not
229
- // re-parented before the host is visually ready. Closing stays attached
230
- // through progress 0 so the final frame can land in the matched host.
231
- const attachThreshold = closing.get() === 1 ? 0 : 0.001;
232
- const { teleport, ...slotProps } = slotsMap.get()[id]?.props ?? {};
233
- const shouldTeleport = isTeleportEnabled(teleport);
368
+ const slot = activeSlotsMap.get()[boundaryId];
369
+ const { teleport, ...slotProps } = slot?.props ?? {};
370
+ const shouldTeleport = shouldAttachBoundaryPortal({
371
+ enabled: isPortalEnabled,
372
+ teleport,
373
+ });
374
+ const visibleName = visiblePortalHostName.get();
234
375
 
235
376
  return {
236
377
  // Preserve portal slot props from the interpolator while keeping
237
- // hostName owned by the attachment gate below.
378
+ // hostName owned by the attachment gate below. Handoff
379
+ // waits until the receiving interpolator owns styles for the same host;
380
+ // after that, it stays attached until teleport is disabled or retargeted.
238
381
  ...slotProps,
239
382
  hostName:
240
- shouldTeleport && progress.get() >= attachThreshold
241
- ? attachedHostName.get()
383
+ shouldTeleport && visibleName
384
+ ? visibleName
242
385
  : PORTAL_HOST_NAME_RESET_VALUE,
243
386
  };
244
387
  });
@@ -249,8 +392,7 @@ export const Portal = memo(function Portal({
249
392
  // cannot collapse the slot.
250
393
  const placeholderStyle = useAnimatedStyle(() => {
251
394
  "worklet";
252
- const hostName = attachedHostName.get();
253
- const isAttached = hostName !== null;
395
+ const isAttached = visiblePortalHostName.get() !== null;
254
396
  const width = placeholderWidth.get();
255
397
  const height = placeholderHeight.get();
256
398
 
@@ -261,20 +403,39 @@ export const Portal = memo(function Portal({
261
403
  return { width, height };
262
404
  });
263
405
 
264
- if (isPortalEnabled && TransitionAwareTeleport) {
406
+ const handleOnLayout = useCallback(
407
+ (layout: LayoutRectangle) => {
408
+ "worklet";
409
+ const { width, height } = layout;
410
+ if (width === 0 || height === 0) {
411
+ return;
412
+ }
413
+
414
+ const hasValidDimensions =
415
+ placeholderHeight.get() !== 0 && placeholderWidth.get() !== 0;
416
+
417
+ if (!hasValidDimensions) {
418
+ placeholderWidth.set(width);
419
+ placeholderHeight.set(height);
420
+ }
421
+ },
422
+ [placeholderHeight, placeholderWidth],
423
+ );
424
+
425
+ if (isPortalEnabled && AnimatedNativePortal) {
265
426
  return (
266
427
  <Animated.View
267
428
  ref={placeholderRef}
268
- onLayout={(event) => {
269
- placeholderWidth.set(event.nativeEvent.layout.width);
270
- placeholderHeight.set(event.nativeEvent.layout.height);
271
- }}
429
+ onLayout={({ nativeEvent: { layout } }) =>
430
+ runOnUI(handleOnLayout)(layout)
431
+ }
272
432
  style={placeholderStyle}
273
433
  collapsable={false}
274
434
  >
275
- <TransitionAwareTeleport animatedProps={teleportProps} name={id}>
435
+ {placeholderChildren}
436
+ <AnimatedNativePortal animatedProps={teleportProps} name={boundaryId}>
276
437
  <Animated.View style={placeholderStyle}>{children}</Animated.View>
277
- </TransitionAwareTeleport>
438
+ </AnimatedNativePortal>
278
439
  </Animated.View>
279
440
  );
280
441
  }
@@ -1,12 +1,15 @@
1
1
  import { useLayoutEffect, useState } from "react";
2
2
  import type { View } from "react-native";
3
3
  import {
4
+ cancelAnimation,
4
5
  measure,
5
6
  runOnJS,
6
7
  runOnUI,
7
8
  useAnimatedReaction,
8
9
  useAnimatedRef,
9
10
  useSharedValue,
11
+ withDelay,
12
+ withTiming,
10
13
  } from "react-native-reanimated";
11
14
  import { useOriginContext } from "../../../../providers/screen/origin.provider";
12
15
  import { ScrollStore } from "../../../../stores/scroll.store";
@@ -19,6 +22,8 @@ import {
19
22
  setPortalHostBounds,
20
23
  } from "../stores/host-bounds.store";
21
24
 
25
+ const HOST_MEASUREMENT_RETRY_DELAY_MS = 16;
26
+
22
27
  type UseHostMeasurementParams = {
23
28
  capturesScroll: boolean;
24
29
  enabled: boolean;
@@ -37,6 +42,7 @@ export const useHostMeasurement = ({
37
42
  const [canRenderHosts, setCanRenderHosts] = useState<boolean>(false);
38
43
  const { originRef } = useOriginContext();
39
44
  const hasMeasuredHost = useSharedValue(false);
45
+ const retryToken = useSharedValue(0);
40
46
 
41
47
  useAnimatedReaction(
42
48
  () => {
@@ -45,10 +51,17 @@ export const useHostMeasurement = ({
45
51
  return null;
46
52
  }
47
53
 
48
- return hasMeasuredHost.get();
54
+ return [hasMeasuredHost.get(), retryToken.get()] as const;
49
55
  },
50
- (hasAlreadyMeasured) => {
56
+ (state) => {
51
57
  "worklet";
58
+ if (!state) {
59
+ cancelAnimation(retryToken);
60
+ return;
61
+ }
62
+
63
+ const [hasAlreadyMeasured] = state;
64
+
52
65
  if (!enabled || hasAlreadyMeasured) {
53
66
  return;
54
67
  }
@@ -57,9 +70,17 @@ export const useHostMeasurement = ({
57
70
  const measuredOrigin = measure(originRef);
58
71
 
59
72
  if (!measured || !measuredOrigin) {
73
+ cancelAnimation(retryToken);
74
+ retryToken.set(
75
+ withDelay(
76
+ HOST_MEASUREMENT_RETRY_DELAY_MS,
77
+ withTiming(retryToken.get() + 1, { duration: 0 }),
78
+ ),
79
+ );
60
80
  return;
61
81
  }
62
82
 
83
+ cancelAnimation(retryToken);
63
84
  hasMeasuredHost.set(true);
64
85
 
65
86
  // A measurement taken mid rubber-band would bake the transient