@hanzogui/native 2.0.0-rc.41-hanzoai.5

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 (283) hide show
  1. package/.turbo/turbo-build.log +2 -0
  2. package/dist/cjs/PressBoundary.cjs +92 -0
  3. package/dist/cjs/PressBoundary.native.js +105 -0
  4. package/dist/cjs/PressBoundary.native.js.map +1 -0
  5. package/dist/cjs/burntState.cjs +46 -0
  6. package/dist/cjs/burntState.native.js +49 -0
  7. package/dist/cjs/burntState.native.js.map +1 -0
  8. package/dist/cjs/components.cjs +71 -0
  9. package/dist/cjs/components.native.js +77 -0
  10. package/dist/cjs/components.native.js.map +1 -0
  11. package/dist/cjs/gesture-handler.cjs +36 -0
  12. package/dist/cjs/gesture-handler.native.js +39 -0
  13. package/dist/cjs/gesture-handler.native.js.map +1 -0
  14. package/dist/cjs/gestureState.cjs +178 -0
  15. package/dist/cjs/gestureState.native.js +191 -0
  16. package/dist/cjs/gestureState.native.js.map +1 -0
  17. package/dist/cjs/globalState.cjs +45 -0
  18. package/dist/cjs/globalState.native.js +48 -0
  19. package/dist/cjs/globalState.native.js.map +1 -0
  20. package/dist/cjs/index.cjs +53 -0
  21. package/dist/cjs/index.native.js +56 -0
  22. package/dist/cjs/index.native.js.map +1 -0
  23. package/dist/cjs/keyboardControllerState.cjs +49 -0
  24. package/dist/cjs/keyboardControllerState.native.js +52 -0
  25. package/dist/cjs/keyboardControllerState.native.js.map +1 -0
  26. package/dist/cjs/linearGradientState.cjs +45 -0
  27. package/dist/cjs/linearGradientState.native.js +48 -0
  28. package/dist/cjs/linearGradientState.native.js.map +1 -0
  29. package/dist/cjs/nativeMenuContext.cjs +29 -0
  30. package/dist/cjs/nativeMenuContext.native.js +32 -0
  31. package/dist/cjs/nativeMenuContext.native.js.map +1 -0
  32. package/dist/cjs/portalState.cjs +45 -0
  33. package/dist/cjs/portalState.native.js +48 -0
  34. package/dist/cjs/portalState.native.js.map +1 -0
  35. package/dist/cjs/safeAreaState.cjs +73 -0
  36. package/dist/cjs/safeAreaState.native.js +76 -0
  37. package/dist/cjs/safeAreaState.native.js.map +1 -0
  38. package/dist/cjs/setup-burnt.cjs +17 -0
  39. package/dist/cjs/setup-burnt.native.js +20 -0
  40. package/dist/cjs/setup-burnt.native.js.map +1 -0
  41. package/dist/cjs/setup-expo-linear-gradient.cjs +16 -0
  42. package/dist/cjs/setup-expo-linear-gradient.native.js +19 -0
  43. package/dist/cjs/setup-expo-linear-gradient.native.js.map +1 -0
  44. package/dist/cjs/setup-gesture-handler.cjs +67 -0
  45. package/dist/cjs/setup-gesture-handler.native.js +70 -0
  46. package/dist/cjs/setup-gesture-handler.native.js.map +1 -0
  47. package/dist/cjs/setup-keyboard-controller.cjs +0 -0
  48. package/dist/cjs/setup-keyboard-controller.native.js +36 -0
  49. package/dist/cjs/setup-keyboard-controller.native.js.map +1 -0
  50. package/dist/cjs/setup-safe-area.cjs +3 -0
  51. package/dist/cjs/setup-safe-area.native.js +23 -0
  52. package/dist/cjs/setup-safe-area.native.js.map +1 -0
  53. package/dist/cjs/setup-teleport.cjs +18 -0
  54. package/dist/cjs/setup-teleport.native.js +21 -0
  55. package/dist/cjs/setup-teleport.native.js.map +1 -0
  56. package/dist/cjs/setup-worklets.cjs +21 -0
  57. package/dist/cjs/setup-worklets.native.js +24 -0
  58. package/dist/cjs/setup-worklets.native.js.map +1 -0
  59. package/dist/cjs/setup-zeego.cjs +22 -0
  60. package/dist/cjs/setup-zeego.native.js +25 -0
  61. package/dist/cjs/setup-zeego.native.js.map +1 -0
  62. package/dist/cjs/types.cjs +18 -0
  63. package/dist/cjs/types.native.js +21 -0
  64. package/dist/cjs/types.native.js.map +1 -0
  65. package/dist/cjs/workletsState.cjs +48 -0
  66. package/dist/cjs/workletsState.native.js +51 -0
  67. package/dist/cjs/workletsState.native.js.map +1 -0
  68. package/dist/cjs/zeegoState.cjs +46 -0
  69. package/dist/cjs/zeegoState.native.js +49 -0
  70. package/dist/cjs/zeegoState.native.js.map +1 -0
  71. package/dist/esm/PressBoundary.mjs +56 -0
  72. package/dist/esm/PressBoundary.mjs.map +1 -0
  73. package/dist/esm/PressBoundary.native.js +66 -0
  74. package/dist/esm/PressBoundary.native.js.map +1 -0
  75. package/dist/esm/burntState.mjs +21 -0
  76. package/dist/esm/burntState.mjs.map +1 -0
  77. package/dist/esm/burntState.native.js +21 -0
  78. package/dist/esm/burntState.native.js.map +1 -0
  79. package/dist/esm/components.mjs +44 -0
  80. package/dist/esm/components.mjs.map +1 -0
  81. package/dist/esm/components.native.js +47 -0
  82. package/dist/esm/components.native.js.map +1 -0
  83. package/dist/esm/gesture-handler.mjs +6 -0
  84. package/dist/esm/gesture-handler.mjs.map +1 -0
  85. package/dist/esm/gesture-handler.native.js +6 -0
  86. package/dist/esm/gesture-handler.native.js.map +1 -0
  87. package/dist/esm/gestureState.mjs +151 -0
  88. package/dist/esm/gestureState.mjs.map +1 -0
  89. package/dist/esm/gestureState.native.js +161 -0
  90. package/dist/esm/gestureState.native.js.map +1 -0
  91. package/dist/esm/globalState.mjs +20 -0
  92. package/dist/esm/globalState.mjs.map +1 -0
  93. package/dist/esm/globalState.native.js +20 -0
  94. package/dist/esm/globalState.native.js.map +1 -0
  95. package/dist/esm/index.js +13 -0
  96. package/dist/esm/index.js.map +1 -0
  97. package/dist/esm/index.mjs +13 -0
  98. package/dist/esm/index.mjs.map +1 -0
  99. package/dist/esm/index.native.js +13 -0
  100. package/dist/esm/index.native.js.map +1 -0
  101. package/dist/esm/keyboardControllerState.mjs +22 -0
  102. package/dist/esm/keyboardControllerState.mjs.map +1 -0
  103. package/dist/esm/keyboardControllerState.native.js +22 -0
  104. package/dist/esm/keyboardControllerState.native.js.map +1 -0
  105. package/dist/esm/linearGradientState.mjs +20 -0
  106. package/dist/esm/linearGradientState.mjs.map +1 -0
  107. package/dist/esm/linearGradientState.native.js +20 -0
  108. package/dist/esm/linearGradientState.native.js.map +1 -0
  109. package/dist/esm/nativeMenuContext.mjs +4 -0
  110. package/dist/esm/nativeMenuContext.mjs.map +1 -0
  111. package/dist/esm/nativeMenuContext.native.js +4 -0
  112. package/dist/esm/nativeMenuContext.native.js.map +1 -0
  113. package/dist/esm/portalState.mjs +20 -0
  114. package/dist/esm/portalState.mjs.map +1 -0
  115. package/dist/esm/portalState.native.js +20 -0
  116. package/dist/esm/portalState.native.js.map +1 -0
  117. package/dist/esm/safeAreaState.mjs +48 -0
  118. package/dist/esm/safeAreaState.mjs.map +1 -0
  119. package/dist/esm/safeAreaState.native.js +48 -0
  120. package/dist/esm/safeAreaState.native.js.map +1 -0
  121. package/dist/esm/setup-burnt.mjs +18 -0
  122. package/dist/esm/setup-burnt.mjs.map +1 -0
  123. package/dist/esm/setup-burnt.native.js +18 -0
  124. package/dist/esm/setup-burnt.native.js.map +1 -0
  125. package/dist/esm/setup-expo-linear-gradient.mjs +17 -0
  126. package/dist/esm/setup-expo-linear-gradient.mjs.map +1 -0
  127. package/dist/esm/setup-expo-linear-gradient.native.js +17 -0
  128. package/dist/esm/setup-expo-linear-gradient.native.js.map +1 -0
  129. package/dist/esm/setup-gesture-handler.mjs +41 -0
  130. package/dist/esm/setup-gesture-handler.mjs.map +1 -0
  131. package/dist/esm/setup-gesture-handler.native.js +41 -0
  132. package/dist/esm/setup-gesture-handler.native.js.map +1 -0
  133. package/dist/esm/setup-keyboard-controller.mjs +2 -0
  134. package/dist/esm/setup-keyboard-controller.mjs.map +1 -0
  135. package/dist/esm/setup-keyboard-controller.native.js +34 -0
  136. package/dist/esm/setup-keyboard-controller.native.js.map +1 -0
  137. package/dist/esm/setup-safe-area.mjs +4 -0
  138. package/dist/esm/setup-safe-area.mjs.map +1 -0
  139. package/dist/esm/setup-safe-area.native.js +21 -0
  140. package/dist/esm/setup-safe-area.native.js.map +1 -0
  141. package/dist/esm/setup-teleport.mjs +19 -0
  142. package/dist/esm/setup-teleport.mjs.map +1 -0
  143. package/dist/esm/setup-teleport.native.js +19 -0
  144. package/dist/esm/setup-teleport.native.js.map +1 -0
  145. package/dist/esm/setup-worklets.mjs +22 -0
  146. package/dist/esm/setup-worklets.mjs.map +1 -0
  147. package/dist/esm/setup-worklets.native.js +22 -0
  148. package/dist/esm/setup-worklets.native.js.map +1 -0
  149. package/dist/esm/setup-zeego.mjs +23 -0
  150. package/dist/esm/setup-zeego.mjs.map +1 -0
  151. package/dist/esm/setup-zeego.native.js +23 -0
  152. package/dist/esm/setup-zeego.native.js.map +1 -0
  153. package/dist/esm/types.mjs +2 -0
  154. package/dist/esm/types.mjs.map +1 -0
  155. package/dist/esm/types.native.js +2 -0
  156. package/dist/esm/types.native.js.map +1 -0
  157. package/dist/esm/workletsState.mjs +23 -0
  158. package/dist/esm/workletsState.mjs.map +1 -0
  159. package/dist/esm/workletsState.native.js +23 -0
  160. package/dist/esm/workletsState.native.js.map +1 -0
  161. package/dist/esm/zeegoState.mjs +21 -0
  162. package/dist/esm/zeegoState.mjs.map +1 -0
  163. package/dist/esm/zeegoState.native.js +21 -0
  164. package/dist/esm/zeegoState.native.js.map +1 -0
  165. package/gesture-handler/index.cjs +1 -0
  166. package/gesture-handler/index.js +1 -0
  167. package/gesture-handler/index.native.cjs +1 -0
  168. package/gesture-handler/index.native.js +1 -0
  169. package/gesture-handler.cjs +1 -0
  170. package/package.json +208 -0
  171. package/setup-burnt/index.cjs +2 -0
  172. package/setup-burnt/index.js +2 -0
  173. package/setup-burnt/index.native.cjs +2 -0
  174. package/setup-burnt/index.native.js +2 -0
  175. package/setup-burnt.cjs +1 -0
  176. package/setup-expo-linear-gradient/index.cjs +2 -0
  177. package/setup-expo-linear-gradient/index.js +2 -0
  178. package/setup-expo-linear-gradient/index.native.cjs +2 -0
  179. package/setup-expo-linear-gradient/index.native.js +2 -0
  180. package/setup-expo-linear-gradient.cjs +1 -0
  181. package/setup-gesture-handler/index.cjs +2 -0
  182. package/setup-gesture-handler/index.js +2 -0
  183. package/setup-gesture-handler/index.native.cjs +2 -0
  184. package/setup-gesture-handler/index.native.js +2 -0
  185. package/setup-gesture-handler.cjs +1 -0
  186. package/setup-keyboard-controller/index.cjs +2 -0
  187. package/setup-keyboard-controller/index.js +2 -0
  188. package/setup-keyboard-controller/index.native.cjs +2 -0
  189. package/setup-keyboard-controller/index.native.js +2 -0
  190. package/setup-keyboard-controller.cjs +1 -0
  191. package/setup-safe-area/index.cjs +2 -0
  192. package/setup-safe-area/index.js +2 -0
  193. package/setup-safe-area/index.native.cjs +2 -0
  194. package/setup-safe-area/index.native.js +2 -0
  195. package/setup-safe-area.cjs +1 -0
  196. package/setup-teleport/index.cjs +2 -0
  197. package/setup-teleport/index.js +2 -0
  198. package/setup-teleport/index.native.cjs +2 -0
  199. package/setup-teleport/index.native.js +2 -0
  200. package/setup-teleport.cjs +1 -0
  201. package/setup-worklets/index.cjs +2 -0
  202. package/setup-worklets/index.js +2 -0
  203. package/setup-worklets/index.native.cjs +2 -0
  204. package/setup-worklets/index.native.js +2 -0
  205. package/setup-worklets.cjs +1 -0
  206. package/setup-zeego/index.cjs +2 -0
  207. package/setup-zeego/index.js +2 -0
  208. package/setup-zeego/index.native.cjs +2 -0
  209. package/setup-zeego/index.native.js +2 -0
  210. package/setup-zeego.cjs +1 -0
  211. package/src/PressBoundary.tsx +81 -0
  212. package/src/burntState.ts +28 -0
  213. package/src/components.tsx +48 -0
  214. package/src/gesture-handler.ts +17 -0
  215. package/src/gestureState.ts +260 -0
  216. package/src/globalState.ts +32 -0
  217. package/src/index.ts +88 -0
  218. package/src/keyboardControllerState.ts +29 -0
  219. package/src/linearGradientState.ts +27 -0
  220. package/src/nativeMenuContext.ts +4 -0
  221. package/src/portalState.ts +27 -0
  222. package/src/safeAreaState.ts +50 -0
  223. package/src/setup-burnt.ts +38 -0
  224. package/src/setup-expo-linear-gradient.ts +36 -0
  225. package/src/setup-gesture-handler.ts +78 -0
  226. package/src/setup-keyboard-controller.ts +60 -0
  227. package/src/setup-keyboard-controller.web.ts +6 -0
  228. package/src/setup-safe-area.ts +56 -0
  229. package/src/setup-teleport.ts +36 -0
  230. package/src/setup-worklets.ts +49 -0
  231. package/src/setup-zeego.ts +42 -0
  232. package/src/types.ts +88 -0
  233. package/src/workletsState.ts +30 -0
  234. package/src/zeegoState.ts +28 -0
  235. package/tsconfig.json +12 -0
  236. package/types/PressBoundary.d.ts +14 -0
  237. package/types/PressBoundary.d.ts.map +11 -0
  238. package/types/burntState.d.ts +9 -0
  239. package/types/burntState.d.ts.map +11 -0
  240. package/types/components.d.ts +20 -0
  241. package/types/components.d.ts.map +11 -0
  242. package/types/gesture-handler.d.ts +8 -0
  243. package/types/gesture-handler.d.ts.map +11 -0
  244. package/types/gestureState.d.ts +29 -0
  245. package/types/gestureState.d.ts.map +11 -0
  246. package/types/globalState.d.ts +8 -0
  247. package/types/globalState.d.ts.map +11 -0
  248. package/types/index.d.ts +43 -0
  249. package/types/index.d.ts.map +11 -0
  250. package/types/keyboardControllerState.d.ts +7 -0
  251. package/types/keyboardControllerState.d.ts.map +11 -0
  252. package/types/linearGradientState.d.ts +9 -0
  253. package/types/linearGradientState.d.ts.map +11 -0
  254. package/types/nativeMenuContext.d.ts +4 -0
  255. package/types/nativeMenuContext.d.ts.map +11 -0
  256. package/types/portalState.d.ts +9 -0
  257. package/types/portalState.d.ts.map +11 -0
  258. package/types/safeAreaState.d.ts +13 -0
  259. package/types/safeAreaState.d.ts.map +11 -0
  260. package/types/setup-burnt.d.ts +3 -0
  261. package/types/setup-burnt.d.ts.map +11 -0
  262. package/types/setup-expo-linear-gradient.d.ts +3 -0
  263. package/types/setup-expo-linear-gradient.d.ts.map +11 -0
  264. package/types/setup-gesture-handler.d.ts +10 -0
  265. package/types/setup-gesture-handler.d.ts.map +11 -0
  266. package/types/setup-keyboard-controller.d.ts +3 -0
  267. package/types/setup-keyboard-controller.d.ts.map +11 -0
  268. package/types/setup-keyboard-controller.web.d.ts +2 -0
  269. package/types/setup-keyboard-controller.web.d.ts.map +11 -0
  270. package/types/setup-safe-area.d.ts +3 -0
  271. package/types/setup-safe-area.d.ts.map +11 -0
  272. package/types/setup-teleport.d.ts +3 -0
  273. package/types/setup-teleport.d.ts.map +11 -0
  274. package/types/setup-worklets.d.ts +3 -0
  275. package/types/setup-worklets.d.ts.map +11 -0
  276. package/types/setup-zeego.d.ts +3 -0
  277. package/types/setup-zeego.d.ts.map +11 -0
  278. package/types/types.d.ts +76 -0
  279. package/types/types.d.ts.map +11 -0
  280. package/types/workletsState.d.ts +9 -0
  281. package/types/workletsState.d.ts.map +11 -0
  282. package/types/zeegoState.d.ts +9 -0
  283. package/types/zeegoState.d.ts.map +11 -0
@@ -0,0 +1,2 @@
1
+ // compat with metro without package exports
2
+ Object.assign(module.exports, require('../dist/cjs/setup-worklets.native.js'))
@@ -0,0 +1 @@
1
+ Object.assign(module.exports, require('./dist/cjs/setup-worklets.cjs'))
@@ -0,0 +1,2 @@
1
+ // compat with hanzogui static compiler
2
+ Object.assign(module.exports, require('../dist/cjs/setup-zeego.cjs'))
@@ -0,0 +1,2 @@
1
+ // compat with metro without package exports
2
+ Object.assign(module.exports, require('../dist/cjs/setup-zeego.cjs'))
@@ -0,0 +1,2 @@
1
+ // compat with hanzogui static compiler
2
+ Object.assign(module.exports, require('../dist/cjs/setup-zeego.native.js'))
@@ -0,0 +1,2 @@
1
+ // compat with metro without package exports
2
+ Object.assign(module.exports, require('../dist/cjs/setup-zeego.native.js'))
@@ -0,0 +1 @@
1
+ Object.assign(module.exports, require('./dist/cjs/setup-zeego.cjs'))
@@ -0,0 +1,81 @@
1
+ import React from 'react'
2
+ import { View, type ViewProps } from 'react-native'
3
+ import {
4
+ claimExternalPressOwnership,
5
+ releaseExternalPressOwnership,
6
+ type ExternalPressOwnershipToken,
7
+ } from './gestureState'
8
+
9
+ export interface PressBoundaryProps extends ViewProps {
10
+ enabled?: boolean
11
+ /**
12
+ * Alias for enabling the boundary. The behavior is limited to Hanzogui's
13
+ * shared press ownership and does not patch arbitrary RN bubbling.
14
+ */
15
+ stopPropagation?: boolean
16
+ debugName?: string | null
17
+ }
18
+
19
+ function composeFirst<T extends (...args: any[]) => void>(ours: T, theirs?: T) {
20
+ return (...args: Parameters<T>) => {
21
+ ours(...args)
22
+ theirs?.(...args)
23
+ }
24
+ }
25
+
26
+ function composeLast<T extends (...args: any[]) => void>(theirs: T | undefined, ours: T) {
27
+ return (...args: Parameters<T>) => {
28
+ theirs?.(...args)
29
+ ours(...args)
30
+ }
31
+ }
32
+
33
+ export const PressBoundary: React.ForwardRefExoticComponent<
34
+ PressBoundaryProps & React.RefAttributes<View>
35
+ > = React.forwardRef<View, PressBoundaryProps>(function PressBoundary(
36
+ {
37
+ enabled,
38
+ stopPropagation,
39
+ debugName,
40
+ onTouchStart,
41
+ onTouchEnd,
42
+ onTouchCancel,
43
+ onResponderGrant,
44
+ onResponderRelease,
45
+ onResponderTerminate,
46
+ ...props
47
+ },
48
+ forwardedRef
49
+ ) {
50
+ const tokenRef = React.useRef<ExternalPressOwnershipToken | null>(null)
51
+ const isEnabled = enabled ?? stopPropagation ?? true
52
+
53
+ const claim = React.useCallback((): void => {
54
+ if (!isEnabled) return
55
+ if (tokenRef.current) {
56
+ releaseExternalPressOwnership(tokenRef.current, debugName)
57
+ }
58
+ tokenRef.current = claimExternalPressOwnership(debugName)
59
+ }, [debugName, isEnabled])
60
+
61
+ const release = React.useCallback((): void => {
62
+ if (!tokenRef.current) return
63
+ releaseExternalPressOwnership(tokenRef.current, debugName)
64
+ tokenRef.current = null
65
+ }, [debugName])
66
+
67
+ React.useEffect(() => release, [release])
68
+
69
+ return (
70
+ <View
71
+ ref={forwardedRef}
72
+ {...props}
73
+ onTouchStart={composeFirst(claim, onTouchStart)}
74
+ onTouchEnd={composeLast(onTouchEnd, release)}
75
+ onTouchCancel={composeLast(onTouchCancel, release)}
76
+ onResponderGrant={composeFirst(claim, onResponderGrant)}
77
+ onResponderRelease={composeLast(onResponderRelease, release)}
78
+ onResponderTerminate={composeLast(onResponderTerminate, release)}
79
+ />
80
+ )
81
+ })
@@ -0,0 +1,28 @@
1
+ import { createGlobalState } from './globalState'
2
+ import type { BurntState } from './types'
3
+
4
+ const state = createGlobalState<BurntState>(`burnt`, {
5
+ enabled: false,
6
+ toast: null,
7
+ dismissAllAlerts: null,
8
+ })
9
+
10
+ export interface BurntAccessor {
11
+ readonly isEnabled: boolean
12
+ readonly state: BurntState
13
+ set(newState: BurntState): void
14
+ }
15
+
16
+ export function getBurnt(): BurntAccessor {
17
+ return {
18
+ get isEnabled(): boolean {
19
+ return state.get().enabled
20
+ },
21
+ get state(): BurntState {
22
+ return state.get()
23
+ },
24
+ set(newState: BurntState): void {
25
+ state.set(newState)
26
+ },
27
+ }
28
+ }
@@ -0,0 +1,48 @@
1
+ import type { ReactNode } from 'react'
2
+ import { getPortal } from './portalState'
3
+ import type {
4
+ NativePortalProps,
5
+ NativePortalHostProps,
6
+ NativePortalProviderProps,
7
+ } from './types'
8
+
9
+ export type { NativePortalProps, NativePortalHostProps, NativePortalProviderProps }
10
+
11
+ /**
12
+ * Renders children into a teleport Portal when available.
13
+ * Returns null when teleport is not set up (allows fallback handling by caller).
14
+ */
15
+ export function NativePortal({
16
+ hostName = 'root',
17
+ children,
18
+ }: NativePortalProps): ReactNode {
19
+ const state = getPortal().state
20
+ if (state.type !== 'teleport') return null
21
+
22
+ const { Portal } = (globalThis as any).__hanzogui_teleport
23
+ return <Portal hostName={hostName}>{children}</Portal>
24
+ }
25
+
26
+ /**
27
+ * Renders a teleport PortalHost when available.
28
+ * Returns null when teleport is not set up.
29
+ */
30
+ export function NativePortalHost({ name }: NativePortalHostProps): ReactNode {
31
+ const state = getPortal().state
32
+ if (state.type !== 'teleport') return null
33
+
34
+ const { PortalHost } = (globalThis as any).__hanzogui_teleport
35
+ return <PortalHost name={name} />
36
+ }
37
+
38
+ /**
39
+ * Wraps children with teleport PortalProvider when available.
40
+ * Returns children as-is when teleport is not set up.
41
+ */
42
+ export function NativePortalProvider({ children }: NativePortalProviderProps): ReactNode {
43
+ const state = getPortal().state
44
+ if (state.type !== 'teleport') return <>{children}</>
45
+
46
+ const { PortalProvider } = (globalThis as any).__hanzogui_teleport
47
+ return <PortalProvider>{children}</PortalProvider>
48
+ }
@@ -0,0 +1,17 @@
1
+ export { getGestureHandler } from './gestureState'
2
+ export type {
3
+ ExternalPressOwnershipToken,
4
+ GestureHandlerAccessor,
5
+ PressGestureConfig,
6
+ } from './gestureState'
7
+ export {
8
+ claimExternalPressOwnership as unstable_claimExternalPressOwnership,
9
+ releaseExternalPressOwnership as unstable_releaseExternalPressOwnership,
10
+ } from './gestureState'
11
+ export { PressBoundary } from './PressBoundary'
12
+ export type { PressBoundaryProps } from './PressBoundary'
13
+ export {
14
+ getGestureHandlerConfig,
15
+ setupGestureHandler,
16
+ type GestureHandlerConfig,
17
+ } from './setup-gesture-handler'
@@ -0,0 +1,260 @@
1
+ import { createGlobalState } from './globalState'
2
+ import type { GestureState } from './types'
3
+
4
+ const state = createGlobalState<GestureState>(`gesture`, {
5
+ enabled: false,
6
+ Gesture: null,
7
+ GestureDetector: null,
8
+ ScrollView: null,
9
+ })
10
+
11
+ let pressGestureDebugId = 0
12
+ let externalPressDebugId = 0
13
+
14
+ type PressOwnerSource = 'internal' | 'external' | null
15
+
16
+ function getEventPointerId(e: any): number | null {
17
+ const pointerId =
18
+ e?.pointerId ??
19
+ e?.pointer?.id ??
20
+ e?.event?.pointerId ??
21
+ e?.event?.pointer?.id ??
22
+ e?.nativeEvent?.pointerId ??
23
+ e?.nativeEvent?.id ??
24
+ e?.event?.nativeEvent?.pointerId ??
25
+ e?.event?.nativeEvent?.id ??
26
+ null
27
+
28
+ return pointerId == null || Number.isNaN(pointerId) ? null : Number(pointerId)
29
+ }
30
+
31
+ /**
32
+ * Global press coordination - ensures only innermost pressable fires press events,
33
+ * matching RN Pressable/responder system semantics where deepest component wins.
34
+ * Uses a grace period to allow child gestures to steal ownership from parent,
35
+ * since RNGH fires parent gestures before child gestures.
36
+ */
37
+ const pressState = {
38
+ owner: null as object | null,
39
+ ownerId: null as number | null,
40
+ ownerSource: null as PressOwnerSource,
41
+ ownerPointerId: null as number | null,
42
+ timestamp: 0,
43
+ }
44
+
45
+ export interface Insets {
46
+ top?: number
47
+ left?: number
48
+ bottom?: number
49
+ right?: number
50
+ }
51
+
52
+ export type PressGestureConfig = {
53
+ debugName?: string | null
54
+ onPressIn?: (e: any) => void
55
+ onPressOut?: (e: any) => void
56
+ onPress?: (e: any) => void
57
+ onLongPress?: (e: any) => void
58
+ delayLongPress?: number
59
+ hitSlop?: number | Insets | null
60
+ }
61
+
62
+ export interface GestureHandlerAccessor {
63
+ readonly isEnabled: boolean
64
+ readonly state: GestureState
65
+ set(updates: Partial<GestureState>): void
66
+ disable(): void
67
+ createPressGesture(config: PressGestureConfig): any
68
+ }
69
+
70
+ export type ExternalPressOwnershipToken = object
71
+
72
+ function resetPressOwner() {
73
+ pressState.owner = null
74
+ pressState.ownerId = null
75
+ pressState.ownerSource = null
76
+ pressState.ownerPointerId = null
77
+ pressState.timestamp = 0
78
+ }
79
+
80
+ function resetStaleOwner(now: number, debugName?: string | null) {
81
+ if (now - pressState.timestamp > 2000) {
82
+ resetPressOwner()
83
+ }
84
+ }
85
+
86
+ export function claimExternalPressOwnership(
87
+ debugName?: string | null
88
+ ): ExternalPressOwnershipToken {
89
+ const now = Date.now()
90
+ resetStaleOwner(now, debugName)
91
+
92
+ const token = {}
93
+ const ownerId = ++externalPressDebugId
94
+
95
+ pressState.owner = token
96
+ pressState.ownerId = ownerId
97
+ pressState.ownerSource = 'external'
98
+ pressState.timestamp = now
99
+
100
+ return token
101
+ }
102
+
103
+ export function releaseExternalPressOwnership(
104
+ token: ExternalPressOwnershipToken | null | undefined,
105
+ debugName?: string | null
106
+ ): void {
107
+ if (!token || pressState.owner !== token) {
108
+ return
109
+ }
110
+ resetPressOwner()
111
+ }
112
+
113
+ export function getGestureHandler(): GestureHandlerAccessor {
114
+ return {
115
+ get isEnabled(): boolean {
116
+ return state.get().enabled
117
+ },
118
+ get state(): GestureState {
119
+ return state.get()
120
+ },
121
+ set(updates: Partial<GestureState>): void {
122
+ Object.assign(state.get(), updates)
123
+ },
124
+
125
+ disable(): void {
126
+ state.get().enabled = false
127
+ },
128
+
129
+ createPressGesture(config: PressGestureConfig): any {
130
+ const { Gesture } = state.get()
131
+ if (!Gesture) return null
132
+
133
+ const longPressDuration = config.delayLongPress ?? 500
134
+
135
+ // unique token for this gesture instance - used to track ownership
136
+ const myToken = {}
137
+ const myDebugId = ++pressGestureDebugId
138
+ let didLongPress = false
139
+ let didPressIn = false
140
+ let pressInTimer: ReturnType<typeof setTimeout> | null = null
141
+
142
+ // Grace period for child gestures to steal ownership from parent.
143
+ // RNGH fires parent before child, but we want innermost to win.
144
+ // Claims typically span a few ms, 24ms gives enough room to observe
145
+ // ordering while debugging slower frames.
146
+ const GRACE_PERIOD_MS = process.env.TAMAGUI_RNGH_PRESS_DELAY
147
+ ? +process.env.TAMAGUI_RNGH_PRESS_DELAY
148
+ : 24
149
+
150
+ const tryClaimOwnership = (e: any) => {
151
+ const now = Date.now()
152
+ resetStaleOwner(now, config.debugName)
153
+
154
+ const currentPointerId = getEventPointerId(e)
155
+ const isSameTouchPointer =
156
+ currentPointerId == null ||
157
+ pressState.ownerPointerId == null ||
158
+ pressState.ownerPointerId === currentPointerId
159
+
160
+ if (
161
+ pressState.owner === null ||
162
+ (pressState.ownerSource === 'internal' && isSameTouchPointer)
163
+ ) {
164
+ pressState.owner = myToken
165
+ pressState.ownerId = myDebugId
166
+ pressState.ownerSource = 'internal'
167
+ pressState.ownerPointerId = currentPointerId
168
+ pressState.timestamp = now
169
+ }
170
+ return pressState.owner === myToken
171
+ }
172
+
173
+ const isOwner = () => pressState.owner === myToken
174
+
175
+ const releaseOwnership = () => {
176
+ if (pressInTimer) {
177
+ clearTimeout(pressInTimer)
178
+ pressInTimer = null
179
+ }
180
+ if (pressState.owner === myToken) {
181
+ resetPressOwner()
182
+ }
183
+ }
184
+
185
+ const firePressIn = (e: any) => {
186
+ if (!didPressIn && isOwner()) {
187
+ didPressIn = true
188
+ config.onPressIn?.(e)
189
+ }
190
+ }
191
+
192
+ const schedulePressIn = (e: any) => {
193
+ if (pressInTimer) {
194
+ clearTimeout(pressInTimer)
195
+ }
196
+ pressInTimer = setTimeout(() => {
197
+ pressInTimer = null
198
+ if (isOwner()) {
199
+ firePressIn(e)
200
+ }
201
+ }, GRACE_PERIOD_MS + 1)
202
+ }
203
+
204
+ // Tap gesture for regular presses
205
+ // Use long maxDuration to not cancel during long presses
206
+ const tap = Gesture.Tap()
207
+ .runOnJS(true)
208
+ .maxDuration(10000) // allow very long presses
209
+ .onBegin((e: unknown) => {
210
+ didLongPress = false
211
+ didPressIn = false
212
+ tryClaimOwnership(e)
213
+ // Defer onPressIn until after the grace window so child pressables
214
+ // can steal ownership, but flush it on tap end for very fast taps.
215
+ schedulePressIn(e)
216
+ })
217
+ .onEnd((e: unknown) => {
218
+ if (isOwner() && !didLongPress) {
219
+ firePressIn(e)
220
+ config.onPress?.(e)
221
+ }
222
+ })
223
+ .onFinalize((e: unknown) => {
224
+ if (isOwner()) {
225
+ config.onPressOut?.(e)
226
+ releaseOwnership()
227
+ } else if (didPressIn) {
228
+ // we already fired onPressIn but lost ownership before finalize
229
+ // (e.g. finger dragged onto a sibling pressable and that one
230
+ // claimed ownership). fire onPressOut so callers can clear their
231
+ // press state — otherwise pressStyle stays stuck on this view.
232
+ didPressIn = false
233
+ config.onPressOut?.(e)
234
+ }
235
+ })
236
+
237
+ if (config.hitSlop) tap.hitSlop(config.hitSlop)
238
+
239
+ // if no long press handler, just use tap
240
+ if (!config.onLongPress) return tap
241
+
242
+ // LongPress gesture for long press handling
243
+ const longPress = Gesture.LongPress()
244
+ .runOnJS(true)
245
+ .minDuration(longPressDuration)
246
+ .onStart((e: any) => {
247
+ didLongPress = true
248
+ if (isOwner()) {
249
+ firePressIn(e)
250
+ config.onLongPress?.(e)
251
+ }
252
+ })
253
+
254
+ if (config.hitSlop) longPress.hitSlop(config.hitSlop)
255
+
256
+ // exclusive: longPress has priority, tap is fallback for quick presses
257
+ return Gesture.Exclusive(longPress, tap)
258
+ },
259
+ }
260
+ }
@@ -0,0 +1,32 @@
1
+ export function createGlobalState<T extends { enabled: boolean }>(
2
+ key: string,
3
+ defaultValue: T
4
+ ): {
5
+ get: () => T
6
+ set: (next: T) => void
7
+ } {
8
+ const GLOBAL_KEY = `__hanzogui_${key}__`
9
+
10
+ type HanzoguiGlobal = typeof globalThis & {
11
+ [GLOBAL_KEY]?: T
12
+ }
13
+
14
+ function getGlobalState(): T {
15
+ const g = globalThis as HanzoguiGlobal
16
+ if (!g[GLOBAL_KEY]) {
17
+ // reset on module load so reloadReactNative gets a clean state
18
+ // (globalThis persists across reloads but module scope re-evaluates)
19
+ g[GLOBAL_KEY] = defaultValue
20
+ }
21
+ return g[GLOBAL_KEY]!
22
+ }
23
+
24
+ function setGlobalState(newState: T): void {
25
+ ;(globalThis as HanzoguiGlobal)[GLOBAL_KEY] = newState
26
+ }
27
+
28
+ return {
29
+ get: getGlobalState,
30
+ set: setGlobalState,
31
+ }
32
+ }
package/src/index.ts ADDED
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @hanzogui/native
3
+ *
4
+ * Native setup modules for Hanzogui. Import these at the top of your app entry point.
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * // In your app entry (index.js or App.tsx)
9
+ * import '@hanzogui/native/setup-teleport'
10
+ * import '@hanzogui/native/setup-gesture-handler'
11
+ * import '@hanzogui/native/setup-worklets'
12
+ * import '@hanzogui/native/setup-safe-area'
13
+ * import '@hanzogui/native/expo-linear-gradient'
14
+ * import '@hanzogui/native/setup-keyboard-controller'
15
+ *
16
+ * // Then use Hanzogui components normally
17
+ * // Sheet will automatically use native gestures when available
18
+ * // LinearGradient will use expo-linear-gradient when installed
19
+ * ```
20
+ */
21
+
22
+ // types
23
+ export type {
24
+ NativePortalState,
25
+ GestureState,
26
+ WorkletsState,
27
+ SafeAreaState,
28
+ SafeAreaInsets,
29
+ SafeAreaFrame,
30
+ SafeAreaMetrics,
31
+ LinearGradientState,
32
+ ZeegoState,
33
+ BurntState,
34
+ NativePortalProps,
35
+ NativePortalHostProps,
36
+ NativePortalProviderProps,
37
+ } from './types'
38
+
39
+ // portal
40
+ export { getPortal } from './portalState'
41
+ export type { PortalAccessor } from './portalState'
42
+
43
+ // gesture handler
44
+ export { getGestureHandler } from './gestureState'
45
+ export {
46
+ claimExternalPressOwnership as unstable_claimExternalPressOwnership,
47
+ releaseExternalPressOwnership as unstable_releaseExternalPressOwnership,
48
+ } from './gestureState'
49
+ export type {
50
+ ExternalPressOwnershipToken,
51
+ GestureHandlerAccessor,
52
+ PressGestureConfig,
53
+ } from './gestureState'
54
+ // NOTE: setupGestureHandler is exported from setup-gesture-handler.ts entry point,
55
+ // not here, to avoid bundler pulling in RNGH require during tree-shaking
56
+ export type { GestureHandlerConfig } from './setup-gesture-handler'
57
+
58
+ // worklets
59
+ export { getWorklets } from './workletsState'
60
+ export type { WorkletsAccessor } from './workletsState'
61
+
62
+ // safe area
63
+ export { getSafeArea } from './safeAreaState'
64
+ export type { SafeAreaAccessor } from './safeAreaState'
65
+
66
+ // linear gradient
67
+ export { getLinearGradient } from './linearGradientState'
68
+ export type { LinearGradientAccessor } from './linearGradientState'
69
+
70
+ // keyboard controller state exports (safe - no side effects)
71
+ export {
72
+ isKeyboardControllerEnabled,
73
+ getKeyboardControllerState,
74
+ setKeyboardControllerState,
75
+ } from './keyboardControllerState'
76
+ export type { KeyboardControllerState } from './keyboardControllerState'
77
+
78
+ // zeego (native menus)
79
+ export { getZeego } from './zeegoState'
80
+ export type { ZeegoAccessor } from './zeegoState'
81
+ export { NativeMenuContext } from './nativeMenuContext'
82
+
83
+ // burnt (native toasts)
84
+ export { getBurnt } from './burntState'
85
+ export type { BurntAccessor } from './burntState'
86
+
87
+ // components
88
+ export { NativePortal, NativePortalHost, NativePortalProvider } from './components'
@@ -0,0 +1,29 @@
1
+ import { createGlobalState } from './globalState'
2
+ import type { KeyboardControllerState } from './types'
3
+
4
+ export type { KeyboardControllerState }
5
+
6
+ const state = createGlobalState<KeyboardControllerState>(`keyboard_controller`, {
7
+ enabled: false,
8
+ KeyboardProvider: null,
9
+ KeyboardAwareScrollView: null,
10
+ useKeyboardHandler: null,
11
+ useReanimatedKeyboardAnimation: null,
12
+ KeyboardController: null,
13
+ KeyboardEvents: null,
14
+ KeyboardStickyView: null,
15
+ })
16
+
17
+ export function isKeyboardControllerEnabled(): boolean {
18
+ return state.get().enabled
19
+ }
20
+
21
+ export function getKeyboardControllerState(): KeyboardControllerState {
22
+ return state.get()
23
+ }
24
+
25
+ export function setKeyboardControllerState(
26
+ updates: Partial<KeyboardControllerState>
27
+ ): void {
28
+ Object.assign(state.get(), updates)
29
+ }
@@ -0,0 +1,27 @@
1
+ import { createGlobalState } from './globalState'
2
+ import type { LinearGradientState } from './types'
3
+
4
+ const state = createGlobalState<LinearGradientState>(`linear_gradient`, {
5
+ enabled: false,
6
+ Component: null,
7
+ })
8
+
9
+ export interface LinearGradientAccessor {
10
+ readonly isEnabled: boolean
11
+ readonly state: LinearGradientState
12
+ set(newState: LinearGradientState): void
13
+ }
14
+
15
+ export function getLinearGradient(): LinearGradientAccessor {
16
+ return {
17
+ get isEnabled(): boolean {
18
+ return state.get().enabled
19
+ },
20
+ get state(): LinearGradientState {
21
+ return state.get()
22
+ },
23
+ set(newState: LinearGradientState): void {
24
+ state.set(newState)
25
+ },
26
+ }
27
+ }
@@ -0,0 +1,4 @@
1
+ import type React from 'react'
2
+ import { createContext } from 'react'
3
+
4
+ export const NativeMenuContext: React.Context<boolean> = createContext(false)
@@ -0,0 +1,27 @@
1
+ import { createGlobalState } from './globalState'
2
+ import type { NativePortalState } from './types'
3
+
4
+ const state = createGlobalState<NativePortalState>(`portal`, {
5
+ enabled: false,
6
+ type: null,
7
+ })
8
+
9
+ export interface PortalAccessor {
10
+ readonly isEnabled: boolean
11
+ readonly state: NativePortalState
12
+ set(newState: NativePortalState): void
13
+ }
14
+
15
+ export function getPortal(): PortalAccessor {
16
+ return {
17
+ get isEnabled(): boolean {
18
+ return state.get().enabled
19
+ },
20
+ get state(): NativePortalState {
21
+ return state.get()
22
+ },
23
+ set(newState: NativePortalState): void {
24
+ state.set(newState)
25
+ },
26
+ }
27
+ }