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

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 (367) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +42 -31
  3. package/RNTrueSheet.podspec +10 -2
  4. package/android/build.gradle +2 -1
  5. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +174 -49
  6. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerViewManager.kt +7 -0
  7. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +371 -18
  8. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +14 -0
  9. package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +150 -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/TrueSheetPackage.kt +5 -4
  15. package/android/src/main/java/com/lodev09/truesheet/TrueSheetPeekView.kt +72 -0
  16. package/android/src/main/java/com/lodev09/truesheet/TrueSheetPeekViewManager.kt +33 -0
  17. package/android/src/main/java/com/lodev09/truesheet/TrueSheetStateUpdater.kt +45 -0
  18. package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +526 -231
  19. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +1217 -603
  20. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +136 -29
  21. package/android/src/main/java/com/lodev09/truesheet/core/RNScreensEventObserver.kt +63 -0
  22. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetBehavior.kt +36 -0
  23. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetView.kt +255 -0
  24. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt +303 -0
  25. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +277 -0
  26. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDimView.kt +162 -0
  27. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetGrabberView.kt +180 -0
  28. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetKeyboardObserver.kt +207 -0
  29. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetStackManager.kt +220 -0
  30. package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetDragEvents.kt +71 -0
  31. package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetFocusEvents.kt +65 -0
  32. package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetLifecycleEvents.kt +112 -0
  33. package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetStateEvents.kt +56 -0
  34. package/android/src/main/java/com/lodev09/truesheet/utils/KeyboardUtils.kt +84 -0
  35. package/android/src/main/java/com/lodev09/truesheet/utils/ScreenUtils.kt +93 -67
  36. package/android/src/main/java/com/lodev09/truesheet/utils/ViewUtils.kt +30 -0
  37. package/android/src/main/jni/CMakeLists.txt +63 -0
  38. package/android/src/main/jni/TrueSheetSpec.h +19 -0
  39. package/android/src/main/jni/TrueSheetStateUpdater.cpp +96 -0
  40. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h +24 -0
  41. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +43 -0
  42. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.h +28 -0
  43. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.cpp +11 -0
  44. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.h +37 -0
  45. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewComponentDescriptor.h +24 -0
  46. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +56 -0
  47. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.h +28 -0
  48. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.cpp +11 -0
  49. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.h +41 -0
  50. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.cpp +18 -0
  51. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.h +16 -0
  52. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewComponentDescriptor.h +28 -0
  53. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +61 -0
  54. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.h +45 -0
  55. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.cpp +23 -0
  56. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.h +52 -0
  57. package/ios/TrueSheetContainerView.h +81 -6
  58. package/ios/TrueSheetContainerView.mm +275 -21
  59. package/ios/TrueSheetContentView.h +38 -1
  60. package/ios/TrueSheetContentView.mm +413 -43
  61. package/ios/TrueSheetFooterView.h +27 -2
  62. package/ios/TrueSheetFooterView.mm +141 -35
  63. package/ios/{events/OnDidDismissEvent.h → TrueSheetHeaderView.h} +10 -7
  64. package/ios/TrueSheetHeaderView.mm +64 -0
  65. package/ios/TrueSheetModule.mm +92 -5
  66. package/ios/TrueSheetPeekView.h +32 -0
  67. package/ios/TrueSheetPeekView.mm +99 -0
  68. package/ios/TrueSheetView.h +7 -15
  69. package/ios/TrueSheetView.mm +633 -215
  70. package/ios/TrueSheetViewController.h +84 -16
  71. package/ios/TrueSheetViewController.mm +1136 -333
  72. package/ios/core/RNScreensEventObserver.h +46 -0
  73. package/ios/core/RNScreensEventObserver.mm +280 -0
  74. package/ios/core/TrueSheetBlurView.h +27 -0
  75. package/ios/core/TrueSheetBlurView.mm +82 -0
  76. package/ios/core/TrueSheetDetentCalculator.h +107 -0
  77. package/ios/core/TrueSheetDetentCalculator.mm +197 -0
  78. package/ios/core/TrueSheetGrabberView.h +72 -0
  79. package/ios/core/TrueSheetGrabberView.mm +178 -0
  80. package/ios/core/TrueSheetKeyboardObserver.h +39 -0
  81. package/ios/core/TrueSheetKeyboardObserver.mm +112 -0
  82. package/ios/events/TrueSheetDragEvents.h +39 -0
  83. package/ios/events/TrueSheetDragEvents.mm +62 -0
  84. package/ios/events/{OnPositionChangeEvent.h → TrueSheetFocusEvents.h} +8 -5
  85. package/ios/events/TrueSheetFocusEvents.mm +49 -0
  86. package/ios/events/TrueSheetLifecycleEvents.h +40 -0
  87. package/ios/events/TrueSheetLifecycleEvents.mm +71 -0
  88. package/ios/events/TrueSheetStateEvents.h +35 -0
  89. package/ios/events/TrueSheetStateEvents.mm +49 -0
  90. package/ios/tvos/TrueSheetStubs.mm +154 -0
  91. package/ios/{events/OnMountEvent.h → utils/BlurUtil.h} +5 -7
  92. package/ios/utils/BlurUtil.mm +69 -0
  93. package/ios/utils/GestureUtil.h +7 -0
  94. package/ios/utils/GestureUtil.mm +12 -0
  95. package/ios/utils/PlatformUtil.h +15 -0
  96. package/ios/utils/UIView+FirstResponder.h +15 -0
  97. package/ios/utils/UIView+FirstResponder.mm +26 -0
  98. package/ios/{events/OnWillDismissEvent.h → utils/UIView+ScrollEdgeInteraction.h} +6 -7
  99. package/ios/utils/UIView+ScrollEdgeInteraction.mm +62 -0
  100. package/ios/utils/WindowUtil.mm +17 -1
  101. package/lib/module/TrueSheet.js +224 -64
  102. package/lib/module/TrueSheet.js.map +1 -1
  103. package/lib/module/TrueSheet.web.js +1201 -0
  104. package/lib/module/TrueSheet.web.js.map +1 -0
  105. package/lib/module/TrueSheetPeek.js +15 -0
  106. package/lib/module/TrueSheetPeek.js.map +1 -0
  107. package/lib/module/TrueSheetPeek.web.js +55 -0
  108. package/lib/module/TrueSheetPeek.web.js.map +1 -0
  109. package/lib/module/TrueSheetProvider.js +28 -0
  110. package/lib/module/TrueSheetProvider.js.map +1 -0
  111. package/lib/module/TrueSheetProvider.web.js +157 -0
  112. package/lib/module/TrueSheetProvider.web.js.map +1 -0
  113. package/lib/module/fabric/TrueSheetContainerViewNativeComponent.ts +1 -1
  114. package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +5 -1
  115. package/lib/module/fabric/TrueSheetFooterViewNativeComponent.ts +10 -2
  116. package/lib/module/fabric/TrueSheetHeaderViewNativeComponent.ts +8 -0
  117. package/lib/module/fabric/TrueSheetPeekViewNativeComponent.ts +8 -0
  118. package/lib/module/fabric/TrueSheetViewNativeComponent.ts +105 -18
  119. package/lib/module/index.js +3 -3
  120. package/lib/module/index.js.map +1 -1
  121. package/lib/module/mocks/index.js +93 -0
  122. package/lib/module/mocks/index.js.map +1 -0
  123. package/lib/module/mocks/navigation.js +85 -0
  124. package/lib/module/mocks/navigation.js.map +1 -0
  125. package/lib/module/mocks/reanimated.js +91 -0
  126. package/lib/module/mocks/reanimated.js.map +1 -0
  127. package/lib/module/navigation/TrueSheetRouter.js +170 -0
  128. package/lib/module/navigation/TrueSheetRouter.js.map +1 -0
  129. package/lib/module/navigation/TrueSheetView.js +71 -0
  130. package/lib/module/navigation/TrueSheetView.js.map +1 -0
  131. package/lib/module/navigation/createTrueSheetNavigator.js +63 -0
  132. package/lib/module/navigation/createTrueSheetNavigator.js.map +1 -0
  133. package/lib/module/navigation/index.js +6 -0
  134. package/lib/module/navigation/index.js.map +1 -0
  135. package/lib/module/navigation/screen/ReanimatedTrueSheetScreen.js +56 -0
  136. package/lib/module/navigation/screen/ReanimatedTrueSheetScreen.js.map +1 -0
  137. package/lib/module/navigation/screen/TrueSheetScreen.js +49 -0
  138. package/lib/module/navigation/screen/TrueSheetScreen.js.map +1 -0
  139. package/lib/module/navigation/screen/index.js +5 -0
  140. package/lib/module/navigation/screen/index.js.map +1 -0
  141. package/lib/module/navigation/screen/types.js +4 -0
  142. package/lib/module/navigation/screen/types.js.map +1 -0
  143. package/lib/module/navigation/screen/useSheetScreenState.js +68 -0
  144. package/lib/module/navigation/screen/useSheetScreenState.js.map +1 -0
  145. package/lib/module/navigation/types.js +4 -0
  146. package/lib/module/navigation/types.js.map +1 -0
  147. package/lib/module/navigation/useTrueSheetNavigation.js +24 -0
  148. package/lib/module/navigation/useTrueSheetNavigation.js.map +1 -0
  149. package/lib/module/reanimated/ReanimatedTrueSheet.js +15 -9
  150. package/lib/module/reanimated/ReanimatedTrueSheet.js.map +1 -1
  151. package/lib/module/reanimated/ReanimatedTrueSheet.web.js +81 -0
  152. package/lib/module/reanimated/ReanimatedTrueSheet.web.js.map +1 -0
  153. package/lib/module/reanimated/ReanimatedTrueSheetProvider.js +4 -2
  154. package/lib/module/reanimated/ReanimatedTrueSheetProvider.js.map +1 -1
  155. package/lib/module/reanimated/index.js +2 -2
  156. package/lib/module/reanimated/index.js.map +1 -1
  157. package/lib/module/reanimated/useReanimatedPositionChangeHandler.web.js +20 -0
  158. package/lib/module/reanimated/useReanimatedPositionChangeHandler.web.js.map +1 -0
  159. package/lib/module/specs/NativeTrueSheetModule.js.map +1 -1
  160. package/lib/module/web/constants.js +16 -0
  161. package/lib/module/web/constants.js.map +1 -0
  162. package/lib/module/web/vaul/README.md +9 -0
  163. package/lib/module/web/vaul/browser.js +30 -0
  164. package/lib/module/web/vaul/browser.js.map +1 -0
  165. package/lib/module/web/vaul/constants.js +15 -0
  166. package/lib/module/web/vaul/constants.js.map +1 -0
  167. package/lib/module/web/vaul/context.js +59 -0
  168. package/lib/module/web/vaul/context.js.map +1 -0
  169. package/lib/module/web/vaul/helpers.js +93 -0
  170. package/lib/module/web/vaul/helpers.js.map +1 -0
  171. package/lib/module/web/vaul/index.js +1309 -0
  172. package/lib/module/web/vaul/index.js.map +1 -0
  173. package/lib/module/web/vaul/style.css +287 -0
  174. package/lib/module/web/vaul/style.css.d.js +2 -0
  175. package/lib/module/web/vaul/style.css.d.js.map +1 -0
  176. package/lib/module/web/vaul/types.js +2 -0
  177. package/lib/module/web/vaul/types.js.map +1 -0
  178. package/lib/module/web/vaul/use-composed-refs.js +34 -0
  179. package/lib/module/web/vaul/use-composed-refs.js.map +1 -0
  180. package/lib/module/web/vaul/use-controllable-state.js +54 -0
  181. package/lib/module/web/vaul/use-controllable-state.js.map +1 -0
  182. package/lib/module/web/vaul/use-position-fixed.js +123 -0
  183. package/lib/module/web/vaul/use-position-fixed.js.map +1 -0
  184. package/lib/module/web/vaul/use-prevent-scroll.js +258 -0
  185. package/lib/module/web/vaul/use-prevent-scroll.js.map +1 -0
  186. package/lib/module/web/vaul/use-scale-background.js +57 -0
  187. package/lib/module/web/vaul/use-scale-background.js.map +1 -0
  188. package/lib/module/web/vaul/use-snap-points.js +305 -0
  189. package/lib/module/web/vaul/use-snap-points.js.map +1 -0
  190. package/lib/typescript/src/TrueSheet.d.ts +51 -14
  191. package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
  192. package/lib/typescript/src/TrueSheet.types.d.ts +463 -54
  193. package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
  194. package/lib/typescript/src/TrueSheet.web.d.ts +5 -0
  195. package/lib/typescript/src/TrueSheet.web.d.ts.map +1 -0
  196. package/lib/typescript/src/TrueSheetPeek.d.ts +9 -0
  197. package/lib/typescript/src/TrueSheetPeek.d.ts.map +1 -0
  198. package/lib/typescript/src/TrueSheetPeek.web.d.ts +28 -0
  199. package/lib/typescript/src/TrueSheetPeek.web.d.ts.map +1 -0
  200. package/lib/typescript/src/TrueSheetProvider.d.ts +18 -0
  201. package/lib/typescript/src/TrueSheetProvider.d.ts.map +1 -0
  202. package/lib/typescript/src/TrueSheetProvider.web.d.ts +27 -0
  203. package/lib/typescript/src/TrueSheetProvider.web.d.ts.map +1 -0
  204. package/lib/typescript/src/fabric/TrueSheetContainerViewNativeComponent.d.ts.map +1 -1
  205. package/lib/typescript/src/fabric/TrueSheetContentViewNativeComponent.d.ts.map +1 -1
  206. package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts +2 -0
  207. package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts.map +1 -1
  208. package/lib/typescript/src/fabric/TrueSheetHeaderViewNativeComponent.d.ts +6 -0
  209. package/lib/typescript/src/fabric/TrueSheetHeaderViewNativeComponent.d.ts.map +1 -0
  210. package/lib/typescript/src/fabric/TrueSheetPeekViewNativeComponent.d.ts +6 -0
  211. package/lib/typescript/src/fabric/TrueSheetPeekViewNativeComponent.d.ts.map +1 -0
  212. package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +67 -16
  213. package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
  214. package/lib/typescript/src/index.d.ts +2 -2
  215. package/lib/typescript/src/index.d.ts.map +1 -1
  216. package/lib/typescript/src/mocks/index.d.ts +43 -0
  217. package/lib/typescript/src/mocks/index.d.ts.map +1 -0
  218. package/lib/typescript/src/mocks/navigation.d.ts +66 -0
  219. package/lib/typescript/src/mocks/navigation.d.ts.map +1 -0
  220. package/lib/typescript/src/mocks/reanimated.d.ts +48 -0
  221. package/lib/typescript/src/mocks/reanimated.d.ts.map +1 -0
  222. package/lib/typescript/src/navigation/TrueSheetRouter.d.ts +57 -0
  223. package/lib/typescript/src/navigation/TrueSheetRouter.d.ts.map +1 -0
  224. package/lib/typescript/src/navigation/TrueSheetView.d.ts +10 -0
  225. package/lib/typescript/src/navigation/TrueSheetView.d.ts.map +1 -0
  226. package/lib/typescript/src/navigation/createTrueSheetNavigator.d.ts +35 -0
  227. package/lib/typescript/src/navigation/createTrueSheetNavigator.d.ts.map +1 -0
  228. package/lib/typescript/src/navigation/index.d.ts +6 -0
  229. package/lib/typescript/src/navigation/index.d.ts.map +1 -0
  230. package/lib/typescript/src/navigation/screen/ReanimatedTrueSheetScreen.d.ts +3 -0
  231. package/lib/typescript/src/navigation/screen/ReanimatedTrueSheetScreen.d.ts.map +1 -0
  232. package/lib/typescript/src/navigation/screen/TrueSheetScreen.d.ts +3 -0
  233. package/lib/typescript/src/navigation/screen/TrueSheetScreen.d.ts.map +1 -0
  234. package/lib/typescript/src/navigation/screen/index.d.ts +4 -0
  235. package/lib/typescript/src/navigation/screen/index.d.ts.map +1 -0
  236. package/lib/typescript/src/navigation/screen/types.d.ts +15 -0
  237. package/lib/typescript/src/navigation/screen/types.d.ts.map +1 -0
  238. package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts +35 -0
  239. package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts.map +1 -0
  240. package/lib/typescript/src/navigation/types.d.ts +153 -0
  241. package/lib/typescript/src/navigation/types.d.ts.map +1 -0
  242. package/lib/typescript/src/navigation/useTrueSheetNavigation.d.ts +23 -0
  243. package/lib/typescript/src/navigation/useTrueSheetNavigation.d.ts.map +1 -0
  244. package/lib/typescript/src/reanimated/ReanimatedTrueSheet.d.ts.map +1 -1
  245. package/lib/typescript/src/reanimated/ReanimatedTrueSheet.web.d.ts +41 -0
  246. package/lib/typescript/src/reanimated/ReanimatedTrueSheet.web.d.ts.map +1 -0
  247. package/lib/typescript/src/reanimated/ReanimatedTrueSheetProvider.d.ts +8 -2
  248. package/lib/typescript/src/reanimated/ReanimatedTrueSheetProvider.d.ts.map +1 -1
  249. package/lib/typescript/src/reanimated/useReanimatedPositionChangeHandler.web.d.ts +15 -0
  250. package/lib/typescript/src/reanimated/useReanimatedPositionChangeHandler.web.d.ts.map +1 -0
  251. package/lib/typescript/src/specs/NativeTrueSheetModule.d.ts +25 -3
  252. package/lib/typescript/src/specs/NativeTrueSheetModule.d.ts.map +1 -1
  253. package/lib/typescript/src/web/constants.d.ts +14 -0
  254. package/lib/typescript/src/web/constants.d.ts.map +1 -0
  255. package/lib/typescript/src/web/vaul/browser.d.ts +8 -0
  256. package/lib/typescript/src/web/vaul/browser.d.ts.map +1 -0
  257. package/lib/typescript/src/web/vaul/constants.d.ts +13 -0
  258. package/lib/typescript/src/web/vaul/constants.d.ts.map +1 -0
  259. package/lib/typescript/src/web/vaul/context.d.ts +53 -0
  260. package/lib/typescript/src/web/vaul/context.d.ts.map +1 -0
  261. package/lib/typescript/src/web/vaul/helpers.d.ts +17 -0
  262. package/lib/typescript/src/web/vaul/helpers.d.ts.map +1 -0
  263. package/lib/typescript/src/web/vaul/index.d.ts +228 -0
  264. package/lib/typescript/src/web/vaul/index.d.ts.map +1 -0
  265. package/lib/typescript/src/web/vaul/types.d.ts +7 -0
  266. package/lib/typescript/src/web/vaul/types.d.ts.map +1 -0
  267. package/lib/typescript/src/web/vaul/use-composed-refs.d.ts +14 -0
  268. package/lib/typescript/src/web/vaul/use-composed-refs.d.ts.map +1 -0
  269. package/lib/typescript/src/web/vaul/use-controllable-state.d.ts +9 -0
  270. package/lib/typescript/src/web/vaul/use-controllable-state.d.ts.map +1 -0
  271. package/lib/typescript/src/web/vaul/use-position-fixed.d.ts +19 -0
  272. package/lib/typescript/src/web/vaul/use-position-fixed.d.ts.map +1 -0
  273. package/lib/typescript/src/web/vaul/use-prevent-scroll.d.ts +18 -0
  274. package/lib/typescript/src/web/vaul/use-prevent-scroll.d.ts.map +1 -0
  275. package/lib/typescript/src/web/vaul/use-scale-background.d.ts +2 -0
  276. package/lib/typescript/src/web/vaul/use-scale-background.d.ts.map +1 -0
  277. package/lib/typescript/src/web/vaul/use-snap-points.d.ts +38 -0
  278. package/lib/typescript/src/web/vaul/use-snap-points.d.ts.map +1 -0
  279. package/package.json +78 -34
  280. package/react-native.config.js +9 -2
  281. package/src/TrueSheet.tsx +276 -60
  282. package/src/TrueSheet.types.ts +525 -71
  283. package/src/TrueSheet.web.tsx +1366 -0
  284. package/src/TrueSheetPeek.tsx +11 -0
  285. package/src/TrueSheetPeek.web.tsx +63 -0
  286. package/src/TrueSheetProvider.tsx +33 -0
  287. package/src/TrueSheetProvider.web.tsx +220 -0
  288. package/src/fabric/TrueSheetContainerViewNativeComponent.ts +1 -1
  289. package/src/fabric/TrueSheetContentViewNativeComponent.ts +5 -1
  290. package/src/fabric/TrueSheetFooterViewNativeComponent.ts +10 -2
  291. package/src/fabric/TrueSheetHeaderViewNativeComponent.ts +8 -0
  292. package/src/fabric/TrueSheetPeekViewNativeComponent.ts +8 -0
  293. package/src/fabric/TrueSheetViewNativeComponent.ts +105 -18
  294. package/src/index.ts +2 -2
  295. package/src/mocks/index.ts +89 -0
  296. package/src/mocks/navigation.ts +72 -0
  297. package/src/mocks/reanimated.ts +101 -0
  298. package/src/navigation/TrueSheetRouter.ts +234 -0
  299. package/src/navigation/TrueSheetView.tsx +99 -0
  300. package/src/navigation/createTrueSheetNavigator.tsx +93 -0
  301. package/src/navigation/index.ts +14 -0
  302. package/src/navigation/screen/ReanimatedTrueSheetScreen.tsx +61 -0
  303. package/src/navigation/screen/TrueSheetScreen.tsx +54 -0
  304. package/src/navigation/screen/index.ts +3 -0
  305. package/src/navigation/screen/types.ts +21 -0
  306. package/src/navigation/screen/useSheetScreenState.ts +107 -0
  307. package/src/navigation/types.ts +219 -0
  308. package/src/navigation/useTrueSheetNavigation.ts +26 -0
  309. package/src/reanimated/ReanimatedTrueSheet.tsx +12 -7
  310. package/src/reanimated/ReanimatedTrueSheet.web.tsx +75 -0
  311. package/src/reanimated/ReanimatedTrueSheetProvider.tsx +12 -8
  312. package/src/reanimated/useReanimatedPositionChangeHandler.web.ts +31 -0
  313. package/src/specs/NativeTrueSheetModule.ts +28 -3
  314. package/src/web/constants.ts +13 -0
  315. package/src/web/vaul/README.md +9 -0
  316. package/src/web/vaul/browser.ts +38 -0
  317. package/src/web/vaul/constants.ts +20 -0
  318. package/src/web/vaul/context.ts +101 -0
  319. package/src/web/vaul/helpers.ts +124 -0
  320. package/src/web/vaul/index.tsx +1740 -0
  321. package/src/web/vaul/style.css +287 -0
  322. package/src/web/vaul/style.css.d.ts +1 -0
  323. package/src/web/vaul/types.ts +7 -0
  324. package/src/web/vaul/use-composed-refs.ts +35 -0
  325. package/src/web/vaul/use-controllable-state.ts +66 -0
  326. package/src/web/vaul/use-position-fixed.ts +147 -0
  327. package/src/web/vaul/use-prevent-scroll.ts +309 -0
  328. package/src/web/vaul/use-scale-background.ts +64 -0
  329. package/src/web/vaul/use-snap-points.ts +455 -0
  330. package/android/src/main/java/com/lodev09/truesheet/events/DetentChangeEvent.kt +0 -26
  331. package/android/src/main/java/com/lodev09/truesheet/events/DidDismissEvent.kt +0 -20
  332. package/android/src/main/java/com/lodev09/truesheet/events/DidPresentEvent.kt +0 -26
  333. package/android/src/main/java/com/lodev09/truesheet/events/DragBeginEvent.kt +0 -26
  334. package/android/src/main/java/com/lodev09/truesheet/events/DragChangeEvent.kt +0 -26
  335. package/android/src/main/java/com/lodev09/truesheet/events/DragEndEvent.kt +0 -26
  336. package/android/src/main/java/com/lodev09/truesheet/events/MountEvent.kt +0 -20
  337. package/android/src/main/java/com/lodev09/truesheet/events/PositionChangeEvent.kt +0 -32
  338. package/android/src/main/java/com/lodev09/truesheet/events/SizeChangeEvent.kt +0 -27
  339. package/android/src/main/java/com/lodev09/truesheet/events/WillDismissEvent.kt +0 -20
  340. package/android/src/main/java/com/lodev09/truesheet/events/WillPresentEvent.kt +0 -26
  341. package/android/src/main/res/values/styles.xml +0 -8
  342. package/ios/events/OnDetentChangeEvent.h +0 -28
  343. package/ios/events/OnDetentChangeEvent.mm +0 -30
  344. package/ios/events/OnDidDismissEvent.mm +0 -25
  345. package/ios/events/OnDidPresentEvent.h +0 -28
  346. package/ios/events/OnDidPresentEvent.mm +0 -30
  347. package/ios/events/OnDragBeginEvent.h +0 -28
  348. package/ios/events/OnDragBeginEvent.mm +0 -30
  349. package/ios/events/OnDragChangeEvent.h +0 -28
  350. package/ios/events/OnDragChangeEvent.mm +0 -30
  351. package/ios/events/OnDragEndEvent.h +0 -28
  352. package/ios/events/OnDragEndEvent.mm +0 -30
  353. package/ios/events/OnMountEvent.mm +0 -25
  354. package/ios/events/OnPositionChangeEvent.mm +0 -32
  355. package/ios/events/OnSizeChangeEvent.h +0 -28
  356. package/ios/events/OnSizeChangeEvent.mm +0 -30
  357. package/ios/events/OnWillDismissEvent.mm +0 -25
  358. package/ios/events/OnWillPresentEvent.h +0 -28
  359. package/ios/events/OnWillPresentEvent.mm +0 -30
  360. package/ios/utils/LayoutUtil.h +0 -44
  361. package/ios/utils/LayoutUtil.mm +0 -50
  362. package/lib/module/TrueSheetGrabber.js +0 -51
  363. package/lib/module/TrueSheetGrabber.js.map +0 -1
  364. package/lib/typescript/src/TrueSheetGrabber.d.ts +0 -39
  365. package/lib/typescript/src/TrueSheetGrabber.d.ts.map +0 -1
  366. package/src/TrueSheetGrabber.tsx +0 -82
  367. package/src/__mocks__/index.js +0 -67
@@ -0,0 +1,46 @@
1
+ //
2
+ // Created by Jovanni Lo (@lodev09)
3
+ // Copyright (c) 2024-present. All rights reserved.
4
+ //
5
+ // This source code is licensed under the MIT license found in the
6
+ // LICENSE file in the root directory of this source tree.
7
+ //
8
+
9
+ #ifdef RCT_NEW_ARCH_ENABLED
10
+
11
+ #import <UIKit/UIKit.h>
12
+ #import <react/renderer/components/TrueSheetSpec/TrueSheetViewState.h>
13
+
14
+ NS_ASSUME_NONNULL_BEGIN
15
+
16
+ @class TrueSheetView;
17
+
18
+ @protocol RNScreensEventObserverDelegate <NSObject>
19
+
20
+ - (void)presenterScreenWillDisappear;
21
+ - (void)presenterScreenWillAppear;
22
+
23
+ - (void)presenterInteractiveDismissDidBegin;
24
+ - (void)presenterInteractiveDismissDidUpdate:(CGFloat)progress;
25
+ - (void)presenterInteractiveDismissDidEnd:(BOOL)cancelled duration:(NSTimeInterval)duration;
26
+
27
+ @end
28
+
29
+ /**
30
+ * Observes react-native-screens lifecycle events via C++ EventDispatcher.
31
+ * Detects when the presenting screen unmounts while sheet is presented.
32
+ */
33
+ @interface RNScreensEventObserver : NSObject
34
+
35
+ @property (nonatomic, weak) TrueSheetView<RNScreensEventObserverDelegate> *delegate;
36
+
37
+ - (void)startObservingWithState:(const facebook::react::TrueSheetViewState &)state;
38
+ - (void)stopObserving;
39
+
40
+ - (void)capturePresenterScreenFromView:(UIView *)view;
41
+
42
+ @end
43
+
44
+ NS_ASSUME_NONNULL_END
45
+
46
+ #endif // RCT_NEW_ARCH_ENABLED
@@ -0,0 +1,280 @@
1
+ //
2
+ // Created by Jovanni Lo (@lodev09)
3
+ // Copyright (c) 2024-present. All rights reserved.
4
+ //
5
+ // This source code is licensed under the MIT license found in the
6
+ // LICENSE file in the root directory of this source tree.
7
+ //
8
+
9
+ #ifdef RCT_NEW_ARCH_ENABLED
10
+
11
+ #import "RNScreensEventObserver.h"
12
+ #import "TrueSheetView.h"
13
+
14
+ #import <react/renderer/core/EventDispatcher.h>
15
+ #import <react/renderer/core/ShadowNodeFamily.h>
16
+
17
+ using namespace facebook::react;
18
+
19
+ @implementation RNScreensEventObserver {
20
+ std::weak_ptr<const EventDispatcher> _eventDispatcher;
21
+ std::shared_ptr<const EventListener> _eventListener;
22
+ NSInteger _presenterScreenTag;
23
+ NSMutableSet<NSNumber *> *_screenTags;
24
+ __weak UIViewController *_presenterScreenController;
25
+ __weak UIViewController *_parentScreenController;
26
+ __weak UIWindow *_window;
27
+ BOOL _dismissedByNavigation;
28
+ BOOL _pendingInteractiveDismiss;
29
+ BOOL _pendingInteractiveAppear;
30
+
31
+ CADisplayLink *_interactiveDisplayLink;
32
+ __weak id<UIViewControllerTransitionCoordinator> _interactiveCoordinator;
33
+ BOOL _isInteractiveTracking;
34
+ BOOL _interactiveEnded;
35
+ }
36
+
37
+ - (instancetype)init {
38
+ if (self = [super init]) {
39
+ _presenterScreenTag = 0;
40
+ _screenTags = [NSMutableSet new];
41
+ _presenterScreenController = nil;
42
+ _parentScreenController = nil;
43
+ _window = nil;
44
+ }
45
+ return self;
46
+ }
47
+
48
+ - (void)dealloc {
49
+ [self stopObserving];
50
+ }
51
+
52
+ - (void)startObservingWithState:(const TrueSheetViewState &)state {
53
+ if (!_eventDispatcher.expired()) {
54
+ return;
55
+ }
56
+
57
+ if (auto dispatcherPtr = state.getEventDispatcher().lock()) {
58
+ _eventDispatcher = state.getEventDispatcher();
59
+
60
+ __weak RNScreensEventObserver *weakSelf = self;
61
+
62
+ _eventListener = std::make_shared<const EventListener>([weakSelf](const RawEvent &event) {
63
+ RNScreensEventObserver *strongSelf = weakSelf;
64
+ if (!strongSelf) {
65
+ return false;
66
+ }
67
+
68
+ if (auto family = event.shadowNodeFamily.lock()) {
69
+ Tag screenTag = family->getTag();
70
+ if (![strongSelf->_screenTags containsObject:@(screenTag)]) {
71
+ return false;
72
+ }
73
+
74
+ BOOL interactive = [strongSelf isInteractiveTransition];
75
+
76
+ if (event.type == "topWillDisappear") {
77
+ if (interactive) {
78
+ // Track the swipe in realtime so the sheet slides closed with the screen,
79
+ // and reverses if the gesture is cancelled. Falls back to dismissing once
80
+ // the pop commits when realtime tracking can't start.
81
+ if (![strongSelf beginInteractiveTracking]) {
82
+ strongSelf->_pendingInteractiveDismiss = YES;
83
+ }
84
+ } else if ([strongSelf shouldDismissForScreenTag:screenTag]) {
85
+ strongSelf->_dismissedByNavigation = YES;
86
+ [strongSelf.delegate presenterScreenWillDisappear];
87
+ }
88
+ } else if (event.type == "topDisappear") {
89
+ if (strongSelf->_isInteractiveTracking && !strongSelf->_interactiveEnded) {
90
+ // Safety net: end as committed if the coordinator's interaction-change
91
+ // notification didn't fire before the screen finished disappearing.
92
+ [strongSelf endInteractiveTrackingCancelled:NO duration:0.3];
93
+ } else if (strongSelf->_pendingInteractiveDismiss) {
94
+ strongSelf->_pendingInteractiveDismiss = NO;
95
+ strongSelf->_dismissedByNavigation = YES;
96
+ [strongSelf.delegate presenterScreenWillDisappear];
97
+ }
98
+ } else if (event.type == "topWillAppear") {
99
+ if (strongSelf->_dismissedByNavigation) {
100
+ if (interactive) {
101
+ strongSelf->_pendingInteractiveAppear = YES;
102
+ } else {
103
+ strongSelf->_dismissedByNavigation = NO;
104
+ [strongSelf.delegate presenterScreenWillAppear];
105
+ }
106
+ }
107
+ strongSelf->_pendingInteractiveDismiss = NO;
108
+ } else if (event.type == "topAppear") {
109
+ if (strongSelf->_pendingInteractiveAppear) {
110
+ strongSelf->_pendingInteractiveAppear = NO;
111
+ strongSelf->_dismissedByNavigation = NO;
112
+ [strongSelf.delegate presenterScreenWillAppear];
113
+ }
114
+ } else if (event.type == "topGestureCancel") {
115
+ strongSelf->_pendingInteractiveDismiss = NO;
116
+ strongSelf->_pendingInteractiveAppear = NO;
117
+ if (strongSelf->_isInteractiveTracking && !strongSelf->_interactiveEnded) {
118
+ // Safety net for cancel in case the coordinator notification didn't fire.
119
+ [strongSelf endInteractiveTrackingCancelled:YES duration:0.3];
120
+ }
121
+ }
122
+ }
123
+ return false;
124
+ });
125
+
126
+ dispatcherPtr->addListener(_eventListener);
127
+ }
128
+ }
129
+
130
+ - (void)stopObserving {
131
+ [self stopInteractiveTracking];
132
+
133
+ if (_eventListener) {
134
+ if (auto dispatcher = _eventDispatcher.lock()) {
135
+ dispatcher->removeListener(_eventListener);
136
+ }
137
+ _eventListener = nullptr;
138
+ }
139
+ _eventDispatcher.reset();
140
+ }
141
+
142
+ - (void)capturePresenterScreenFromView:(UIView *)view {
143
+ _presenterScreenTag = 0;
144
+ [_screenTags removeAllObjects];
145
+ _presenterScreenController = nil;
146
+ _parentScreenController = nil;
147
+ _window = view.window;
148
+
149
+ Class screenViewClass = NSClassFromString(@"RNSScreenView");
150
+ if (!screenViewClass)
151
+ return;
152
+
153
+ for (UIView *current = view.superview; current; current = current.superview) {
154
+ if ([current isKindOfClass:screenViewClass]) {
155
+ [_screenTags addObject:@(current.tag)];
156
+
157
+ UIViewController *screenVC = nil;
158
+ for (UIResponder *r = current.nextResponder; r; r = r.nextResponder) {
159
+ if ([r isKindOfClass:[UIViewController class]]) {
160
+ screenVC = (UIViewController *)r;
161
+ break;
162
+ }
163
+ }
164
+
165
+ if (!_presenterScreenController) {
166
+ _presenterScreenTag = current.tag;
167
+ _presenterScreenController = screenVC;
168
+ } else if (!_parentScreenController && screenVC) {
169
+ _parentScreenController = screenVC;
170
+ }
171
+ }
172
+ }
173
+ }
174
+
175
+ - (BOOL)isInteractiveTransition {
176
+ UINavigationController *navController = _presenterScreenController.navigationController;
177
+ return navController.transitionCoordinator.isInteractive;
178
+ }
179
+
180
+ #pragma mark - Interactive Dismiss Tracking
181
+
182
+ - (BOOL)beginInteractiveTracking {
183
+ if (_isInteractiveTracking) {
184
+ return YES;
185
+ }
186
+
187
+ UINavigationController *navController = _presenterScreenController.navigationController;
188
+ id<UIViewControllerTransitionCoordinator> coordinator = navController.transitionCoordinator;
189
+ if (!coordinator || !coordinator.isInteractive) {
190
+ return NO;
191
+ }
192
+
193
+ _isInteractiveTracking = YES;
194
+ _interactiveEnded = NO;
195
+ _interactiveCoordinator = coordinator;
196
+
197
+ [self.delegate presenterInteractiveDismissDidBegin];
198
+
199
+ _interactiveDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleInteractiveTick)];
200
+ [_interactiveDisplayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
201
+
202
+ __weak RNScreensEventObserver *weakSelf = self;
203
+ [coordinator notifyWhenInteractionChangesUsingBlock:^(id<UIViewControllerTransitionCoordinatorContext> context) {
204
+ RNScreensEventObserver *strongSelf = weakSelf;
205
+ if (!strongSelf || strongSelf->_interactiveEnded || context.isInteractive) {
206
+ return;
207
+ }
208
+ [strongSelf endInteractiveTrackingCancelled:context.isCancelled duration:context.transitionDuration];
209
+ }];
210
+
211
+ return YES;
212
+ }
213
+
214
+ - (void)handleInteractiveTick {
215
+ if (!_isInteractiveTracking) {
216
+ return;
217
+ }
218
+ id<UIViewControllerTransitionCoordinator> coordinator = _interactiveCoordinator;
219
+ if (!coordinator) {
220
+ return;
221
+ }
222
+ [self.delegate presenterInteractiveDismissDidUpdate:coordinator.percentComplete];
223
+ }
224
+
225
+ - (void)endInteractiveTrackingCancelled:(BOOL)cancelled duration:(NSTimeInterval)duration {
226
+ if (_interactiveEnded) {
227
+ return;
228
+ }
229
+ [self stopInteractiveTracking];
230
+ [self.delegate presenterInteractiveDismissDidEnd:cancelled duration:duration];
231
+ }
232
+
233
+ - (void)stopInteractiveTracking {
234
+ _interactiveEnded = YES;
235
+ _isInteractiveTracking = NO;
236
+ _interactiveCoordinator = nil;
237
+ [_interactiveDisplayLink invalidate];
238
+ _interactiveDisplayLink = nil;
239
+ }
240
+
241
+ - (BOOL)shouldDismissForScreenTag:(NSInteger)screenTag {
242
+ // For parent screens (not immediate presenter), check if the presenter screen is being removed
243
+ // This handles nested stack removal case
244
+ if (screenTag != _presenterScreenTag) {
245
+ UINavigationController *parentNav = _parentScreenController.navigationController;
246
+
247
+ // Modal case: parent's nav is presented -> let sheet dismiss naturally
248
+ // Nested stack case: parent's nav is not presented (embedded) -> need to dismiss
249
+ if (parentNav.presentingViewController != nil) {
250
+ return NO;
251
+ }
252
+
253
+ if (!_parentScreenController) {
254
+ return NO;
255
+ }
256
+
257
+ // If presenter view is no longer in window, the nested stack is being removed
258
+ UIView *presenterView = [_window viewWithTag:_presenterScreenTag];
259
+ if (presenterView == nil || presenterView.window == nil) {
260
+ return YES;
261
+ }
262
+
263
+ return NO;
264
+ }
265
+
266
+ // For immediate presenter screen
267
+ UINavigationController *navController = _presenterScreenController.navigationController;
268
+
269
+ if (!navController || navController.isBeingDismissed) {
270
+ return YES;
271
+ }
272
+
273
+ // Dismiss if presenter is no longer top of nav stack (pushed/popped)
274
+ // Skip if still top (e.g. modal dismiss - sheet dismisses naturally)
275
+ return navController.topViewController != _presenterScreenController;
276
+ }
277
+
278
+ @end
279
+
280
+ #endif // RCT_NEW_ARCH_ENABLED
@@ -0,0 +1,27 @@
1
+ //
2
+ // Created by Jovanni Lo (@lodev09)
3
+ // Copyright (c) 2024-present. All rights reserved.
4
+ //
5
+ // This source code is licensed under the MIT license found in the
6
+ // LICENSE file in the root directory of this source tree.
7
+ //
8
+
9
+ #import <UIKit/UIKit.h>
10
+ #import <react/renderer/components/TrueSheetSpec/Props.h>
11
+
12
+ NS_ASSUME_NONNULL_BEGIN
13
+
14
+ @interface TrueSheetBlurView : UIVisualEffectView
15
+
16
+ @property (nonatomic, assign) facebook::react::TrueSheetViewBackgroundBlur backgroundBlur;
17
+ @property (nonatomic, strong, nullable) NSNumber *blurIntensity;
18
+ @property (nonatomic, assign) BOOL blurInteraction;
19
+
20
+ /// Adds the blur view to a parent view with proper constraints
21
+ - (void)addToView:(UIView *)parentView;
22
+
23
+ - (void)applyBlurEffect;
24
+
25
+ @end
26
+
27
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,82 @@
1
+ //
2
+ // Created by Jovanni Lo (@lodev09)
3
+ // Copyright (c) 2024-present. All rights reserved.
4
+ //
5
+ // This source code is licensed under the MIT license found in the
6
+ // LICENSE file in the root directory of this source tree.
7
+ //
8
+
9
+ #import "TrueSheetBlurView.h"
10
+ #import "BlurUtil.h"
11
+
12
+ #import <react/renderer/components/TrueSheetSpec/Props.h>
13
+
14
+ using namespace facebook::react;
15
+
16
+ @implementation TrueSheetBlurView {
17
+ UIViewPropertyAnimator *_blurAnimator;
18
+ }
19
+
20
+ #pragma mark - Initialization
21
+
22
+ - (instancetype)init {
23
+ if (self = [super init]) {
24
+ _blurInteraction = YES;
25
+ }
26
+ return self;
27
+ }
28
+
29
+ #pragma mark - Public
30
+
31
+ - (void)addToView:(UIView *)parentView {
32
+ if (self.superview == parentView) {
33
+ return;
34
+ }
35
+
36
+ self.frame = parentView.bounds;
37
+ self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
38
+ [parentView insertSubview:self atIndex:0];
39
+ }
40
+
41
+ - (void)clearAnimator {
42
+ if (_blurAnimator) {
43
+ [_blurAnimator stopAnimation:YES];
44
+ _blurAnimator = nil;
45
+ }
46
+ }
47
+
48
+ - (void)applyBlurEffect {
49
+ self.userInteractionEnabled = self.blurInteraction;
50
+
51
+ if (self.backgroundBlur == TrueSheetViewBackgroundBlur::None) {
52
+ [self clearAnimator];
53
+ self.effect = nil;
54
+ return;
55
+ }
56
+
57
+ UIBlurEffectStyle style = [BlurUtil blurEffectStyleFromEnum:self.backgroundBlur];
58
+ UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:style];
59
+
60
+ CGFloat intensity =
61
+ (self.blurIntensity && [self.blurIntensity floatValue] >= 0) ? [self.blurIntensity floatValue] / 100.0 : 1.0;
62
+
63
+ if (intensity >= 1.0) {
64
+ [self clearAnimator];
65
+ self.effect = blurEffect;
66
+ return;
67
+ }
68
+
69
+ if (!_blurAnimator) {
70
+ __weak __typeof(self) weakSelf = self;
71
+ _blurAnimator = [[UIViewPropertyAnimator alloc] initWithDuration:1.0
72
+ curve:UIViewAnimationCurveLinear
73
+ animations:^{
74
+ weakSelf.effect = blurEffect;
75
+ }];
76
+ }
77
+
78
+ _blurAnimator.pausesOnCompletion = YES;
79
+ _blurAnimator.fractionComplete = intensity;
80
+ }
81
+
82
+ @end
@@ -0,0 +1,107 @@
1
+ //
2
+ // Created by Jovanni Lo (@lodev09)
3
+ // Copyright (c) 2024-present. All rights reserved.
4
+ //
5
+ // This source code is licensed under the MIT license found in the
6
+ // LICENSE file in the root directory of this source tree.
7
+ //
8
+
9
+ #import <UIKit/UIKit.h>
10
+
11
+ NS_ASSUME_NONNULL_BEGIN
12
+
13
+ /**
14
+ Protocol that provides dynamic measurements for detent calculations.
15
+ Implemented by TrueSheetViewController to supply real-time values.
16
+ */
17
+ @protocol TrueSheetDetentCalculatorDelegate <NSObject>
18
+
19
+ @property (nonatomic, readonly) CGFloat screenHeight;
20
+ @property (nonatomic, readonly) CGFloat currentPosition;
21
+ @property (nonatomic, strong, readonly) NSArray<NSNumber *> *detents;
22
+ @property (nonatomic, strong, readonly, nullable) NSNumber *contentHeight;
23
+ @property (nonatomic, strong, readonly, nullable) NSNumber *headerHeight;
24
+ @property (nonatomic, readonly) BOOL absoluteHeader;
25
+ @property (nonatomic, strong, readonly, nullable) NSNumber *footerHeight;
26
+ @property (nonatomic, readonly) BOOL absoluteFooter;
27
+ @property (nonatomic, strong, readonly, nullable) NSNumber *peekContentHeight;
28
+
29
+ @end
30
+
31
+ /**
32
+ Encapsulates all detent-related calculations for the sheet.
33
+ */
34
+ @interface TrueSheetDetentCalculator : NSObject
35
+
36
+ @property (nonatomic, weak, nullable) id<TrueSheetDetentCalculatorDelegate> delegate;
37
+ @property (nonatomic, assign) CGFloat maxDetentHeight;
38
+ @property (nonatomic, strong, nullable) NSMutableArray<NSNumber *> *resolvedDetentHeights;
39
+
40
+ /**
41
+ Returns the detent value (0-1 fraction) for a given index.
42
+ For auto (-1) detents, calculates based on content + header height.
43
+ For peek (-2) detents, calculates based on header + footer height.
44
+ */
45
+ - (CGFloat)detentValueForIndex:(NSInteger)index;
46
+
47
+ /**
48
+ Returns the height for auto (-1) detents: content + header + footer height.
49
+ An absolute (floating) header or footer contributes no height.
50
+ */
51
+ - (CGFloat)autoHeight;
52
+
53
+ /**
54
+ Returns the height for peek (-2) detents: header + footer + peek content height.
55
+ A relative footer is pushed off-screen at peek, so it contributes no height.
56
+ Falls back to 150 when none is present — matches the iOS 26
57
+ floating small-detent threshold.
58
+ */
59
+ - (CGFloat)peekHeight;
60
+
61
+ /**
62
+ Learns the offset between resolver height and actual presented height for a detent.
63
+ Called when the sheet settles at a detent.
64
+ */
65
+ - (void)learnOffsetForDetentIndex:(NSInteger)index;
66
+
67
+ /**
68
+ Returns the expected sheet height for a detent index: the UIKit-resolved
69
+ height plus the learned offset.
70
+ */
71
+ - (CGFloat)resolvedHeightForIndex:(NSInteger)index;
72
+
73
+ /**
74
+ Finds the segment between detents for a given position.
75
+ Returns YES if position is between two detents, NO if at edges.
76
+ outIndex: The lower detent index of the segment (-1 if above first detent)
77
+ outProgress: Progress within the segment (0-1)
78
+ */
79
+ - (BOOL)findSegmentForPosition:(CGFloat)position outIndex:(NSInteger *)outIndex outProgress:(CGFloat *)outProgress;
80
+
81
+ /**
82
+ Returns a continuous index value representing position between detents.
83
+ Examples: 0.5 means halfway between detent 0 and 1
84
+ -0.3 means 30% toward closed from detent 0
85
+ */
86
+ - (CGFloat)interpolatedIndexForPosition:(CGFloat)position;
87
+
88
+ /**
89
+ Returns the interpolated detent value for a given position.
90
+ Useful for getting a smooth detent value during drag.
91
+ */
92
+ - (CGFloat)interpolatedDetentForPosition:(CGFloat)position;
93
+
94
+ /**
95
+ Clears all resolved heights and learned offsets.
96
+ Called when detents configuration changes.
97
+ */
98
+ - (void)clearResolvedHeights;
99
+
100
+ /**
101
+ Sets the count of detents (initializes storage for resolved positions).
102
+ */
103
+ - (void)setDetentCount:(NSInteger)count;
104
+
105
+ @end
106
+
107
+ NS_ASSUME_NONNULL_END