@lodev09/react-native-true-sheet 4.0.0-beta.0 → 4.0.0-beta.10

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 (430) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +62 -30
  3. package/RNTrueSheet.podspec +10 -2
  4. package/android/build.gradle +24 -2
  5. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +189 -47
  6. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerViewManager.kt +7 -0
  7. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +401 -19
  8. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +18 -0
  9. package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +145 -21
  10. package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterViewManager.kt +14 -0
  11. package/android/src/main/java/com/lodev09/truesheet/TrueSheetHeaderView.kt +38 -0
  12. package/android/src/main/java/com/lodev09/truesheet/TrueSheetHeaderViewManager.kt +28 -0
  13. package/android/src/main/java/com/lodev09/truesheet/TrueSheetModule.kt +84 -24
  14. package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayView.kt +106 -0
  15. package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayViewManager.kt +45 -0
  16. package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +6 -4
  17. package/android/src/main/java/com/lodev09/truesheet/TrueSheetPeekView.kt +72 -0
  18. package/android/src/main/java/com/lodev09/truesheet/TrueSheetPeekViewManager.kt +33 -0
  19. package/android/src/main/java/com/lodev09/truesheet/TrueSheetStateUpdater.kt +63 -0
  20. package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +564 -226
  21. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +1399 -598
  22. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +161 -29
  23. package/android/src/main/java/com/lodev09/truesheet/core/RNScreensEventObserver.kt +63 -0
  24. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetBehavior.kt +36 -0
  25. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetView.kt +255 -0
  26. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt +375 -0
  27. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +299 -0
  28. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDimView.kt +162 -0
  29. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetGrabberView.kt +180 -0
  30. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetKeyboardObserver.kt +207 -0
  31. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetOverlayRootView.kt +137 -0
  32. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetStackManager.kt +220 -0
  33. package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetDragEvents.kt +71 -0
  34. package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetFocusEvents.kt +65 -0
  35. package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetLifecycleEvents.kt +127 -0
  36. package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetStateEvents.kt +56 -0
  37. package/android/src/main/java/com/lodev09/truesheet/utils/KeyboardUtils.kt +84 -0
  38. package/android/src/main/java/com/lodev09/truesheet/utils/ScreenUtils.kt +93 -67
  39. package/android/src/main/java/com/lodev09/truesheet/utils/TouchEventDeduper.kt +31 -0
  40. package/android/src/main/java/com/lodev09/truesheet/utils/ViewUtils.kt +42 -0
  41. package/android/src/main/jni/CMakeLists.txt +63 -0
  42. package/android/src/main/jni/TrueSheetSpec.h +20 -0
  43. package/android/src/main/jni/TrueSheetStateUpdater.cpp +96 -0
  44. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h +16 -0
  45. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +68 -0
  46. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.h +33 -0
  47. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.cpp +11 -0
  48. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.h +39 -0
  49. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewComponentDescriptor.h +24 -0
  50. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +63 -0
  51. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.h +28 -0
  52. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.cpp +11 -0
  53. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.h +41 -0
  54. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.cpp +18 -0
  55. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.h +16 -0
  56. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetLayoutUtils.h +46 -0
  57. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewComponentDescriptor.h +21 -0
  58. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.cpp +17 -0
  59. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.h +36 -0
  60. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewComponentDescriptor.h +28 -0
  61. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +30 -0
  62. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.h +45 -0
  63. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.cpp +23 -0
  64. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.h +52 -0
  65. package/ios/TrueSheetContainerView.h +88 -6
  66. package/ios/TrueSheetContainerView.mm +278 -21
  67. package/ios/TrueSheetContentView.h +54 -1
  68. package/ios/TrueSheetContentView.mm +371 -47
  69. package/ios/TrueSheetFooterView.h +33 -2
  70. package/ios/TrueSheetFooterView.mm +187 -35
  71. package/ios/{events/OnWillDismissEvent.h → TrueSheetHeaderView.h} +10 -7
  72. package/ios/TrueSheetHeaderView.mm +64 -0
  73. package/ios/TrueSheetModule.h +2 -7
  74. package/ios/TrueSheetModule.mm +98 -20
  75. package/ios/TrueSheetOverlayView.h +32 -0
  76. package/ios/TrueSheetOverlayView.mm +161 -0
  77. package/ios/TrueSheetPeekView.h +32 -0
  78. package/ios/TrueSheetPeekView.mm +99 -0
  79. package/ios/TrueSheetView.h +7 -15
  80. package/ios/TrueSheetView.mm +775 -215
  81. package/ios/TrueSheetViewController.h +94 -16
  82. package/ios/TrueSheetViewController.mm +1316 -331
  83. package/ios/core/RNScreensEventObserver.h +46 -0
  84. package/ios/core/RNScreensEventObserver.mm +280 -0
  85. package/ios/core/TrueSheetBlurView.h +27 -0
  86. package/ios/core/TrueSheetBlurView.mm +82 -0
  87. package/ios/core/TrueSheetDetentCalculator.h +107 -0
  88. package/ios/core/TrueSheetDetentCalculator.mm +197 -0
  89. package/ios/core/TrueSheetGrabberView.h +72 -0
  90. package/ios/core/TrueSheetGrabberView.mm +188 -0
  91. package/ios/core/TrueSheetKeyboardObserver.h +39 -0
  92. package/ios/core/TrueSheetKeyboardObserver.mm +112 -0
  93. package/ios/core/TrueSheetOverlayContainerView.h +31 -0
  94. package/ios/core/TrueSheetOverlayContainerView.mm +35 -0
  95. package/ios/events/TrueSheetDragEvents.h +39 -0
  96. package/ios/events/TrueSheetDragEvents.mm +62 -0
  97. package/ios/events/{OnPositionChangeEvent.h → TrueSheetFocusEvents.h} +8 -5
  98. package/ios/events/TrueSheetFocusEvents.mm +49 -0
  99. package/ios/events/TrueSheetLifecycleEvents.h +42 -0
  100. package/ios/events/TrueSheetLifecycleEvents.mm +79 -0
  101. package/ios/events/TrueSheetStateEvents.h +35 -0
  102. package/ios/events/TrueSheetStateEvents.mm +49 -0
  103. package/ios/tvos/TrueSheetStubs.mm +166 -0
  104. package/ios/{events/OnMountEvent.h → utils/BlurUtil.h} +5 -7
  105. package/ios/utils/BlurUtil.mm +69 -0
  106. package/ios/utils/GestureUtil.h +7 -0
  107. package/ios/utils/GestureUtil.mm +12 -0
  108. package/ios/utils/PlatformUtil.h +15 -0
  109. package/ios/utils/UIView+FirstResponder.h +15 -0
  110. package/ios/utils/UIView+FirstResponder.mm +26 -0
  111. package/ios/utils/UIView+ScrollEdgeInteraction.h +26 -0
  112. package/ios/utils/UIView+ScrollEdgeInteraction.mm +84 -0
  113. package/ios/utils/WindowUtil.mm +17 -1
  114. package/lib/module/TrueSheet.js +349 -74
  115. package/lib/module/TrueSheet.js.map +1 -1
  116. package/lib/module/TrueSheet.web.js +1270 -0
  117. package/lib/module/TrueSheet.web.js.map +1 -0
  118. package/lib/module/TrueSheetOverlay.js +30 -0
  119. package/lib/module/TrueSheetOverlay.js.map +1 -0
  120. package/lib/module/TrueSheetOverlay.web.js +35 -0
  121. package/lib/module/TrueSheetOverlay.web.js.map +1 -0
  122. package/lib/module/TrueSheetPeek.js +15 -0
  123. package/lib/module/TrueSheetPeek.js.map +1 -0
  124. package/lib/module/TrueSheetPeek.web.js +55 -0
  125. package/lib/module/TrueSheetPeek.web.js.map +1 -0
  126. package/lib/module/TrueSheetProvider.js +28 -0
  127. package/lib/module/TrueSheetProvider.js.map +1 -0
  128. package/lib/module/TrueSheetProvider.web.js +157 -0
  129. package/lib/module/TrueSheetProvider.web.js.map +1 -0
  130. package/lib/module/fabric/TrueSheetContainerViewNativeComponent.ts +1 -1
  131. package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +5 -1
  132. package/lib/module/fabric/TrueSheetFooterViewNativeComponent.ts +10 -2
  133. package/lib/module/fabric/TrueSheetHeaderViewNativeComponent.ts +8 -0
  134. package/lib/module/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
  135. package/lib/module/fabric/TrueSheetPeekViewNativeComponent.ts +8 -0
  136. package/lib/module/fabric/TrueSheetViewNativeComponent.ts +110 -18
  137. package/lib/module/index.js +4 -3
  138. package/lib/module/index.js.map +1 -1
  139. package/lib/module/mocks/index.js +103 -0
  140. package/lib/module/mocks/index.js.map +1 -0
  141. package/lib/module/mocks/navigation.js +95 -0
  142. package/lib/module/mocks/navigation.js.map +1 -0
  143. package/lib/module/mocks/navigationExpoRouter.js +21 -0
  144. package/lib/module/mocks/navigationExpoRouter.js.map +1 -0
  145. package/lib/module/mocks/reanimated.js +91 -0
  146. package/lib/module/mocks/reanimated.js.map +1 -0
  147. package/lib/module/navigation/TrueSheetNavigatorContent.js +73 -0
  148. package/lib/module/navigation/TrueSheetNavigatorContent.js.map +1 -0
  149. package/lib/module/navigation/actions.js +50 -0
  150. package/lib/module/navigation/actions.js.map +1 -0
  151. package/lib/module/navigation/base-types.js +2 -0
  152. package/lib/module/navigation/base-types.js.map +1 -0
  153. package/lib/module/navigation/createTrueSheetRouter.js +157 -0
  154. package/lib/module/navigation/createTrueSheetRouter.js.map +1 -0
  155. package/lib/module/navigation/expo-router/base-types.js +2 -0
  156. package/lib/module/navigation/expo-router/base-types.js.map +1 -0
  157. package/lib/module/navigation/expo-router/index.js +50 -0
  158. package/lib/module/navigation/expo-router/index.js.map +1 -0
  159. package/lib/module/navigation/expo-router/types.js +4 -0
  160. package/lib/module/navigation/expo-router/types.js.map +1 -0
  161. package/lib/module/navigation/index.js +47 -0
  162. package/lib/module/navigation/index.js.map +1 -0
  163. package/lib/module/navigation/navigator.js +10 -0
  164. package/lib/module/navigation/navigator.js.map +1 -0
  165. package/lib/module/navigation/screen/ReanimatedTrueSheetScreen.js +56 -0
  166. package/lib/module/navigation/screen/ReanimatedTrueSheetScreen.js.map +1 -0
  167. package/lib/module/navigation/screen/TrueSheetScreen.js +49 -0
  168. package/lib/module/navigation/screen/TrueSheetScreen.js.map +1 -0
  169. package/lib/module/navigation/screen/index.js +5 -0
  170. package/lib/module/navigation/screen/index.js.map +1 -0
  171. package/lib/module/navigation/screen/types.js +4 -0
  172. package/lib/module/navigation/screen/types.js.map +1 -0
  173. package/lib/module/navigation/screen/useSheetScreenState.js +69 -0
  174. package/lib/module/navigation/screen/useSheetScreenState.js.map +1 -0
  175. package/lib/module/navigation/types.js +4 -0
  176. package/lib/module/navigation/types.js.map +1 -0
  177. package/lib/module/navigation/useTrueSheetNavigation.js +24 -0
  178. package/lib/module/navigation/useTrueSheetNavigation.js.map +1 -0
  179. package/lib/module/reanimated/ReanimatedTrueSheet.js +15 -9
  180. package/lib/module/reanimated/ReanimatedTrueSheet.js.map +1 -1
  181. package/lib/module/reanimated/ReanimatedTrueSheet.web.js +81 -0
  182. package/lib/module/reanimated/ReanimatedTrueSheet.web.js.map +1 -0
  183. package/lib/module/reanimated/ReanimatedTrueSheetProvider.js +4 -2
  184. package/lib/module/reanimated/ReanimatedTrueSheetProvider.js.map +1 -1
  185. package/lib/module/reanimated/index.js +2 -2
  186. package/lib/module/reanimated/index.js.map +1 -1
  187. package/lib/module/reanimated/useReanimatedPositionChangeHandler.web.js +20 -0
  188. package/lib/module/reanimated/useReanimatedPositionChangeHandler.web.js.map +1 -0
  189. package/lib/module/specs/NativeTrueSheetModule.js.map +1 -1
  190. package/lib/module/web/constants.js +16 -0
  191. package/lib/module/web/constants.js.map +1 -0
  192. package/lib/module/web/dom.js +10 -0
  193. package/lib/module/web/dom.js.map +1 -0
  194. package/lib/module/web/vaul/README.md +9 -0
  195. package/lib/module/web/vaul/browser.js +30 -0
  196. package/lib/module/web/vaul/browser.js.map +1 -0
  197. package/lib/module/web/vaul/constants.js +19 -0
  198. package/lib/module/web/vaul/constants.js.map +1 -0
  199. package/lib/module/web/vaul/context.js +59 -0
  200. package/lib/module/web/vaul/context.js.map +1 -0
  201. package/lib/module/web/vaul/helpers.js +99 -0
  202. package/lib/module/web/vaul/helpers.js.map +1 -0
  203. package/lib/module/web/vaul/index.js +1342 -0
  204. package/lib/module/web/vaul/index.js.map +1 -0
  205. package/lib/module/web/vaul/style.css +287 -0
  206. package/lib/module/web/vaul/style.css.d.js +2 -0
  207. package/lib/module/web/vaul/style.css.d.js.map +1 -0
  208. package/lib/module/web/vaul/types.js +2 -0
  209. package/lib/module/web/vaul/types.js.map +1 -0
  210. package/lib/module/web/vaul/use-composed-refs.js +34 -0
  211. package/lib/module/web/vaul/use-composed-refs.js.map +1 -0
  212. package/lib/module/web/vaul/use-controllable-state.js +54 -0
  213. package/lib/module/web/vaul/use-controllable-state.js.map +1 -0
  214. package/lib/module/web/vaul/use-position-fixed.js +123 -0
  215. package/lib/module/web/vaul/use-position-fixed.js.map +1 -0
  216. package/lib/module/web/vaul/use-prevent-scroll.js +258 -0
  217. package/lib/module/web/vaul/use-prevent-scroll.js.map +1 -0
  218. package/lib/module/web/vaul/use-scale-background.js +57 -0
  219. package/lib/module/web/vaul/use-scale-background.js.map +1 -0
  220. package/lib/module/web/vaul/use-snap-points.js +305 -0
  221. package/lib/module/web/vaul/use-snap-points.js.map +1 -0
  222. package/lib/typescript/src/TrueSheet.d.ts +57 -14
  223. package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
  224. package/lib/typescript/src/TrueSheet.types.d.ts +535 -55
  225. package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
  226. package/lib/typescript/src/TrueSheet.web.d.ts +5 -0
  227. package/lib/typescript/src/TrueSheet.web.d.ts.map +1 -0
  228. package/lib/typescript/src/TrueSheetOverlay.d.ts +8 -0
  229. package/lib/typescript/src/TrueSheetOverlay.d.ts.map +1 -0
  230. package/lib/typescript/src/TrueSheetOverlay.web.d.ts +8 -0
  231. package/lib/typescript/src/TrueSheetOverlay.web.d.ts.map +1 -0
  232. package/lib/typescript/src/TrueSheetPeek.d.ts +9 -0
  233. package/lib/typescript/src/TrueSheetPeek.d.ts.map +1 -0
  234. package/lib/typescript/src/TrueSheetPeek.web.d.ts +28 -0
  235. package/lib/typescript/src/TrueSheetPeek.web.d.ts.map +1 -0
  236. package/lib/typescript/src/TrueSheetProvider.d.ts +18 -0
  237. package/lib/typescript/src/TrueSheetProvider.d.ts.map +1 -0
  238. package/lib/typescript/src/TrueSheetProvider.web.d.ts +27 -0
  239. package/lib/typescript/src/TrueSheetProvider.web.d.ts.map +1 -0
  240. package/lib/typescript/src/fabric/TrueSheetContainerViewNativeComponent.d.ts.map +1 -1
  241. package/lib/typescript/src/fabric/TrueSheetContentViewNativeComponent.d.ts.map +1 -1
  242. package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts +2 -0
  243. package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts.map +1 -1
  244. package/lib/typescript/src/fabric/TrueSheetHeaderViewNativeComponent.d.ts +6 -0
  245. package/lib/typescript/src/fabric/TrueSheetHeaderViewNativeComponent.d.ts.map +1 -0
  246. package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts +6 -0
  247. package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts.map +1 -0
  248. package/lib/typescript/src/fabric/TrueSheetPeekViewNativeComponent.d.ts +6 -0
  249. package/lib/typescript/src/fabric/TrueSheetPeekViewNativeComponent.d.ts.map +1 -0
  250. package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +71 -16
  251. package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
  252. package/lib/typescript/src/index.d.ts +3 -2
  253. package/lib/typescript/src/index.d.ts.map +1 -1
  254. package/lib/typescript/src/mocks/index.d.ts +47 -0
  255. package/lib/typescript/src/mocks/index.d.ts.map +1 -0
  256. package/lib/typescript/src/mocks/navigation.d.ts +70 -0
  257. package/lib/typescript/src/mocks/navigation.d.ts.map +1 -0
  258. package/lib/typescript/src/mocks/navigationExpoRouter.d.ts +22 -0
  259. package/lib/typescript/src/mocks/navigationExpoRouter.d.ts.map +1 -0
  260. package/lib/typescript/src/mocks/reanimated.d.ts +48 -0
  261. package/lib/typescript/src/mocks/reanimated.d.ts.map +1 -0
  262. package/lib/typescript/src/navigation/TrueSheetNavigatorContent.d.ts +5 -0
  263. package/lib/typescript/src/navigation/TrueSheetNavigatorContent.d.ts.map +1 -0
  264. package/lib/typescript/src/navigation/actions.d.ts +71 -0
  265. package/lib/typescript/src/navigation/actions.d.ts.map +1 -0
  266. package/lib/typescript/src/navigation/base-types.d.ts +9 -0
  267. package/lib/typescript/src/navigation/base-types.d.ts.map +1 -0
  268. package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts +3 -0
  269. package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts.map +1 -0
  270. package/lib/typescript/src/navigation/expo-router/base-types.d.ts +8 -0
  271. package/lib/typescript/src/navigation/expo-router/base-types.d.ts.map +1 -0
  272. package/lib/typescript/src/navigation/expo-router/index.d.ts +37 -0
  273. package/lib/typescript/src/navigation/expo-router/index.d.ts.map +1 -0
  274. package/lib/typescript/src/navigation/expo-router/types.d.ts +44 -0
  275. package/lib/typescript/src/navigation/expo-router/types.d.ts.map +1 -0
  276. package/lib/typescript/src/navigation/index.d.ts +45 -0
  277. package/lib/typescript/src/navigation/index.d.ts.map +1 -0
  278. package/lib/typescript/src/navigation/navigator.d.ts +7 -0
  279. package/lib/typescript/src/navigation/navigator.d.ts.map +1 -0
  280. package/lib/typescript/src/navigation/screen/ReanimatedTrueSheetScreen.d.ts +3 -0
  281. package/lib/typescript/src/navigation/screen/ReanimatedTrueSheetScreen.d.ts.map +1 -0
  282. package/lib/typescript/src/navigation/screen/TrueSheetScreen.d.ts +3 -0
  283. package/lib/typescript/src/navigation/screen/TrueSheetScreen.d.ts.map +1 -0
  284. package/lib/typescript/src/navigation/screen/index.d.ts +4 -0
  285. package/lib/typescript/src/navigation/screen/index.d.ts.map +1 -0
  286. package/lib/typescript/src/navigation/screen/types.d.ts +14 -0
  287. package/lib/typescript/src/navigation/screen/types.d.ts.map +1 -0
  288. package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts +34 -0
  289. package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts.map +1 -0
  290. package/lib/typescript/src/navigation/types.d.ts +213 -0
  291. package/lib/typescript/src/navigation/types.d.ts.map +1 -0
  292. package/lib/typescript/src/navigation/useTrueSheetNavigation.d.ts +23 -0
  293. package/lib/typescript/src/navigation/useTrueSheetNavigation.d.ts.map +1 -0
  294. package/lib/typescript/src/reanimated/ReanimatedTrueSheet.d.ts.map +1 -1
  295. package/lib/typescript/src/reanimated/ReanimatedTrueSheet.web.d.ts +41 -0
  296. package/lib/typescript/src/reanimated/ReanimatedTrueSheet.web.d.ts.map +1 -0
  297. package/lib/typescript/src/reanimated/ReanimatedTrueSheetProvider.d.ts +8 -2
  298. package/lib/typescript/src/reanimated/ReanimatedTrueSheetProvider.d.ts.map +1 -1
  299. package/lib/typescript/src/reanimated/useReanimatedPositionChangeHandler.web.d.ts +15 -0
  300. package/lib/typescript/src/reanimated/useReanimatedPositionChangeHandler.web.d.ts.map +1 -0
  301. package/lib/typescript/src/specs/NativeTrueSheetModule.d.ts +25 -3
  302. package/lib/typescript/src/specs/NativeTrueSheetModule.d.ts.map +1 -1
  303. package/lib/typescript/src/web/constants.d.ts +14 -0
  304. package/lib/typescript/src/web/constants.d.ts.map +1 -0
  305. package/lib/typescript/src/web/dom.d.ts +7 -0
  306. package/lib/typescript/src/web/dom.d.ts.map +1 -0
  307. package/lib/typescript/src/web/vaul/browser.d.ts +8 -0
  308. package/lib/typescript/src/web/vaul/browser.d.ts.map +1 -0
  309. package/lib/typescript/src/web/vaul/constants.d.ts +14 -0
  310. package/lib/typescript/src/web/vaul/constants.d.ts.map +1 -0
  311. package/lib/typescript/src/web/vaul/context.d.ts +54 -0
  312. package/lib/typescript/src/web/vaul/context.d.ts.map +1 -0
  313. package/lib/typescript/src/web/vaul/helpers.d.ts +17 -0
  314. package/lib/typescript/src/web/vaul/helpers.d.ts.map +1 -0
  315. package/lib/typescript/src/web/vaul/index.d.ts +234 -0
  316. package/lib/typescript/src/web/vaul/index.d.ts.map +1 -0
  317. package/lib/typescript/src/web/vaul/types.d.ts +7 -0
  318. package/lib/typescript/src/web/vaul/types.d.ts.map +1 -0
  319. package/lib/typescript/src/web/vaul/use-composed-refs.d.ts +14 -0
  320. package/lib/typescript/src/web/vaul/use-composed-refs.d.ts.map +1 -0
  321. package/lib/typescript/src/web/vaul/use-controllable-state.d.ts +9 -0
  322. package/lib/typescript/src/web/vaul/use-controllable-state.d.ts.map +1 -0
  323. package/lib/typescript/src/web/vaul/use-position-fixed.d.ts +19 -0
  324. package/lib/typescript/src/web/vaul/use-position-fixed.d.ts.map +1 -0
  325. package/lib/typescript/src/web/vaul/use-prevent-scroll.d.ts +18 -0
  326. package/lib/typescript/src/web/vaul/use-prevent-scroll.d.ts.map +1 -0
  327. package/lib/typescript/src/web/vaul/use-scale-background.d.ts +2 -0
  328. package/lib/typescript/src/web/vaul/use-scale-background.d.ts.map +1 -0
  329. package/lib/typescript/src/web/vaul/use-snap-points.d.ts +38 -0
  330. package/lib/typescript/src/web/vaul/use-snap-points.d.ts.map +1 -0
  331. package/package.json +104 -37
  332. package/react-native.config.js +10 -2
  333. package/src/TrueSheet.tsx +424 -70
  334. package/src/TrueSheet.types.ts +602 -72
  335. package/src/TrueSheet.web.tsx +1437 -0
  336. package/src/TrueSheetOverlay.tsx +24 -0
  337. package/src/TrueSheetOverlay.web.tsx +33 -0
  338. package/src/TrueSheetPeek.tsx +11 -0
  339. package/src/TrueSheetPeek.web.tsx +64 -0
  340. package/src/TrueSheetProvider.tsx +33 -0
  341. package/src/TrueSheetProvider.web.tsx +220 -0
  342. package/src/fabric/TrueSheetContainerViewNativeComponent.ts +1 -1
  343. package/src/fabric/TrueSheetContentViewNativeComponent.ts +5 -1
  344. package/src/fabric/TrueSheetFooterViewNativeComponent.ts +10 -2
  345. package/src/fabric/TrueSheetHeaderViewNativeComponent.ts +8 -0
  346. package/src/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
  347. package/src/fabric/TrueSheetPeekViewNativeComponent.ts +8 -0
  348. package/src/fabric/TrueSheetViewNativeComponent.ts +110 -18
  349. package/src/index.ts +3 -2
  350. package/src/mocks/index.ts +96 -0
  351. package/src/mocks/navigation.ts +79 -0
  352. package/src/mocks/navigationExpoRouter.ts +41 -0
  353. package/src/mocks/reanimated.ts +100 -0
  354. package/src/navigation/TrueSheetNavigatorContent.tsx +106 -0
  355. package/src/navigation/actions.ts +78 -0
  356. package/src/navigation/base-types.ts +20 -0
  357. package/src/navigation/createTrueSheetRouter.ts +194 -0
  358. package/src/navigation/expo-router/base-types.ts +18 -0
  359. package/src/navigation/expo-router/index.ts +90 -0
  360. package/src/navigation/expo-router/types.ts +116 -0
  361. package/src/navigation/index.ts +80 -0
  362. package/src/navigation/navigator.ts +18 -0
  363. package/src/navigation/screen/ReanimatedTrueSheetScreen.tsx +61 -0
  364. package/src/navigation/screen/TrueSheetScreen.tsx +54 -0
  365. package/src/navigation/screen/index.ts +3 -0
  366. package/src/navigation/screen/types.ts +19 -0
  367. package/src/navigation/screen/useSheetScreenState.ts +102 -0
  368. package/src/navigation/types.ts +302 -0
  369. package/src/navigation/useTrueSheetNavigation.ts +26 -0
  370. package/src/reanimated/ReanimatedTrueSheet.tsx +12 -7
  371. package/src/reanimated/ReanimatedTrueSheet.web.tsx +75 -0
  372. package/src/reanimated/ReanimatedTrueSheetProvider.tsx +12 -8
  373. package/src/reanimated/useReanimatedPositionChangeHandler.web.ts +31 -0
  374. package/src/specs/NativeTrueSheetModule.ts +28 -3
  375. package/src/web/constants.ts +13 -0
  376. package/src/web/dom.ts +9 -0
  377. package/src/web/vaul/README.md +9 -0
  378. package/src/web/vaul/browser.ts +38 -0
  379. package/src/web/vaul/constants.ts +24 -0
  380. package/src/web/vaul/context.ts +102 -0
  381. package/src/web/vaul/helpers.ts +131 -0
  382. package/src/web/vaul/index.tsx +1785 -0
  383. package/src/web/vaul/style.css +287 -0
  384. package/src/web/vaul/style.css.d.ts +1 -0
  385. package/src/web/vaul/types.ts +7 -0
  386. package/src/web/vaul/use-composed-refs.ts +35 -0
  387. package/src/web/vaul/use-controllable-state.ts +66 -0
  388. package/src/web/vaul/use-position-fixed.ts +147 -0
  389. package/src/web/vaul/use-prevent-scroll.ts +309 -0
  390. package/src/web/vaul/use-scale-background.ts +64 -0
  391. package/src/web/vaul/use-snap-points.ts +455 -0
  392. package/android/src/main/java/com/lodev09/truesheet/events/DetentChangeEvent.kt +0 -26
  393. package/android/src/main/java/com/lodev09/truesheet/events/DidDismissEvent.kt +0 -20
  394. package/android/src/main/java/com/lodev09/truesheet/events/DidPresentEvent.kt +0 -26
  395. package/android/src/main/java/com/lodev09/truesheet/events/DragBeginEvent.kt +0 -26
  396. package/android/src/main/java/com/lodev09/truesheet/events/DragChangeEvent.kt +0 -26
  397. package/android/src/main/java/com/lodev09/truesheet/events/DragEndEvent.kt +0 -26
  398. package/android/src/main/java/com/lodev09/truesheet/events/MountEvent.kt +0 -20
  399. package/android/src/main/java/com/lodev09/truesheet/events/PositionChangeEvent.kt +0 -32
  400. package/android/src/main/java/com/lodev09/truesheet/events/SizeChangeEvent.kt +0 -27
  401. package/android/src/main/java/com/lodev09/truesheet/events/WillDismissEvent.kt +0 -20
  402. package/android/src/main/java/com/lodev09/truesheet/events/WillPresentEvent.kt +0 -26
  403. package/android/src/main/res/values/styles.xml +0 -8
  404. package/ios/events/OnDetentChangeEvent.h +0 -28
  405. package/ios/events/OnDetentChangeEvent.mm +0 -30
  406. package/ios/events/OnDidDismissEvent.h +0 -26
  407. package/ios/events/OnDidDismissEvent.mm +0 -25
  408. package/ios/events/OnDidPresentEvent.h +0 -28
  409. package/ios/events/OnDidPresentEvent.mm +0 -30
  410. package/ios/events/OnDragBeginEvent.h +0 -28
  411. package/ios/events/OnDragBeginEvent.mm +0 -30
  412. package/ios/events/OnDragChangeEvent.h +0 -28
  413. package/ios/events/OnDragChangeEvent.mm +0 -30
  414. package/ios/events/OnDragEndEvent.h +0 -28
  415. package/ios/events/OnDragEndEvent.mm +0 -30
  416. package/ios/events/OnMountEvent.mm +0 -25
  417. package/ios/events/OnPositionChangeEvent.mm +0 -32
  418. package/ios/events/OnSizeChangeEvent.h +0 -28
  419. package/ios/events/OnSizeChangeEvent.mm +0 -30
  420. package/ios/events/OnWillDismissEvent.mm +0 -25
  421. package/ios/events/OnWillPresentEvent.h +0 -28
  422. package/ios/events/OnWillPresentEvent.mm +0 -30
  423. package/ios/utils/LayoutUtil.h +0 -44
  424. package/ios/utils/LayoutUtil.mm +0 -50
  425. package/lib/module/TrueSheetGrabber.js +0 -51
  426. package/lib/module/TrueSheetGrabber.js.map +0 -1
  427. package/lib/typescript/src/TrueSheetGrabber.d.ts +0 -39
  428. package/lib/typescript/src/TrueSheetGrabber.d.ts.map +0 -1
  429. package/src/TrueSheetGrabber.tsx +0 -82
  430. package/src/__mocks__/index.js +0 -67
@@ -0,0 +1,455 @@
1
+ // @ts-nocheck — vendored upstream, incompatible with noUncheckedIndexedAccess
2
+ import React from 'react';
3
+ import { set, isVertical } from './helpers';
4
+ import { DEFAULT_PEEK_HEIGHT, TRANSITIONS, VELOCITY_THRESHOLD } from './constants';
5
+ import { useControllableState } from './use-controllable-state';
6
+ import type { DrawerDirection } from './types';
7
+
8
+ export function useSnapPoints({
9
+ activeSnapPointProp,
10
+ setActiveSnapPointProp,
11
+ snapPoints,
12
+ drawerRef,
13
+ overlayRef,
14
+ fadeFromIndex,
15
+ onSnapPointChange,
16
+ direction = 'bottom',
17
+ container,
18
+ snapToSequentialPoint,
19
+ isOpen,
20
+ contentHeight,
21
+ detachedOffset = 0,
22
+ maxContentHeight,
23
+ peekHeight,
24
+ initialAnimated = true,
25
+ }: {
26
+ activeSnapPointProp?: number | string | null;
27
+ setActiveSnapPointProp?(snapPoint: number | null | string): void;
28
+ snapPoints?: (number | string)[];
29
+ fadeFromIndex?: number;
30
+ drawerRef: React.RefObject<HTMLDivElement | null>;
31
+ overlayRef: React.RefObject<HTMLDivElement | null>;
32
+ onSnapPointChange(activeSnapPointIndex: number): void;
33
+ direction?: DrawerDirection;
34
+ container?: HTMLElement | null | undefined;
35
+ snapToSequentialPoint?: boolean;
36
+ isOpen?: boolean;
37
+ contentHeight?: number;
38
+ detachedOffset?: number;
39
+ maxContentHeight?: number;
40
+ peekHeight?: number;
41
+ initialAnimated?: boolean;
42
+ }) {
43
+ const [activeSnapPoint, setActiveSnapPoint] = useControllableState<string | number | null>({
44
+ prop: activeSnapPointProp,
45
+ defaultProp: snapPoints?.[0],
46
+ onChange: setActiveSnapPointProp,
47
+ });
48
+
49
+ const [windowDimensions, setWindowDimensions] = React.useState(
50
+ typeof window !== 'undefined'
51
+ ? {
52
+ innerWidth: window.innerWidth,
53
+ innerHeight: window.innerHeight,
54
+ }
55
+ : undefined
56
+ );
57
+
58
+ React.useEffect(() => {
59
+ function onResize() {
60
+ setWindowDimensions({
61
+ innerWidth: window.innerWidth,
62
+ innerHeight: window.innerHeight,
63
+ });
64
+ }
65
+ window.addEventListener('resize', onResize);
66
+
67
+ return () => window.removeEventListener('resize', onResize);
68
+ }, []);
69
+
70
+ const isLastSnapPoint = React.useMemo(
71
+ () => activeSnapPoint === snapPoints?.[snapPoints.length - 1] || null,
72
+ [snapPoints, activeSnapPoint]
73
+ );
74
+
75
+ const activeSnapPointIndex = React.useMemo(
76
+ () => snapPoints?.findIndex((snapPoint) => snapPoint === activeSnapPoint) ?? null,
77
+ [snapPoints, activeSnapPoint]
78
+ );
79
+
80
+ const shouldFade =
81
+ (snapPoints &&
82
+ snapPoints.length > 0 &&
83
+ (fadeFromIndex || fadeFromIndex === 0) &&
84
+ !Number.isNaN(fadeFromIndex) &&
85
+ snapPoints[fadeFromIndex] === activeSnapPoint) ||
86
+ !snapPoints;
87
+
88
+ const snapPointsOffset = React.useMemo(() => {
89
+ const containerSize = container
90
+ ? {
91
+ width: container.getBoundingClientRect().width,
92
+ height: container.getBoundingClientRect().height,
93
+ }
94
+ : typeof window !== 'undefined'
95
+ ? { width: window.innerWidth, height: window.innerHeight }
96
+ : { width: 0, height: 0 };
97
+
98
+ // Shrink the effective vertical area by detachedOffset so snap math
99
+ // reserves a fixed gap at the bottom — the floating card stays offset
100
+ // from the viewport edge through drag, snap and resize.
101
+ const effectiveHeight = Math.max(0, containerSize.height - (detachedOffset || 0));
102
+
103
+ return (
104
+ snapPoints?.map((snapPoint) => {
105
+ // 'auto' resolves to measured content height. Falls back to half the
106
+ // container so the initial snap is close to final before ResizeObserver
107
+ // reports a real measurement. 'peek' resolves to the caller-measured
108
+ // header + footer height.
109
+ const resolved =
110
+ snapPoint === 'auto'
111
+ ? `${contentHeight && contentHeight > 0 ? contentHeight : effectiveHeight / 2}px`
112
+ : snapPoint === 'peek'
113
+ ? `${peekHeight && peekHeight > 0 ? peekHeight : DEFAULT_PEEK_HEIGHT}px`
114
+ : snapPoint;
115
+ const isPx = typeof resolved === 'string';
116
+ let snapPointAsNumber = 0;
117
+
118
+ if (isPx) {
119
+ snapPointAsNumber = parseInt(resolved, 10);
120
+ }
121
+
122
+ if (isVertical(direction)) {
123
+ const rawHeight = isPx
124
+ ? snapPointAsNumber
125
+ : windowDimensions
126
+ ? resolved * effectiveHeight
127
+ : 0;
128
+ // Cap px/'auto' snap points so a content taller than the viewport
129
+ // doesn't push the drawer past the top edge (offset would go
130
+ // negative). Fractional detents are already ≤ effectiveHeight.
131
+ // `maxContentHeight`, when set, caps the visible sheet further so
132
+ // full/'auto' detents respect the user's ceiling.
133
+ const ceiling =
134
+ maxContentHeight !== undefined
135
+ ? Math.min(effectiveHeight, maxContentHeight)
136
+ : effectiveHeight;
137
+ const height = Math.min(rawHeight, ceiling);
138
+
139
+ if (windowDimensions) {
140
+ return direction === 'bottom' ? effectiveHeight - height : -effectiveHeight + height;
141
+ }
142
+
143
+ return height;
144
+ }
145
+ const rawWidth = isPx
146
+ ? snapPointAsNumber
147
+ : windowDimensions
148
+ ? resolved * containerSize.width
149
+ : 0;
150
+ const width = Math.min(rawWidth, containerSize.width);
151
+
152
+ if (windowDimensions) {
153
+ return direction === 'right' ? containerSize.width - width : -containerSize.width + width;
154
+ }
155
+
156
+ return width;
157
+ }) ?? []
158
+ );
159
+ }, [
160
+ snapPoints,
161
+ windowDimensions,
162
+ container,
163
+ contentHeight,
164
+ detachedOffset,
165
+ maxContentHeight,
166
+ peekHeight,
167
+ ]);
168
+
169
+ const activeSnapPointOffset = React.useMemo(
170
+ () => (activeSnapPointIndex !== null ? snapPointsOffset?.[activeSnapPointIndex] : null),
171
+ [snapPointsOffset, activeSnapPointIndex]
172
+ );
173
+
174
+ // Detached-only: the drawer sits inside a clip wrapper. When drag overshoots
175
+ // below the lowest detent we translate the wrapper by the excess so the
176
+ // whole floating card follows the pointer instead of the drawer sliding
177
+ // behind the wrapper's rounded-bottom clip.
178
+ const setDetachedWrapperTransform = (y: number, animated: boolean) => {
179
+ if (!drawerRef.current || !isVertical(direction)) return;
180
+ const wrapper = drawerRef.current.closest<HTMLElement>('[data-vaul-detached-wrapper]');
181
+ if (!wrapper) return;
182
+ set(wrapper, {
183
+ transition: animated
184
+ ? `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(',')})`
185
+ : 'none',
186
+ transform: `translate3d(0, ${y}px, 0)`,
187
+ });
188
+ };
189
+
190
+ // Skip the transition on the very first snap when the consumer opts out of
191
+ // the initial presentation animation. All subsequent snaps still animate.
192
+ const hasSnappedRef = React.useRef(false);
193
+ const snapToPoint = React.useCallback(
194
+ (dimension: number) => {
195
+ const newSnapPointIndex =
196
+ snapPointsOffset?.findIndex((snapPointDim) => snapPointDim === dimension) ?? null;
197
+ onSnapPointChange(newSnapPointIndex);
198
+
199
+ const animateThisSnap = hasSnappedRef.current || initialAnimated;
200
+ hasSnappedRef.current = true;
201
+ // `--snap-point-height` transitions alongside `transform` (registered via
202
+ // @property) so layouts derived from it (e.g. the scrollable fill) resize
203
+ // in sync with the drawer's slide instead of jumping to the target.
204
+ set(drawerRef.current, {
205
+ 'transition': animateThisSnap
206
+ ? `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(',')}), --snap-point-height ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(',')})`
207
+ : 'none',
208
+ 'transform': isVertical(direction)
209
+ ? `translate3d(0, ${dimension}px, 0)`
210
+ : `translate3d(${dimension}px, 0, 0)`,
211
+ '--snap-point-height': `${dimension}px`,
212
+ });
213
+
214
+ // Snapping implies drag overshoot (if any) should be undone.
215
+ setDetachedWrapperTransform(0, animateThisSnap);
216
+
217
+ if (
218
+ snapPointsOffset &&
219
+ newSnapPointIndex !== snapPointsOffset.length - 1 &&
220
+ fadeFromIndex !== undefined &&
221
+ newSnapPointIndex !== fadeFromIndex &&
222
+ newSnapPointIndex < fadeFromIndex
223
+ ) {
224
+ set(overlayRef.current, {
225
+ transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(',')})`,
226
+ opacity: '0',
227
+ pointerEvents: 'none',
228
+ });
229
+ } else {
230
+ set(overlayRef.current, {
231
+ transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(',')})`,
232
+ opacity: '1',
233
+ pointerEvents: 'auto',
234
+ });
235
+ }
236
+
237
+ setActiveSnapPoint(snapPoints?.[Math.max(newSnapPointIndex, 0)]);
238
+ },
239
+ [drawerRef.current, snapPoints, snapPointsOffset, fadeFromIndex, overlayRef, setActiveSnapPoint]
240
+ );
241
+
242
+ React.useEffect(() => {
243
+ if (!isOpen) return;
244
+ if (activeSnapPoint || activeSnapPointProp) {
245
+ const newIndex =
246
+ snapPoints?.findIndex(
247
+ (snapPoint) => snapPoint === activeSnapPointProp || snapPoint === activeSnapPoint
248
+ ) ?? -1;
249
+ if (snapPointsOffset && newIndex !== -1 && typeof snapPointsOffset[newIndex] === 'number') {
250
+ snapToPoint(snapPointsOffset[newIndex] as number);
251
+ }
252
+ }
253
+ }, [isOpen, activeSnapPoint, activeSnapPointProp, snapPoints, snapPointsOffset, snapToPoint]);
254
+
255
+ function onRelease({
256
+ draggedDistance,
257
+ closeDrawer,
258
+ velocity,
259
+ dismissible,
260
+ }: {
261
+ draggedDistance: number;
262
+ closeDrawer: () => void;
263
+ velocity: number;
264
+ dismissible: boolean;
265
+ }) {
266
+ if (fadeFromIndex === undefined) return;
267
+
268
+ const currentPosition =
269
+ direction === 'bottom' || direction === 'right'
270
+ ? (activeSnapPointOffset ?? 0) - draggedDistance
271
+ : (activeSnapPointOffset ?? 0) + draggedDistance;
272
+ const isOverlaySnapPoint = activeSnapPointIndex === fadeFromIndex - 1;
273
+ const isFirst = activeSnapPointIndex === 0;
274
+ const hasDraggedUp = draggedDistance > 0;
275
+
276
+ if (isOverlaySnapPoint) {
277
+ set(overlayRef.current, {
278
+ transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(',')})`,
279
+ });
280
+ }
281
+
282
+ // Distance-based dismiss: when overshooting past the lowest detent by more
283
+ // than half of its visible height, commit to dismiss regardless of
284
+ // velocity — lets a slow drag-down still close the sheet.
285
+ if (
286
+ dismissible &&
287
+ (direction === 'bottom' || direction === 'right') &&
288
+ currentPosition > snapPointsOffset[0]
289
+ ) {
290
+ const viewportDim = isVertical(direction) ? window.innerHeight : window.innerWidth;
291
+ const effectiveDim = Math.max(0, viewportDim - (detachedOffset || 0));
292
+ const visibleAtLowest = Math.max(0, effectiveDim - snapPointsOffset[0]);
293
+ const overshoot = currentPosition - snapPointsOffset[0];
294
+ if (overshoot > visibleAtLowest * 0.5) {
295
+ closeDrawer();
296
+ return;
297
+ }
298
+ }
299
+
300
+ if (!snapToSequentialPoint && velocity > 2 && !hasDraggedUp) {
301
+ if (dismissible) closeDrawer();
302
+ else snapToPoint(snapPointsOffset[0]); // snap to initial point
303
+ return;
304
+ }
305
+
306
+ if (!snapToSequentialPoint && velocity > 2 && hasDraggedUp && snapPointsOffset && snapPoints) {
307
+ snapToPoint(snapPointsOffset[snapPoints.length - 1] as number);
308
+ return;
309
+ }
310
+
311
+ // Find the closest snap point to the current position
312
+ const closestSnapPoint = snapPointsOffset?.reduce((prev, curr) => {
313
+ if (typeof prev !== 'number' || typeof curr !== 'number') return prev;
314
+
315
+ return Math.abs(curr - currentPosition) < Math.abs(prev - currentPosition) ? curr : prev;
316
+ });
317
+
318
+ const dim = isVertical(direction) ? window.innerHeight : window.innerWidth;
319
+ if (velocity > VELOCITY_THRESHOLD && Math.abs(draggedDistance) < dim * 0.4) {
320
+ const dragDirection = hasDraggedUp ? 1 : -1; // 1 = up, -1 = down
321
+
322
+ // Don't do anything if we swipe upwards while being on the last snap point
323
+ if (dragDirection > 0 && isLastSnapPoint && snapPoints) {
324
+ snapToPoint(snapPointsOffset[snapPoints.length - 1]);
325
+ return;
326
+ }
327
+
328
+ if (isFirst && dragDirection < 0 && dismissible) {
329
+ closeDrawer();
330
+ }
331
+
332
+ if (activeSnapPointIndex === null) return;
333
+
334
+ snapToPoint(snapPointsOffset[activeSnapPointIndex + dragDirection]);
335
+ return;
336
+ }
337
+
338
+ snapToPoint(closestSnapPoint);
339
+ }
340
+
341
+ function onDrag({ draggedDistance }: { draggedDistance: number }) {
342
+ if (activeSnapPointOffset === null) return;
343
+ const newValue =
344
+ direction === 'bottom' || direction === 'right'
345
+ ? activeSnapPointOffset - draggedDistance
346
+ : activeSnapPointOffset + draggedDistance;
347
+
348
+ // Don't do anything if we exceed the last(biggest) snap point
349
+ if (
350
+ (direction === 'bottom' || direction === 'right') &&
351
+ newValue < snapPointsOffset[snapPointsOffset.length - 1]
352
+ ) {
353
+ return;
354
+ }
355
+ if (
356
+ (direction === 'top' || direction === 'left') &&
357
+ newValue > snapPointsOffset[snapPointsOffset.length - 1]
358
+ ) {
359
+ return;
360
+ }
361
+
362
+ // Past the lowest detent: cap the drawer and translate the detached
363
+ // wrapper by the excess so the floating card follows the pointer.
364
+ if ((direction === 'bottom' || direction === 'right') && newValue > snapPointsOffset[0]) {
365
+ const excess = newValue - snapPointsOffset[0];
366
+ set(drawerRef.current, {
367
+ 'transform': isVertical(direction)
368
+ ? `translate3d(0, ${snapPointsOffset[0]}px, 0)`
369
+ : `translate3d(${snapPointsOffset[0]}px, 0, 0)`,
370
+ '--snap-point-height': `${snapPointsOffset[0]}px`,
371
+ });
372
+ setDetachedWrapperTransform(excess, false);
373
+ return;
374
+ }
375
+
376
+ setDetachedWrapperTransform(0, false);
377
+ // Keep `--snap-point-height` tracking the live drag position so layouts
378
+ // derived from it (e.g. the scrollable fill) resize with the drawer
379
+ // instead of staying cut off at the last detent's visible height.
380
+ set(drawerRef.current, {
381
+ 'transform': isVertical(direction)
382
+ ? `translate3d(0, ${newValue}px, 0)`
383
+ : `translate3d(${newValue}px, 0, 0)`,
384
+ '--snap-point-height': `${newValue}px`,
385
+ });
386
+ }
387
+
388
+ function getPercentageDragged(absDraggedDistance: number, isDraggingDown: boolean) {
389
+ if (
390
+ !snapPoints ||
391
+ typeof activeSnapPointIndex !== 'number' ||
392
+ !snapPointsOffset ||
393
+ fadeFromIndex === undefined
394
+ )
395
+ return null;
396
+
397
+ // fadeFromIndex === 0 means every snap point is fully dimmed. Only the dismiss drag
398
+ // (toward close from the smallest detent) should fade the overlay out, interpolating
399
+ // opacity by distance from the smallest snap to the fully-dismissed position.
400
+ if (fadeFromIndex === 0) {
401
+ if (activeSnapPointIndex === 0 && !isDraggingDown) {
402
+ const activeOffset = snapPointsOffset[activeSnapPointIndex];
403
+ if (activeOffset === undefined) return 0;
404
+ const windowDim = isVertical(direction) ? window.innerHeight : window.innerWidth;
405
+ const dismissOffset =
406
+ direction === 'bottom' || direction === 'right' ? windowDim : -windowDim;
407
+ const dismissRange = Math.abs(dismissOffset - activeOffset);
408
+ return dismissRange > 0 ? Math.min(1, absDraggedDistance / dismissRange) : 0;
409
+ }
410
+ return 0;
411
+ }
412
+
413
+ // If this is true we are dragging to a snap point that is supposed to have an overlay
414
+ const isOverlaySnapPoint = activeSnapPointIndex === fadeFromIndex - 1;
415
+ const isOverlaySnapPointOrHigher = activeSnapPointIndex >= fadeFromIndex;
416
+
417
+ if (isOverlaySnapPointOrHigher && isDraggingDown) {
418
+ return 0;
419
+ }
420
+
421
+ // Don't animate, but still use this one if we are dragging away from the overlaySnapPoint
422
+ if (isOverlaySnapPoint && !isDraggingDown) return 1;
423
+ if (!shouldFade && !isOverlaySnapPoint) return null;
424
+
425
+ // Either fadeFrom index or the one before
426
+ const targetSnapPointIndex = isOverlaySnapPoint
427
+ ? activeSnapPointIndex + 1
428
+ : activeSnapPointIndex - 1;
429
+
430
+ // Get the distance from overlaySnapPoint to the one before or vice-versa to calculate the opacity percentage accordingly
431
+ const snapPointDistance = isOverlaySnapPoint
432
+ ? snapPointsOffset[targetSnapPointIndex] - snapPointsOffset[targetSnapPointIndex - 1]
433
+ : snapPointsOffset[targetSnapPointIndex + 1] - snapPointsOffset[targetSnapPointIndex];
434
+
435
+ const percentageDragged = absDraggedDistance / Math.abs(snapPointDistance);
436
+
437
+ if (isOverlaySnapPoint) {
438
+ return 1 - percentageDragged;
439
+ } else {
440
+ return percentageDragged;
441
+ }
442
+ }
443
+
444
+ return {
445
+ isLastSnapPoint,
446
+ activeSnapPoint,
447
+ shouldFade,
448
+ getPercentageDragged,
449
+ setActiveSnapPoint,
450
+ activeSnapPointIndex,
451
+ onRelease,
452
+ onDrag,
453
+ snapPointsOffset,
454
+ };
455
+ }
@@ -1,26 +0,0 @@
1
- package com.lodev09.truesheet.events
2
-
3
- import com.facebook.react.bridge.Arguments
4
- import com.facebook.react.bridge.WritableMap
5
- import com.facebook.react.uimanager.events.Event
6
-
7
- /**
8
- * Fired when the active detent changes
9
- * Payload: { index: number, position: number }
10
- */
11
- class DetentChangeEvent(surfaceId: Int, viewId: Int, private val index: Int, private val position: Float) :
12
- Event<DetentChangeEvent>(surfaceId, viewId) {
13
-
14
- override fun getEventName(): String = EVENT_NAME
15
-
16
- override fun getEventData(): WritableMap =
17
- Arguments.createMap().apply {
18
- putInt("index", index)
19
- putDouble("position", position.toDouble())
20
- }
21
-
22
- companion object {
23
- const val EVENT_NAME = "topDetentChange"
24
- const val REGISTRATION_NAME = "onDetentChange"
25
- }
26
- }
@@ -1,20 +0,0 @@
1
- package com.lodev09.truesheet.events
2
-
3
- import com.facebook.react.bridge.Arguments
4
- import com.facebook.react.bridge.WritableMap
5
- import com.facebook.react.uimanager.events.Event
6
-
7
- /**
8
- * Fired after the sheet dismissal is complete
9
- */
10
- class DidDismissEvent(surfaceId: Int, viewId: Int) : Event<DidDismissEvent>(surfaceId, viewId) {
11
-
12
- override fun getEventName(): String = EVENT_NAME
13
-
14
- override fun getEventData(): WritableMap = Arguments.createMap()
15
-
16
- companion object {
17
- const val EVENT_NAME = "topDidDismiss"
18
- const val REGISTRATION_NAME = "onDidDismiss"
19
- }
20
- }
@@ -1,26 +0,0 @@
1
- package com.lodev09.truesheet.events
2
-
3
- import com.facebook.react.bridge.Arguments
4
- import com.facebook.react.bridge.WritableMap
5
- import com.facebook.react.uimanager.events.Event
6
-
7
- /**
8
- * Fired after the sheet presentation is complete
9
- * Payload: { index: number, position: number }
10
- */
11
- class DidPresentEvent(surfaceId: Int, viewId: Int, private val index: Int, private val position: Float) :
12
- Event<DidPresentEvent>(surfaceId, viewId) {
13
-
14
- override fun getEventName(): String = EVENT_NAME
15
-
16
- override fun getEventData(): WritableMap =
17
- Arguments.createMap().apply {
18
- putInt("index", index)
19
- putDouble("position", position.toDouble())
20
- }
21
-
22
- companion object {
23
- const val EVENT_NAME = "topDidPresent"
24
- const val REGISTRATION_NAME = "onDidPresent"
25
- }
26
- }
@@ -1,26 +0,0 @@
1
- package com.lodev09.truesheet.events
2
-
3
- import com.facebook.react.bridge.Arguments
4
- import com.facebook.react.bridge.WritableMap
5
- import com.facebook.react.uimanager.events.Event
6
-
7
- /**
8
- * Fired when user starts dragging the sheet
9
- * Payload: { index: number, position: number }
10
- */
11
- class DragBeginEvent(surfaceId: Int, viewId: Int, private val index: Int, private val position: Float) :
12
- Event<DragBeginEvent>(surfaceId, viewId) {
13
-
14
- override fun getEventName(): String = EVENT_NAME
15
-
16
- override fun getEventData(): WritableMap =
17
- Arguments.createMap().apply {
18
- putInt("index", index)
19
- putDouble("position", position.toDouble())
20
- }
21
-
22
- companion object {
23
- const val EVENT_NAME = "topDragBegin"
24
- const val REGISTRATION_NAME = "onDragBegin"
25
- }
26
- }
@@ -1,26 +0,0 @@
1
- package com.lodev09.truesheet.events
2
-
3
- import com.facebook.react.bridge.Arguments
4
- import com.facebook.react.bridge.WritableMap
5
- import com.facebook.react.uimanager.events.Event
6
-
7
- /**
8
- * Fired continuously while user is dragging the sheet
9
- * Payload: { index: number, position: number }
10
- */
11
- class DragChangeEvent(surfaceId: Int, viewId: Int, private val index: Int, private val position: Float) :
12
- Event<DragChangeEvent>(surfaceId, viewId) {
13
-
14
- override fun getEventName(): String = EVENT_NAME
15
-
16
- override fun getEventData(): WritableMap =
17
- Arguments.createMap().apply {
18
- putInt("index", index)
19
- putDouble("position", position.toDouble())
20
- }
21
-
22
- companion object {
23
- const val EVENT_NAME = "topDragChange"
24
- const val REGISTRATION_NAME = "onDragChange"
25
- }
26
- }
@@ -1,26 +0,0 @@
1
- package com.lodev09.truesheet.events
2
-
3
- import com.facebook.react.bridge.Arguments
4
- import com.facebook.react.bridge.WritableMap
5
- import com.facebook.react.uimanager.events.Event
6
-
7
- /**
8
- * Fired when user stops dragging the sheet
9
- * Payload: { index: number, position: number }
10
- */
11
- class DragEndEvent(surfaceId: Int, viewId: Int, private val index: Int, private val position: Float) :
12
- Event<DragEndEvent>(surfaceId, viewId) {
13
-
14
- override fun getEventName(): String = EVENT_NAME
15
-
16
- override fun getEventData(): WritableMap =
17
- Arguments.createMap().apply {
18
- putInt("index", index)
19
- putDouble("position", position.toDouble())
20
- }
21
-
22
- companion object {
23
- const val EVENT_NAME = "topDragEnd"
24
- const val REGISTRATION_NAME = "onDragEnd"
25
- }
26
- }
@@ -1,20 +0,0 @@
1
- package com.lodev09.truesheet.events
2
-
3
- import com.facebook.react.bridge.Arguments
4
- import com.facebook.react.bridge.WritableMap
5
- import com.facebook.react.uimanager.events.Event
6
-
7
- /**
8
- * Fired when the sheet component is mounted and ready
9
- */
10
- class MountEvent(surfaceId: Int, viewId: Int) : Event<MountEvent>(surfaceId, viewId) {
11
-
12
- override fun getEventName(): String = EVENT_NAME
13
-
14
- override fun getEventData(): WritableMap = Arguments.createMap()
15
-
16
- companion object {
17
- const val EVENT_NAME = "topMount"
18
- const val REGISTRATION_NAME = "onMount"
19
- }
20
- }
@@ -1,32 +0,0 @@
1
- package com.lodev09.truesheet.events
2
-
3
- import com.facebook.react.bridge.Arguments
4
- import com.facebook.react.bridge.WritableMap
5
- import com.facebook.react.uimanager.events.Event
6
-
7
- /**
8
- * Fired continuously for position updates during drag and animation
9
- * Payload: { index: number, position: number, transitioning: boolean }
10
- */
11
- class PositionChangeEvent(
12
- surfaceId: Int,
13
- viewId: Int,
14
- private val index: Int,
15
- private val position: Float,
16
- private val transitioning: Boolean = false
17
- ) : Event<PositionChangeEvent>(surfaceId, viewId) {
18
-
19
- override fun getEventName(): String = EVENT_NAME
20
-
21
- override fun getEventData(): WritableMap =
22
- Arguments.createMap().apply {
23
- putInt("index", index)
24
- putDouble("position", position.toDouble())
25
- putBoolean("transitioning", transitioning)
26
- }
27
-
28
- companion object {
29
- const val EVENT_NAME = "topPositionChange"
30
- const val REGISTRATION_NAME = "onPositionChange"
31
- }
32
- }
@@ -1,27 +0,0 @@
1
- package com.lodev09.truesheet.events
2
-
3
- import com.facebook.react.bridge.Arguments
4
- import com.facebook.react.bridge.WritableMap
5
- import com.facebook.react.uimanager.PixelUtil
6
- import com.facebook.react.uimanager.events.Event
7
-
8
- /**
9
- * Fired when the root view's size changes
10
- * Payload: { width: number, height: number }
11
- */
12
- class SizeChangeEvent(surfaceId: Int, viewId: Int, private val width: Int, private val height: Int) :
13
- Event<SizeChangeEvent>(surfaceId, viewId) {
14
-
15
- override fun getEventName(): String = EVENT_NAME
16
-
17
- override fun getEventData(): WritableMap =
18
- Arguments.createMap().apply {
19
- putDouble("width", PixelUtil.toDIPFromPixel(width.toFloat()).toDouble())
20
- putDouble("height", PixelUtil.toDIPFromPixel(height.toFloat()).toDouble())
21
- }
22
-
23
- companion object {
24
- const val EVENT_NAME = "topSizeChange"
25
- const val REGISTRATION_NAME = "onSizeChange"
26
- }
27
- }