@hanzogui/sheet 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. package/LICENSE +21 -0
  2. package/controller/index.cjs +2 -0
  3. package/controller/index.d.ts +5 -0
  4. package/controller/index.js +2 -0
  5. package/controller/index.native.cjs +2 -0
  6. package/controller/index.native.js +2 -0
  7. package/dist/cjs/GestureDetectorWrapper.cjs +48 -0
  8. package/dist/cjs/GestureDetectorWrapper.native.js +53 -0
  9. package/dist/cjs/GestureDetectorWrapper.native.js.map +1 -0
  10. package/dist/cjs/GestureSheetContext.cjs +52 -0
  11. package/dist/cjs/GestureSheetContext.native.js +56 -0
  12. package/dist/cjs/GestureSheetContext.native.js.map +1 -0
  13. package/dist/cjs/Sheet.cjs +117 -0
  14. package/dist/cjs/Sheet.native.js +120 -0
  15. package/dist/cjs/Sheet.native.js.map +1 -0
  16. package/dist/cjs/SheetContext.cjs +32 -0
  17. package/dist/cjs/SheetContext.native.js +35 -0
  18. package/dist/cjs/SheetContext.native.js.map +1 -0
  19. package/dist/cjs/SheetController.cjs +65 -0
  20. package/dist/cjs/SheetController.native.js +71 -0
  21. package/dist/cjs/SheetController.native.js.map +1 -0
  22. package/dist/cjs/SheetImplementationCustom.cjs +472 -0
  23. package/dist/cjs/SheetImplementationCustom.native.js +524 -0
  24. package/dist/cjs/SheetImplementationCustom.native.js.map +1 -0
  25. package/dist/cjs/SheetScrollView.cjs +180 -0
  26. package/dist/cjs/SheetScrollView.native.js +197 -0
  27. package/dist/cjs/SheetScrollView.native.js.map +1 -0
  28. package/dist/cjs/constants.cjs +32 -0
  29. package/dist/cjs/constants.native.js +35 -0
  30. package/dist/cjs/constants.native.js.map +1 -0
  31. package/dist/cjs/contexts.cjs +42 -0
  32. package/dist/cjs/contexts.native.js +45 -0
  33. package/dist/cjs/contexts.native.js.map +1 -0
  34. package/dist/cjs/controller.cjs +29 -0
  35. package/dist/cjs/controller.native.js +32 -0
  36. package/dist/cjs/controller.native.js.map +1 -0
  37. package/dist/cjs/createSheet.cjs +191 -0
  38. package/dist/cjs/createSheet.native.js +208 -0
  39. package/dist/cjs/createSheet.native.js.map +1 -0
  40. package/dist/cjs/gestureState.cjs +39 -0
  41. package/dist/cjs/gestureState.native.js +42 -0
  42. package/dist/cjs/gestureState.native.js.map +1 -0
  43. package/dist/cjs/helpers.cjs +31 -0
  44. package/dist/cjs/helpers.native.js +35 -0
  45. package/dist/cjs/helpers.native.js.map +1 -0
  46. package/dist/cjs/index.cjs +28 -0
  47. package/dist/cjs/index.native.js +31 -0
  48. package/dist/cjs/index.native.js.map +1 -0
  49. package/dist/cjs/nativeSheet.cjs +87 -0
  50. package/dist/cjs/nativeSheet.native.js +101 -0
  51. package/dist/cjs/nativeSheet.native.js.map +1 -0
  52. package/dist/cjs/setupGestureHandler.cjs +46 -0
  53. package/dist/cjs/setupGestureHandler.native.js +50 -0
  54. package/dist/cjs/setupGestureHandler.native.js.map +1 -0
  55. package/dist/cjs/types.cjs +16 -0
  56. package/dist/cjs/types.native.js +19 -0
  57. package/dist/cjs/types.native.js.map +1 -0
  58. package/dist/cjs/useGestureHandlerPan.cjs +136 -0
  59. package/dist/cjs/useGestureHandlerPan.native.js +145 -0
  60. package/dist/cjs/useGestureHandlerPan.native.js.map +1 -0
  61. package/dist/cjs/useKeyboardControllerSheet.cjs +38 -0
  62. package/dist/cjs/useKeyboardControllerSheet.native.js +114 -0
  63. package/dist/cjs/useKeyboardControllerSheet.native.js.map +1 -0
  64. package/dist/cjs/useSheet.cjs +27 -0
  65. package/dist/cjs/useSheet.native.js +32 -0
  66. package/dist/cjs/useSheet.native.js.map +1 -0
  67. package/dist/cjs/useSheetController.cjs +50 -0
  68. package/dist/cjs/useSheetController.native.js +53 -0
  69. package/dist/cjs/useSheetController.native.js.map +1 -0
  70. package/dist/cjs/useSheetOffscreenSize.cjs +51 -0
  71. package/dist/cjs/useSheetOffscreenSize.native.js +61 -0
  72. package/dist/cjs/useSheetOffscreenSize.native.js.map +1 -0
  73. package/dist/cjs/useSheetOpenState.cjs +49 -0
  74. package/dist/cjs/useSheetOpenState.native.js +56 -0
  75. package/dist/cjs/useSheetOpenState.native.js.map +1 -0
  76. package/dist/cjs/useSheetProviderProps.cjs +133 -0
  77. package/dist/cjs/useSheetProviderProps.native.js +153 -0
  78. package/dist/cjs/useSheetProviderProps.native.js.map +1 -0
  79. package/dist/cjs/useSheetScrollViewGestures.cjs +123 -0
  80. package/dist/cjs/useSheetScrollViewGestures.native.js +110 -0
  81. package/dist/cjs/useSheetScrollViewGestures.native.js.map +1 -0
  82. package/dist/esm/GestureDetectorWrapper.mjs +25 -0
  83. package/dist/esm/GestureDetectorWrapper.mjs.map +1 -0
  84. package/dist/esm/GestureDetectorWrapper.native.js +27 -0
  85. package/dist/esm/GestureDetectorWrapper.native.js.map +1 -0
  86. package/dist/esm/GestureSheetContext.mjs +28 -0
  87. package/dist/esm/GestureSheetContext.mjs.map +1 -0
  88. package/dist/esm/GestureSheetContext.native.js +29 -0
  89. package/dist/esm/GestureSheetContext.native.js.map +1 -0
  90. package/dist/esm/Sheet.mjs +89 -0
  91. package/dist/esm/Sheet.mjs.map +1 -0
  92. package/dist/esm/Sheet.native.js +89 -0
  93. package/dist/esm/Sheet.native.js.map +1 -0
  94. package/dist/esm/SheetContext.mjs +6 -0
  95. package/dist/esm/SheetContext.mjs.map +1 -0
  96. package/dist/esm/SheetContext.native.js +6 -0
  97. package/dist/esm/SheetContext.native.js.map +1 -0
  98. package/dist/esm/SheetController.mjs +31 -0
  99. package/dist/esm/SheetController.mjs.map +1 -0
  100. package/dist/esm/SheetController.native.js +34 -0
  101. package/dist/esm/SheetController.native.js.map +1 -0
  102. package/dist/esm/SheetImplementationCustom.mjs +437 -0
  103. package/dist/esm/SheetImplementationCustom.mjs.map +1 -0
  104. package/dist/esm/SheetImplementationCustom.native.js +487 -0
  105. package/dist/esm/SheetImplementationCustom.native.js.map +1 -0
  106. package/dist/esm/SheetScrollView.mjs +146 -0
  107. package/dist/esm/SheetScrollView.mjs.map +1 -0
  108. package/dist/esm/SheetScrollView.native.js +160 -0
  109. package/dist/esm/SheetScrollView.native.js.map +1 -0
  110. package/dist/esm/constants.mjs +6 -0
  111. package/dist/esm/constants.mjs.map +1 -0
  112. package/dist/esm/constants.native.js +6 -0
  113. package/dist/esm/constants.native.js.map +1 -0
  114. package/dist/esm/contexts.mjs +7 -0
  115. package/dist/esm/contexts.mjs.map +1 -0
  116. package/dist/esm/contexts.native.js +7 -0
  117. package/dist/esm/contexts.native.js.map +1 -0
  118. package/dist/esm/controller.mjs +4 -0
  119. package/dist/esm/controller.mjs.map +1 -0
  120. package/dist/esm/controller.native.js +4 -0
  121. package/dist/esm/controller.native.js.map +1 -0
  122. package/dist/esm/createSheet.mjs +168 -0
  123. package/dist/esm/createSheet.mjs.map +1 -0
  124. package/dist/esm/createSheet.native.js +182 -0
  125. package/dist/esm/createSheet.native.js.map +1 -0
  126. package/dist/esm/gestureState.mjs +13 -0
  127. package/dist/esm/gestureState.mjs.map +1 -0
  128. package/dist/esm/gestureState.native.js +13 -0
  129. package/dist/esm/gestureState.native.js.map +1 -0
  130. package/dist/esm/helpers.mjs +8 -0
  131. package/dist/esm/helpers.mjs.map +1 -0
  132. package/dist/esm/helpers.native.js +9 -0
  133. package/dist/esm/helpers.native.js.map +1 -0
  134. package/dist/esm/index.js +12 -0
  135. package/dist/esm/index.js.map +1 -0
  136. package/dist/esm/index.mjs +12 -0
  137. package/dist/esm/index.mjs.map +1 -0
  138. package/dist/esm/index.native.js +12 -0
  139. package/dist/esm/index.native.js.map +1 -0
  140. package/dist/esm/nativeSheet.mjs +63 -0
  141. package/dist/esm/nativeSheet.mjs.map +1 -0
  142. package/dist/esm/nativeSheet.native.js +74 -0
  143. package/dist/esm/nativeSheet.native.js.map +1 -0
  144. package/dist/esm/setupGestureHandler.mjs +22 -0
  145. package/dist/esm/setupGestureHandler.mjs.map +1 -0
  146. package/dist/esm/setupGestureHandler.native.js +23 -0
  147. package/dist/esm/setupGestureHandler.native.js.map +1 -0
  148. package/dist/esm/types.mjs +2 -0
  149. package/dist/esm/types.mjs.map +1 -0
  150. package/dist/esm/types.native.js +2 -0
  151. package/dist/esm/types.native.js.map +1 -0
  152. package/dist/esm/useGestureHandlerPan.mjs +113 -0
  153. package/dist/esm/useGestureHandlerPan.mjs.map +1 -0
  154. package/dist/esm/useGestureHandlerPan.native.js +119 -0
  155. package/dist/esm/useGestureHandlerPan.native.js.map +1 -0
  156. package/dist/esm/useKeyboardControllerSheet.mjs +15 -0
  157. package/dist/esm/useKeyboardControllerSheet.mjs.map +1 -0
  158. package/dist/esm/useKeyboardControllerSheet.native.js +88 -0
  159. package/dist/esm/useKeyboardControllerSheet.native.js.map +1 -0
  160. package/dist/esm/useSheet.mjs +4 -0
  161. package/dist/esm/useSheet.mjs.map +1 -0
  162. package/dist/esm/useSheet.native.js +6 -0
  163. package/dist/esm/useSheet.native.js.map +1 -0
  164. package/dist/esm/useSheetController.mjs +15 -0
  165. package/dist/esm/useSheetController.mjs.map +1 -0
  166. package/dist/esm/useSheetController.native.js +15 -0
  167. package/dist/esm/useSheetController.native.js.map +1 -0
  168. package/dist/esm/useSheetOffscreenSize.mjs +28 -0
  169. package/dist/esm/useSheetOffscreenSize.mjs.map +1 -0
  170. package/dist/esm/useSheetOffscreenSize.native.js +35 -0
  171. package/dist/esm/useSheetOffscreenSize.native.js.map +1 -0
  172. package/dist/esm/useSheetOpenState.mjs +26 -0
  173. package/dist/esm/useSheetOpenState.mjs.map +1 -0
  174. package/dist/esm/useSheetOpenState.native.js +30 -0
  175. package/dist/esm/useSheetOpenState.native.js.map +1 -0
  176. package/dist/esm/useSheetProviderProps.mjs +99 -0
  177. package/dist/esm/useSheetProviderProps.mjs.map +1 -0
  178. package/dist/esm/useSheetProviderProps.native.js +116 -0
  179. package/dist/esm/useSheetProviderProps.native.js.map +1 -0
  180. package/dist/esm/useSheetScrollViewGestures.mjs +100 -0
  181. package/dist/esm/useSheetScrollViewGestures.mjs.map +1 -0
  182. package/dist/esm/useSheetScrollViewGestures.native.js +84 -0
  183. package/dist/esm/useSheetScrollViewGestures.native.js.map +1 -0
  184. package/dist/jsx/GestureDetectorWrapper.mjs +25 -0
  185. package/dist/jsx/GestureDetectorWrapper.mjs.map +1 -0
  186. package/dist/jsx/GestureDetectorWrapper.native.js +53 -0
  187. package/dist/jsx/GestureDetectorWrapper.native.js.map +1 -0
  188. package/dist/jsx/GestureSheetContext.mjs +28 -0
  189. package/dist/jsx/GestureSheetContext.mjs.map +1 -0
  190. package/dist/jsx/GestureSheetContext.native.js +56 -0
  191. package/dist/jsx/GestureSheetContext.native.js.map +1 -0
  192. package/dist/jsx/Sheet.mjs +89 -0
  193. package/dist/jsx/Sheet.mjs.map +1 -0
  194. package/dist/jsx/Sheet.native.js +120 -0
  195. package/dist/jsx/Sheet.native.js.map +1 -0
  196. package/dist/jsx/SheetContext.mjs +6 -0
  197. package/dist/jsx/SheetContext.mjs.map +1 -0
  198. package/dist/jsx/SheetContext.native.js +35 -0
  199. package/dist/jsx/SheetContext.native.js.map +1 -0
  200. package/dist/jsx/SheetController.mjs +31 -0
  201. package/dist/jsx/SheetController.mjs.map +1 -0
  202. package/dist/jsx/SheetController.native.js +71 -0
  203. package/dist/jsx/SheetController.native.js.map +1 -0
  204. package/dist/jsx/SheetImplementationCustom.mjs +437 -0
  205. package/dist/jsx/SheetImplementationCustom.mjs.map +1 -0
  206. package/dist/jsx/SheetImplementationCustom.native.js +524 -0
  207. package/dist/jsx/SheetImplementationCustom.native.js.map +1 -0
  208. package/dist/jsx/SheetScrollView.mjs +146 -0
  209. package/dist/jsx/SheetScrollView.mjs.map +1 -0
  210. package/dist/jsx/SheetScrollView.native.js +197 -0
  211. package/dist/jsx/SheetScrollView.native.js.map +1 -0
  212. package/dist/jsx/constants.mjs +6 -0
  213. package/dist/jsx/constants.mjs.map +1 -0
  214. package/dist/jsx/constants.native.js +35 -0
  215. package/dist/jsx/constants.native.js.map +1 -0
  216. package/dist/jsx/contexts.mjs +7 -0
  217. package/dist/jsx/contexts.mjs.map +1 -0
  218. package/dist/jsx/contexts.native.js +45 -0
  219. package/dist/jsx/contexts.native.js.map +1 -0
  220. package/dist/jsx/controller.mjs +4 -0
  221. package/dist/jsx/controller.mjs.map +1 -0
  222. package/dist/jsx/controller.native.js +32 -0
  223. package/dist/jsx/controller.native.js.map +1 -0
  224. package/dist/jsx/createSheet.mjs +168 -0
  225. package/dist/jsx/createSheet.mjs.map +1 -0
  226. package/dist/jsx/createSheet.native.js +208 -0
  227. package/dist/jsx/createSheet.native.js.map +1 -0
  228. package/dist/jsx/gestureState.mjs +13 -0
  229. package/dist/jsx/gestureState.mjs.map +1 -0
  230. package/dist/jsx/gestureState.native.js +42 -0
  231. package/dist/jsx/gestureState.native.js.map +1 -0
  232. package/dist/jsx/helpers.mjs +8 -0
  233. package/dist/jsx/helpers.mjs.map +1 -0
  234. package/dist/jsx/helpers.native.js +35 -0
  235. package/dist/jsx/helpers.native.js.map +1 -0
  236. package/dist/jsx/index.js +12 -0
  237. package/dist/jsx/index.js.map +1 -0
  238. package/dist/jsx/index.mjs +12 -0
  239. package/dist/jsx/index.mjs.map +1 -0
  240. package/dist/jsx/index.native.js +31 -0
  241. package/dist/jsx/index.native.js.map +1 -0
  242. package/dist/jsx/nativeSheet.mjs +63 -0
  243. package/dist/jsx/nativeSheet.mjs.map +1 -0
  244. package/dist/jsx/nativeSheet.native.js +101 -0
  245. package/dist/jsx/nativeSheet.native.js.map +1 -0
  246. package/dist/jsx/setupGestureHandler.mjs +22 -0
  247. package/dist/jsx/setupGestureHandler.mjs.map +1 -0
  248. package/dist/jsx/setupGestureHandler.native.js +50 -0
  249. package/dist/jsx/setupGestureHandler.native.js.map +1 -0
  250. package/dist/jsx/types.mjs +2 -0
  251. package/dist/jsx/types.mjs.map +1 -0
  252. package/dist/jsx/types.native.js +19 -0
  253. package/dist/jsx/types.native.js.map +1 -0
  254. package/dist/jsx/useGestureHandlerPan.mjs +113 -0
  255. package/dist/jsx/useGestureHandlerPan.mjs.map +1 -0
  256. package/dist/jsx/useGestureHandlerPan.native.js +145 -0
  257. package/dist/jsx/useGestureHandlerPan.native.js.map +1 -0
  258. package/dist/jsx/useKeyboardControllerSheet.mjs +15 -0
  259. package/dist/jsx/useKeyboardControllerSheet.mjs.map +1 -0
  260. package/dist/jsx/useKeyboardControllerSheet.native.js +114 -0
  261. package/dist/jsx/useKeyboardControllerSheet.native.js.map +1 -0
  262. package/dist/jsx/useSheet.mjs +4 -0
  263. package/dist/jsx/useSheet.mjs.map +1 -0
  264. package/dist/jsx/useSheet.native.js +32 -0
  265. package/dist/jsx/useSheet.native.js.map +1 -0
  266. package/dist/jsx/useSheetController.mjs +15 -0
  267. package/dist/jsx/useSheetController.mjs.map +1 -0
  268. package/dist/jsx/useSheetController.native.js +53 -0
  269. package/dist/jsx/useSheetController.native.js.map +1 -0
  270. package/dist/jsx/useSheetOffscreenSize.mjs +28 -0
  271. package/dist/jsx/useSheetOffscreenSize.mjs.map +1 -0
  272. package/dist/jsx/useSheetOffscreenSize.native.js +61 -0
  273. package/dist/jsx/useSheetOffscreenSize.native.js.map +1 -0
  274. package/dist/jsx/useSheetOpenState.mjs +26 -0
  275. package/dist/jsx/useSheetOpenState.mjs.map +1 -0
  276. package/dist/jsx/useSheetOpenState.native.js +56 -0
  277. package/dist/jsx/useSheetOpenState.native.js.map +1 -0
  278. package/dist/jsx/useSheetProviderProps.mjs +99 -0
  279. package/dist/jsx/useSheetProviderProps.mjs.map +1 -0
  280. package/dist/jsx/useSheetProviderProps.native.js +153 -0
  281. package/dist/jsx/useSheetProviderProps.native.js.map +1 -0
  282. package/dist/jsx/useSheetScrollViewGestures.mjs +100 -0
  283. package/dist/jsx/useSheetScrollViewGestures.mjs.map +1 -0
  284. package/dist/jsx/useSheetScrollViewGestures.native.js +110 -0
  285. package/dist/jsx/useSheetScrollViewGestures.native.js.map +1 -0
  286. package/next.md +78 -0
  287. package/package.json +96 -0
  288. package/setup-gesture-handler/index.cjs +2 -0
  289. package/setup-gesture-handler/index.js +2 -0
  290. package/setup-gesture-handler/index.native.cjs +2 -0
  291. package/setup-gesture-handler/index.native.js +2 -0
  292. package/setup-gesture-handler.cjs +1 -0
  293. package/src/GestureDetectorWrapper.tsx +41 -0
  294. package/src/GestureSheetContext.tsx +62 -0
  295. package/src/Sheet.tsx +114 -0
  296. package/src/SheetContext.tsx +11 -0
  297. package/src/SheetController.tsx +44 -0
  298. package/src/SheetImplementationCustom.tsx +868 -0
  299. package/src/SheetScrollView.tsx +195 -0
  300. package/src/constants.tsx +5 -0
  301. package/src/contexts.ts +9 -0
  302. package/src/controller.ts +9 -0
  303. package/src/createSheet.tsx +296 -0
  304. package/src/gestureState.ts +24 -0
  305. package/src/helpers.tsx +31 -0
  306. package/src/index.ts +11 -0
  307. package/src/nativeSheet.tsx +89 -0
  308. package/src/setupGestureHandler.ts +34 -0
  309. package/src/types.tsx +181 -0
  310. package/src/useGestureHandlerPan.tsx +364 -0
  311. package/src/useKeyboardControllerSheet.native.ts +136 -0
  312. package/src/useKeyboardControllerSheet.ts +26 -0
  313. package/src/useSheet.tsx +3 -0
  314. package/src/useSheetController.tsx +27 -0
  315. package/src/useSheetOffscreenSize.tsx +49 -0
  316. package/src/useSheetOpenState.tsx +33 -0
  317. package/src/useSheetProviderProps.tsx +223 -0
  318. package/src/useSheetScrollViewGestures.native.ts +163 -0
  319. package/src/useSheetScrollViewGestures.ts +194 -0
  320. package/tsconfig.json +56 -0
  321. package/types/GestureDetectorWrapper.d.ts +14 -0
  322. package/types/GestureSheetContext.d.ts +36 -0
  323. package/types/Sheet.d.ts +183 -0
  324. package/types/SheetContext.d.ts +43 -0
  325. package/types/SheetController.d.ts +6 -0
  326. package/types/SheetImplementationCustom.d.ts +36 -0
  327. package/types/SheetScrollView.d.ts +40 -0
  328. package/types/constants.d.ts +5 -0
  329. package/types/contexts.d.ts +6 -0
  330. package/types/controller.d.ts +3 -0
  331. package/types/createSheet.d.ts +194 -0
  332. package/types/gestureState.d.ts +11 -0
  333. package/types/helpers.d.ts +2 -0
  334. package/types/index.d.ts +12 -0
  335. package/types/nativeSheet.d.ts +10 -0
  336. package/types/setupGestureHandler.d.ts +11 -0
  337. package/types/types.d.ts +147 -0
  338. package/types/useGestureHandlerPan.d.ts +44 -0
  339. package/types/useKeyboardControllerSheet.d.ts +7 -0
  340. package/types/useKeyboardControllerSheet.native.d.ts +13 -0
  341. package/types/useSheet.d.ts +2 -0
  342. package/types/useSheetController.d.ts +17 -0
  343. package/types/useSheetOffscreenSize.d.ts +3 -0
  344. package/types/useSheetOpenState.d.ts +9 -0
  345. package/types/useSheetProviderProps.d.ts +36 -0
  346. package/types/useSheetScrollViewGestures.d.ts +12 -0
  347. package/types/useSheetScrollViewGestures.native.d.ts +21 -0
@@ -0,0 +1,195 @@
1
+ import { composeRefs } from '@hanzogui/compose-refs'
2
+ import { isWeb, View, type GetRef } from '@hanzogui/core'
3
+ import type { ScrollViewProps } from '@hanzogui/scroll-view'
4
+ import { ScrollView } from '@hanzogui/scroll-view'
5
+ import { useControllableState } from '@hanzogui/use-controllable-state'
6
+ import React, { useEffect, useRef, useState } from 'react'
7
+ import type { ScrollView as RNScrollView } from 'react-native'
8
+ import { useGestureSheetContext } from './GestureSheetContext'
9
+ import { getGestureHandlerState, isGestureHandlerEnabled } from './gestureState'
10
+ import { useSheetContext } from './SheetContext'
11
+ import type { SheetScopedProps } from './types'
12
+ import { useSheetScrollViewGestures } from './useSheetScrollViewGestures'
13
+
14
+ const SHEET_SCROLL_VIEW_NAME = 'SheetScrollView'
15
+
16
+ export const SheetScrollView = React.forwardRef<
17
+ GetRef<typeof ScrollView>,
18
+ ScrollViewProps
19
+ >(
20
+ (
21
+ {
22
+ __scopeSheet,
23
+ children,
24
+ onScroll,
25
+ scrollEnabled: scrollEnabledProp,
26
+ ...props
27
+ }: SheetScopedProps<ScrollViewProps>,
28
+ ref
29
+ ) => {
30
+ const context = useSheetContext(SHEET_SCROLL_VIEW_NAME, __scopeSheet)
31
+ const gestureContext = useGestureSheetContext()
32
+ const { scrollBridge, setHasScrollView } = context
33
+ const [scrollEnabled] = useControllableState({
34
+ prop: scrollEnabledProp,
35
+ defaultProp: true,
36
+ })
37
+ const scrollRef = React.useRef<RNScrollView | null>(null)
38
+
39
+ const panGestureRef = gestureContext?.panGestureRef
40
+ const { ScrollView: RNGHScrollView } = getGestureHandlerState()
41
+ const useRNGHScrollView = isGestureHandlerEnabled() && RNGHScrollView && panGestureRef
42
+
43
+ // RNGH scroll locking state
44
+ const currentScrollOffset = useRef(0)
45
+ const lockedScrollY = useRef(0)
46
+
47
+ const setScrollEnabled = (next: boolean, lockTo?: number) => {
48
+ if (!next) {
49
+ const lockY = lockTo ?? currentScrollOffset.current
50
+ lockedScrollY.current = lockY
51
+ scrollBridge.scrollLockY = lockY
52
+ scrollRef.current?.scrollTo?.({ x: 0, y: lockY, animated: false })
53
+ } else {
54
+ lockedScrollY.current = currentScrollOffset.current
55
+ scrollBridge.scrollLockY = undefined
56
+ }
57
+ }
58
+
59
+ const forceScrollTo = (y: number) => {
60
+ scrollRef.current?.scrollTo?.({ x: 0, y, animated: false })
61
+ }
62
+
63
+ useEffect(() => {
64
+ setHasScrollView(true)
65
+ if (isGestureHandlerEnabled()) {
66
+ scrollBridge.setScrollEnabled = setScrollEnabled
67
+ scrollBridge.forceScrollTo = forceScrollTo
68
+ }
69
+ return () => {
70
+ setHasScrollView(false)
71
+ scrollBridge.setScrollEnabled = undefined
72
+ scrollBridge.forceScrollTo = undefined
73
+ }
74
+ }, [])
75
+
76
+ const [hasScrollableContent, setHasScrollableContent] = useState(true)
77
+ const parentHeight = useRef(0)
78
+ const contentHeight = useRef(0)
79
+
80
+ const updateScrollable = () => {
81
+ if (parentHeight.current && contentHeight.current) {
82
+ setHasScrollableContent(contentHeight.current > parentHeight.current)
83
+ }
84
+ }
85
+
86
+ useEffect(() => {
87
+ scrollBridge.hasScrollableContent = hasScrollableContent
88
+ }, [hasScrollableContent])
89
+
90
+ // platform-specific gesture handling
91
+ const gestureProps = useSheetScrollViewGestures({
92
+ scrollRef,
93
+ scrollBridge,
94
+ hasScrollableContent,
95
+ scrollEnabled,
96
+ setScrollEnabled,
97
+ })
98
+
99
+ // content wrapper for measuring height
100
+ const contentWrapper = (
101
+ <View
102
+ onLayout={(e) => {
103
+ const height = Math.floor(e.nativeEvent.layout.height)
104
+ if (height !== contentHeight.current) {
105
+ contentHeight.current = height
106
+ updateScrollable()
107
+ }
108
+ }}
109
+ >
110
+ {children}
111
+ </View>
112
+ )
113
+
114
+ // RNGH ScrollView path
115
+ if (useRNGHScrollView && RNGHScrollView && panGestureRef) {
116
+ const RNGHComponent = RNGHScrollView as any
117
+ return (
118
+ <RNGHComponent
119
+ ref={composeRefs(scrollRef as any, ref)}
120
+ style={{ flex: 1 }}
121
+ scrollEventThrottle={1}
122
+ scrollEnabled={scrollEnabled}
123
+ simultaneousHandlers={[panGestureRef]}
124
+ onLayout={(e: any) => {
125
+ parentHeight.current = Math.ceil(e.nativeEvent.layout.height)
126
+ updateScrollable()
127
+ }}
128
+ onScroll={(e: any) => {
129
+ const { y } = e.nativeEvent.contentOffset
130
+ currentScrollOffset.current = y
131
+
132
+ if (scrollBridge.scrollLockY !== undefined) {
133
+ if (y !== scrollBridge.scrollLockY) {
134
+ scrollRef.current?.scrollTo?.({
135
+ x: 0,
136
+ y: scrollBridge.scrollLockY,
137
+ animated: false,
138
+ })
139
+ }
140
+ scrollBridge.y = scrollBridge.scrollLockY
141
+ onScroll?.({
142
+ ...e,
143
+ nativeEvent: {
144
+ ...e.nativeEvent,
145
+ contentOffset: {
146
+ ...e.nativeEvent.contentOffset,
147
+ y: scrollBridge.scrollLockY,
148
+ },
149
+ },
150
+ })
151
+ return
152
+ }
153
+
154
+ scrollBridge.y = y
155
+ if (y > 0) scrollBridge.scrollStartY = -1
156
+ onScroll?.(e)
157
+ }}
158
+ contentContainerStyle={{ minHeight: '100%' }}
159
+ bounces={false}
160
+ keyboardShouldPersistTaps="always"
161
+ keyboardDismissMode="none"
162
+ {...props}
163
+ >
164
+ {contentWrapper}
165
+ </RNGHComponent>
166
+ )
167
+ }
168
+
169
+ // fallback ScrollView with platform-specific gesture props
170
+ return (
171
+ <ScrollView
172
+ onLayout={(e) => {
173
+ parentHeight.current = Math.ceil(e.nativeEvent.layout.height)
174
+ updateScrollable()
175
+ }}
176
+ ref={composeRefs(scrollRef as any, ref)}
177
+ flex={1}
178
+ scrollEventThrottle={1}
179
+ className="_ovs-contain"
180
+ scrollEnabled={scrollEnabled}
181
+ onScroll={(e) => {
182
+ const { y } = e.nativeEvent.contentOffset
183
+ scrollBridge.y = y
184
+ if (y > 0) scrollBridge.scrollStartY = -1
185
+ onScroll?.(e)
186
+ }}
187
+ contentContainerStyle={{ minHeight: '100%' }}
188
+ {...gestureProps}
189
+ {...props}
190
+ >
191
+ {contentWrapper}
192
+ </ScrollView>
193
+ )
194
+ }
195
+ )
@@ -0,0 +1,5 @@
1
+ export const constants = {}
2
+
3
+ export const SHEET_NAME = 'Sheet'
4
+ export const SHEET_HANDLE_NAME = 'SheetHandle'
5
+ export const SHEET_OVERLAY_NAME = 'SheetOverlay'
@@ -0,0 +1,9 @@
1
+ import React from 'react'
2
+
3
+ export const ParentSheetContext = React.createContext({
4
+ zIndex: 100_000,
5
+ })
6
+
7
+ export const SheetInsideSheetContext = React.createContext<
8
+ ((hasChild: boolean) => void) | null
9
+ >(null)
@@ -0,0 +1,9 @@
1
+ // Lightweight controller exports - no styled components
2
+ // Use this entry point when you only need SheetController without the full Sheet
3
+
4
+ export { SheetController } from './SheetController'
5
+ export {
6
+ SheetControllerContext,
7
+ useSheetController,
8
+ type SheetControllerContextValue,
9
+ } from './useSheetController'
@@ -0,0 +1,296 @@
1
+ import { useComposedRefs } from '@hanzogui/compose-refs'
2
+ import { useIsomorphicLayoutEffect } from '@hanzogui/constants'
3
+ import type {
4
+ GetProps,
5
+ ViewProps,
6
+ GuiComponent,
7
+ GuiComponentExpectingVariants,
8
+ GuiElement,
9
+ } from '@hanzogui/core'
10
+ import { View } from '@hanzogui/core'
11
+ import { composeEventHandlers, withStaticProperties } from '@hanzogui/helpers'
12
+ import { resolveViewZIndex } from '@hanzogui/portal'
13
+ import { RemoveScroll } from '@hanzogui/remove-scroll'
14
+ import { useDidFinishSSR } from '@hanzogui/use-did-finish-ssr'
15
+ import { StackZIndexContext } from '@hanzogui/z-index-stack'
16
+ import type { ForwardRefExoticComponent, FunctionComponent, RefAttributes } from 'react'
17
+ import { forwardRef, memo, useMemo, useEffect, useRef } from 'react'
18
+ import type { View as RNView } from 'react-native'
19
+ import { Platform } from 'react-native'
20
+ import { SHEET_HANDLE_NAME, SHEET_NAME, SHEET_OVERLAY_NAME } from './constants'
21
+ import { getNativeSheet } from './nativeSheet'
22
+ import { useSheetContext } from './SheetContext'
23
+ import { SheetImplementationCustom } from './SheetImplementationCustom'
24
+ import { SheetScrollView } from './SheetScrollView'
25
+ import type { SheetProps, SheetScopedProps } from './types'
26
+ import { useSheetController } from './useSheetController'
27
+ import { useSheetOffscreenSize } from './useSheetOffscreenSize'
28
+
29
+ type SharedSheetProps = {
30
+ open?: boolean
31
+ }
32
+
33
+ type BaseProps = ViewProps & SharedSheetProps
34
+
35
+ type SheetStyledComponent = GuiComponentExpectingVariants<BaseProps, SharedSheetProps>
36
+
37
+ export function createSheet<
38
+ H extends GuiComponent | SheetStyledComponent,
39
+ F extends GuiComponent | SheetStyledComponent,
40
+ O extends GuiComponent | SheetStyledComponent,
41
+ >({ Handle, Frame, Overlay }: { Handle: H; Frame: F; Overlay: O }) {
42
+ const SheetHandle = Handle.styleable<any>(
43
+ (
44
+ { __scopeSheet, ...props }: SheetScopedProps<SheetStyledComponent>,
45
+ forwardedRef
46
+ ) => {
47
+ const context = useSheetContext(SHEET_HANDLE_NAME, __scopeSheet)
48
+ const composedRef = useComposedRefs<GuiElement>(context.handleRef, forwardedRef)
49
+
50
+ // track if sheet was being dragged to prevent onPress toggle after drag
51
+ const wasDraggingRef = useRef(false)
52
+
53
+ // subscribe to parent dragging changes to track if we dragged during this press
54
+ useEffect(() => {
55
+ if (!context.scrollBridge) return
56
+ return context.scrollBridge.onParentDragging((isDragging: boolean) => {
57
+ if (isDragging) {
58
+ wasDraggingRef.current = true
59
+ }
60
+ })
61
+ }, [context.scrollBridge])
62
+
63
+ if (context.onlyShowFrame) {
64
+ return null
65
+ }
66
+
67
+ return (
68
+ // @ts-ignore
69
+ <Handle
70
+ ref={composedRef}
71
+ onPressIn={() => {
72
+ // reset at start of new press
73
+ wasDraggingRef.current = false
74
+ }}
75
+ onPress={() => {
76
+ // skip toggle if this was a drag gesture
77
+ if (wasDraggingRef.current) {
78
+ wasDraggingRef.current = false
79
+ return
80
+ }
81
+ // don't toggle to the bottom snap position when dismissOnSnapToBottom set
82
+ const max =
83
+ context.snapPoints.length + (context.dismissOnSnapToBottom ? -1 : 0)
84
+ const nextPos = (context.position + 1) % max
85
+ context.setPosition(nextPos)
86
+ }}
87
+ open={context.open}
88
+ {...props}
89
+ />
90
+ )
91
+ }
92
+ )
93
+
94
+ /* -------------------------------------------------------------------------------------------------
95
+ * SheetOverlay
96
+ * -----------------------------------------------------------------------------------------------*/
97
+
98
+ const SheetOverlay = Overlay.styleable<SheetScopedProps<{}>>((propsIn, ref) => {
99
+ const { __scopeSheet, ...props } = propsIn
100
+ const context = useSheetContext(SHEET_OVERLAY_NAME, __scopeSheet)
101
+
102
+ // this ones a bit weird for legacy reasons, we need to hoist it above <Sheet /> AnimatedView
103
+ // so we just pass it up to context
104
+
105
+ const element = useMemo(() => {
106
+ return (
107
+ // @ts-ignore
108
+ <Overlay
109
+ {...props}
110
+ onPress={composeEventHandlers(
111
+ props.onPress,
112
+ context.dismissOnOverlayPress
113
+ ? () => {
114
+ context.setOpen(false)
115
+ }
116
+ : undefined
117
+ )}
118
+ />
119
+ )
120
+ }, [props.onPress, props.opacity, context.dismissOnOverlayPress])
121
+
122
+ useIsomorphicLayoutEffect(() => {
123
+ context.onOverlayComponent?.(element)
124
+ }, [element])
125
+
126
+ if (context.onlyShowFrame) {
127
+ return null
128
+ }
129
+
130
+ return null
131
+ })
132
+
133
+ /* -------------------------------------------------------------------------------------------------
134
+ * Sheet
135
+ * -----------------------------------------------------------------------------------------------*/
136
+
137
+ type ExtraFrameProps = {
138
+ /**
139
+ * By default the sheet adds a view below its bottom that extends down another 50%,
140
+ * this is useful if your Sheet has a spring animation that bounces "past" the top when
141
+ * opening, preventing it from showing the content underneath.
142
+ */
143
+ disableHideBottomOverflow?: boolean
144
+
145
+ /**
146
+ * Adds padding accounting for the currently offscreen content, so if you put a flex element inside
147
+ * the sheet, it will always flex to the height of the visible amount of the sheet. If this is not
148
+ * turned on, the inner content is always set to the max height of the sheet.
149
+ */
150
+ adjustPaddingForOffscreenContent?: boolean
151
+ }
152
+
153
+ const SheetFrame = Frame.styleable<SheetProps & ExtraFrameProps>(
154
+ (
155
+ {
156
+ __scopeSheet,
157
+ adjustPaddingForOffscreenContent,
158
+ disableHideBottomOverflow,
159
+ children,
160
+ ...props
161
+ },
162
+ forwardedRef
163
+ ) => {
164
+ const context = useSheetContext(SHEET_NAME, __scopeSheet)
165
+ const { hasFit, disableRemoveScroll, frameSize, contentRef, open } = context
166
+ const composedContentRef = useComposedRefs(forwardedRef, contentRef)
167
+ const offscreenSize = useSheetOffscreenSize(context)
168
+
169
+ // FIX: Store the frameSize when open for use during close animation
170
+ const stableFrameSize = useRef(frameSize)
171
+ useEffect(() => {
172
+ if (open && frameSize) {
173
+ stableFrameSize.current = frameSize
174
+ }
175
+ }, [open, frameSize])
176
+
177
+ const sheetContents = useMemo(() => {
178
+ // FIX: Use fixed height during close animation to prevent content-driven resizing
179
+ const shouldUseFixedHeight = hasFit && !open && stableFrameSize.current
180
+
181
+ return (
182
+ // @ts-expect-error
183
+ <Frame
184
+ ref={composedContentRef}
185
+ flex={hasFit && open ? 0 : 1}
186
+ flexBasis={hasFit ? 'auto' : undefined}
187
+ height={
188
+ shouldUseFixedHeight
189
+ ? stableFrameSize.current
190
+ : hasFit
191
+ ? undefined
192
+ : frameSize
193
+ }
194
+ pointerEvents={open ? 'auto' : 'none'}
195
+ data-state={open ? 'open' : 'closed'}
196
+ {...props}
197
+ >
198
+ <StackZIndexContext zIndex={resolveViewZIndex(props.zIndex)}>
199
+ {children}
200
+ </StackZIndexContext>
201
+
202
+ {adjustPaddingForOffscreenContent && (
203
+ <View data-sheet-offscreen-pad height={offscreenSize} width="100%" />
204
+ )}
205
+ </Frame>
206
+ )
207
+ }, [
208
+ open,
209
+ props,
210
+ frameSize,
211
+ offscreenSize,
212
+ adjustPaddingForOffscreenContent,
213
+ hasFit,
214
+ ])
215
+
216
+ return (
217
+ <>
218
+ <RemoveScroll enabled={!disableRemoveScroll && context.open}>
219
+ {sheetContents}
220
+ </RemoveScroll>
221
+
222
+ {/* below frame hide when bouncing past 100% */}
223
+ {!disableHideBottomOverflow && (
224
+ // @ts-ignore
225
+ <Frame
226
+ {...props}
227
+ componentName="SheetCover"
228
+ children={null}
229
+ // Don't inherit testID - this is a visual helper element
230
+ testID={undefined}
231
+ id={undefined}
232
+ position="absolute"
233
+ bottom="-100%"
234
+ zIndex={-1}
235
+ height={context.frameSize}
236
+ left={0}
237
+ right={0}
238
+ borderWidth={0}
239
+ borderRadius={0}
240
+ shadowOpacity={0}
241
+ />
242
+ )}
243
+ </>
244
+ )
245
+ }
246
+ ) as any as ForwardRefExoticComponent<
247
+ SheetScopedProps<
248
+ Omit<GetProps<typeof Frame>, keyof ExtraFrameProps> & ExtraFrameProps
249
+ >
250
+ >
251
+
252
+ const Sheet = forwardRef<RNView, SheetProps>(function Sheet(props, ref) {
253
+ const hydrated = useDidFinishSSR()
254
+ const { isShowingNonSheet } = useSheetController()
255
+
256
+ let SheetImplementation = SheetImplementationCustom
257
+
258
+ if (props.native && Platform.OS === 'ios') {
259
+ if (process.env.HANZO_GUI_TARGET === 'native') {
260
+ const impl = getNativeSheet('ios')
261
+ if (impl) {
262
+ // @ts-expect-error accepting external sheet implementation
263
+ SheetImplementation = impl
264
+ }
265
+ }
266
+ }
267
+
268
+ /**
269
+ * Performance is sensitive here so avoid all the hooks below with this
270
+ */
271
+ if (isShowingNonSheet || !hydrated) {
272
+ return null
273
+ }
274
+
275
+ return <SheetImplementation ref={ref} {...props} />
276
+ })
277
+
278
+ const components = {
279
+ Frame: SheetFrame,
280
+ Overlay: SheetOverlay,
281
+ Handle: SheetHandle,
282
+ ScrollView: SheetScrollView,
283
+ }
284
+
285
+ const Controlled = withStaticProperties(Sheet, components) as any as FunctionComponent<
286
+ Omit<SheetProps, 'open' | 'onOpenChange'> & RefAttributes<RNView>
287
+ > &
288
+ typeof components
289
+
290
+ return withStaticProperties(Sheet, {
291
+ ...components,
292
+ Controlled,
293
+ })
294
+ }
295
+
296
+ /* -------------------------------------------------------------------------------------------------*/
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Re-export gesture state from @hanzogui/native.
3
+ * Sheet uses this for backward compatibility with existing code.
4
+ */
5
+
6
+ import { getGestureHandler, type GestureState } from '@hanzogui/native'
7
+
8
+ export type { GestureState as GestureHandlerState } from '@hanzogui/native'
9
+
10
+ // backward compat helpers
11
+ export function isGestureHandlerEnabled(): boolean {
12
+ return getGestureHandler().isEnabled
13
+ }
14
+
15
+ export function getGestureHandlerState(): GestureState {
16
+ return getGestureHandler().state
17
+ }
18
+
19
+ export function setGestureHandlerState(updates: Partial<GestureState>): void {
20
+ getGestureHandler().set(updates)
21
+ }
22
+
23
+ // alias for backward compatibility
24
+ export const setGestureState = setGestureHandlerState
@@ -0,0 +1,31 @@
1
+ export function resisted(y: number, minY: number, maxOverflow = 25) {
2
+ // If we're not past the boundary, return the original position
3
+ if (y >= minY) {
4
+ return y
5
+ }
6
+
7
+ // Calculate how far we've gone past the boundary
8
+ const pastBoundary = minY - y
9
+
10
+ // Use a square root function for very gentle resistance
11
+ // This creates a milder resistance curve than logarithmic
12
+ // Reduced multiplier from 1.5 to 1.0 for even less resistance
13
+ const resistedDistance = Math.sqrt(pastBoundary) * 2
14
+
15
+ // Return the position with resistance applied
16
+ return minY - resistedDistance
17
+ }
18
+
19
+ // // set all the way off screen
20
+ // // + 0.1 ensures this is unique - see hasntMeasured ref
21
+
22
+ // let hiddenSize: number
23
+
24
+ // export function getHiddenSize() {
25
+ // if (hiddenSize == undefined) {
26
+ // // this trigger reflow on web avoid doing on startup
27
+ // const screen = Dimensions.get('screen')
28
+ // hiddenSize = Math.max(screen.height, screen.width) + 0.1
29
+ // }
30
+ // return hiddenSize
31
+ // }
package/src/index.ts ADDED
@@ -0,0 +1,11 @@
1
+ export * from './Sheet'
2
+ export * from './useSheet'
3
+ export * from './createSheet'
4
+ export * from './SheetController'
5
+ export * from './useSheetController'
6
+ export * from './useSheetOpenState'
7
+ export * from './useSheetOffscreenSize'
8
+ export * from './SheetScrollView'
9
+ export * from './nativeSheet'
10
+ export * from './types'
11
+ export * from './contexts'
@@ -0,0 +1,89 @@
1
+ import { YStack } from '@hanzogui/stacks'
2
+ import type { FunctionComponent } from 'react'
3
+ import { useEffect, useRef } from 'react'
4
+ import { View } from 'react-native'
5
+ import { SheetProvider } from './SheetContext'
6
+ import type { SheetProps } from './types'
7
+ import { useSheetOpenState } from './useSheetOpenState'
8
+ import { useSheetProviderProps } from './useSheetProviderProps'
9
+
10
+ // import { useSheetSnapPoints } from './useSheetSnapPoints'
11
+
12
+ type SheetNativePlatforms = 'ios'
13
+
14
+ const nativeSheets: Record<SheetNativePlatforms, FunctionComponent<SheetProps> | null> = {
15
+ ios: null,
16
+ }
17
+
18
+ export function getNativeSheet(platform: SheetNativePlatforms) {
19
+ return nativeSheets[platform]
20
+ }
21
+
22
+ export function setupNativeSheet(
23
+ platform: SheetNativePlatforms,
24
+ RNIOSModal: { ModalSheetView: any; ModalSheetViewMainContent: any }
25
+ ) {
26
+ const { ModalSheetView, ModalSheetViewMainContent } = RNIOSModal
27
+
28
+ if (platform === 'ios') {
29
+ nativeSheets[platform] = (props: SheetProps) => {
30
+ const state = useSheetOpenState(props)
31
+ const providerProps = useSheetProviderProps(props, state)
32
+ // const { position } = providerProps
33
+ // const { positions } = useSheetSnapPoints(providerProps)
34
+
35
+ const { open, setOpen } = state
36
+ const ref = useRef<{
37
+ presentModal: Function
38
+ dismissModal: Function
39
+ }>(undefined)
40
+
41
+ useEffect(() => {
42
+ if (open) {
43
+ ref.current?.presentModal()
44
+ } else {
45
+ ref.current?.dismissModal()
46
+ }
47
+ }, [open])
48
+
49
+ function setOpenInternal(next: boolean) {
50
+ props.onOpenChange?.(open)
51
+ setOpen(next)
52
+ }
53
+
54
+ // modalContentPreferredContentSize={{
55
+ // mode: 'percent',
56
+ // percentWidth: '100%',
57
+ // percentHeight:
58
+ // }}
59
+
60
+ return (
61
+ <>
62
+ <SheetProvider setHasScrollView={emptyFn} {...providerProps} onlyShowFrame>
63
+ <ModalSheetView ref={ref} onModalDidDismiss={() => setOpenInternal(false)}>
64
+ <ModalSheetViewMainContent>
65
+ <View style={{ flex: 1 }}>{props.children}</View>
66
+ </ModalSheetViewMainContent>
67
+ </ModalSheetView>
68
+
69
+ {/* for some reason select triggers wont show on native if this isn't inside the actual tree not inside implementation... */}
70
+ {/* so just hiding it here for now... not great... */}
71
+ <YStack
72
+ position="absolute"
73
+ opacity={0}
74
+ pointerEvents="none"
75
+ width={0}
76
+ height={0}
77
+ >
78
+ {props.children}
79
+ </YStack>
80
+ </SheetProvider>
81
+ </>
82
+ )
83
+ }
84
+ }
85
+ }
86
+
87
+ const emptyFn = () => {
88
+ // TODO
89
+ }