@tamagui/sheet 2.0.0-rc.9 → 2.1.0

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 (469) hide show
  1. package/.turbo/turbo-build.log +2 -0
  2. package/controller/index.cjs +2 -1
  3. package/controller/index.js +2 -0
  4. package/controller/index.native.cjs +2 -0
  5. package/controller/index.native.js +2 -0
  6. package/dist/cjs/GestureDetectorWrapper.cjs +27 -21
  7. package/dist/cjs/GestureDetectorWrapper.native.js +33 -28
  8. package/dist/cjs/GestureDetectorWrapper.native.js.map +1 -1
  9. package/dist/cjs/GestureSheetContext.cjs +14 -12
  10. package/dist/cjs/GestureSheetContext.native.js +29 -27
  11. package/dist/cjs/GestureSheetContext.native.js.map +1 -1
  12. package/dist/cjs/Sheet.cjs +88 -86
  13. package/dist/cjs/Sheet.native.js +88 -86
  14. package/dist/cjs/Sheet.native.js.map +1 -1
  15. package/dist/cjs/SheetContext.cjs +16 -14
  16. package/dist/cjs/SheetContext.native.js +16 -14
  17. package/dist/cjs/SheetContext.native.js.map +1 -1
  18. package/dist/cjs/SheetController.cjs +40 -32
  19. package/dist/cjs/SheetController.native.js +62 -54
  20. package/dist/cjs/SheetController.native.js.map +1 -1
  21. package/dist/cjs/SheetImplementationCustom.cjs +617 -429
  22. package/dist/cjs/SheetImplementationCustom.native.js +647 -474
  23. package/dist/cjs/SheetImplementationCustom.native.js.map +1 -1
  24. package/dist/cjs/SheetScrollView.cjs +198 -135
  25. package/dist/cjs/SheetScrollView.native.js +216 -163
  26. package/dist/cjs/SheetScrollView.native.js.map +1 -1
  27. package/dist/cjs/constants.cjs +16 -14
  28. package/dist/cjs/constants.native.js +16 -14
  29. package/dist/cjs/constants.native.js.map +1 -1
  30. package/dist/cjs/contexts.cjs +27 -25
  31. package/dist/cjs/contexts.native.js +29 -27
  32. package/dist/cjs/contexts.native.js.map +1 -1
  33. package/dist/cjs/controller.cjs +14 -12
  34. package/dist/cjs/controller.native.js +14 -12
  35. package/dist/cjs/controller.native.js.map +1 -1
  36. package/dist/cjs/createSheet.cjs +159 -160
  37. package/dist/cjs/createSheet.native.js +172 -180
  38. package/dist/cjs/createSheet.native.js.map +1 -1
  39. package/dist/cjs/gestureState.cjs +12 -10
  40. package/dist/cjs/gestureState.native.js +12 -10
  41. package/dist/cjs/gestureState.native.js.map +1 -1
  42. package/dist/cjs/helpers.cjs +17 -13
  43. package/dist/cjs/helpers.native.js +17 -13
  44. package/dist/cjs/helpers.native.js.map +1 -1
  45. package/dist/cjs/index.cjs +7 -5
  46. package/dist/cjs/index.native.js +7 -5
  47. package/dist/cjs/index.native.js.map +1 -1
  48. package/dist/cjs/keyboardAvoidance.cjs +42 -0
  49. package/dist/cjs/keyboardAvoidance.native.js +46 -0
  50. package/dist/cjs/keyboardAvoidance.native.js.map +1 -0
  51. package/dist/cjs/nativeSheet.cjs +68 -55
  52. package/dist/cjs/nativeSheet.native.js +77 -68
  53. package/dist/cjs/nativeSheet.native.js.map +1 -1
  54. package/dist/cjs/setupGestureHandler.cjs +24 -18
  55. package/dist/cjs/setupGestureHandler.native.js +24 -19
  56. package/dist/cjs/setupGestureHandler.native.js.map +1 -1
  57. package/dist/cjs/types.cjs +7 -5
  58. package/dist/cjs/types.native.js +7 -5
  59. package/dist/cjs/types.native.js.map +1 -1
  60. package/dist/cjs/useGestureHandlerPan.cjs +181 -111
  61. package/dist/cjs/useGestureHandlerPan.native.js +183 -115
  62. package/dist/cjs/useGestureHandlerPan.native.js.map +1 -1
  63. package/dist/cjs/useKeyboardControllerSheet.cjs +76 -18
  64. package/dist/cjs/useKeyboardControllerSheet.native.js +100 -82
  65. package/dist/cjs/useKeyboardControllerSheet.native.js.map +1 -1
  66. package/dist/cjs/useSheet.cjs +12 -10
  67. package/dist/cjs/useSheet.native.js +16 -14
  68. package/dist/cjs/useSheet.native.js.map +1 -1
  69. package/dist/cjs/useSheetController.cjs +35 -33
  70. package/dist/cjs/useSheetController.native.js +37 -35
  71. package/dist/cjs/useSheetController.native.js.map +1 -1
  72. package/dist/cjs/useSheetOffscreenSize.cjs +35 -23
  73. package/dist/cjs/useSheetOffscreenSize.native.js +36 -27
  74. package/dist/cjs/useSheetOffscreenSize.native.js.map +1 -1
  75. package/dist/cjs/useSheetOpenState.cjs +28 -25
  76. package/dist/cjs/useSheetOpenState.native.js +39 -37
  77. package/dist/cjs/useSheetOpenState.native.js.map +1 -1
  78. package/dist/cjs/useSheetProviderProps.cjs +129 -81
  79. package/dist/cjs/useSheetProviderProps.native.js +165 -122
  80. package/dist/cjs/useSheetProviderProps.native.js.map +1 -1
  81. package/dist/cjs/useSheetScrollViewGestures.cjs +129 -81
  82. package/dist/cjs/useSheetScrollViewGestures.native.js +128 -79
  83. package/dist/cjs/useSheetScrollViewGestures.native.js.map +1 -1
  84. package/dist/cjs/webViewport.cjs +50 -0
  85. package/dist/cjs/webViewport.native.js +54 -0
  86. package/dist/cjs/webViewport.native.js.map +1 -0
  87. package/dist/esm/GestureDetectorWrapper.mjs +12 -8
  88. package/dist/esm/GestureDetectorWrapper.mjs.map +1 -1
  89. package/dist/esm/GestureDetectorWrapper.native.js +18 -15
  90. package/dist/esm/GestureDetectorWrapper.native.js.map +1 -1
  91. package/dist/esm/GestureSheetContext.native.js +14 -14
  92. package/dist/esm/GestureSheetContext.native.js.map +1 -1
  93. package/dist/esm/Sheet.mjs +70 -70
  94. package/dist/esm/Sheet.mjs.map +1 -1
  95. package/dist/esm/Sheet.native.js +70 -70
  96. package/dist/esm/Sheet.native.js.map +1 -1
  97. package/dist/esm/SheetContext.mjs +2 -2
  98. package/dist/esm/SheetContext.mjs.map +1 -1
  99. package/dist/esm/SheetContext.native.js +2 -2
  100. package/dist/esm/SheetContext.native.js.map +1 -1
  101. package/dist/esm/SheetController.mjs +12 -6
  102. package/dist/esm/SheetController.mjs.map +1 -1
  103. package/dist/esm/SheetController.native.js +18 -12
  104. package/dist/esm/SheetController.native.js.map +1 -1
  105. package/dist/esm/SheetImplementationCustom.mjs +575 -389
  106. package/dist/esm/SheetImplementationCustom.mjs.map +1 -1
  107. package/dist/esm/SheetImplementationCustom.native.js +601 -434
  108. package/dist/esm/SheetImplementationCustom.native.js.map +1 -1
  109. package/dist/esm/SheetScrollView.mjs +165 -104
  110. package/dist/esm/SheetScrollView.mjs.map +1 -1
  111. package/dist/esm/SheetScrollView.native.js +184 -133
  112. package/dist/esm/SheetScrollView.native.js.map +1 -1
  113. package/dist/esm/constants.mjs +4 -4
  114. package/dist/esm/constants.mjs.map +1 -1
  115. package/dist/esm/constants.native.js +4 -4
  116. package/dist/esm/constants.native.js.map +1 -1
  117. package/dist/esm/contexts.mjs +3 -3
  118. package/dist/esm/contexts.mjs.map +1 -1
  119. package/dist/esm/contexts.native.js +3 -3
  120. package/dist/esm/contexts.native.js.map +1 -1
  121. package/dist/esm/createSheet.mjs +130 -133
  122. package/dist/esm/createSheet.mjs.map +1 -1
  123. package/dist/esm/createSheet.native.js +142 -152
  124. package/dist/esm/createSheet.native.js.map +1 -1
  125. package/dist/esm/helpers.mjs +5 -3
  126. package/dist/esm/helpers.mjs.map +1 -1
  127. package/dist/esm/helpers.native.js +5 -3
  128. package/dist/esm/helpers.native.js.map +1 -1
  129. package/dist/esm/index.js +11 -11
  130. package/dist/esm/index.js.map +1 -6
  131. package/dist/esm/keyboardAvoidance.mjs +17 -0
  132. package/dist/esm/keyboardAvoidance.mjs.map +1 -0
  133. package/dist/esm/keyboardAvoidance.native.js +18 -0
  134. package/dist/esm/keyboardAvoidance.native.js.map +1 -0
  135. package/dist/esm/nativeSheet.mjs +49 -38
  136. package/dist/esm/nativeSheet.mjs.map +1 -1
  137. package/dist/esm/nativeSheet.native.js +55 -48
  138. package/dist/esm/nativeSheet.native.js.map +1 -1
  139. package/dist/esm/setupGestureHandler.mjs +12 -8
  140. package/dist/esm/setupGestureHandler.mjs.map +1 -1
  141. package/dist/esm/setupGestureHandler.native.js +12 -9
  142. package/dist/esm/setupGestureHandler.native.js.map +1 -1
  143. package/dist/esm/useGestureHandlerPan.mjs +167 -99
  144. package/dist/esm/useGestureHandlerPan.mjs.map +1 -1
  145. package/dist/esm/useGestureHandlerPan.native.js +168 -102
  146. package/dist/esm/useGestureHandlerPan.native.js.map +1 -1
  147. package/dist/esm/useKeyboardControllerSheet.mjs +65 -9
  148. package/dist/esm/useKeyboardControllerSheet.mjs.map +1 -1
  149. package/dist/esm/useKeyboardControllerSheet.native.js +85 -69
  150. package/dist/esm/useKeyboardControllerSheet.native.js.map +1 -1
  151. package/dist/esm/useSheetController.mjs +11 -11
  152. package/dist/esm/useSheetController.mjs.map +1 -1
  153. package/dist/esm/useSheetController.native.js +11 -11
  154. package/dist/esm/useSheetController.native.js.map +1 -1
  155. package/dist/esm/useSheetOffscreenSize.mjs +23 -13
  156. package/dist/esm/useSheetOffscreenSize.mjs.map +1 -1
  157. package/dist/esm/useSheetOffscreenSize.native.js +24 -17
  158. package/dist/esm/useSheetOffscreenSize.native.js.map +1 -1
  159. package/dist/esm/useSheetOpenState.mjs +14 -13
  160. package/dist/esm/useSheetOpenState.mjs.map +1 -1
  161. package/dist/esm/useSheetOpenState.native.js +17 -17
  162. package/dist/esm/useSheetOpenState.native.js.map +1 -1
  163. package/dist/esm/useSheetProviderProps.mjs +101 -55
  164. package/dist/esm/useSheetProviderProps.mjs.map +1 -1
  165. package/dist/esm/useSheetProviderProps.native.js +137 -96
  166. package/dist/esm/useSheetProviderProps.native.js.map +1 -1
  167. package/dist/esm/useSheetScrollViewGestures.mjs +117 -71
  168. package/dist/esm/useSheetScrollViewGestures.mjs.map +1 -1
  169. package/dist/esm/useSheetScrollViewGestures.native.js +116 -69
  170. package/dist/esm/useSheetScrollViewGestures.native.js.map +1 -1
  171. package/dist/esm/webViewport.mjs +22 -0
  172. package/dist/esm/webViewport.mjs.map +1 -0
  173. package/dist/esm/webViewport.native.js +23 -0
  174. package/dist/esm/webViewport.native.js.map +1 -0
  175. package/dist/jsx/GestureDetectorWrapper.mjs +12 -8
  176. package/dist/jsx/GestureDetectorWrapper.mjs.map +1 -1
  177. package/dist/jsx/GestureDetectorWrapper.native.js +33 -28
  178. package/dist/jsx/GestureDetectorWrapper.native.js.map +1 -1
  179. package/dist/jsx/GestureSheetContext.native.js +29 -27
  180. package/dist/jsx/GestureSheetContext.native.js.map +1 -1
  181. package/dist/jsx/Sheet.mjs +70 -70
  182. package/dist/jsx/Sheet.mjs.map +1 -1
  183. package/dist/jsx/Sheet.native.js +88 -86
  184. package/dist/jsx/Sheet.native.js.map +1 -1
  185. package/dist/jsx/SheetContext.mjs +2 -2
  186. package/dist/jsx/SheetContext.mjs.map +1 -1
  187. package/dist/jsx/SheetContext.native.js +16 -14
  188. package/dist/jsx/SheetContext.native.js.map +1 -1
  189. package/dist/jsx/SheetController.mjs +12 -6
  190. package/dist/jsx/SheetController.mjs.map +1 -1
  191. package/dist/jsx/SheetController.native.js +62 -54
  192. package/dist/jsx/SheetController.native.js.map +1 -1
  193. package/dist/jsx/SheetImplementationCustom.mjs +575 -389
  194. package/dist/jsx/SheetImplementationCustom.mjs.map +1 -1
  195. package/dist/jsx/SheetImplementationCustom.native.js +647 -474
  196. package/dist/jsx/SheetImplementationCustom.native.js.map +1 -1
  197. package/dist/jsx/SheetScrollView.mjs +165 -104
  198. package/dist/jsx/SheetScrollView.mjs.map +1 -1
  199. package/dist/jsx/SheetScrollView.native.js +216 -163
  200. package/dist/jsx/SheetScrollView.native.js.map +1 -1
  201. package/dist/jsx/constants.mjs +4 -4
  202. package/dist/jsx/constants.mjs.map +1 -1
  203. package/dist/jsx/constants.native.js +16 -14
  204. package/dist/jsx/constants.native.js.map +1 -1
  205. package/dist/jsx/contexts.mjs +3 -3
  206. package/dist/jsx/contexts.mjs.map +1 -1
  207. package/dist/jsx/contexts.native.js +29 -27
  208. package/dist/jsx/contexts.native.js.map +1 -1
  209. package/dist/jsx/controller.native.js +14 -12
  210. package/dist/jsx/createSheet.mjs +130 -133
  211. package/dist/jsx/createSheet.mjs.map +1 -1
  212. package/dist/jsx/createSheet.native.js +172 -180
  213. package/dist/jsx/createSheet.native.js.map +1 -1
  214. package/dist/jsx/gestureState.native.js +12 -10
  215. package/dist/jsx/gestureState.native.js.map +1 -1
  216. package/dist/jsx/helpers.mjs +5 -3
  217. package/dist/jsx/helpers.mjs.map +1 -1
  218. package/dist/jsx/helpers.native.js +17 -13
  219. package/dist/jsx/helpers.native.js.map +1 -1
  220. package/dist/jsx/index.js +11 -11
  221. package/dist/jsx/index.js.map +1 -6
  222. package/dist/jsx/index.native.js +7 -5
  223. package/dist/jsx/index.native.js.map +1 -1
  224. package/dist/jsx/keyboardAvoidance.mjs +17 -0
  225. package/dist/jsx/keyboardAvoidance.mjs.map +1 -0
  226. package/dist/jsx/keyboardAvoidance.native.js +46 -0
  227. package/dist/jsx/keyboardAvoidance.native.js.map +1 -0
  228. package/dist/jsx/nativeSheet.mjs +49 -38
  229. package/dist/jsx/nativeSheet.mjs.map +1 -1
  230. package/dist/jsx/nativeSheet.native.js +77 -68
  231. package/dist/jsx/nativeSheet.native.js.map +1 -1
  232. package/dist/jsx/setupGestureHandler.mjs +12 -8
  233. package/dist/jsx/setupGestureHandler.mjs.map +1 -1
  234. package/dist/jsx/setupGestureHandler.native.js +24 -19
  235. package/dist/jsx/setupGestureHandler.native.js.map +1 -1
  236. package/dist/jsx/types.native.js +7 -5
  237. package/dist/jsx/useGestureHandlerPan.mjs +167 -99
  238. package/dist/jsx/useGestureHandlerPan.mjs.map +1 -1
  239. package/dist/jsx/useGestureHandlerPan.native.js +183 -115
  240. package/dist/jsx/useGestureHandlerPan.native.js.map +1 -1
  241. package/dist/jsx/useKeyboardControllerSheet.mjs +65 -9
  242. package/dist/jsx/useKeyboardControllerSheet.mjs.map +1 -1
  243. package/dist/jsx/useKeyboardControllerSheet.native.js +100 -82
  244. package/dist/jsx/useKeyboardControllerSheet.native.js.map +1 -1
  245. package/dist/jsx/useSheet.native.js +16 -14
  246. package/dist/jsx/useSheetController.mjs +11 -11
  247. package/dist/jsx/useSheetController.mjs.map +1 -1
  248. package/dist/jsx/useSheetController.native.js +37 -35
  249. package/dist/jsx/useSheetController.native.js.map +1 -1
  250. package/dist/jsx/useSheetOffscreenSize.mjs +23 -13
  251. package/dist/jsx/useSheetOffscreenSize.mjs.map +1 -1
  252. package/dist/jsx/useSheetOffscreenSize.native.js +36 -27
  253. package/dist/jsx/useSheetOffscreenSize.native.js.map +1 -1
  254. package/dist/jsx/useSheetOpenState.mjs +14 -13
  255. package/dist/jsx/useSheetOpenState.mjs.map +1 -1
  256. package/dist/jsx/useSheetOpenState.native.js +39 -37
  257. package/dist/jsx/useSheetOpenState.native.js.map +1 -1
  258. package/dist/jsx/useSheetProviderProps.mjs +101 -55
  259. package/dist/jsx/useSheetProviderProps.mjs.map +1 -1
  260. package/dist/jsx/useSheetProviderProps.native.js +165 -122
  261. package/dist/jsx/useSheetProviderProps.native.js.map +1 -1
  262. package/dist/jsx/useSheetScrollViewGestures.mjs +117 -71
  263. package/dist/jsx/useSheetScrollViewGestures.mjs.map +1 -1
  264. package/dist/jsx/useSheetScrollViewGestures.native.js +128 -79
  265. package/dist/jsx/useSheetScrollViewGestures.native.js.map +1 -1
  266. package/dist/jsx/webViewport.mjs +22 -0
  267. package/dist/jsx/webViewport.mjs.map +1 -0
  268. package/dist/jsx/webViewport.native.js +54 -0
  269. package/dist/jsx/webViewport.native.js.map +1 -0
  270. package/next.md +78 -0
  271. package/package.json +29 -39
  272. package/setup-gesture-handler/index.cjs +2 -0
  273. package/setup-gesture-handler/index.js +2 -0
  274. package/setup-gesture-handler/index.native.cjs +2 -0
  275. package/setup-gesture-handler/index.native.js +2 -0
  276. package/src/GestureDetectorWrapper.tsx +0 -3
  277. package/src/SheetController.tsx +4 -1
  278. package/src/SheetImplementationCustom.tsx +414 -84
  279. package/src/SheetScrollView.tsx +74 -9
  280. package/src/keyboardAvoidance.ts +30 -0
  281. package/src/nativeSheet.tsx +9 -1
  282. package/src/types.tsx +16 -1
  283. package/src/useGestureHandlerPan.tsx +5 -15
  284. package/src/useKeyboardControllerSheet.ts +106 -10
  285. package/src/useSheetController.tsx +4 -0
  286. package/src/useSheetProviderProps.tsx +17 -0
  287. package/src/useSheetScrollViewGestures.ts +23 -2
  288. package/src/webViewport.ts +52 -0
  289. package/test/keyboardAvoidance.test.ts +53 -0
  290. package/tsconfig.json +57 -0
  291. package/types/GestureDetectorWrapper.d.ts.map +1 -1
  292. package/types/Sheet.d.ts +3 -0
  293. package/types/Sheet.d.ts.map +1 -1
  294. package/types/SheetContext.d.ts +4 -0
  295. package/types/SheetContext.d.ts.map +1 -1
  296. package/types/SheetController.d.ts +1 -1
  297. package/types/SheetController.d.ts.map +1 -1
  298. package/types/SheetImplementationCustom.d.ts +3 -0
  299. package/types/SheetImplementationCustom.d.ts.map +1 -1
  300. package/types/SheetScrollView.d.ts.map +1 -1
  301. package/types/createSheet.d.ts +3 -0
  302. package/types/createSheet.d.ts.map +1 -1
  303. package/types/keyboardAvoidance.d.ts +8 -0
  304. package/types/keyboardAvoidance.d.ts.map +1 -0
  305. package/types/nativeSheet.d.ts.map +1 -1
  306. package/types/types.d.ts +10 -1
  307. package/types/types.d.ts.map +1 -1
  308. package/types/useGestureHandlerPan.d.ts.map +1 -1
  309. package/types/useKeyboardControllerSheet.d.ts +14 -3
  310. package/types/useKeyboardControllerSheet.d.ts.map +1 -1
  311. package/types/useSheetController.d.ts +3 -0
  312. package/types/useSheetController.d.ts.map +1 -1
  313. package/types/useSheetProviderProps.d.ts +4 -0
  314. package/types/useSheetProviderProps.d.ts.map +1 -1
  315. package/types/useSheetScrollViewGestures.d.ts.map +1 -1
  316. package/types/webViewport.d.ts +30 -0
  317. package/types/webViewport.d.ts.map +1 -0
  318. package/dist/cjs/GestureDetectorWrapper.js +0 -29
  319. package/dist/cjs/GestureDetectorWrapper.js.map +0 -6
  320. package/dist/cjs/GestureSheetContext.js +0 -43
  321. package/dist/cjs/GestureSheetContext.js.map +0 -6
  322. package/dist/cjs/Sheet.js +0 -104
  323. package/dist/cjs/Sheet.js.map +0 -6
  324. package/dist/cjs/SheetContext.js +0 -28
  325. package/dist/cjs/SheetContext.js.map +0 -6
  326. package/dist/cjs/SheetController.js +0 -52
  327. package/dist/cjs/SheetController.js.map +0 -6
  328. package/dist/cjs/SheetImplementationCustom.js +0 -393
  329. package/dist/cjs/SheetImplementationCustom.js.map +0 -6
  330. package/dist/cjs/SheetScrollView.js +0 -137
  331. package/dist/cjs/SheetScrollView.js.map +0 -6
  332. package/dist/cjs/constants.js +0 -24
  333. package/dist/cjs/constants.js.map +0 -6
  334. package/dist/cjs/contexts.js +0 -33
  335. package/dist/cjs/contexts.js.map +0 -6
  336. package/dist/cjs/controller.js +0 -23
  337. package/dist/cjs/controller.js.map +0 -6
  338. package/dist/cjs/createSheet.js +0 -152
  339. package/dist/cjs/createSheet.js.map +0 -6
  340. package/dist/cjs/gestureState.js +0 -34
  341. package/dist/cjs/gestureState.js.map +0 -6
  342. package/dist/cjs/helpers.js +0 -26
  343. package/dist/cjs/helpers.js.map +0 -6
  344. package/dist/cjs/index.js +0 -25
  345. package/dist/cjs/index.js.map +0 -6
  346. package/dist/cjs/nativeSheet.js +0 -56
  347. package/dist/cjs/nativeSheet.js.map +0 -6
  348. package/dist/cjs/setupGestureHandler.js +0 -38
  349. package/dist/cjs/setupGestureHandler.js.map +0 -6
  350. package/dist/cjs/types.js +0 -14
  351. package/dist/cjs/types.js.map +0 -6
  352. package/dist/cjs/useGestureHandlerPan.js +0 -126
  353. package/dist/cjs/useGestureHandlerPan.js.map +0 -6
  354. package/dist/cjs/useKeyboardControllerSheet.js +0 -34
  355. package/dist/cjs/useKeyboardControllerSheet.js.map +0 -6
  356. package/dist/cjs/useSheet.js +0 -22
  357. package/dist/cjs/useSheet.js.map +0 -6
  358. package/dist/cjs/useSheetController.js +0 -39
  359. package/dist/cjs/useSheetController.js.map +0 -6
  360. package/dist/cjs/useSheetOffscreenSize.js +0 -43
  361. package/dist/cjs/useSheetOffscreenSize.js.map +0 -6
  362. package/dist/cjs/useSheetOpenState.js +0 -37
  363. package/dist/cjs/useSheetOpenState.js.map +0 -6
  364. package/dist/cjs/useSheetProviderProps.js +0 -130
  365. package/dist/cjs/useSheetProviderProps.js.map +0 -6
  366. package/dist/cjs/useSheetScrollViewGestures.js +0 -102
  367. package/dist/cjs/useSheetScrollViewGestures.js.map +0 -6
  368. package/dist/esm/GestureDetectorWrapper.js +0 -15
  369. package/dist/esm/GestureDetectorWrapper.js.map +0 -6
  370. package/dist/esm/GestureSheetContext.js +0 -28
  371. package/dist/esm/GestureSheetContext.js.map +0 -6
  372. package/dist/esm/Sheet.js +0 -92
  373. package/dist/esm/Sheet.js.map +0 -6
  374. package/dist/esm/SheetContext.js +0 -13
  375. package/dist/esm/SheetContext.js.map +0 -6
  376. package/dist/esm/SheetController.js +0 -31
  377. package/dist/esm/SheetController.js.map +0 -6
  378. package/dist/esm/SheetImplementationCustom.js +0 -395
  379. package/dist/esm/SheetImplementationCustom.js.map +0 -6
  380. package/dist/esm/SheetScrollView.js +0 -122
  381. package/dist/esm/SheetScrollView.js.map +0 -6
  382. package/dist/esm/constants.js +0 -8
  383. package/dist/esm/constants.js.map +0 -6
  384. package/dist/esm/contexts.js +0 -9
  385. package/dist/esm/contexts.js.map +0 -6
  386. package/dist/esm/controller.js +0 -11
  387. package/dist/esm/controller.js.map +0 -6
  388. package/dist/esm/createSheet.js +0 -153
  389. package/dist/esm/createSheet.js.map +0 -6
  390. package/dist/esm/gestureState.js +0 -18
  391. package/dist/esm/gestureState.js.map +0 -6
  392. package/dist/esm/helpers.js +0 -10
  393. package/dist/esm/helpers.js.map +0 -6
  394. package/dist/esm/nativeSheet.js +0 -46
  395. package/dist/esm/nativeSheet.js.map +0 -6
  396. package/dist/esm/setupGestureHandler.js +0 -22
  397. package/dist/esm/setupGestureHandler.js.map +0 -6
  398. package/dist/esm/types.js +0 -1
  399. package/dist/esm/types.js.map +0 -6
  400. package/dist/esm/useGestureHandlerPan.js +0 -111
  401. package/dist/esm/useGestureHandlerPan.js.map +0 -6
  402. package/dist/esm/useKeyboardControllerSheet.js +0 -18
  403. package/dist/esm/useKeyboardControllerSheet.js.map +0 -6
  404. package/dist/esm/useSheet.js +0 -6
  405. package/dist/esm/useSheet.js.map +0 -6
  406. package/dist/esm/useSheetController.js +0 -15
  407. package/dist/esm/useSheetController.js.map +0 -6
  408. package/dist/esm/useSheetOffscreenSize.js +0 -27
  409. package/dist/esm/useSheetOffscreenSize.js.map +0 -6
  410. package/dist/esm/useSheetOpenState.js +0 -22
  411. package/dist/esm/useSheetOpenState.js.map +0 -6
  412. package/dist/esm/useSheetProviderProps.js +0 -109
  413. package/dist/esm/useSheetProviderProps.js.map +0 -6
  414. package/dist/esm/useSheetScrollViewGestures.js +0 -86
  415. package/dist/esm/useSheetScrollViewGestures.js.map +0 -6
  416. package/dist/jsx/GestureDetectorWrapper.js +0 -15
  417. package/dist/jsx/GestureDetectorWrapper.js.map +0 -6
  418. package/dist/jsx/GestureSheetContext.js +0 -28
  419. package/dist/jsx/GestureSheetContext.js.map +0 -6
  420. package/dist/jsx/Sheet.js +0 -92
  421. package/dist/jsx/Sheet.js.map +0 -6
  422. package/dist/jsx/SheetContext.js +0 -13
  423. package/dist/jsx/SheetContext.js.map +0 -6
  424. package/dist/jsx/SheetController.js +0 -31
  425. package/dist/jsx/SheetController.js.map +0 -6
  426. package/dist/jsx/SheetImplementationCustom.js +0 -395
  427. package/dist/jsx/SheetImplementationCustom.js.map +0 -6
  428. package/dist/jsx/SheetScrollView.js +0 -122
  429. package/dist/jsx/SheetScrollView.js.map +0 -6
  430. package/dist/jsx/constants.js +0 -8
  431. package/dist/jsx/constants.js.map +0 -6
  432. package/dist/jsx/contexts.js +0 -9
  433. package/dist/jsx/contexts.js.map +0 -6
  434. package/dist/jsx/controller.js +0 -11
  435. package/dist/jsx/controller.js.map +0 -6
  436. package/dist/jsx/createSheet.js +0 -153
  437. package/dist/jsx/createSheet.js.map +0 -6
  438. package/dist/jsx/gestureState.js +0 -18
  439. package/dist/jsx/gestureState.js.map +0 -6
  440. package/dist/jsx/helpers.js +0 -10
  441. package/dist/jsx/helpers.js.map +0 -6
  442. package/dist/jsx/nativeSheet.js +0 -46
  443. package/dist/jsx/nativeSheet.js.map +0 -6
  444. package/dist/jsx/setupGestureHandler.js +0 -22
  445. package/dist/jsx/setupGestureHandler.js.map +0 -6
  446. package/dist/jsx/types.js +0 -1
  447. package/dist/jsx/types.js.map +0 -6
  448. package/dist/jsx/useGestureHandlerPan.js +0 -111
  449. package/dist/jsx/useGestureHandlerPan.js.map +0 -6
  450. package/dist/jsx/useKeyboardControllerSheet.js +0 -18
  451. package/dist/jsx/useKeyboardControllerSheet.js.map +0 -6
  452. package/dist/jsx/useSheet.js +0 -6
  453. package/dist/jsx/useSheet.js.map +0 -6
  454. package/dist/jsx/useSheetController.js +0 -15
  455. package/dist/jsx/useSheetController.js.map +0 -6
  456. package/dist/jsx/useSheetOffscreenSize.js +0 -27
  457. package/dist/jsx/useSheetOffscreenSize.js.map +0 -6
  458. package/dist/jsx/useSheetOpenState.js +0 -22
  459. package/dist/jsx/useSheetOpenState.js.map +0 -6
  460. package/dist/jsx/useSheetProviderProps.js +0 -109
  461. package/dist/jsx/useSheetProviderProps.js.map +0 -6
  462. package/dist/jsx/useSheetScrollViewGestures.js +0 -86
  463. package/dist/jsx/useSheetScrollViewGestures.js.map +0 -6
  464. package/types/GestureDetectorWrapper.native.d.ts +0 -14
  465. package/types/gestureState.native.d.ts +0 -12
  466. package/types/setupGestureHandler.native.d.ts +0 -41
  467. package/types/useGestureHandlerPan.native.d.ts +0 -33
  468. package/types/useSheetScrollViewGestures.web.d.ts +0 -15
  469. package/types/useSheetScrollViewGestures.web.d.ts.map +0 -1
@@ -5,7 +5,6 @@ import { isWeb, useIsomorphicLayoutEffect } from '@tamagui/constants'
5
5
  import {
6
6
  LayoutMeasurementController,
7
7
  View as TamaguiView,
8
- Theme,
9
8
  useConfiguration,
10
9
  useDidFinishSSR,
11
10
  useEvent,
@@ -23,8 +22,15 @@ import type {
23
22
  import { Dimensions, PanResponder, View } from 'react-native'
24
23
  import { ParentSheetContext, SheetInsideSheetContext } from './contexts'
25
24
  import { GestureDetectorWrapper } from './GestureDetectorWrapper'
25
+ import { getGestureHandlerState } from './gestureState'
26
26
  import { GestureSheetProvider } from './GestureSheetContext'
27
27
  import { resisted } from './helpers'
28
+ import { getKeyboardOccludedHeight } from './keyboardAvoidance'
29
+ import {
30
+ getStableLayoutViewportHeight,
31
+ getWebKeyboardHeight,
32
+ MIN_KEYBOARD_HEIGHT,
33
+ } from './webViewport'
28
34
  import { SheetProvider } from './SheetContext'
29
35
  import type { SheetProps, SnapPointsMode } from './types'
30
36
  import { useGestureHandlerPan } from './useGestureHandlerPan'
@@ -34,6 +40,14 @@ import { useSheetProviderProps } from './useSheetProviderProps'
34
40
 
35
41
  const hiddenSize = 10_000.1
36
42
 
43
+ // the re-established rngh root for a modal sheet (see modal branch below).
44
+ // GestureHandlerRootView does its own native touch interception and ignores
45
+ // pointerEvents, so it would block the whole app while the sheet sits closed
46
+ // but mounted. instead it stays full-width for correct child layout/measurement
47
+ // and collapses to 0 height when closed so it has no hit area.
48
+ const rnghRootStyleOpen = { width: '100%', height: '100%' } as const
49
+ const rnghRootStyleClosed = { width: '100%', height: 0 } as const
50
+
37
51
  // safe area top inset, cached per-session (device-constant value)
38
52
  let _cachedSafeAreaTop: number | undefined
39
53
  function getSafeAreaTopInset(): number {
@@ -48,6 +62,19 @@ let sheetHiddenStyleSheet: HTMLStyleElement | null = null
48
62
  // on web we are always relative to window, on to screen
49
63
  const relativeDimensionTo = isWeb ? 'window' : 'screen'
50
64
 
65
+ // height of the viewport the sheet positions against. on web this MUST be the
66
+ // stable layout viewport and NOT Dimensions.get('window') — react-native-web's
67
+ // Dimensions tracks visualViewport, which shrinks by the soft keyboard. capping
68
+ // frameSize / maxContentSize against that shrinking value corrupts the fit-mode
69
+ // math (translateY = screenSize - frameSize), detaching the sheet's bottom from
70
+ // the screen edge when the keyboard opens. NOTE: window.innerHeight is NOT
71
+ // stable on real iOS Safari (it shrinks with the keyboard too), so we use the
72
+ // self-correcting baseline from webViewport instead. see getStableLayoutViewportHeight.
73
+ function getStableViewportHeight(): number {
74
+ if (isWeb && typeof window !== 'undefined') return getStableLayoutViewportHeight()
75
+ return Dimensions.get(relativeDimensionTo).height
76
+ }
77
+
51
78
  export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
52
79
  function SheetImplementationCustom(props, forwardedRef) {
53
80
  const parentSheet = React.useContext(ParentSheetContext)
@@ -61,6 +88,7 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
61
88
  unmountChildrenWhenHidden = false,
62
89
  portalProps,
63
90
  containerComponent: ContainerComponent = React.Fragment,
91
+ onAnimationComplete,
64
92
  } = props
65
93
 
66
94
  const state = useSheetOpenState(props)
@@ -83,6 +111,8 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
83
111
  maxSnapPoint,
84
112
  } = providerProps
85
113
  const { open, controller, isHidden } = state
114
+ const openRef = React.useRef(open)
115
+ openRef.current = open
86
116
 
87
117
  const sheetRef = React.useRef<View>(undefined as unknown as View)
88
118
  const ref = useComposedRefs(forwardedRef, sheetRef, providerProps.contentRef as any)
@@ -130,6 +160,19 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
130
160
  setIsShowingInnerSheet(hasChild)
131
161
  }, [])
132
162
 
163
+ // keyboard state tracking — just tracks height/visibility, no position animation.
164
+ // Position animation is handled via keyboard-adjusted positions below,
165
+ // matching the react-native-actions-sheet pattern.
166
+ const {
167
+ keyboardHeight,
168
+ isKeyboardVisible,
169
+ dismissKeyboard,
170
+ pauseKeyboardHandler,
171
+ flushPendingHide,
172
+ } = useKeyboardControllerSheet({
173
+ enabled: Boolean(moveOnKeyboardChange),
174
+ })
175
+
133
176
  // FIX: Store stable frameSize to prevent recalculation during exit animation
134
177
  const stableFrameSize = React.useRef(frameSize)
135
178
 
@@ -140,31 +183,84 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
140
183
  }
141
184
  }, [open, frameSize])
142
185
 
186
+ // WEB keyboard anchor freeze. on real iOS Safari opening the keyboard shrinks
187
+ // the visual viewport AND innerHeight AND the measured layout, which would
188
+ // re-derive screenSize/frameSize smaller, recompute the fit positions, and
189
+ // fly the frame up then back down ("goes back down after the keyboard opens").
190
+ // so we snapshot the pre-keyboard geometry — captured every render while the
191
+ // keyboard is CLOSED, which dodges the open-transition race where a shrunk
192
+ // onLayout lands before isKeyboardVisible flips — and use it for the anchor
193
+ // math while the keyboard is open. the sheet then stays put; only the scroll
194
+ // content shifts to clear the keyboard (keyboardOccludedHeight padding below
195
+ // + SheetScrollView's frozen height).
196
+ // this sheet is the kind the web keyboard anchor freeze is designed for — a
197
+ // fit-mode web sheet opted into keyboard handling. percent/constant sheets
198
+ // keep the live geometry (their height isn't pinned, so a frozen anchor
199
+ // would mismatch).
200
+ const isWebKbSheet = isWeb && hasFit && moveOnKeyboardChange
201
+
202
+ // whether we ever captured geometry while the keyboard was CLOSED. that's the
203
+ // authoritative baseline; until we have it, the autofocus-on-open seed below
204
+ // reconstructs one from keyboard-up measurements.
205
+ const hasCleanKbBaseline = React.useRef(false)
206
+ // the autofocus-on-open seed has settled on a stable frame height (the
207
+ // unclipped content stopped growing). until then we keep the seed phase open.
208
+ const seedSettled = React.useRef(false)
209
+ const stableKbGeom = React.useRef({ frame: 0, screen: 0 })
210
+ if ((!isWeb || !isKeyboardVisible) && frameSize > 0 && screenSize > 0) {
211
+ // keyboard-free render — the authoritative baseline. mutate in place: the
212
+ // ref is only ever read field-by-field, never identity-compared, so this
213
+ // avoids a per-render allocation.
214
+ stableKbGeom.current.frame = frameSize
215
+ stableKbGeom.current.screen = screenSize
216
+ hasCleanKbBaseline.current = true
217
+ } else if (
218
+ isWebKbSheet &&
219
+ isKeyboardVisible &&
220
+ !hasCleanKbBaseline.current &&
221
+ screenSize > 0
222
+ ) {
223
+ // AUTOFOCUS-ON-OPEN seed. when the input autofocuses as the sheet animates
224
+ // in, the keyboard rises BEFORE any keyboard-free layout lands, so the
225
+ // branch above never runs (frameSize/screenSize were 0 the whole time the
226
+ // keyboard was up) and freezeForKb stays false, collapsing the sheet to the
227
+ // shrunk consumer maxHeight. instead, reconstruct the baseline from the
228
+ // keyboard-up render: screen = the stable layout viewport
229
+ // (keyboard-independent). the frame is grown by the seeding layout path
230
+ // below: while seeding, the tail padding is suppressed and the scroll view
231
+ // is unclipped (via keyboardStableFrameHeight = stable screen), so the frame
232
+ // converges on its pure pre-keyboard content height across a couple layout
233
+ // passes. a real keyboard-free render later replaces it with the exact value
234
+ // (branch above).
235
+ stableKbGeom.current.screen = Math.max(stableKbGeom.current.screen, screenSize)
236
+ }
237
+ // are we still reconstructing the baseline from a keyboard-up render? true
238
+ // until either a clean baseline lands or the seeded frame settles.
239
+ const seedingKbBaseline =
240
+ isWebKbSheet &&
241
+ isKeyboardVisible &&
242
+ !hasCleanKbBaseline.current &&
243
+ !seedSettled.current
244
+ const freezeForKb =
245
+ isWebKbSheet && isKeyboardVisible && stableKbGeom.current.frame > 0
246
+ const effScreenSize = freezeForKb ? stableKbGeom.current.screen : screenSize
247
+
143
248
  // use stableFrameSize when closing to prevent position jumps during exit animation
144
249
  // but when opening, always use the current frameSize so positions update correctly
145
- const effectiveFrameSize = open ? frameSize : stableFrameSize.current || frameSize
250
+ const effectiveFrameSize = freezeForKb
251
+ ? stableKbGeom.current.frame
252
+ : open
253
+ ? frameSize
254
+ : stableFrameSize.current || frameSize
146
255
 
147
256
  const positions = React.useMemo(
148
257
  () =>
149
258
  snapPoints.map((point) =>
150
- getYPositions(snapPointsMode, point, screenSize, effectiveFrameSize)
259
+ getYPositions(snapPointsMode, point, effScreenSize, effectiveFrameSize)
151
260
  ),
152
- [screenSize, effectiveFrameSize, snapPoints, snapPointsMode]
261
+ [effScreenSize, effectiveFrameSize, snapPoints, snapPointsMode]
153
262
  )
154
263
 
155
- // keyboard state tracking — just tracks height/visibility, no position animation.
156
- // Position animation is handled via keyboard-adjusted positions below,
157
- // matching the react-native-actions-sheet pattern.
158
- const {
159
- keyboardHeight,
160
- isKeyboardVisible,
161
- dismissKeyboard,
162
- pauseKeyboardHandler,
163
- flushPendingHide,
164
- } = useKeyboardControllerSheet({
165
- enabled: !isWeb && Boolean(moveOnKeyboardChange),
166
- })
167
-
168
264
  const [isDragging, setIsDragging_] = React.useState(false)
169
265
 
170
266
  // synchronous dragging ref — set BEFORE async state commits.
@@ -186,28 +282,32 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
186
282
  [pauseKeyboardHandler, flushPendingHide]
187
283
  )
188
284
 
189
- // keyboard-adjusted positions: shift snap points up by keyboard height
190
- // when keyboard is visible. This drives both gesture snap calculation
191
- // and animation targets — keyboard never dismissed during drag.
192
- // Capped at safe area top inset so the sheet never goes above the notch/status bar
193
- // (matching the react-native-actions-sheet pattern).
285
+ // keyboard-adjusted snap positions.
194
286
  //
195
- // IMPORTANT: frozen during drag to prevent gesture handler recreation.
196
- // When user drags, TextInput may blur keyboard dismisses positions would revert,
197
- // causing the gesture useMemo to recreate and cancel the active drag.
198
- // The post-drag reconciliation effect handles animating to correct position after drag ends.
287
+ // WEB: the sheet stays ANCHORED at the bottom and keeps its full pre-keyboard
288
+ // height it does NOT shift up or resize. Shifting/resizing with the
289
+ // translateY model detaches the bottom from the screen edge or teleports it.
290
+ // Instead the frame's anchor geometry is frozen (effScreenSize/effectiveFrameSize
291
+ // above) and its height is pinned (keyboardStableFrameHeight -> SheetScrollView);
292
+ // the scroll content is padded by keyboardOccludedHeight and the browser
293
+ // scroll-into-view lifts the focused input above the keyboard. So
294
+ // activePositions === positions on web.
295
+ //
296
+ // NATIVE: shift snap points up by keyboard height (the native keyboard is
297
+ // opaque and pushes content), capped at the safe-area top inset.
298
+ //
299
+ // IMPORTANT: frozen during drag to prevent gesture handler recreation —
300
+ // when a TextInput blurs mid-drag the keyboard state would otherwise revert
301
+ // and recreate the gesture useMemo, cancelling the active drag.
199
302
  const activePositionsRef = React.useRef(positions)
200
303
  const activePositions = React.useMemo(() => {
201
- // during drag, return frozen positions to prevent gesture handler recreation.
202
- // check both state (for re-render trigger) and ref (for synchronous check
203
- // when keyboard hide event fires before isDragging state commits)
204
304
  if (isDragging || isDraggingRef.current) return activePositionsRef.current
205
305
 
206
306
  let result: number[]
207
- if (!isKeyboardVisible || keyboardHeight <= 0) {
307
+ if (isWeb || !isKeyboardVisible || keyboardHeight <= 0) {
208
308
  result = positions
209
309
  } else {
210
- const safeAreaTop = isWeb ? 0 : getSafeAreaTopInset()
310
+ const safeAreaTop = getSafeAreaTopInset()
211
311
  result = positions.map((p) => {
212
312
  // don't adjust the off-screen/close position (from dismissOnSnapToBottom's 0% snap)
213
313
  // — it must stay at screenSize so the user can drag between real snap points
@@ -220,6 +320,40 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
220
320
  return result
221
321
  }, [positions, isKeyboardVisible, keyboardHeight, screenSize, isDragging])
222
322
 
323
+ const keyboardOccludedHeight = seedingKbBaseline
324
+ ? // while seeding, suppress the keyboard tail padding so the frame measures
325
+ // its PURE pre-keyboard content height (the padding would otherwise inflate
326
+ // it toward the full screen). re-enabled once the baseline is captured.
327
+ 0
328
+ : getKeyboardOccludedHeight({
329
+ frameSize: effectiveFrameSize,
330
+ isKeyboardVisible,
331
+ keyboardHeight,
332
+ screenSize: effScreenSize,
333
+ sheetY: position >= 0 ? activePositions[position] : undefined,
334
+ })
335
+
336
+ // the authoritative pre-keyboard frame height to pin the scroll view to while
337
+ // the keyboard is open (web). stableKbGeom.frame is captured every render the
338
+ // keyboard is closed, so it survives the open transition; SheetScrollView
339
+ // gates application on its own live keyboard check.
340
+ //
341
+ // AUTOFOCUS-ON-OPEN seed: while still reconstructing the baseline (seeding,
342
+ // not yet settled) we use the STABLE SCREEN SIZE — a safe upper bound (a fit
343
+ // frame never exceeds the screen) that is > 0, so SheetScrollView's height
344
+ // override engages and UNCLIPS the scroll view from the shrunk consumer
345
+ // maxHeight. with the tail padding suppressed (above) the content then lays
346
+ // out to its pure intrinsic height, which the seeding layout grows the frame
347
+ // baseline toward across a couple passes. once settled (or once a real
348
+ // keyboard-free baseline lands) we pin that exact frame height.
349
+ const keyboardStableFrameHeight = !isWebKbSheet
350
+ ? 0
351
+ : seedingKbBaseline
352
+ ? stableKbGeom.current.screen || screenSize
353
+ : stableKbGeom.current.frame > 0
354
+ ? stableKbGeom.current.frame
355
+ : 0
356
+
223
357
  const { useAnimatedNumber, useAnimatedNumberStyle, useAnimatedNumberReaction } =
224
358
  animationDriver
225
359
  const AnimatedView = (animationDriver.View ?? TamaguiView) as typeof Animated.View
@@ -254,6 +388,9 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
254
388
 
255
389
  const hasScrollView = React.useRef(false)
256
390
 
391
+ // safety fallback timer for sheet close opacity
392
+ const opacityFallbackTimer = React.useRef<ReturnType<typeof setTimeout> | null>(null)
393
+
257
394
  useAnimatedNumberReaction(
258
395
  {
259
396
  value: animatedNumber,
@@ -273,6 +410,12 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
273
410
  // when reaching top, enable scroll; when leaving top, disable scroll
274
411
  // this preemptively sets scroll state before any gestures start
275
412
  if (nowAtTop) {
413
+ // if scroll drifted during drag (e.g. fast swipe from position 1),
414
+ // reset it to 0 before enabling free scroll
415
+ if (scrollBridge.y > 0) {
416
+ scrollBridge.forceScrollTo?.(0)
417
+ scrollBridge.y = 0
418
+ }
276
419
  scrollBridge.scrollLockY = undefined
277
420
  scrollBridge.setScrollEnabled?.(true)
278
421
  } else {
@@ -296,17 +439,61 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
296
439
  const animateTo = useEvent((position: number, animationOverride?: any) => {
297
440
  if (frameSize === 0) return
298
441
 
299
- let toValue = isHidden || position === -1 ? screenSize : activePositions[position]
442
+ // use effScreenSize (the frozen anchor space the positions were built in) for
443
+ // the off-screen/close target too, so a close while the keyboard is still up
444
+ // animates fully out instead of to a mismatched live screenSize.
445
+ let toValue =
446
+ isHidden || position === -1 ? effScreenSize : activePositions[position]
300
447
 
301
448
  if (at.current === toValue) return
302
449
 
303
450
  at.current = toValue
304
451
  stopSpring()
305
452
 
453
+ const isOpenAnimation = position !== -1 && !isHidden
454
+
455
+ // clear any pending fallback timer
456
+ if (opacityFallbackTimer.current) {
457
+ clearTimeout(opacityFallbackTimer.current)
458
+ opacityFallbackTimer.current = null
459
+ }
460
+
461
+ const animationCompleteCallback = () => {
462
+ if (opacityFallbackTimer.current) {
463
+ clearTimeout(opacityFallbackTimer.current)
464
+ opacityFallbackTimer.current = null
465
+ }
466
+ // use openRef (live) not open (stale closure) — if the sheet
467
+ // was reopened before this callback fires (e.g. cancelled close
468
+ // animation), we must not hide it
469
+ if (!isOpenAnimation && !openRef.current) {
470
+ setOpacity(0)
471
+ }
472
+ onAnimationComplete?.({ open: isOpenAnimation })
473
+ // also notify the SheetController so a parent (e.g. Dialog adapt)
474
+ // can hold the sheet's children mounted until the slide-out is done
475
+ controller?.onAnimationComplete?.({ open: isOpenAnimation })
476
+ }
477
+
478
+ // safety fallback: if animation callback never fires, still hide the sheet
479
+ if (!isOpenAnimation) {
480
+ opacityFallbackTimer.current = setTimeout(() => {
481
+ opacityFallbackTimer.current = null
482
+ // check live open state via ref — sheet may have reopened (e.g. adapt handoff)
483
+ if (!openRef.current) {
484
+ setOpacity(0)
485
+ }
486
+ }, 1000)
487
+ }
488
+
306
489
  // skip animation when adapting from dialog to sheet
307
490
  if (skipAdaptAnimation.current) {
308
491
  skipAdaptAnimation.current = false
309
- animatedNumber.setValue(toValue, { type: 'timing', duration: 0 })
492
+ animatedNumber.setValue(
493
+ toValue,
494
+ { type: 'timing', duration: 0 },
495
+ animationCompleteCallback
496
+ )
310
497
  return
311
498
  }
312
499
 
@@ -315,7 +502,8 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
315
502
  animationOverride || {
316
503
  type: 'spring',
317
504
  ...transitionConfig,
318
- }
505
+ },
506
+ animationCompleteCallback
319
507
  )
320
508
  })
321
509
 
@@ -347,6 +535,16 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
347
535
  return
348
536
  }
349
537
 
538
+ // never fight an active drag: the gesture owns the animated position. on
539
+ // web the AnimatedView's onLayout re-fires with sub-pixel jitter as the
540
+ // frame translates (frameSize 499.99996 <-> 500.00003), and since frameSize
541
+ // is a dep of this effect that would re-run it mid-pull and snap the sheet
542
+ // back to its resting snap point. read the live ref so drag-end (which the
543
+ // reconcile-after-drag effect handles) isn't gated by stale deps.
544
+ if (isDraggingRef.current) {
545
+ return
546
+ }
547
+
350
548
  if (!frameSize || !screenSize || isHidden || (hasntMeasured && !open)) {
351
549
  return
352
550
  }
@@ -384,7 +582,11 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
384
582
  if (!frameSize) return
385
583
  if (isShowingInnerSheet) return
386
584
 
387
- const minY = positions[0]
585
+ // use keyboard-adjusted positions (matches the RNGH path): when the
586
+ // keyboard is open the sheet sits at activePositions[0], so clamping drags
587
+ // against the un-adjusted positions[0] would rubber-band the sheet down to
588
+ // near the bottom on any drag.
589
+ const minY = activePositions[0]
388
590
  scrollBridge.paneMinY = minY
389
591
  let startY = at.current
390
592
 
@@ -427,8 +629,8 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
427
629
  let closestPoint = 0
428
630
  let dist = Number.POSITIVE_INFINITY
429
631
 
430
- for (let i = 0; i < positions.length; i++) {
431
- const position = positions[i]
632
+ for (let i = 0; i < activePositions.length; i++) {
633
+ const position = activePositions[i]
432
634
  const curDist = end > position ? end - position : position - end
433
635
  if (curDist < dist) {
434
636
  dist = curDist
@@ -460,6 +662,16 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
460
662
  return true
461
663
  }
462
664
 
665
+ // touch is on the ScrollView node — the web scroll-view gesture hook
666
+ // owns it and drives drag/release through scrollBridge directly (it
667
+ // re-baselines via scrollBridge.startPanDrag on each pan handoff). if
668
+ // we also granted here, RNW's PanResponder would set the animated
669
+ // position from a second, differently-based offset every move and the
670
+ // sheet would jitter/jump. defer entirely to the hook.
671
+ if (scrollBridge.scrollNodeTouched) {
672
+ return false
673
+ }
674
+
463
675
  if (scrollBridge.hasScrollableContent === true) {
464
676
  if (scrollBridge.scrollLock) {
465
677
  return false
@@ -505,6 +717,17 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
505
717
 
506
718
  let isExternalDrag = false
507
719
 
720
+ // re-baseline a pan drag to the current animated position. the web
721
+ // scroll-view hook calls this on every transition INTO pan ownership
722
+ // (including handoffs back from scroll), so its panDragOffset — which it
723
+ // resets to 0 at each pan entry — is measured from where the sheet
724
+ // actually is now, not from where the gesture first grabbed it. without
725
+ // this the sheet would jump to a stale origin on a scroll→pan handoff.
726
+ scrollBridge.startPanDrag = () => {
727
+ isExternalDrag = true
728
+ grant()
729
+ }
730
+
508
731
  scrollBridge.drag = (dy) => {
509
732
  if (!isExternalDrag) {
510
733
  isExternalDrag = true
@@ -546,10 +769,22 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
546
769
  onPanResponderTerminate: finish,
547
770
  onPanResponderRelease: finish,
548
771
  })
549
- }, [disableDrag, isShowingInnerSheet, animateTo, frameSize, positions, setPosition])
772
+ }, [
773
+ disableDrag,
774
+ isShowingInnerSheet,
775
+ animateTo,
776
+ frameSize,
777
+ activePositions,
778
+ setPosition,
779
+ ])
550
780
 
551
- // animate to keyboard-adjusted position when keyboard state changes
781
+ // animate to keyboard-adjusted position when keyboard state changes.
782
+ // WEB skips this: the sheet stays anchored at its frozen position/height
783
+ // (activePositions don't change with the keyboard, and the anchor geometry is
784
+ // frozen), so there's nothing to re-animate. Running a timing animation here
785
+ // would only introduce movement where the sheet should hold perfectly still.
552
786
  React.useEffect(() => {
787
+ if (isWeb) return
553
788
  if (isDragging || isHidden || !open || disableAnimation) return
554
789
  if (!frameSize || !screenSize) return
555
790
  // use timing animation to match iOS keyboard animation (~250ms)
@@ -577,6 +812,11 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
577
812
  React.useEffect(() => {
578
813
  if (!open && isKeyboardVisible) {
579
814
  dismissKeyboard()
815
+ // if the sheet was closed mid-drag the keyboard-hide handler was paused
816
+ // and a hide could be left pending — clear it so isKeyboardVisible can't
817
+ // stick true after the sheet is gone. (no-op for a normal close.)
818
+ pauseKeyboardHandler.current = false
819
+ flushPendingHide()
580
820
  }
581
821
  }, [open])
582
822
 
@@ -601,61 +841,128 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
601
841
  pauseKeyboardHandler,
602
842
  })
603
843
 
604
- const handleAnimationViewLayout = React.useCallback(
844
+ // ignore any layout measured while the soft keyboard is up (web +
845
+ // moveOnKeyboardChange): the visual viewport (which RN's web layout follows)
846
+ // shrinks, so the height would be the collapsed sheet — keeping it would
847
+ // recompute the fit anchor and fly the frame. a LIVE DOM check, NOT the
848
+ // isKeyboardVisible React state, is required: the state lags the resize, so
849
+ // the first shrunk onLayout lands before the flag flips. holding the measured
850
+ // sizes keeps the sheet anchored; the scroll content shifts to clear the kb.
851
+ const ignoreLayoutForKeyboard = useEvent(
852
+ () => isWeb && moveOnKeyboardChange && getWebKeyboardHeight() >= MIN_KEYBOARD_HEIGHT
853
+ )
854
+
855
+ // AUTOFOCUS-ON-OPEN seed gates. normally a layout measured while the keyboard
856
+ // is up is dropped (it's the shrunk/collapsed sheet). but if the keyboard rose
857
+ // before ANY keyboard-free baseline was captured (the autofocus race),
858
+ // dropping every measurement leaves frameSize/screenSize stuck at 0 forever
859
+ // and the freeze never engages.
860
+ //
861
+ // frame: while seeding (not settled) the scroll view is unclipped and the
862
+ // tail padding suppressed, so the frame measures toward its pure pre-keyboard
863
+ // content height. the first keyboard-up pass is still clipped at the consumer
864
+ // maxHeight; the override only unclips it the following pass, so the frame
865
+ // grows. we take the MAX and mark the seed SETTLED once it stops growing
866
+ // (handled in handleAnimationViewLayout) — then later keyboard-up layouts are
867
+ // dropped again so the re-enabled tail padding can't inflate the frame.
868
+ const shouldSeedKbFrame = useEvent(
869
+ () =>
870
+ isWebKbSheet &&
871
+ !hasCleanKbBaseline.current &&
872
+ !seedSettled.current &&
873
+ ignoreLayoutForKeyboard()
874
+ )
875
+ // screen (= maxContentSize): keep reconstructing from the stable viewport for
876
+ // the whole keyboard-up-without-clean-baseline window.
877
+ const shouldSeedKbScreen = useEvent(
878
+ () => isWebKbSheet && !hasCleanKbBaseline.current && ignoreLayoutForKeyboard()
879
+ )
880
+
881
+ const handleAnimationViewLayout = useEvent((e: LayoutChangeEvent) => {
882
+ // don't update frameSize during exit animation to prevent position jumps
883
+ if (!open && stableFrameSize.current !== 0) {
884
+ return
885
+ }
886
+
887
+ const seeding = shouldSeedKbFrame()
888
+ if (!seeding && ignoreLayoutForKeyboard()) return
889
+
890
+ // avoid bugs where it grows forever for whatever reason
891
+ // For inline mode (non-modal), don't cap at window height - use actual layout
892
+ const layoutHeight = e.nativeEvent?.layout.height
893
+ // while seeding, the keyboardStableFrameHeight fallback has unclipped the
894
+ // scroll view (capped at the stable screen) and the tail padding is
895
+ // suppressed, so this measures the pure pre-keyboard content height — cap it
896
+ // at the stable viewport like modal does.
897
+ const next =
898
+ modal || seeding
899
+ ? Math.min(layoutHeight, getStableViewportHeight())
900
+ : layoutHeight
901
+ if (!next) return
902
+ // round: web onLayout reports sub-pixel heights (e.g. 499.99996) that jitter
903
+ // frame to frame as the view transforms; the raw float would re-fire every
904
+ // effect that depends on frameSize on each drag move.
905
+ const rounded = Math.round(next)
906
+ // seeding the frame: grow the baseline toward the unclipped content height.
907
+ // the first keyboard-up pass is clipped; the scroll-view override unclips it
908
+ // the next pass so it grows. once a pass doesn't exceed the running max the
909
+ // content has settled — mark the seed done so the next render exits the seed
910
+ // phase (freezeForKb pins this height, tail padding re-enables for scroll).
911
+ if (seeding) {
912
+ if (rounded > stableKbGeom.current.frame) {
913
+ stableKbGeom.current.frame = rounded
914
+ } else if (stableKbGeom.current.frame > 0) {
915
+ seedSettled.current = true
916
+ }
917
+ }
918
+ setFrameSize(rounded)
919
+ })
920
+
921
+ const handleMaxContentViewLayout = React.useCallback(
605
922
  (e: LayoutChangeEvent) => {
606
- // FIX: Don't update frameSize during exit animation to prevent position jumps
607
- if (!open && stableFrameSize.current !== 0) {
923
+ // same keyboard guard so screenSize (= maxContentSize) stays the full
924
+ // pre-keyboard viewport except while seeding the baseline (see above),
925
+ // where we use the stable layout viewport directly so screenSize lands at
926
+ // the full pre-keyboard height instead of the shrunk visual viewport.
927
+ if (shouldSeedKbScreen()) {
928
+ setMaxContentSize(Math.round(getStableViewportHeight()))
608
929
  return
609
930
  }
610
-
931
+ if (ignoreLayoutForKeyboard()) return
611
932
  // avoid bugs where it grows forever for whatever reason
612
- // For inline mode (non-modal), don't cap at window height - use actual layout
613
- const layoutHeight = e.nativeEvent?.layout.height
614
- const next = modal
615
- ? Math.min(layoutHeight, Dimensions.get(relativeDimensionTo).height)
616
- : layoutHeight
933
+ const next = Math.min(e.nativeEvent?.layout.height, getStableViewportHeight())
617
934
  if (!next) return
618
- setFrameSize(next)
935
+ // round to avoid sub-pixel churn re-firing size-dependent effects
936
+ setMaxContentSize(Math.round(next))
619
937
  },
620
- [open, modal]
938
+ [ignoreLayoutForKeyboard, shouldSeedKbScreen]
621
939
  )
622
940
 
623
- const handleMaxContentViewLayout = React.useCallback((e: LayoutChangeEvent) => {
624
- // avoid bugs where it grows forever for whatever reason
625
- const next = Math.min(
626
- e.nativeEvent?.layout.height,
627
- Dimensions.get(relativeDimensionTo).height
628
- )
629
- if (!next) return
630
- setMaxContentSize(next)
631
- }, [])
941
+ const getAnimatedNumberStyle = React.useCallback(
942
+ (val: number) => {
943
+ 'worklet'
944
+ const translateY = frameSize === 0 ? hiddenSize : val
632
945
 
633
- const animatedStyle = useAnimatedNumberStyle(animatedNumber, (val) => {
634
- 'worklet'
635
- const translateY = frameSize === 0 ? hiddenSize : val
946
+ return {
947
+ transform: [{ translateY }],
948
+ }
949
+ },
950
+ [frameSize]
951
+ )
636
952
 
637
- return {
638
- transform: [{ translateY }],
639
- }
640
- })
953
+ const animatedStyle = useAnimatedNumberStyle(animatedNumber, getAnimatedNumberStyle)
641
954
 
642
955
  // we need to set this *after* fully closed to 0, to avoid it overlapping
643
956
  // the page when resizing quickly on web for example
644
957
  const [opacity, setOpacity] = React.useState(open ? 1 : 0)
645
958
  if (open && opacity === 0) {
646
959
  setOpacity(1)
647
- }
648
- React.useEffect(() => {
649
- if (!open) {
650
- // need to wait for animation complete, for now lets just do it naively
651
- const tm = setTimeout(() => {
652
- setOpacity(0)
653
- }, 400)
654
- return () => {
655
- clearTimeout(tm)
656
- }
960
+ // cancel any pending close fallback — sheet is reopening
961
+ if (opacityFallbackTimer.current) {
962
+ clearTimeout(opacityFallbackTimer.current)
963
+ opacityFallbackTimer.current = null
657
964
  }
658
- }, [open])
965
+ }
659
966
 
660
967
  const forcedContentHeight = hasFit
661
968
  ? undefined
@@ -676,7 +983,14 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
676
983
  let contents = (
677
984
  <LayoutMeasurementController disable={!open}>
678
985
  <ParentSheetContext.Provider value={nextParentContext}>
679
- <SheetProvider {...providerProps} setHasScrollView={setHasScrollView}>
986
+ <SheetProvider
987
+ {...providerProps}
988
+ keyboardOccludedHeight={keyboardOccludedHeight}
989
+ isKeyboardVisible={isKeyboardVisible}
990
+ keyboardStableFrameHeight={keyboardStableFrameHeight}
991
+ isKeyboardSeeding={seedingKbBaseline}
992
+ setHasScrollView={setHasScrollView}
993
+ >
680
994
  <GestureSheetProvider
681
995
  isDragging={isDragging}
682
996
  blockPan={blockPan}
@@ -761,14 +1075,30 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
761
1075
  const shouldMountChildren = unmountChildrenWhenHidden ? !!opacity : true
762
1076
 
763
1077
  if (modal) {
1078
+ // a modal sheet is teleported through <Portal> to the root portal host.
1079
+ // that host is mounted by TamaguiProvider, which may sit ABOVE the app's
1080
+ // GestureHandlerRootView - so the teleported content lands outside any
1081
+ // rngh root and every gesture inside the sheet (the drag pan, pressables
1082
+ // on the rngh press path) silently goes dead. re-establish an rngh root
1083
+ // around the teleported content so it works regardless of where the app
1084
+ // mounts GestureHandlerRootView.
1085
+ //
1086
+ // the root stays mounted and full-width whenever the sheet content is
1087
+ // (so child layout/measurement/close-animation are unaffected) and only
1088
+ // collapses to 0 height while closed so it occupies no hit area - see
1089
+ // rnghRootStyleOpen/Closed above for why pointerEvents can't be used.
1090
+ const RNGHRoot = getGestureHandlerState().RootView
1091
+ const mountedContents = shouldMountChildren ? (
1092
+ <ContainerComponent>{contents}</ContainerComponent>
1093
+ ) : null
764
1094
  const modalContents = (
765
1095
  <Portal stackZIndex={zIndex} {...portalProps}>
766
- {shouldMountChildren && (
767
- <ContainerComponent>
768
- <Theme contain forceClassName name={themeName}>
769
- {contents}
770
- </Theme>
771
- </ContainerComponent>
1096
+ {mountedContents && RNGHRoot ? (
1097
+ <RNGHRoot style={open ? rnghRootStyleOpen : rnghRootStyleClosed}>
1098
+ {mountedContents}
1099
+ </RNGHRoot>
1100
+ ) : (
1101
+ mountedContents
772
1102
  )}
773
1103
  </Portal>
774
1104
  )