react-native-screen-transitions 3.11.2 → 3.11.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 (255) hide show
  1. package/lib/commonjs/native-stack/views/NativeStackView.native.js +1 -1
  2. package/lib/commonjs/native-stack/views/NativeStackView.native.js.map +1 -1
  3. package/lib/commonjs/shared/components/boundary/components/boundary-lifecycle.js +36 -0
  4. package/lib/commonjs/shared/components/boundary/components/boundary-lifecycle.js.map +1 -0
  5. package/lib/commonjs/shared/components/boundary/hooks/lifecycles/use-initial-destination-measurement.js +1 -13
  6. package/lib/commonjs/shared/components/boundary/hooks/lifecycles/use-initial-destination-measurement.js.map +1 -1
  7. package/lib/commonjs/shared/components/boundary/hooks/lifecycles/use-refresh-boundary.js +9 -2
  8. package/lib/commonjs/shared/components/boundary/hooks/lifecycles/use-refresh-boundary.js.map +1 -1
  9. package/lib/commonjs/shared/components/boundary/hooks/use-boundary-measurement.js +3 -2
  10. package/lib/commonjs/shared/components/boundary/hooks/use-boundary-measurement.js.map +1 -1
  11. package/lib/commonjs/shared/components/boundary/hooks/use-measurer.js +9 -2
  12. package/lib/commonjs/shared/components/boundary/hooks/use-measurer.js.map +1 -1
  13. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/components/host.js +5 -12
  14. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/components/host.js.map +1 -1
  15. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/components/portal-boundary-host.js +25 -43
  16. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/components/portal-boundary-host.js.map +1 -1
  17. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/helpers/local-measurement.js +13 -0
  18. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/helpers/local-measurement.js.map +1 -0
  19. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/helpers/offset-style.js +8 -31
  20. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/helpers/offset-style.js.map +1 -1
  21. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/hooks/use-active-portal-boundary-host.js +14 -19
  22. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/hooks/use-active-portal-boundary-host.js.map +1 -1
  23. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/hooks/use-boundary-portal-attachment.js +8 -0
  24. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/hooks/use-boundary-portal-attachment.js.map +1 -1
  25. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/hooks/use-host-measurement.js +19 -47
  26. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/hooks/use-host-measurement.js.map +1 -1
  27. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/index.js.map +1 -1
  28. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/stores/portal-boundary-host.store.js +1 -1
  29. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/stores/portal-boundary-host.store.js.map +1 -1
  30. package/lib/commonjs/shared/components/boundary/providers/boundary-root.provider.js +19 -17
  31. package/lib/commonjs/shared/components/boundary/providers/boundary-root.provider.js.map +1 -1
  32. package/lib/commonjs/shared/components/boundary/utils/refresh-signals.js +19 -5
  33. package/lib/commonjs/shared/components/boundary/utils/refresh-signals.js.map +1 -1
  34. package/lib/commonjs/shared/components/screen-container/layers/backdrop.js +11 -7
  35. package/lib/commonjs/shared/components/screen-container/layers/backdrop.js.map +1 -1
  36. package/lib/commonjs/shared/components/screen-lifecycle/hooks/helpers/close-interception-rules.js +31 -0
  37. package/lib/commonjs/shared/components/screen-lifecycle/hooks/helpers/close-interception-rules.js.map +1 -0
  38. package/lib/commonjs/shared/components/screen-lifecycle/hooks/use-close-completion.js +26 -0
  39. package/lib/commonjs/shared/components/screen-lifecycle/hooks/use-close-completion.js.map +1 -0
  40. package/lib/commonjs/shared/components/screen-lifecycle/hooks/use-close-transition-intent.js +60 -86
  41. package/lib/commonjs/shared/components/screen-lifecycle/hooks/use-close-transition-intent.js.map +1 -1
  42. package/lib/commonjs/shared/components/screen-lifecycle/hooks/use-transition-start-controller.js +1 -5
  43. package/lib/commonjs/shared/components/screen-lifecycle/hooks/use-transition-start-controller.js.map +1 -1
  44. package/lib/commonjs/shared/components/screen-lifecycle/index.js +9 -6
  45. package/lib/commonjs/shared/components/screen-lifecycle/index.js.map +1 -1
  46. package/lib/commonjs/shared/hooks/navigation/use-navigation-helpers.js +28 -6
  47. package/lib/commonjs/shared/hooks/navigation/use-navigation-helpers.js.map +1 -1
  48. package/lib/commonjs/shared/providers/helpers/measured-bounds-writes.js +1 -2
  49. package/lib/commonjs/shared/providers/helpers/measured-bounds-writes.js.map +1 -1
  50. package/lib/commonjs/shared/providers/screen/gestures/hooks/use-screen-gesture-config.js +9 -2
  51. package/lib/commonjs/shared/providers/screen/gestures/hooks/use-screen-gesture-config.js.map +1 -1
  52. package/lib/commonjs/shared/providers/screen/gestures/pan/behavior/pan-lifecycle.js +4 -5
  53. package/lib/commonjs/shared/providers/screen/gestures/pan/behavior/pan-lifecycle.js.map +1 -1
  54. package/lib/commonjs/shared/providers/screen/gestures/pan/behavior/use-pan-behavior.js +2 -3
  55. package/lib/commonjs/shared/providers/screen/gestures/pan/behavior/use-pan-behavior.js.map +1 -1
  56. package/lib/commonjs/shared/providers/screen/gestures/pinch/behavior/pinch-lifecycle.js +4 -5
  57. package/lib/commonjs/shared/providers/screen/gestures/pinch/behavior/pinch-lifecycle.js.map +1 -1
  58. package/lib/commonjs/shared/providers/screen/gestures/pinch/behavior/use-pinch-behavior.js +2 -3
  59. package/lib/commonjs/shared/providers/screen/gestures/pinch/behavior/use-pinch-behavior.js.map +1 -1
  60. package/lib/commonjs/shared/providers/screen/gestures/shared/policy.js +9 -5
  61. package/lib/commonjs/shared/providers/screen/gestures/shared/policy.js.map +1 -1
  62. package/lib/commonjs/shared/providers/stack/blank-stack-state/blank-stack-controller.js +5 -1
  63. package/lib/commonjs/shared/providers/stack/blank-stack-state/blank-stack-controller.js.map +1 -1
  64. package/lib/commonjs/shared/stores/bounds/internals/links.js +1 -1
  65. package/lib/commonjs/shared/stores/bounds/internals/links.js.map +1 -1
  66. package/lib/commonjs/shared/stores/system.store.js +1 -2
  67. package/lib/commonjs/shared/stores/system.store.js.map +1 -1
  68. package/lib/commonjs/shared/utils/animation/animate-to-progress.js +0 -22
  69. package/lib/commonjs/shared/utils/animation/animate-to-progress.js.map +1 -1
  70. package/lib/commonjs/shared/utils/navigation/close-action-replay.js +22 -0
  71. package/lib/commonjs/shared/utils/navigation/close-action-replay.js.map +1 -0
  72. package/lib/module/native-stack/views/NativeStackView.native.js +1 -1
  73. package/lib/module/native-stack/views/NativeStackView.native.js.map +1 -1
  74. package/lib/module/shared/components/boundary/components/boundary-lifecycle.js +32 -0
  75. package/lib/module/shared/components/boundary/components/boundary-lifecycle.js.map +1 -0
  76. package/lib/module/shared/components/boundary/hooks/lifecycles/use-initial-destination-measurement.js +1 -13
  77. package/lib/module/shared/components/boundary/hooks/lifecycles/use-initial-destination-measurement.js.map +1 -1
  78. package/lib/module/shared/components/boundary/hooks/lifecycles/use-refresh-boundary.js +9 -2
  79. package/lib/module/shared/components/boundary/hooks/lifecycles/use-refresh-boundary.js.map +1 -1
  80. package/lib/module/shared/components/boundary/hooks/use-boundary-measurement.js +3 -2
  81. package/lib/module/shared/components/boundary/hooks/use-boundary-measurement.js.map +1 -1
  82. package/lib/module/shared/components/boundary/hooks/use-measurer.js +9 -2
  83. package/lib/module/shared/components/boundary/hooks/use-measurer.js.map +1 -1
  84. package/lib/module/shared/components/boundary/portal/components/boundary-portal/components/host.js +5 -12
  85. package/lib/module/shared/components/boundary/portal/components/boundary-portal/components/host.js.map +1 -1
  86. package/lib/module/shared/components/boundary/portal/components/boundary-portal/components/portal-boundary-host.js +27 -45
  87. package/lib/module/shared/components/boundary/portal/components/boundary-portal/components/portal-boundary-host.js.map +1 -1
  88. package/lib/module/shared/components/boundary/portal/components/boundary-portal/helpers/local-measurement.js +8 -0
  89. package/lib/module/shared/components/boundary/portal/components/boundary-portal/helpers/local-measurement.js.map +1 -0
  90. package/lib/module/shared/components/boundary/portal/components/boundary-portal/helpers/offset-style.js +8 -32
  91. package/lib/module/shared/components/boundary/portal/components/boundary-portal/helpers/offset-style.js.map +1 -1
  92. package/lib/module/shared/components/boundary/portal/components/boundary-portal/hooks/use-active-portal-boundary-host.js +15 -20
  93. package/lib/module/shared/components/boundary/portal/components/boundary-portal/hooks/use-active-portal-boundary-host.js.map +1 -1
  94. package/lib/module/shared/components/boundary/portal/components/boundary-portal/hooks/use-boundary-portal-attachment.js +8 -0
  95. package/lib/module/shared/components/boundary/portal/components/boundary-portal/hooks/use-boundary-portal-attachment.js.map +1 -1
  96. package/lib/module/shared/components/boundary/portal/components/boundary-portal/hooks/use-host-measurement.js +20 -48
  97. package/lib/module/shared/components/boundary/portal/components/boundary-portal/hooks/use-host-measurement.js.map +1 -1
  98. package/lib/module/shared/components/boundary/portal/components/boundary-portal/index.js.map +1 -1
  99. package/lib/module/shared/components/boundary/portal/components/boundary-portal/stores/portal-boundary-host.store.js +1 -1
  100. package/lib/module/shared/components/boundary/portal/components/boundary-portal/stores/portal-boundary-host.store.js.map +1 -1
  101. package/lib/module/shared/components/boundary/providers/boundary-root.provider.js +20 -18
  102. package/lib/module/shared/components/boundary/providers/boundary-root.provider.js.map +1 -1
  103. package/lib/module/shared/components/boundary/utils/refresh-signals.js +19 -5
  104. package/lib/module/shared/components/boundary/utils/refresh-signals.js.map +1 -1
  105. package/lib/module/shared/components/screen-container/layers/backdrop.js +12 -8
  106. package/lib/module/shared/components/screen-container/layers/backdrop.js.map +1 -1
  107. package/lib/module/shared/components/screen-lifecycle/hooks/helpers/close-interception-rules.js +25 -0
  108. package/lib/module/shared/components/screen-lifecycle/hooks/helpers/close-interception-rules.js.map +1 -0
  109. package/lib/module/shared/components/screen-lifecycle/hooks/use-close-completion.js +21 -0
  110. package/lib/module/shared/components/screen-lifecycle/hooks/use-close-completion.js.map +1 -0
  111. package/lib/module/shared/components/screen-lifecycle/hooks/use-close-transition-intent.js +60 -85
  112. package/lib/module/shared/components/screen-lifecycle/hooks/use-close-transition-intent.js.map +1 -1
  113. package/lib/module/shared/components/screen-lifecycle/hooks/use-transition-start-controller.js +1 -5
  114. package/lib/module/shared/components/screen-lifecycle/hooks/use-transition-start-controller.js.map +1 -1
  115. package/lib/module/shared/components/screen-lifecycle/index.js +9 -6
  116. package/lib/module/shared/components/screen-lifecycle/index.js.map +1 -1
  117. package/lib/module/shared/hooks/navigation/use-navigation-helpers.js +29 -7
  118. package/lib/module/shared/hooks/navigation/use-navigation-helpers.js.map +1 -1
  119. package/lib/module/shared/providers/helpers/measured-bounds-writes.js +1 -2
  120. package/lib/module/shared/providers/helpers/measured-bounds-writes.js.map +1 -1
  121. package/lib/module/shared/providers/screen/gestures/hooks/use-screen-gesture-config.js +9 -2
  122. package/lib/module/shared/providers/screen/gestures/hooks/use-screen-gesture-config.js.map +1 -1
  123. package/lib/module/shared/providers/screen/gestures/pan/behavior/pan-lifecycle.js +4 -5
  124. package/lib/module/shared/providers/screen/gestures/pan/behavior/pan-lifecycle.js.map +1 -1
  125. package/lib/module/shared/providers/screen/gestures/pan/behavior/use-pan-behavior.js +2 -3
  126. package/lib/module/shared/providers/screen/gestures/pan/behavior/use-pan-behavior.js.map +1 -1
  127. package/lib/module/shared/providers/screen/gestures/pinch/behavior/pinch-lifecycle.js +4 -5
  128. package/lib/module/shared/providers/screen/gestures/pinch/behavior/pinch-lifecycle.js.map +1 -1
  129. package/lib/module/shared/providers/screen/gestures/pinch/behavior/use-pinch-behavior.js +2 -3
  130. package/lib/module/shared/providers/screen/gestures/pinch/behavior/use-pinch-behavior.js.map +1 -1
  131. package/lib/module/shared/providers/screen/gestures/shared/policy.js +9 -5
  132. package/lib/module/shared/providers/screen/gestures/shared/policy.js.map +1 -1
  133. package/lib/module/shared/providers/stack/blank-stack-state/blank-stack-controller.js +5 -1
  134. package/lib/module/shared/providers/stack/blank-stack-state/blank-stack-controller.js.map +1 -1
  135. package/lib/module/shared/stores/bounds/internals/links.js +1 -1
  136. package/lib/module/shared/stores/bounds/internals/links.js.map +1 -1
  137. package/lib/module/shared/stores/system.store.js +1 -2
  138. package/lib/module/shared/stores/system.store.js.map +1 -1
  139. package/lib/module/shared/utils/animation/animate-to-progress.js +0 -22
  140. package/lib/module/shared/utils/animation/animate-to-progress.js.map +1 -1
  141. package/lib/module/shared/utils/navigation/close-action-replay.js +16 -0
  142. package/lib/module/shared/utils/navigation/close-action-replay.js.map +1 -0
  143. package/lib/typescript/native-stack/views/NativeStackView.native.d.ts.map +1 -1
  144. package/lib/typescript/shared/components/boundary/components/boundary-lifecycle.d.ts +18 -0
  145. package/lib/typescript/shared/components/boundary/components/boundary-lifecycle.d.ts.map +1 -0
  146. package/lib/typescript/shared/components/boundary/hooks/lifecycles/use-initial-destination-measurement.d.ts +1 -2
  147. package/lib/typescript/shared/components/boundary/hooks/lifecycles/use-initial-destination-measurement.d.ts.map +1 -1
  148. package/lib/typescript/shared/components/boundary/hooks/lifecycles/use-refresh-boundary.d.ts.map +1 -1
  149. package/lib/typescript/shared/components/boundary/hooks/use-boundary-measurement.d.ts +3 -2
  150. package/lib/typescript/shared/components/boundary/hooks/use-boundary-measurement.d.ts.map +1 -1
  151. package/lib/typescript/shared/components/boundary/hooks/use-measurer.d.ts +3 -2
  152. package/lib/typescript/shared/components/boundary/hooks/use-measurer.d.ts.map +1 -1
  153. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/components/host.d.ts.map +1 -1
  154. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/components/portal-boundary-host.d.ts +5 -1
  155. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/components/portal-boundary-host.d.ts.map +1 -1
  156. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/helpers/local-measurement.d.ts +4 -0
  157. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/helpers/local-measurement.d.ts.map +1 -0
  158. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/helpers/offset-style.d.ts +4 -17
  159. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/helpers/offset-style.d.ts.map +1 -1
  160. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/hooks/use-active-portal-boundary-host.d.ts +3 -1
  161. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/hooks/use-active-portal-boundary-host.d.ts.map +1 -1
  162. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/hooks/use-boundary-portal-attachment.d.ts.map +1 -1
  163. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/hooks/use-host-measurement.d.ts +5 -9
  164. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/hooks/use-host-measurement.d.ts.map +1 -1
  165. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/stores/portal-boundary-host.store.d.ts +2 -1
  166. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/stores/portal-boundary-host.store.d.ts.map +1 -1
  167. package/lib/typescript/shared/components/boundary/providers/boundary-root.provider.d.ts +2 -1
  168. package/lib/typescript/shared/components/boundary/providers/boundary-root.provider.d.ts.map +1 -1
  169. package/lib/typescript/shared/components/boundary/types.d.ts +6 -0
  170. package/lib/typescript/shared/components/boundary/types.d.ts.map +1 -1
  171. package/lib/typescript/shared/components/boundary/utils/refresh-signals.d.ts +1 -0
  172. package/lib/typescript/shared/components/boundary/utils/refresh-signals.d.ts.map +1 -1
  173. package/lib/typescript/shared/components/screen-container/layers/backdrop.d.ts.map +1 -1
  174. package/lib/typescript/shared/components/screen-lifecycle/hooks/helpers/close-interception-rules.d.ts +27 -0
  175. package/lib/typescript/shared/components/screen-lifecycle/hooks/helpers/close-interception-rules.d.ts.map +1 -0
  176. package/lib/typescript/shared/components/screen-lifecycle/hooks/use-close-completion.d.ts +7 -0
  177. package/lib/typescript/shared/components/screen-lifecycle/hooks/use-close-completion.d.ts.map +1 -0
  178. package/lib/typescript/shared/components/screen-lifecycle/hooks/use-close-transition-intent.d.ts +2 -7
  179. package/lib/typescript/shared/components/screen-lifecycle/hooks/use-close-transition-intent.d.ts.map +1 -1
  180. package/lib/typescript/shared/components/screen-lifecycle/hooks/use-transition-start-controller.d.ts +1 -3
  181. package/lib/typescript/shared/components/screen-lifecycle/hooks/use-transition-start-controller.d.ts.map +1 -1
  182. package/lib/typescript/shared/components/screen-lifecycle/index.d.ts.map +1 -1
  183. package/lib/typescript/shared/hooks/navigation/use-navigation-helpers.d.ts +1 -0
  184. package/lib/typescript/shared/hooks/navigation/use-navigation-helpers.d.ts.map +1 -1
  185. package/lib/typescript/shared/providers/screen/gestures/hooks/use-screen-gesture-config.d.ts.map +1 -1
  186. package/lib/typescript/shared/providers/screen/gestures/pan/behavior/pan-lifecycle.d.ts +1 -1
  187. package/lib/typescript/shared/providers/screen/gestures/pan/behavior/pan-lifecycle.d.ts.map +1 -1
  188. package/lib/typescript/shared/providers/screen/gestures/pan/behavior/use-pan-behavior.d.ts.map +1 -1
  189. package/lib/typescript/shared/providers/screen/gestures/pinch/behavior/pinch-lifecycle.d.ts +1 -1
  190. package/lib/typescript/shared/providers/screen/gestures/pinch/behavior/pinch-lifecycle.d.ts.map +1 -1
  191. package/lib/typescript/shared/providers/screen/gestures/pinch/behavior/use-pinch-behavior.d.ts.map +1 -1
  192. package/lib/typescript/shared/providers/screen/gestures/shared/policy.d.ts +2 -1
  193. package/lib/typescript/shared/providers/screen/gestures/shared/policy.d.ts.map +1 -1
  194. package/lib/typescript/shared/providers/screen/gestures/types.d.ts +2 -0
  195. package/lib/typescript/shared/providers/screen/gestures/types.d.ts.map +1 -1
  196. package/lib/typescript/shared/providers/stack/blank-stack-state/blank-stack-controller.d.ts.map +1 -1
  197. package/lib/typescript/shared/stores/system.store.d.ts +1 -2
  198. package/lib/typescript/shared/stores/system.store.d.ts.map +1 -1
  199. package/lib/typescript/shared/utils/animation/animate-to-progress.d.ts +2 -3
  200. package/lib/typescript/shared/utils/animation/animate-to-progress.d.ts.map +1 -1
  201. package/lib/typescript/shared/utils/navigation/close-action-replay.d.ts +4 -0
  202. package/lib/typescript/shared/utils/navigation/close-action-replay.d.ts.map +1 -0
  203. package/package.json +1 -1
  204. package/src/native-stack/views/NativeStackView.native.tsx +3 -1
  205. package/src/shared/components/boundary/components/boundary-lifecycle.tsx +53 -0
  206. package/src/shared/components/boundary/hooks/lifecycles/use-initial-destination-measurement.ts +0 -14
  207. package/src/shared/components/boundary/hooks/lifecycles/use-refresh-boundary.ts +13 -2
  208. package/src/shared/components/boundary/hooks/use-boundary-measurement.ts +7 -2
  209. package/src/shared/components/boundary/hooks/use-measurer.ts +11 -1
  210. package/src/shared/components/boundary/portal/components/boundary-portal/components/host.tsx +13 -11
  211. package/src/shared/components/boundary/portal/components/boundary-portal/components/portal-boundary-host.tsx +44 -55
  212. package/src/shared/components/boundary/portal/components/boundary-portal/helpers/local-measurement.ts +10 -0
  213. package/src/shared/components/boundary/portal/components/boundary-portal/helpers/offset-style.ts +11 -55
  214. package/src/shared/components/boundary/portal/components/boundary-portal/hooks/use-active-portal-boundary-host.ts +20 -24
  215. package/src/shared/components/boundary/portal/components/boundary-portal/hooks/use-boundary-portal-attachment.ts +11 -0
  216. package/src/shared/components/boundary/portal/components/boundary-portal/hooks/use-host-measurement.ts +20 -67
  217. package/src/shared/components/boundary/portal/components/boundary-portal/index.tsx +1 -0
  218. package/src/shared/components/boundary/portal/components/boundary-portal/stores/portal-boundary-host.store.ts +3 -2
  219. package/src/shared/components/boundary/providers/boundary-root.provider.tsx +29 -20
  220. package/src/shared/components/boundary/types.ts +9 -0
  221. package/src/shared/components/boundary/utils/refresh-signals.ts +39 -6
  222. package/src/shared/components/screen-container/layers/backdrop.tsx +11 -7
  223. package/src/shared/components/screen-lifecycle/hooks/helpers/close-interception-rules.ts +64 -0
  224. package/src/shared/components/screen-lifecycle/hooks/use-close-completion.ts +28 -0
  225. package/src/shared/components/screen-lifecycle/hooks/use-close-transition-intent.ts +67 -108
  226. package/src/shared/components/screen-lifecycle/hooks/use-transition-start-controller.ts +0 -12
  227. package/src/shared/components/screen-lifecycle/index.tsx +8 -4
  228. package/src/shared/hooks/navigation/use-navigation-helpers.ts +39 -7
  229. package/src/shared/providers/helpers/measured-bounds-writes.ts +1 -1
  230. package/src/shared/providers/screen/gestures/hooks/use-screen-gesture-config.ts +9 -1
  231. package/src/shared/providers/screen/gestures/pan/behavior/pan-lifecycle.ts +4 -6
  232. package/src/shared/providers/screen/gestures/pan/behavior/use-pan-behavior.ts +1 -3
  233. package/src/shared/providers/screen/gestures/pinch/behavior/pinch-lifecycle.ts +4 -6
  234. package/src/shared/providers/screen/gestures/pinch/behavior/use-pinch-behavior.ts +2 -8
  235. package/src/shared/providers/screen/gestures/shared/policy.ts +17 -6
  236. package/src/shared/providers/screen/gestures/types.ts +2 -0
  237. package/src/shared/providers/stack/blank-stack-state/blank-stack-controller.ts +5 -1
  238. package/src/shared/stores/bounds/internals/links.ts +1 -1
  239. package/src/shared/stores/system.store.ts +1 -2
  240. package/src/shared/utils/animation/animate-to-progress.ts +1 -22
  241. package/src/shared/utils/navigation/close-action-replay.ts +25 -0
  242. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/helpers/active-pair.js +0 -30
  243. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/helpers/active-pair.js.map +0 -1
  244. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/stores/host-bounds.store.js +0 -47
  245. package/lib/commonjs/shared/components/boundary/portal/components/boundary-portal/stores/host-bounds.store.js.map +0 -1
  246. package/lib/module/shared/components/boundary/portal/components/boundary-portal/helpers/active-pair.js +0 -25
  247. package/lib/module/shared/components/boundary/portal/components/boundary-portal/helpers/active-pair.js.map +0 -1
  248. package/lib/module/shared/components/boundary/portal/components/boundary-portal/stores/host-bounds.store.js +0 -40
  249. package/lib/module/shared/components/boundary/portal/components/boundary-portal/stores/host-bounds.store.js.map +0 -1
  250. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/helpers/active-pair.d.ts +0 -9
  251. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/helpers/active-pair.d.ts.map +0 -1
  252. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/stores/host-bounds.store.d.ts +0 -9
  253. package/lib/typescript/shared/components/boundary/portal/components/boundary-portal/stores/host-bounds.store.d.ts.map +0 -1
  254. package/src/shared/components/boundary/portal/components/boundary-portal/helpers/active-pair.ts +0 -36
  255. package/src/shared/components/boundary/portal/components/boundary-portal/stores/host-bounds.store.ts +0 -45
@@ -0,0 +1,53 @@
1
+ import { memo } from "react";
2
+ import type { View } from "react-native";
3
+ import type { AnimatedRef } from "react-native-reanimated";
4
+ import { useDescriptorsStore } from "../../../providers/screen/descriptors";
5
+ import type { BoundTag } from "../../../stores/bounds/types";
6
+ import { useBoundaryMeasurement } from "../hooks/use-boundary-measurement";
7
+ import type {
8
+ BoundaryConfigProps,
9
+ BoundaryLocalMeasurementValue,
10
+ } from "../types";
11
+
12
+ interface BoundaryLifecycleProps {
13
+ boundTag: BoundTag;
14
+ config: BoundaryConfigProps;
15
+ currentScreenKey: string;
16
+ enabled: boolean;
17
+ escapeClipping: boolean;
18
+ handoff: boolean;
19
+ localMeasurement: BoundaryLocalMeasurementValue;
20
+ measuredRef: AnimatedRef<View>;
21
+ style?: unknown;
22
+ }
23
+
24
+ export const BoundaryLifecycle = memo(function BoundaryLifecycle({
25
+ boundTag,
26
+ config,
27
+ currentScreenKey,
28
+ enabled,
29
+ escapeClipping,
30
+ handoff,
31
+ localMeasurement,
32
+ measuredRef,
33
+ style,
34
+ }: BoundaryLifecycleProps) {
35
+ const hasConfiguredInterpolator = useDescriptorsStore(
36
+ (s) => s.derivations.hasConfiguredInterpolator,
37
+ );
38
+
39
+ useBoundaryMeasurement({
40
+ boundTag,
41
+ enabled,
42
+ runtimeEnabled: enabled && hasConfiguredInterpolator,
43
+ currentScreenKey,
44
+ measuredRef,
45
+ style,
46
+ handoff,
47
+ escapeClipping,
48
+ localMeasurement,
49
+ config,
50
+ });
51
+
52
+ return null;
53
+ });
@@ -39,14 +39,12 @@ const MAX_HANDSHAKE_RETRIES = 20;
39
39
  interface UseInitialDestinationMeasurementParams {
40
40
  boundTag: BoundTag;
41
41
  enabled: boolean;
42
- escapeClipping: boolean;
43
42
  measureBoundary: MeasureBoundary;
44
43
  }
45
44
 
46
45
  export const useInitialDestinationMeasurement = ({
47
46
  boundTag,
48
47
  enabled,
49
- escapeClipping,
50
48
  measureBoundary,
51
49
  }: UseInitialDestinationMeasurementParams) => {
52
50
  const { tag, linkKey, group } = boundTag;
@@ -142,18 +140,12 @@ export const useInitialDestinationMeasurement = ({
142
140
  runOnUI(claimLifecycleStartBlock)();
143
141
 
144
142
  return () => {
145
- if (escapeClipping) {
146
- // The portal host owns the release after this boundary hands off.
147
- return;
148
- }
149
-
150
143
  // This is an abandonment fallback, not a second release. Run it on the UI
151
144
  // runtime so it serializes with the handshake's guarded release.
152
145
  runOnUI(releaseLifecycleStartBlock)();
153
146
  };
154
147
  }, [
155
148
  claimLifecycleStartBlock,
156
- escapeClipping,
157
149
  canReceiveDestination,
158
150
  releaseLifecycleStartBlock,
159
151
  ]);
@@ -247,12 +239,6 @@ export const useInitialDestinationMeasurement = ({
247
239
  cancelAnimation(retryToken);
248
240
  handshakeRetries.set(0);
249
241
  hasFinishedInitialMeasurement.set(1);
250
- if (escapeClipping) {
251
- // Screen-level escape has a second readiness phase after destination
252
- // matching: the host must commit before the transition starts, or
253
- // the payload can disappear for a frame.
254
- return;
255
- }
256
242
  releaseLifecycleStartBlock();
257
243
  return;
258
244
  }
@@ -33,14 +33,24 @@ export const useRefreshBoundary = ({
33
33
  refreshScreenKey,
34
34
  "willAnimate",
35
35
  );
36
+ const refreshSettled = AnimationStore.getValue(
37
+ refreshScreenKey,
38
+ "progressSettled",
39
+ );
36
40
  const refreshClosing = AnimationStore.getValue(refreshScreenKey, "closing");
37
41
 
38
42
  useAnimatedReaction(
39
43
  () => {
40
44
  "worklet";
41
45
 
42
- const shouldRefresh = enabled && !!refreshWillAnimate.get();
43
- if (!shouldRefresh) {
46
+ if (!enabled) return null;
47
+
48
+ const shouldRefresh = !!refreshWillAnimate.get();
49
+ const settled = !!refreshSettled.get();
50
+ // A group's active member can change while the transition is settled
51
+ // (for example, paging a destination gallery). Let that member publish
52
+ // fresh bounds even though there is no willAnimate lifecycle pulse yet.
53
+ if (!shouldRefresh && (!group || !settled)) {
44
54
  return null;
45
55
  }
46
56
  const sourcePairKey =
@@ -56,6 +66,7 @@ export const useRefreshBoundary = ({
56
66
  linkId: linkKey,
57
67
  group,
58
68
  shouldRefresh,
69
+ settled,
59
70
  closing: !!refreshClosing.get(),
60
71
  linkState: pairs.get(),
61
72
  });
@@ -3,7 +3,10 @@ import type { View } from "react-native";
3
3
  import type { AnimatedRef } from "react-native-reanimated";
4
4
  import type { BoundTag } from "../../../stores/bounds/types";
5
5
  import { prepareStyleForBounds } from "../../../utils/bounds/helpers/styles/styles";
6
- import type { BoundaryConfigProps } from "../types";
6
+ import type {
7
+ BoundaryConfigProps,
8
+ BoundaryLocalMeasurementValue,
9
+ } from "../types";
7
10
  import { useBoundaryPresence } from "./lifecycles/use-boundary-presence";
8
11
  import { useInitialDestinationMeasurement } from "./lifecycles/use-initial-destination-measurement";
9
12
  import { useInitialSourceMeasurement } from "./lifecycles/use-initial-source-measurement";
@@ -23,6 +26,7 @@ interface UseBoundaryMeasurementParams {
23
26
  style?: unknown;
24
27
  handoff: boolean;
25
28
  escapeClipping: boolean;
29
+ localMeasurement: BoundaryLocalMeasurementValue;
26
30
  config: BoundaryConfigProps;
27
31
  }
28
32
 
@@ -40,6 +44,7 @@ export const useBoundaryMeasurement = ({
40
44
  style,
41
45
  handoff,
42
46
  escapeClipping,
47
+ localMeasurement,
43
48
  config,
44
49
  }: UseBoundaryMeasurementParams) => {
45
50
  const { anchor, scaleMode, target, method } = config;
@@ -58,6 +63,7 @@ export const useBoundaryMeasurement = ({
58
63
  measuredAnimatedRef: measuredRef,
59
64
  handoff,
60
65
  escapeClipping,
66
+ localMeasurement,
61
67
  });
62
68
 
63
69
  // Presence and source capture must not depend on this screen owning an
@@ -81,7 +87,6 @@ export const useBoundaryMeasurement = ({
81
87
  useInitialDestinationMeasurement({
82
88
  boundTag,
83
89
  enabled: runtimeEnabled,
84
- escapeClipping,
85
90
  measureBoundary,
86
91
  });
87
92
 
@@ -8,7 +8,7 @@ import type { BoundTag } from "../../../stores/bounds/types";
8
8
  import { ScrollStore } from "../../../stores/scroll.store";
9
9
  import { SystemStore } from "../../../stores/system.store";
10
10
  import { getVisibilityBlockOffset } from "../../../utils/visibility-block-offset";
11
- import type { MeasureBoundary } from "../types";
11
+ import type { BoundaryLocalMeasurementValue, MeasureBoundary } from "../types";
12
12
  import {
13
13
  attachScrollSnapshotToMeasuredBounds,
14
14
  correctMeasuredBoundsForVisibilityGate,
@@ -24,6 +24,7 @@ interface UseMeasurerParams {
24
24
  measuredAnimatedRef: AnimatedRef<View>;
25
25
  handoff: boolean;
26
26
  escapeClipping: boolean;
27
+ localMeasurement: BoundaryLocalMeasurementValue;
27
28
  }
28
29
 
29
30
  export const useMeasurer = ({
@@ -34,6 +35,7 @@ export const useMeasurer = ({
34
35
  measuredAnimatedRef,
35
36
  handoff,
36
37
  escapeClipping,
38
+ localMeasurement,
37
39
  }: UseMeasurerParams): MeasureBoundary => {
38
40
  const { width: viewportWidth, height: viewportHeight } =
39
41
  useWindowDimensions();
@@ -66,6 +68,13 @@ export const useMeasurer = ({
66
68
  viewportHeight,
67
69
  });
68
70
 
71
+ if (escapeClipping && target.type === "source") {
72
+ localMeasurement.set({
73
+ bounds: measured,
74
+ pairKey: target.pairKey,
75
+ });
76
+ }
77
+
69
78
  /**
70
79
  * - Destination Pass -
71
80
  * Be strict while lifecycle start is blocked for destination capture.
@@ -112,6 +121,7 @@ export const useMeasurer = ({
112
121
  measuredAnimatedRef,
113
122
  handoff,
114
123
  escapeClipping,
124
+ localMeasurement,
115
125
  viewportWidth,
116
126
  viewportHeight,
117
127
  scrollState,
@@ -8,7 +8,6 @@ import {
8
8
  } from "react-native";
9
9
  import Animated from "react-native-reanimated";
10
10
  import { useDescriptorsStore } from "../../../../../../providers/screen/descriptors";
11
- import { useScreenSlots } from "../../../../../../providers/screen/styles";
12
11
  import { PORTAL_POINTER_EVENTS } from "../../../teleport";
13
12
  import { useHostMeasurement } from "../hooks/use-host-measurement";
14
13
  import { registerHost, unregisterHost } from "../stores/host-registry.store";
@@ -34,20 +33,17 @@ function HostImpl({ fallback = false, style }: HostImplProps) {
34
33
  }
35
34
 
36
35
  const hostKey = fallback ? screenKey : generatedHostKeyRef.current;
37
- const capturesScroll = !fallback;
38
36
  const activeBoundaryHosts = useActivePortalBoundaryHosts(hostKey);
39
- const { visibilityBlocked } = useScreenSlots();
37
+
40
38
  const { height: viewportHeight, width: viewportWidth } =
41
39
  useWindowDimensions();
42
40
 
41
+ const measurementKey = activeBoundaryHosts.length
42
+ ? activeBoundaryHosts.map((host) => host.portalHostName).join("|")
43
+ : null;
44
+
43
45
  const measurement = useHostMeasurement({
44
- capturesScroll,
45
- enabled: activeBoundaryHosts.length > 0,
46
- hostKey,
47
- screenKey,
48
- visibilityBlocked,
49
- viewportHeight,
50
- viewportWidth,
46
+ measurementKey,
51
47
  });
52
48
 
53
49
  useLayoutEffect(() => {
@@ -71,7 +67,13 @@ function HostImpl({ fallback = false, style }: HostImplProps) {
71
67
  { width: viewportWidth, height: viewportHeight },
72
68
  ]}
73
69
  >
74
- <PortalBoundaryHost host={host} style={StyleSheet.absoluteFill} />
70
+ <PortalBoundaryHost
71
+ host={host}
72
+ hostBounds={measurement.hostBounds}
73
+ hostMeasurementKey={measurementKey}
74
+ measuredHostKey={measurement.measuredKey}
75
+ style={StyleSheet.absoluteFill}
76
+ />
75
77
  </View>
76
78
  ));
77
79
 
@@ -1,4 +1,4 @@
1
- import { memo, useCallback } from "react";
1
+ import { memo } from "react";
2
2
  import {
3
3
  I18nManager,
4
4
  type StyleProp,
@@ -6,97 +6,86 @@ import {
6
6
  type ViewStyle,
7
7
  } from "react-native";
8
8
  import Animated, {
9
+ type MeasuredDimensions,
10
+ type SharedValue,
11
+ useAnimatedReaction,
9
12
  useAnimatedStyle,
10
- useFrameCallback,
11
- useSharedValue,
12
13
  } from "react-native-reanimated";
13
14
  import { NO_STYLES } from "../../../../../../constants";
14
15
  import { composeSlotStyleWithLocalTransform } from "../../../../../../providers/screen/styles/helpers/compose-slot-style";
15
- import { getLink } from "../../../../../../stores/bounds/internals/links";
16
- import { SystemStore } from "../../../../../../stores/system.store";
17
- import type { ScrollMeasuredDimensions } from "../../../../utils/measured-bounds";
18
16
  import { NativePortalHost, PORTAL_POINTER_EVENTS } from "../../../teleport";
17
+ import { resolveBoundaryLocalMeasurement } from "../helpers/local-measurement";
19
18
  import { resolvePortalOffsetStyle } from "../helpers/offset-style";
20
- import { getPortalHostBounds } from "../stores/host-bounds.store";
21
19
  import type { ActivePortalBoundaryHost } from "../stores/portal-boundary-host.store";
22
20
 
23
21
  const AnimatedPortalBoundaryHost = NativePortalHost
24
22
  ? Animated.createAnimatedComponent(NativePortalHost)
25
23
  : null;
26
24
 
25
+ const getCurrentBoundaryBounds = (host: ActivePortalBoundaryHost) => {
26
+ "worklet";
27
+ return resolveBoundaryLocalMeasurement(
28
+ host.localMeasurement.get(),
29
+ host.pairKey,
30
+ );
31
+ };
32
+
27
33
  type PortalBoundaryHostProps = {
28
34
  host: ActivePortalBoundaryHost;
35
+ hostBounds: SharedValue<MeasuredDimensions | null>;
36
+ hostMeasurementKey: string | null;
37
+ measuredHostKey: SharedValue<string | null>;
29
38
  style?: StyleProp<ViewStyle>;
30
39
  };
31
40
 
32
41
  export const PortalBoundaryHost = memo(function PortalBoundaryHost({
33
42
  host,
43
+ hostBounds,
44
+ hostMeasurementKey,
45
+ measuredHostKey,
34
46
  style,
35
47
  }: PortalBoundaryHostProps) {
36
- const geometryReadyFrames = useSharedValue(0);
37
- const { unblockLifecycleStart } = SystemStore.getBag(host.screenKey).actions;
38
-
39
- const handleFrame = useCallback(() => {
40
- "worklet";
41
- if (host.portalHostReady.get()) {
42
- return;
43
- }
44
-
45
- const link = getLink(host.pairKey, host.boundaryId);
46
- const hasSource = !!link?.source;
47
- const hasHostBounds = getPortalHostBounds(host.hostKey) !== null;
48
- const hasSlot = host.slotsMap.get()[host.boundaryId] !== undefined;
49
- const hasGeometry = hasSource && hasHostBounds && hasSlot;
50
-
51
- if (!hasGeometry) {
52
- geometryReadyFrames.set(0);
53
- return;
54
- }
55
-
56
- if (geometryReadyFrames.get() === 0) {
57
- // Give the source frame, host offset, and slot style one UI frame to
58
- // reach native before Teleport targets this receiver.
59
- geometryReadyFrames.set(1);
60
- return;
61
- }
62
-
63
- host.portalHostReady.set(true);
64
- unblockLifecycleStart();
65
- }, [geometryReadyFrames, host, unblockLifecycleStart]);
66
-
67
- useFrameCallback(handleFrame, true);
48
+ useAnimatedReaction(
49
+ () => {
50
+ "worklet";
51
+ return (
52
+ getCurrentBoundaryBounds(host) !== null &&
53
+ hostBounds.get() !== null &&
54
+ !!hostMeasurementKey &&
55
+ measuredHostKey.get() === hostMeasurementKey
56
+ );
57
+ },
58
+ (ready) => {
59
+ "worklet";
60
+ if (ready) {
61
+ host.portalHostReady.set(true);
62
+ }
63
+ },
64
+ );
68
65
 
69
66
  const hostStyle = useAnimatedStyle(() => {
70
67
  "worklet";
71
- // Strict per-member lookup - a fallback member's source rect would
72
- // misplace this host's teleported content.
73
- const link = getLink(host.pairKey, host.boundaryId);
74
- if (!link?.source) {
68
+ const boundaryBounds = getCurrentBoundaryBounds(host);
69
+ if (!boundaryBounds) {
75
70
  return NO_STYLES;
76
71
  }
77
72
 
78
- const sourceBounds = link.source.bounds as ScrollMeasuredDimensions;
79
- const isCrossScreenPortal = link.source.screenKey !== host.screenKey;
80
-
81
73
  return resolvePortalOffsetStyle({
82
- bounds: sourceBounds,
83
- hostKey: host.hostKey,
84
- placement: isCrossScreenPortal ? "cross-screen" : "same-screen",
74
+ bounds: boundaryBounds,
75
+ hostBounds: hostBounds.get(),
85
76
  });
86
77
  });
87
78
 
88
79
  const contentFrameStyle = useAnimatedStyle(() => {
89
80
  "worklet";
90
- const link = getLink(host.pairKey, host.boundaryId);
91
- if (!link?.source) {
81
+ const boundaryBounds = getCurrentBoundaryBounds(host);
82
+ if (!boundaryBounds) {
92
83
  return NO_STYLES;
93
84
  }
94
85
 
95
- const sourceBounds = link.source.bounds as ScrollMeasuredDimensions;
96
-
97
86
  return {
98
- height: sourceBounds.height,
99
- width: sourceBounds.width,
87
+ height: boundaryBounds.height,
88
+ width: boundaryBounds.width,
100
89
  };
101
90
  });
102
91
  const slotStyle = useAnimatedStyle(() => {
@@ -0,0 +1,10 @@
1
+ import type { ScreenPairKey } from "../../../../../../stores/bounds/types";
2
+ import type { BoundaryLocalMeasurement } from "../../../../types";
3
+
4
+ export const resolveBoundaryLocalMeasurement = (
5
+ measurement: BoundaryLocalMeasurement | null,
6
+ pairKey: ScreenPairKey,
7
+ ) => {
8
+ "worklet";
9
+ return measurement?.pairKey === pairKey ? measurement.bounds : null;
10
+ };
@@ -1,69 +1,25 @@
1
- import type { StyleProps } from "react-native-reanimated";
2
- import { getClampedScrollAxisDelta } from "../../../../../../stores/scroll.store";
3
- import type { ScrollMeasuredDimensions } from "../../../../utils/measured-bounds";
4
- import { getPortalHostBounds } from "../stores/host-bounds.store";
5
-
6
- /**
7
- * The two portal coordinate cases we support:
8
- *
9
- * - same-screen: source and host live on the same screen; re-base the stored
10
- * host frame onto the source measurement's scroll snapshot.
11
- * - cross-screen: source and host live on different screens; the host is the
12
- * replacement coordinate space, so destination scroll is inherited naturally
13
- * from host placement instead of manually propagated.
14
- */
15
- export type PortalOffsetPlacement = "same-screen" | "cross-screen";
1
+ import type { MeasuredDimensions, StyleProps } from "react-native-reanimated";
16
2
 
17
3
  type ResolvePortalOffsetStyleParams = {
18
- /** Source rect, carrying the scroll snapshot taken at measure time. */
19
- bounds: ScrollMeasuredDimensions;
20
- hostKey: string;
21
- placement: PortalOffsetPlacement;
4
+ bounds: MeasuredDimensions;
5
+ hostBounds: MeasuredDimensions | null;
22
6
  };
23
7
 
24
8
  export const resolvePortalOffsetStyle = ({
25
9
  bounds,
26
- hostKey,
27
- placement,
10
+ hostBounds,
28
11
  }: ResolvePortalOffsetStyleParams): StyleProps => {
29
12
  "worklet";
30
- const hostBounds = getPortalHostBounds(hostKey);
31
- const boundsScrollSnapshot = bounds.scroll ?? null;
32
- const hostBoundsScrollSnapshot = hostBounds?.scroll ?? null;
33
-
34
- // same-screen re-bases the static host frame onto the source scroll snapshot.
35
- // Cross-screen hosts are the chosen replacement coordinate space, so their
36
- // destination scroll is represented by where the host itself is mounted.
37
- const alignHostToBoundsScroll = placement === "same-screen";
38
-
39
- const hostSnapshotDeltaX = alignHostToBoundsScroll
40
- ? getClampedScrollAxisDelta(
41
- boundsScrollSnapshot,
42
- hostBoundsScrollSnapshot,
43
- "horizontal",
44
- )
45
- : 0;
46
- const hostSnapshotDeltaY = alignHostToBoundsScroll
47
- ? getClampedScrollAxisDelta(
48
- boundsScrollSnapshot,
49
- hostBoundsScrollSnapshot,
50
- "vertical",
51
- )
52
- : 0;
53
-
54
- // Without registered host bounds the host frame is the origin, so the source
55
- // page position becomes the offset directly.
56
- const adjustedHostPageX = hostBounds
57
- ? hostBounds.pageX - hostSnapshotDeltaX
58
- : 0;
59
- const adjustedHostPageY = hostBounds
60
- ? hostBounds.pageY - hostSnapshotDeltaY
61
- : 0;
13
+ // Both values are measured in page coordinates. Subtracting the host origin
14
+ // gives the boundary's local position inside that host, independent of which
15
+ // scroll container owns either view.
16
+ const hostPageX = hostBounds?.pageX ?? 0;
17
+ const hostPageY = hostBounds?.pageY ?? 0;
62
18
 
63
19
  return {
64
20
  transform: [
65
- { translateY: bounds.pageY - adjustedHostPageY },
66
- { translateX: bounds.pageX - adjustedHostPageX },
21
+ { translateY: bounds.pageY - hostPageY },
22
+ { translateX: bounds.pageX - hostPageX },
67
23
  ],
68
24
  };
69
25
  };
@@ -1,4 +1,4 @@
1
- import { useCallback, useLayoutEffect, useRef, useState } from "react";
1
+ import { useCallback, useLayoutEffect, useState } from "react";
2
2
  import {
3
3
  runOnJS,
4
4
  type SharedValue,
@@ -7,6 +7,7 @@ import {
7
7
  import { getPairKeyForSource } from "../../../../../../stores/bounds/internals/links";
8
8
  import type { ScreenPairKey } from "../../../../../../stores/bounds/types";
9
9
  import type { NormalizedTransitionInterpolatedStyle } from "../../../../../../types/animation.types";
10
+ import type { BoundaryLocalMeasurementValue } from "../../../../types";
10
11
  import { createBoundaryPortalHostName } from "../../../utils/naming";
11
12
  import {
12
13
  mountPortalBoundaryHost,
@@ -17,44 +18,39 @@ type UseActivePortalBoundaryHostParams = {
17
18
  boundaryId: string;
18
19
  currentScreenKey: string;
19
20
  escapeHostKey?: string;
21
+ localMeasurement: BoundaryLocalMeasurementValue;
20
22
  portalHostName: SharedValue<string | null>;
21
23
  portalHostReady: SharedValue<boolean>;
22
24
  slotsMap: SharedValue<NormalizedTransitionInterpolatedStyle>;
23
25
  };
24
26
 
25
- type ActivePortal = {
26
- pairKey: ScreenPairKey;
27
- };
28
-
29
27
  export const useActivePortalBoundaryHost = ({
30
28
  boundaryId,
31
29
  currentScreenKey,
32
30
  escapeHostKey,
31
+ localMeasurement,
33
32
  portalHostName,
34
33
  portalHostReady,
35
34
  slotsMap,
36
35
  }: UseActivePortalBoundaryHostParams) => {
37
- const [activePortal, setActivePortal] = useState<ActivePortal | null>(null);
38
- const activePairKeyRef = useRef<ScreenPairKey | null>(null);
39
-
40
- const updateActivePortal = useCallback((pairKey: ScreenPairKey | null) => {
41
- if (activePairKeyRef.current === pairKey) {
42
- return;
43
- }
36
+ const [activePairKey, setActivePairKey] = useState<ScreenPairKey | null>(
37
+ null,
38
+ );
44
39
 
45
- activePairKeyRef.current = pairKey;
46
- setActivePortal(pairKey ? { pairKey } : null);
40
+ const updateActivePairKey = useCallback((pairKey: ScreenPairKey | null) => {
41
+ setActivePairKey(pairKey);
47
42
  }, []);
48
43
 
49
44
  useAnimatedReaction(
50
45
  () => {
51
46
  "worklet";
52
- const isBoundaryAnimating = slotsMap.get()[boundaryId] !== undefined;
53
- if (!isBoundaryAnimating) {
47
+ const pairKey = getPairKeyForSource(boundaryId, currentScreenKey);
48
+ const measurement = localMeasurement.get();
49
+ if (!pairKey || measurement?.pairKey !== pairKey) {
54
50
  return null;
55
51
  }
56
52
 
57
- return getPairKeyForSource(boundaryId, currentScreenKey);
53
+ return pairKey;
58
54
  },
59
55
  (pairKey, previousPairKey) => {
60
56
  "worklet";
@@ -62,12 +58,12 @@ export const useActivePortalBoundaryHost = ({
62
58
  return;
63
59
  }
64
60
 
65
- runOnJS(updateActivePortal)(pairKey);
61
+ runOnJS(updateActivePairKey)(pairKey);
66
62
  },
67
63
  );
68
64
 
69
65
  useLayoutEffect(() => {
70
- if (!activePortal || !escapeHostKey) {
66
+ if (!activePairKey || !escapeHostKey) {
71
67
  portalHostName.set(null);
72
68
  portalHostReady.set(false);
73
69
  return;
@@ -76,16 +72,16 @@ export const useActivePortalBoundaryHost = ({
76
72
  const nextPortalHostName = createBoundaryPortalHostName(
77
73
  escapeHostKey,
78
74
  boundaryId,
79
- activePortal.pairKey,
75
+ activePairKey,
80
76
  );
81
77
 
82
78
  mountPortalBoundaryHost({
83
79
  boundaryId,
84
80
  hostKey: escapeHostKey,
85
- pairKey: activePortal.pairKey,
81
+ localMeasurement,
82
+ pairKey: activePairKey,
86
83
  portalHostName: nextPortalHostName,
87
84
  portalHostReady,
88
- screenKey: currentScreenKey,
89
85
  slotsMap,
90
86
  });
91
87
  portalHostName.set(nextPortalHostName);
@@ -96,10 +92,10 @@ export const useActivePortalBoundaryHost = ({
96
92
  unmountPortalBoundaryHostByName(nextPortalHostName);
97
93
  };
98
94
  }, [
99
- activePortal,
95
+ activePairKey,
100
96
  boundaryId,
101
- currentScreenKey,
102
97
  escapeHostKey,
98
+ localMeasurement,
103
99
  portalHostName,
104
100
  portalHostReady,
105
101
  slotsMap,
@@ -1,6 +1,7 @@
1
1
  import { useAnimatedProps, useSharedValue } from "react-native-reanimated";
2
2
  import { useDescriptorsStore } from "../../../../../../providers/screen/descriptors";
3
3
  import { useScreenSlots } from "../../../../../../providers/screen/styles";
4
+ import { useBoundaryRootStore } from "../../../../providers/boundary-root.provider";
4
5
  import { PORTAL_HOST_NAME_RESET_VALUE } from "../../../utils/naming";
5
6
  import { isTeleportEnabled } from "../../../utils/teleport-control";
6
7
  import { useActiveHostKey } from "../stores/host-registry.store";
@@ -13,6 +14,13 @@ interface UseBoundaryPortalAttachmentParams {
13
14
  export const useBoundaryPortalAttachment = ({
14
15
  boundaryId,
15
16
  }: UseBoundaryPortalAttachmentParams) => {
17
+ const localMeasurement = useBoundaryRootStore((root) => {
18
+ if (!root) {
19
+ throw new Error("Boundary portal attachment requires a boundary root.");
20
+ }
21
+
22
+ return root.localMeasurement;
23
+ });
16
24
  const currentScreenKey = useDescriptorsStore(
17
25
  (s) => s.derivations.currentScreenKey,
18
26
  );
@@ -25,6 +33,7 @@ export const useBoundaryPortalAttachment = ({
25
33
  boundaryId,
26
34
  currentScreenKey,
27
35
  escapeHostKey,
36
+ localMeasurement,
28
37
  portalHostName,
29
38
  portalHostReady,
30
39
  slotsMap,
@@ -39,10 +48,12 @@ export const useBoundaryPortalAttachment = ({
39
48
  teleport,
40
49
  ...slotProps
41
50
  } = slot?.props ?? {};
51
+
42
52
  const shouldAttach =
43
53
  slot !== undefined &&
44
54
  isTeleportEnabled(teleport) &&
45
55
  portalHostReady.get();
56
+
46
57
  const hostName = shouldAttach
47
58
  ? portalHostName.get()
48
59
  : PORTAL_HOST_NAME_RESET_VALUE;