react-native-gtkx 0.2.0-alpha.2 → 0.3.0-alpha.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 (340) hide show
  1. package/README.md +5 -2
  2. package/dist/aliases/index.d.ts +84 -0
  3. package/dist/aliases/index.js +208 -0
  4. package/dist/aliases/index.js.map +1 -0
  5. package/dist/animated/index.d.ts +2 -0
  6. package/dist/animated/index.js +5 -0
  7. package/dist/animated/index.js.map +1 -1
  8. package/dist/animated/types.d.ts +1 -0
  9. package/dist/animated/types.js.map +1 -1
  10. package/dist/animated/value-animation.js +17 -4
  11. package/dist/animated/value-animation.js.map +1 -1
  12. package/dist/apis/host.gtkx.js +9 -12
  13. package/dist/apis/host.gtkx.js.map +1 -1
  14. package/dist/apis/index.d.ts +4 -2
  15. package/dist/apis/index.js +2 -0
  16. package/dist/apis/index.js.map +1 -1
  17. package/dist/apis/keyboard.d.ts +60 -0
  18. package/dist/apis/keyboard.js +63 -0
  19. package/dist/apis/keyboard.js.map +1 -0
  20. package/dist/apis/log-box.d.ts +15 -0
  21. package/dist/apis/log-box.js +46 -0
  22. package/dist/apis/log-box.js.map +1 -0
  23. package/dist/apis/platform.d.ts +18 -1
  24. package/dist/apis/platform.js.map +1 -1
  25. package/dist/common/index.d.ts +0 -1
  26. package/dist/common/index.js +24 -1
  27. package/dist/common/index.js.map +1 -1
  28. package/dist/components/animated.d.ts +70 -6
  29. package/dist/components/animated.js +559 -46
  30. package/dist/components/animated.js.map +1 -1
  31. package/dist/components/driven-size.d.ts +27 -0
  32. package/dist/components/driven-size.js +85 -0
  33. package/dist/components/driven-size.js.map +1 -0
  34. package/dist/components/find-node-handle.d.ts +11 -0
  35. package/dist/components/find-node-handle.js +53 -0
  36. package/dist/components/find-node-handle.js.map +1 -0
  37. package/dist/components/flat-list.d.ts +3 -2
  38. package/dist/components/flat-list.js.map +1 -1
  39. package/dist/components/frame-scheduler.d.ts +16 -0
  40. package/dist/components/frame-scheduler.js +37 -0
  41. package/dist/components/frame-scheduler.js.map +1 -0
  42. package/dist/components/image.d.ts +6 -1
  43. package/dist/components/image.js +15 -4
  44. package/dist/components/image.js.map +1 -1
  45. package/dist/components/index.d.ts +7 -5
  46. package/dist/components/index.js +5 -3
  47. package/dist/components/index.js.map +1 -1
  48. package/dist/components/measure.d.ts +51 -1
  49. package/dist/components/measure.js +101 -2
  50. package/dist/components/measure.js.map +1 -1
  51. package/dist/components/pressable.d.ts +61 -1
  52. package/dist/components/pressable.js +151 -4
  53. package/dist/components/pressable.js.map +1 -1
  54. package/dist/components/rect-store.d.ts +58 -0
  55. package/dist/components/rect-store.js +124 -3
  56. package/dist/components/rect-store.js.map +1 -1
  57. package/dist/components/root.js +6 -1
  58. package/dist/components/root.js.map +1 -1
  59. package/dist/components/scroll-phase.d.ts +35 -0
  60. package/dist/components/scroll-phase.js +26 -0
  61. package/dist/components/scroll-phase.js.map +1 -0
  62. package/dist/components/scroll-view.d.ts +39 -3
  63. package/dist/components/scroll-view.js +378 -43
  64. package/dist/components/scroll-view.js.map +1 -1
  65. package/dist/components/text-input.js +9 -25
  66. package/dist/components/text-input.js.map +1 -1
  67. package/dist/components/text.d.ts +6 -2
  68. package/dist/components/text.js +43 -8
  69. package/dist/components/text.js.map +1 -1
  70. package/dist/components/use-focus.d.ts +27 -0
  71. package/dist/components/use-focus.js +116 -0
  72. package/dist/components/use-focus.js.map +1 -0
  73. package/dist/components/use-layout-child.d.ts +13 -1
  74. package/dist/components/use-layout-child.js +188 -5
  75. package/dist/components/use-layout-child.js.map +1 -1
  76. package/dist/components/view.d.ts +5 -2
  77. package/dist/components/view.js +18 -13
  78. package/dist/components/view.js.map +1 -1
  79. package/dist/components/virtualized-list.d.ts +45 -5
  80. package/dist/components/virtualized-list.js +90 -24
  81. package/dist/components/virtualized-list.js.map +1 -1
  82. package/dist/components/wheel-scroll-session.d.ts +7 -0
  83. package/dist/components/wheel-scroll-session.js +53 -0
  84. package/dist/components/wheel-scroll-session.js.map +1 -0
  85. package/dist/components/widget-retention.d.ts +35 -0
  86. package/dist/components/widget-retention.js +169 -0
  87. package/dist/components/widget-retention.js.map +1 -0
  88. package/dist/contracts.d.ts +4 -0
  89. package/dist/contracts.js.map +1 -1
  90. package/dist/dnd/context.d.ts +69 -0
  91. package/dist/dnd/context.js +149 -0
  92. package/dist/dnd/context.js.map +1 -0
  93. package/dist/dnd/draggable.d.ts +59 -0
  94. package/dist/dnd/draggable.js +149 -0
  95. package/dist/dnd/draggable.js.map +1 -0
  96. package/dist/dnd/droppable.d.ts +24 -0
  97. package/dist/dnd/droppable.js +74 -0
  98. package/dist/dnd/droppable.js.map +1 -0
  99. package/dist/dnd/gtk-controllers.d.ts +39 -0
  100. package/dist/dnd/gtk-controllers.js +110 -0
  101. package/dist/dnd/gtk-controllers.js.map +1 -0
  102. package/dist/dnd/index.d.ts +6 -0
  103. package/dist/dnd/index.js +31 -0
  104. package/dist/dnd/index.js.map +1 -0
  105. package/dist/dnd/order.d.ts +7 -0
  106. package/dist/dnd/order.js +20 -0
  107. package/dist/dnd/order.js.map +1 -0
  108. package/dist/dnd/payload.d.ts +14 -0
  109. package/dist/dnd/payload.js +41 -0
  110. package/dist/dnd/payload.js.map +1 -0
  111. package/dist/dnd/sortable.d.ts +49 -0
  112. package/dist/dnd/sortable.js +307 -0
  113. package/dist/dnd/sortable.js.map +1 -0
  114. package/dist/dnd/types.d.ts +290 -0
  115. package/dist/dnd/types.js +25 -0
  116. package/dist/dnd/types.js.map +1 -0
  117. package/dist/gesture-handler-compat/builder.d.ts +251 -0
  118. package/dist/gesture-handler-compat/builder.js +513 -0
  119. package/dist/gesture-handler-compat/builder.js.map +1 -0
  120. package/dist/gesture-handler-compat/composition.d.ts +23 -0
  121. package/dist/gesture-handler-compat/composition.js +111 -0
  122. package/dist/gesture-handler-compat/composition.js.map +1 -0
  123. package/dist/gesture-handler-compat/deciders.d.ts +3 -0
  124. package/dist/gesture-handler-compat/deciders.js +47 -0
  125. package/dist/gesture-handler-compat/deciders.js.map +1 -0
  126. package/dist/gesture-handler-compat/detector-runtime.d.ts +44 -0
  127. package/dist/gesture-handler-compat/detector-runtime.js +374 -0
  128. package/dist/gesture-handler-compat/detector-runtime.js.map +1 -0
  129. package/dist/gesture-handler-compat/detector.d.ts +22 -0
  130. package/dist/gesture-handler-compat/detector.js +104 -0
  131. package/dist/gesture-handler-compat/detector.js.map +1 -0
  132. package/dist/gesture-handler-compat/fling.d.ts +24 -0
  133. package/dist/gesture-handler-compat/fling.js +123 -0
  134. package/dist/gesture-handler-compat/fling.js.map +1 -0
  135. package/dist/gesture-handler-compat/force-touch.d.ts +13 -0
  136. package/dist/gesture-handler-compat/force-touch.js +40 -0
  137. package/dist/gesture-handler-compat/force-touch.js.map +1 -0
  138. package/dist/gesture-handler-compat/hooks.d.ts +157 -0
  139. package/dist/gesture-handler-compat/hooks.js +268 -0
  140. package/dist/gesture-handler-compat/hooks.js.map +1 -0
  141. package/dist/gesture-handler-compat/hover.d.ts +2 -0
  142. package/dist/gesture-handler-compat/hover.js +22 -0
  143. package/dist/gesture-handler-compat/hover.js.map +1 -0
  144. package/dist/gesture-handler-compat/index.d.ts +98 -0
  145. package/dist/gesture-handler-compat/index.js +255 -0
  146. package/dist/gesture-handler-compat/index.js.map +1 -0
  147. package/dist/gesture-handler-compat/long-press.d.ts +6 -0
  148. package/dist/gesture-handler-compat/long-press.js +21 -0
  149. package/dist/gesture-handler-compat/long-press.js.map +1 -0
  150. package/dist/gesture-handler-compat/manual.d.ts +2 -0
  151. package/dist/gesture-handler-compat/manual.js +18 -0
  152. package/dist/gesture-handler-compat/manual.js.map +1 -0
  153. package/dist/gesture-handler-compat/native.d.ts +7 -0
  154. package/dist/gesture-handler-compat/native.js +34 -0
  155. package/dist/gesture-handler-compat/native.js.map +1 -0
  156. package/dist/gesture-handler-compat/orchestrator.d.ts +77 -0
  157. package/dist/gesture-handler-compat/orchestrator.js +284 -0
  158. package/dist/gesture-handler-compat/orchestrator.js.map +1 -0
  159. package/dist/gesture-handler-compat/pan.d.ts +23 -0
  160. package/dist/gesture-handler-compat/pan.js +116 -0
  161. package/dist/gesture-handler-compat/pan.js.map +1 -0
  162. package/dist/gesture-handler-compat/recognizer.d.ts +268 -0
  163. package/dist/gesture-handler-compat/recognizer.js +1056 -0
  164. package/dist/gesture-handler-compat/recognizer.js.map +1 -0
  165. package/dist/gesture-handler-compat/relations.d.ts +43 -0
  166. package/dist/gesture-handler-compat/relations.js +128 -0
  167. package/dist/gesture-handler-compat/relations.js.map +1 -0
  168. package/dist/gesture-handler-compat/tap.d.ts +6 -0
  169. package/dist/gesture-handler-compat/tap.js +29 -0
  170. package/dist/gesture-handler-compat/tap.js.map +1 -0
  171. package/dist/gesture-handler-compat/touchpad.d.ts +41 -0
  172. package/dist/gesture-handler-compat/touchpad.js +64 -0
  173. package/dist/gesture-handler-compat/touchpad.js.map +1 -0
  174. package/dist/gesture-handler-compat/types.d.ts +441 -0
  175. package/dist/gesture-handler-compat/types.js +167 -0
  176. package/dist/gesture-handler-compat/types.js.map +1 -0
  177. package/dist/gtk/controllers.d.ts +39 -0
  178. package/dist/gtk/controllers.js +92 -0
  179. package/dist/gtk/controllers.js.map +1 -0
  180. package/dist/gtk/index.d.ts +2 -1
  181. package/dist/gtk/index.js +7 -1
  182. package/dist/gtk/index.js.map +1 -1
  183. package/dist/gtkx/bridge/geometry.js +6 -4
  184. package/dist/gtkx/bridge/geometry.js.map +1 -1
  185. package/dist/gtkx/bridge/index.d.ts +5 -3
  186. package/dist/gtkx/bridge/index.js +6 -3
  187. package/dist/gtkx/bridge/index.js.map +1 -1
  188. package/dist/gtkx/bridge/slot-portal.js.map +1 -1
  189. package/dist/gtkx/bridge/use-signal.js +1 -1
  190. package/dist/gtkx/bridge/use-signal.js.map +1 -1
  191. package/dist/gtkx/bridge/view-box.d.ts +56 -0
  192. package/dist/gtkx/bridge/view-box.js +394 -9
  193. package/dist/gtkx/bridge/view-box.js.map +1 -1
  194. package/dist/gtkx/bridge/widget-css.d.ts +17 -0
  195. package/dist/gtkx/bridge/widget-css.js +72 -0
  196. package/dist/gtkx/bridge/widget-css.js.map +1 -0
  197. package/dist/index.d.ts +3 -3
  198. package/dist/index.js +2 -2
  199. package/dist/index.js.map +1 -1
  200. package/dist/layout/driven-size.d.ts +12 -0
  201. package/dist/layout/driven-size.js +70 -0
  202. package/dist/layout/driven-size.js.map +1 -0
  203. package/dist/layout/engine.d.ts +17 -1
  204. package/dist/layout/engine.js +3 -20
  205. package/dist/layout/engine.js.map +1 -1
  206. package/dist/layout/node.d.ts +13 -0
  207. package/dist/layout/node.js +14 -0
  208. package/dist/layout/node.js.map +1 -1
  209. package/dist/layout/yoga.d.ts +3 -2
  210. package/dist/layout/yoga.js +5 -2
  211. package/dist/layout/yoga.js.map +1 -1
  212. package/dist/mcp/data/generated.d.ts +257 -60
  213. package/dist/mcp/data/generated.js +306 -62
  214. package/dist/mcp/data/generated.js.map +1 -1
  215. package/dist/metro/index.d.ts +10 -0
  216. package/dist/metro/index.js +21 -12
  217. package/dist/metro/index.js.map +1 -1
  218. package/dist/navigation/sidebar.d.ts +16 -0
  219. package/dist/navigation/sidebar.js +65 -1
  220. package/dist/navigation/sidebar.js.map +1 -1
  221. package/dist/reanimated-compat/animated-ref.d.ts +32 -0
  222. package/dist/reanimated-compat/animated-ref.js +57 -0
  223. package/dist/reanimated-compat/animated-ref.js.map +1 -0
  224. package/dist/reanimated-compat/animation.d.ts +177 -0
  225. package/dist/reanimated-compat/animation.js +540 -0
  226. package/dist/reanimated-compat/animation.js.map +1 -0
  227. package/dist/reanimated-compat/color.d.ts +28 -0
  228. package/dist/reanimated-compat/color.js +249 -0
  229. package/dist/reanimated-compat/color.js.map +1 -0
  230. package/dist/reanimated-compat/decay.d.ts +39 -0
  231. package/dist/reanimated-compat/decay.js +96 -0
  232. package/dist/reanimated-compat/decay.js.map +1 -0
  233. package/dist/reanimated-compat/easing.d.ts +30 -0
  234. package/dist/reanimated-compat/easing.js +76 -0
  235. package/dist/reanimated-compat/easing.js.map +1 -0
  236. package/dist/reanimated-compat/hooks.d.ts +14 -0
  237. package/dist/reanimated-compat/hooks.js +217 -0
  238. package/dist/reanimated-compat/hooks.js.map +1 -0
  239. package/dist/reanimated-compat/index.d.ts +258 -0
  240. package/dist/reanimated-compat/index.js +464 -0
  241. package/dist/reanimated-compat/index.js.map +1 -0
  242. package/dist/reanimated-compat/interpolation.d.ts +18 -0
  243. package/dist/reanimated-compat/interpolation.js +122 -0
  244. package/dist/reanimated-compat/interpolation.js.map +1 -0
  245. package/dist/reanimated-compat/layout-animation-config.d.ts +43 -0
  246. package/dist/reanimated-compat/layout-animation-config.js +78 -0
  247. package/dist/reanimated-compat/layout-animation-config.js.map +1 -0
  248. package/dist/reanimated-compat/layout-animation-presets.d.ts +117 -0
  249. package/dist/reanimated-compat/layout-animation-presets.js +498 -0
  250. package/dist/reanimated-compat/layout-animation-presets.js.map +1 -0
  251. package/dist/reanimated-compat/layout-animation-runtime.d.ts +21 -0
  252. package/dist/reanimated-compat/layout-animation-runtime.js +311 -0
  253. package/dist/reanimated-compat/layout-animation-runtime.js.map +1 -0
  254. package/dist/reanimated-compat/layout-animation-view.d.ts +27 -0
  255. package/dist/reanimated-compat/layout-animation-view.js +266 -0
  256. package/dist/reanimated-compat/layout-animation-view.js.map +1 -0
  257. package/dist/reanimated-compat/layout-animation.d.ts +171 -0
  258. package/dist/reanimated-compat/layout-animation.js +469 -0
  259. package/dist/reanimated-compat/layout-animation.js.map +1 -0
  260. package/dist/reanimated-compat/layout-transitions.d.ts +83 -0
  261. package/dist/reanimated-compat/layout-transitions.js +350 -0
  262. package/dist/reanimated-compat/layout-transitions.js.map +1 -0
  263. package/dist/reanimated-compat/mutable.d.ts +29 -0
  264. package/dist/reanimated-compat/mutable.js +139 -0
  265. package/dist/reanimated-compat/mutable.js.map +1 -0
  266. package/dist/reanimated-compat/props.d.ts +18 -0
  267. package/dist/reanimated-compat/props.js +111 -0
  268. package/dist/reanimated-compat/props.js.map +1 -0
  269. package/dist/reanimated-compat/scroll-handler.d.ts +119 -0
  270. package/dist/reanimated-compat/scroll-handler.js +274 -0
  271. package/dist/reanimated-compat/scroll-handler.js.map +1 -0
  272. package/dist/reanimated-compat/scroll-offset.d.ts +12 -0
  273. package/dist/reanimated-compat/scroll-offset.js +104 -0
  274. package/dist/reanimated-compat/scroll-offset.js.map +1 -0
  275. package/dist/reanimated-compat/style.d.ts +90 -0
  276. package/dist/reanimated-compat/style.js +452 -0
  277. package/dist/reanimated-compat/style.js.map +1 -0
  278. package/dist/reanimated-compat/test-timers.d.ts +28 -0
  279. package/dist/reanimated-compat/test-timers.js +136 -0
  280. package/dist/reanimated-compat/test-timers.js.map +1 -0
  281. package/dist/reanimated-compat/threads.d.ts +13 -0
  282. package/dist/reanimated-compat/threads.js +41 -0
  283. package/dist/reanimated-compat/threads.js.map +1 -0
  284. package/dist/reanimated-compat/tracking.d.ts +41 -0
  285. package/dist/reanimated-compat/tracking.js +106 -0
  286. package/dist/reanimated-compat/tracking.js.map +1 -0
  287. package/dist/reanimated-compat/updater-animations.d.ts +36 -0
  288. package/dist/reanimated-compat/updater-animations.js +273 -0
  289. package/dist/reanimated-compat/updater-animations.js.map +1 -0
  290. package/dist/responder/system.d.ts +80 -7
  291. package/dist/responder/system.js +143 -23
  292. package/dist/responder/system.js.map +1 -1
  293. package/dist/responder/use-responder.d.ts +11 -0
  294. package/dist/responder/use-responder.js +225 -6
  295. package/dist/responder/use-responder.js.map +1 -1
  296. package/dist/runner/host-dev.js +1 -1
  297. package/dist/runner/host-dev.js.map +1 -1
  298. package/dist/runner/host.js +1 -1
  299. package/dist/runner/host.js.map +1 -1
  300. package/dist/runner/index.js +3 -3
  301. package/dist/runner/index.js.map +1 -1
  302. package/dist/sea/gtkx-config-module.js +1 -1
  303. package/dist/sea/gtkx-config-module.js.map +1 -1
  304. package/dist/style/absolute-insets.d.ts +26 -0
  305. package/dist/style/absolute-insets.js +113 -0
  306. package/dist/style/absolute-insets.js.map +1 -0
  307. package/dist/style/animated-size.d.ts +25 -0
  308. package/dist/style/animated-size.js +225 -0
  309. package/dist/style/animated-size.js.map +1 -0
  310. package/dist/style/colors.d.ts +17 -0
  311. package/dist/style/colors.js +25 -6
  312. package/dist/style/colors.js.map +1 -1
  313. package/dist/style/imperative-css.d.ts +21 -0
  314. package/dist/style/imperative-css.js +63 -0
  315. package/dist/style/imperative-css.js.map +1 -0
  316. package/dist/style/index.d.ts +2 -1
  317. package/dist/style/index.js +2 -1
  318. package/dist/style/index.js.map +1 -1
  319. package/dist/style/split-style.js +5 -0
  320. package/dist/style/split-style.js.map +1 -1
  321. package/dist/testing/index.js.map +1 -1
  322. package/dist/unsupported-export.d.ts +8 -0
  323. package/dist/unsupported-export.js +66 -0
  324. package/dist/unsupported-export.js.map +1 -0
  325. package/dist/vite/index.d.ts +21 -8
  326. package/dist/vite/index.js +127 -82
  327. package/dist/vite/index.js.map +1 -1
  328. package/dist/vitest/index.d.ts +2 -2
  329. package/dist/vitest/index.js.map +1 -1
  330. package/dist/worklets-compat/index.d.ts +4 -0
  331. package/dist/worklets-compat/index.js +28 -0
  332. package/dist/worklets-compat/index.js.map +1 -0
  333. package/dist/worklets-compat/surface.d.ts +110 -0
  334. package/dist/worklets-compat/surface.js +153 -0
  335. package/dist/worklets-compat/surface.js.map +1 -0
  336. package/package.json +25 -9
  337. package/types.d.ts +9 -0
  338. package/dist/common/list.d.ts +0 -82
  339. package/dist/common/list.js +0 -166
  340. package/dist/common/list.js.map +0 -1
@@ -1,17 +1,19 @@
1
1
  export { ActivityIndicator, type ActivityIndicatorProps, } from "./activity-indicator";
2
- export { Animated, Easing, type AnimatedViewProps, type AnimatedViewStyle, } from "./animated";
2
+ export { Animated, createAnimatedComponent, Easing, type AnimatedComponent, type AnimatedComponentExtraProps, type AnimatedPropsProp, type AnimatedStyleProp, type AnimatedViewProps, type AnimatedViewStyle, } from "./animated";
3
3
  export { AppRegistry, type RunApplicationParams } from "./app-registry";
4
+ export { findNodeHandle } from "./find-node-handle";
4
5
  export { FlatList, SectionList, type FlatListProps, type ListRenderItemInfo, type SectionListData, type SectionListProps, type ViewabilityConfig, type ViewToken, } from "./flat-list";
5
- export { Image, type ImageProps, type ImageSource } from "./image";
6
+ export { Image, type ImageHandle, type ImageProps, type ImageSource, } from "./image";
6
7
  export { Modal, type ModalProps } from "./modal";
7
- export { Pressable, TouchableOpacity, type NativeTouch, type PressableProps, type PressableStateCallbackType, type PressEvent, type TouchableOpacityProps, } from "./pressable";
8
+ export { Pressable, TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback, type NativeTouch, type PressableProps, type PressableStateCallbackType, type PressEvent, type TouchableHighlightProps, type TouchableOpacityProps, type TouchableWithoutFeedbackProps, } from "./pressable";
8
9
  export { IntrinsicRoot, NestedRoot, Root, type IntrinsicRootProps, type NestedRootProps, type RootProps, } from "./root";
9
10
  export { ScrollView, type ScrollEvent, type ScrollViewHandle, type ScrollViewProps, } from "./scroll-view";
10
11
  export { Switch, type SwitchProps } from "./switch";
11
- export { Text, type TextProps } from "./text";
12
+ export { Text, type TextHandle, type TextProps } from "./text";
12
13
  export { TextInput, type TextInputProps } from "./text-input";
13
14
  export { SafeAreaView, StatusBar, View, type ViewHandle, type ViewProps, } from "./view";
14
- export type { MeasureHandle, MeasureInWindowOnSuccessCallback, MeasureLayoutOnSuccessCallback, MeasureOnSuccessCallback, } from "./measure";
15
+ export type { MeasureHandle, MeasureInWindowOnSuccessCallback, MeasureLayoutOnSuccessCallback, MeasureOnSuccessCallback, NodeHandle, } from "./measure";
16
+ export { VirtualizedList, type ItemLayout, type VirtualizedListHandle, type VirtualizedListProps, } from "./virtualized-list";
15
17
  export { type LayoutEvent } from "./use-layout-child";
16
18
  export { default as PanResponder } from "../vendor/react-native/pan-responder";
17
19
  export type { PanResponderCallbacks, PanResponderGestureState, PanResponderInstance, } from "../vendor/react-native/pan-responder";
@@ -1,15 +1,17 @@
1
1
  export { ActivityIndicator, } from "./activity-indicator";
2
- export { Animated, Easing, } from "./animated";
2
+ export { Animated, createAnimatedComponent, Easing, } from "./animated";
3
3
  export { AppRegistry } from "./app-registry";
4
+ export { findNodeHandle } from "./find-node-handle";
4
5
  export { FlatList, SectionList, } from "./flat-list";
5
- export { Image } from "./image";
6
+ export { Image, } from "./image";
6
7
  export { Modal } from "./modal";
7
- export { Pressable, TouchableOpacity, } from "./pressable";
8
+ export { Pressable, TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback, } from "./pressable";
8
9
  export { IntrinsicRoot, NestedRoot, Root, } from "./root";
9
10
  export { ScrollView, } from "./scroll-view";
10
11
  export { Switch } from "./switch";
11
12
  export { Text } from "./text";
12
13
  export { TextInput } from "./text-input";
13
14
  export { SafeAreaView, StatusBar, View, } from "./view";
15
+ export { VirtualizedList, } from "./virtualized-list";
14
16
  export { default as PanResponder } from "../vendor/react-native/pan-responder";
15
17
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,GAElB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,QAAQ,EACR,MAAM,GAGP,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,WAAW,EAA6B,MAAM,gBAAgB,CAAA;AACvE,OAAO,EACL,QAAQ,EACR,WAAW,GAOZ,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,KAAK,EAAqC,MAAM,SAAS,CAAA;AAClE,OAAO,EAAE,KAAK,EAAmB,MAAM,SAAS,CAAA;AAChD,OAAO,EACL,SAAS,EACT,gBAAgB,GAMjB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,aAAa,EACb,UAAU,EACV,IAAI,GAIL,MAAM,QAAQ,CAAA;AACf,OAAO,EACL,UAAU,GAIX,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,MAAM,EAAoB,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,IAAI,EAAkB,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAuB,MAAM,cAAc,CAAA;AAC7D,OAAO,EACL,YAAY,EACZ,SAAS,EACT,IAAI,GAGL,MAAM,QAAQ,CAAA;AAQf,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,sCAAsC,CAAA","sourcesContent":["export {\n ActivityIndicator,\n type ActivityIndicatorProps,\n} from \"./activity-indicator\"\nexport {\n Animated,\n Easing,\n type AnimatedViewProps,\n type AnimatedViewStyle,\n} from \"./animated\"\nexport { AppRegistry, type RunApplicationParams } from \"./app-registry\"\nexport {\n FlatList,\n SectionList,\n type FlatListProps,\n type ListRenderItemInfo,\n type SectionListData,\n type SectionListProps,\n type ViewabilityConfig,\n type ViewToken,\n} from \"./flat-list\"\nexport { Image, type ImageProps, type ImageSource } from \"./image\"\nexport { Modal, type ModalProps } from \"./modal\"\nexport {\n Pressable,\n TouchableOpacity,\n type NativeTouch,\n type PressableProps,\n type PressableStateCallbackType,\n type PressEvent,\n type TouchableOpacityProps,\n} from \"./pressable\"\nexport {\n IntrinsicRoot,\n NestedRoot,\n Root,\n type IntrinsicRootProps,\n type NestedRootProps,\n type RootProps,\n} from \"./root\"\nexport {\n ScrollView,\n type ScrollEvent,\n type ScrollViewHandle,\n type ScrollViewProps,\n} from \"./scroll-view\"\nexport { Switch, type SwitchProps } from \"./switch\"\nexport { Text, type TextProps } from \"./text\"\nexport { TextInput, type TextInputProps } from \"./text-input\"\nexport {\n SafeAreaView,\n StatusBar,\n View,\n type ViewHandle,\n type ViewProps,\n} from \"./view\"\nexport type {\n MeasureHandle,\n MeasureInWindowOnSuccessCallback,\n MeasureLayoutOnSuccessCallback,\n MeasureOnSuccessCallback,\n} from \"./measure\"\nexport { type LayoutEvent } from \"./use-layout-child\"\nexport { default as PanResponder } from \"../vendor/react-native/pan-responder\"\nexport type {\n PanResponderCallbacks,\n PanResponderGestureState,\n PanResponderInstance,\n} from \"../vendor/react-native/pan-responder\"\nexport type {\n GestureResponderEvent,\n ResponderProps,\n TouchHistory,\n TouchRecord,\n} from \"../responder/types\"\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,GAElB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,QAAQ,EACR,uBAAuB,EACvB,MAAM,GAOP,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,WAAW,EAA6B,MAAM,gBAAgB,CAAA;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EACL,QAAQ,EACR,WAAW,GAOZ,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,KAAK,GAIN,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,KAAK,EAAmB,MAAM,SAAS,CAAA;AAChD,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,gBAAgB,EAChB,wBAAwB,GAQzB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,aAAa,EACb,UAAU,EACV,IAAI,GAIL,MAAM,QAAQ,CAAA;AACf,OAAO,EACL,UAAU,GAIX,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,MAAM,EAAoB,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,IAAI,EAAmC,MAAM,QAAQ,CAAA;AAC9D,OAAO,EAAE,SAAS,EAAuB,MAAM,cAAc,CAAA;AAC7D,OAAO,EACL,YAAY,EACZ,SAAS,EACT,IAAI,GAGL,MAAM,QAAQ,CAAA;AAQf,OAAO,EACL,eAAe,GAIhB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,sCAAsC,CAAA","sourcesContent":["export {\n ActivityIndicator,\n type ActivityIndicatorProps,\n} from \"./activity-indicator\"\nexport {\n Animated,\n createAnimatedComponent,\n Easing,\n type AnimatedComponent,\n type AnimatedComponentExtraProps,\n type AnimatedPropsProp,\n type AnimatedStyleProp,\n type AnimatedViewProps,\n type AnimatedViewStyle,\n} from \"./animated\"\nexport { AppRegistry, type RunApplicationParams } from \"./app-registry\"\nexport { findNodeHandle } from \"./find-node-handle\"\nexport {\n FlatList,\n SectionList,\n type FlatListProps,\n type ListRenderItemInfo,\n type SectionListData,\n type SectionListProps,\n type ViewabilityConfig,\n type ViewToken,\n} from \"./flat-list\"\nexport {\n Image,\n type ImageHandle,\n type ImageProps,\n type ImageSource,\n} from \"./image\"\nexport { Modal, type ModalProps } from \"./modal\"\nexport {\n Pressable,\n TouchableHighlight,\n TouchableOpacity,\n TouchableWithoutFeedback,\n type NativeTouch,\n type PressableProps,\n type PressableStateCallbackType,\n type PressEvent,\n type TouchableHighlightProps,\n type TouchableOpacityProps,\n type TouchableWithoutFeedbackProps,\n} from \"./pressable\"\nexport {\n IntrinsicRoot,\n NestedRoot,\n Root,\n type IntrinsicRootProps,\n type NestedRootProps,\n type RootProps,\n} from \"./root\"\nexport {\n ScrollView,\n type ScrollEvent,\n type ScrollViewHandle,\n type ScrollViewProps,\n} from \"./scroll-view\"\nexport { Switch, type SwitchProps } from \"./switch\"\nexport { Text, type TextHandle, type TextProps } from \"./text\"\nexport { TextInput, type TextInputProps } from \"./text-input\"\nexport {\n SafeAreaView,\n StatusBar,\n View,\n type ViewHandle,\n type ViewProps,\n} from \"./view\"\nexport type {\n MeasureHandle,\n MeasureInWindowOnSuccessCallback,\n MeasureLayoutOnSuccessCallback,\n MeasureOnSuccessCallback,\n NodeHandle,\n} from \"./measure\"\nexport {\n VirtualizedList,\n type ItemLayout,\n type VirtualizedListHandle,\n type VirtualizedListProps,\n} from \"./virtualized-list\"\nexport { type LayoutEvent } from \"./use-layout-child\"\nexport { default as PanResponder } from \"../vendor/react-native/pan-responder\"\nexport type {\n PanResponderCallbacks,\n PanResponderGestureState,\n PanResponderInstance,\n} from \"../vendor/react-native/pan-responder\"\nexport type {\n GestureResponderEvent,\n ResponderProps,\n TouchHistory,\n TouchRecord,\n} from \"../responder/types\"\n"]}
@@ -4,10 +4,60 @@ import { type Gtk } from "../gtkx/bridge/index";
4
4
  export type MeasureOnSuccessCallback = (x: number, y: number, width: number, height: number, pageX: number, pageY: number) => void;
5
5
  export type MeasureInWindowOnSuccessCallback = (x: number, y: number, width: number, height: number) => void;
6
6
  export type MeasureLayoutOnSuccessCallback = (left: number, top: number, width: number, height: number) => void;
7
+ /**
8
+ * RN's opaque reference to a mounted host view — what `findNodeHandle`
9
+ * returns and what `measureLayout` accepts as its first argument. A number,
10
+ * as it is on every RN platform: the value crosses no boundary here, but the
11
+ * libraries that ask for one compare it, store it in a map and hand it back,
12
+ * and an object would only be a different type wearing the same name.
13
+ */
14
+ export type NodeHandle = number;
7
15
  /** The measurement half of a component ref, matching RN's method set. */
8
16
  export type MeasureHandle = {
9
17
  measure(callback: MeasureOnSuccessCallback): void;
10
18
  measureInWindow(callback: MeasureInWindowOnSuccessCallback): void;
11
- measureLayout(relativeTo: MeasureHandle, onSuccess: MeasureLayoutOnSuccessCallback, onFail?: () => void): void;
19
+ measureLayout(relativeTo: MeasureHandle | NodeHandle, onSuccess: MeasureLayoutOnSuccessCallback, onFail?: () => void): void;
12
20
  };
21
+ /**
22
+ * @internal Registers `handle` as standing for `widgetRef`'s widget.
23
+ *
24
+ * `createMeasureHandle` does this for the handles it builds; components that
25
+ * COMPOSE one into a larger handle (ScrollView adds `scrollTo`/`scrollToEnd`)
26
+ * create a new object, which is a new identity and therefore needs its own
27
+ * entry — otherwise `measureLayout(scrollViewRef, …)` silently fails.
28
+ */
29
+ export declare const registerHandleWidget: (handle: object, widgetRef: RefObject<Gtk.Widget | null>) => void;
30
+ /**
31
+ * @internal The `Gtk.Widget` behind a component handle, or null when the
32
+ * value is not a handle at all (a component that forwards no ref, or one
33
+ * whose ref is something else entirely).
34
+ *
35
+ * Deliberately not exported from the package: a portable API does not hand
36
+ * out widgets. This is how `createAnimatedComponent` reaches the widget it
37
+ * has to write opacity and transforms to.
38
+ */
39
+ export declare const widgetForHandle: (handle: unknown) => Gtk.Widget | null;
40
+ /**
41
+ * @internal Registers `handle` as standing for whatever widget `other`
42
+ * stands for.
43
+ *
44
+ * For a COMPOSITE that renders a host component and wants to be reachable as
45
+ * that host: a windowed list owns no widget of its own, but the ScrollView it
46
+ * renders is the thing another view measures against and the thing
47
+ * `findNodeHandle` should answer with. RN resolves a `FlatList`'s node handle
48
+ * through to its inner scroll view for the same reason.
49
+ *
50
+ * It deliberately does NOT give the composite `measure()`/`measureInWindow()`
51
+ * — see the note on `VirtualizedListHandle`. Being measurable AGAINST is a
52
+ * weaker claim than reporting your own geometry.
53
+ */
54
+ export declare const registerHandleAlias: (handle: object, other: () => unknown) => void;
55
+ /**
56
+ * @internal The tag standing for the widget behind `handle`, minted on first
57
+ * ask. Null when the value is not a component handle, or when its widget is
58
+ * not mounted — RN returns null in both cases too.
59
+ */
60
+ export declare const nodeHandleFor: (handle: unknown) => NodeHandle | null;
61
+ /** @internal The widget a tag was minted for, or null once it is gone. */
62
+ export declare const widgetForNodeHandle: (tag: NodeHandle) => Gtk.Widget | null;
13
63
  export declare const createMeasureHandle: (widgetRef: RefObject<Gtk.Widget | null>, node: LayoutNodeApi) => MeasureHandle;
@@ -2,7 +2,106 @@ import { computePointIn, computePointInWindow, } from "../gtkx/bridge/index";
2
2
  // measureLayout needs the OTHER view's widget, and the public handle type
3
3
  // deliberately does not carry one — a portable API should not hand out a
4
4
  // Gtk.Widget. The lookup lives here instead, keyed by the handle identity.
5
+ //
6
+ // It is also the seam every animated component reaches through: driving
7
+ // `opacity` and `transform` imperatively needs the widget behind a ref, and
8
+ // this map already holds exactly that association for every component that
9
+ // exposes a handle. Widening it beats adding a second, parallel registry.
5
10
  const widgetOf = new WeakMap();
11
+ /**
12
+ * @internal Registers `handle` as standing for `widgetRef`'s widget.
13
+ *
14
+ * `createMeasureHandle` does this for the handles it builds; components that
15
+ * COMPOSE one into a larger handle (ScrollView adds `scrollTo`/`scrollToEnd`)
16
+ * create a new object, which is a new identity and therefore needs its own
17
+ * entry — otherwise `measureLayout(scrollViewRef, …)` silently fails.
18
+ */
19
+ export const registerHandleWidget = (handle, widgetRef) => {
20
+ widgetOf.set(handle, () => widgetRef.current);
21
+ };
22
+ /**
23
+ * @internal The `Gtk.Widget` behind a component handle, or null when the
24
+ * value is not a handle at all (a component that forwards no ref, or one
25
+ * whose ref is something else entirely).
26
+ *
27
+ * Deliberately not exported from the package: a portable API does not hand
28
+ * out widgets. This is how `createAnimatedComponent` reaches the widget it
29
+ * has to write opacity and transforms to.
30
+ */
31
+ export const widgetForHandle = (handle) => {
32
+ if (handle === null || typeof handle !== "object") {
33
+ return null;
34
+ }
35
+ return widgetOf.get(handle)?.() ?? null;
36
+ };
37
+ // --- node handles --------------------------------------------------------
38
+ //
39
+ // RN's `findNodeHandle` hands out an integer that stands for a mounted host
40
+ // VIEW. On a bridge platform the integer is the native view tag and the
41
+ // number is the only thing that can cross; here nothing has to cross, so the
42
+ // number is minted on demand and means exactly one thing — "the widget it
43
+ // was minted for".
44
+ //
45
+ // Keyed by the WIDGET rather than by the handle object, which is what makes
46
+ // it behave like RN's: two refs onto the same view report the same tag, and
47
+ // the tag survives a re-render that rebuilt the handle object. It is also why
48
+ // this is not a second registry — `widgetOf` above is still the only thing
49
+ // that knows what a handle stands for, and a tag is minted from its answer.
50
+ //
51
+ // A widget that is gone leaves a tag that resolves to null, which is what a
52
+ // stale RN tag does too.
53
+ const tagOfWidget = new WeakMap();
54
+ const widgetOfTag = new Map();
55
+ let nextTag = 1;
56
+ /**
57
+ * @internal Registers `handle` as standing for whatever widget `other`
58
+ * stands for.
59
+ *
60
+ * For a COMPOSITE that renders a host component and wants to be reachable as
61
+ * that host: a windowed list owns no widget of its own, but the ScrollView it
62
+ * renders is the thing another view measures against and the thing
63
+ * `findNodeHandle` should answer with. RN resolves a `FlatList`'s node handle
64
+ * through to its inner scroll view for the same reason.
65
+ *
66
+ * It deliberately does NOT give the composite `measure()`/`measureInWindow()`
67
+ * — see the note on `VirtualizedListHandle`. Being measurable AGAINST is a
68
+ * weaker claim than reporting your own geometry.
69
+ */
70
+ export const registerHandleAlias = (handle, other) => {
71
+ widgetOf.set(handle, () => widgetForHandle(other()));
72
+ };
73
+ /**
74
+ * @internal The tag standing for the widget behind `handle`, minted on first
75
+ * ask. Null when the value is not a component handle, or when its widget is
76
+ * not mounted — RN returns null in both cases too.
77
+ */
78
+ export const nodeHandleFor = (handle) => {
79
+ const widget = widgetForHandle(handle);
80
+ if (widget === null) {
81
+ return null;
82
+ }
83
+ const existing = tagOfWidget.get(widget);
84
+ if (existing !== undefined) {
85
+ return existing;
86
+ }
87
+ const tag = nextTag;
88
+ nextTag += 1;
89
+ tagOfWidget.set(widget, tag);
90
+ widgetOfTag.set(tag, new WeakRef(widget));
91
+ return tag;
92
+ };
93
+ /** @internal The widget a tag was minted for, or null once it is gone. */
94
+ export const widgetForNodeHandle = (tag) => {
95
+ const widget = widgetOfTag.get(tag)?.deref() ?? null;
96
+ if (widget === null) {
97
+ widgetOfTag.delete(tag);
98
+ }
99
+ return widget;
100
+ };
101
+ /** The widget behind either spelling of "that other view" that RN accepts. */
102
+ const widgetForTarget = (target) => typeof target === "number"
103
+ ? widgetForNodeHandle(target)
104
+ : widgetForHandle(target);
6
105
  export const createMeasureHandle = (widgetRef, node) => {
7
106
  const handle = {
8
107
  measure(callback) {
@@ -31,7 +130,7 @@ export const createMeasureHandle = (widgetRef, node) => {
31
130
  },
32
131
  measureLayout(relativeTo, onSuccess, onFail) {
33
132
  const widget = widgetRef.current;
34
- const other = widgetOf.get(relativeTo)?.() ?? null;
133
+ const other = widgetForTarget(relativeTo);
35
134
  const rect = node.getRect();
36
135
  if (!widget || !other || !rect) {
37
136
  onFail?.();
@@ -45,7 +144,7 @@ export const createMeasureHandle = (widgetRef, node) => {
45
144
  onSuccess(origin.x, origin.y, rect.width, rect.height);
46
145
  },
47
146
  };
48
- widgetOf.set(handle, () => widgetRef.current);
147
+ registerHandleWidget(handle, widgetRef);
49
148
  return handle;
50
149
  };
51
150
  //# sourceMappingURL=measure.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"measure.js","sourceRoot":"","sources":["../../src/components/measure.ts"],"names":[],"mappings":"AAeA,OAAO,EACL,cAAc,EACd,oBAAoB,GAErB,MAAM,sBAAsB,CAAA;AAoC7B,0EAA0E;AAC1E,yEAAyE;AACzE,2EAA2E;AAC3E,MAAM,QAAQ,GAAG,IAAI,OAAO,EAA0C,CAAA;AAEtE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,SAAuC,EACvC,IAAmB,EACJ,EAAE;IACjB,MAAM,MAAM,GAAkB;QAC5B,OAAO,CAAC,QAAQ;YACd,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAA;YAChC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAA;YAC3B,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;gBACrB,OAAM;YACR,CAAC;YACD,MAAM,IAAI,GAAG,oBAAoB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;YAC/C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAM;YACR,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;QACnE,CAAC;QAED,eAAe,CAAC,QAAQ;YACtB,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAA;YAChC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAA;YAC3B,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;gBACrB,OAAM;YACR,CAAC;YACD,MAAM,IAAI,GAAG,oBAAoB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;YAC/C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAM;YACR,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QACnD,CAAC;QAED,aAAa,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM;YACzC,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAA;YAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,IAAI,CAAA;YAClD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAA;YAC3B,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC/B,MAAM,EAAE,EAAE,CAAA;gBACV,OAAM;YACR,CAAC;YACD,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;YAClD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,EAAE,EAAE,CAAA;gBACV,OAAM;YACR,CAAC;YACD,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QACxD,CAAC;KACF,CAAA;IAED,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;IAC7C,OAAO,MAAM,CAAA;AACf,CAAC,CAAA","sourcesContent":["// RN's imperative geometry API (measure / measureInWindow / measureLayout),\n// shared by every component that exposes a ref.\n//\n// The size and the parent-relative position come from the Yoga rect the\n// component's layout node already holds — that is the layout truth, and it\n// is what RN reports (a rotated view still measures its own box, not its\n// axis-aligned bounding box). Only the translation into another coordinate\n// space goes through GTK, where compute_point walks the transform chain and\n// therefore already accounts for scroll offsets.\n//\n// RN's contract on failure is to not call back rather than to invent a\n// number: a view whose layout has not been committed yet (before the first\n// onLayout) or that is not in a window has nothing true to report.\nimport type { RefObject } from \"react\"\nimport type { LayoutNodeApi } from \"../contracts\"\nimport {\n computePointIn,\n computePointInWindow,\n type Gtk,\n} from \"../gtkx/bridge/index\"\n\nexport type MeasureOnSuccessCallback = (\n x: number,\n y: number,\n width: number,\n height: number,\n pageX: number,\n pageY: number,\n) => void\n\nexport type MeasureInWindowOnSuccessCallback = (\n x: number,\n y: number,\n width: number,\n height: number,\n) => void\n\nexport type MeasureLayoutOnSuccessCallback = (\n left: number,\n top: number,\n width: number,\n height: number,\n) => void\n\n/** The measurement half of a component ref, matching RN's method set. */\nexport type MeasureHandle = {\n measure(callback: MeasureOnSuccessCallback): void\n measureInWindow(callback: MeasureInWindowOnSuccessCallback): void\n measureLayout(\n relativeTo: MeasureHandle,\n onSuccess: MeasureLayoutOnSuccessCallback,\n onFail?: () => void,\n ): void\n}\n\n// measureLayout needs the OTHER view's widget, and the public handle type\n// deliberately does not carry one — a portable API should not hand out a\n// Gtk.Widget. The lookup lives here instead, keyed by the handle identity.\nconst widgetOf = new WeakMap<MeasureHandle, () => Gtk.Widget | null>()\n\nexport const createMeasureHandle = (\n widgetRef: RefObject<Gtk.Widget | null>,\n node: LayoutNodeApi,\n): MeasureHandle => {\n const handle: MeasureHandle = {\n measure(callback) {\n const widget = widgetRef.current\n const rect = node.getRect()\n if (!widget || !rect) {\n return\n }\n const page = computePointInWindow(widget, 0, 0)\n if (!page) {\n return\n }\n callback(rect.x, rect.y, rect.width, rect.height, page.x, page.y)\n },\n\n measureInWindow(callback) {\n const widget = widgetRef.current\n const rect = node.getRect()\n if (!widget || !rect) {\n return\n }\n const page = computePointInWindow(widget, 0, 0)\n if (!page) {\n return\n }\n callback(page.x, page.y, rect.width, rect.height)\n },\n\n measureLayout(relativeTo, onSuccess, onFail) {\n const widget = widgetRef.current\n const other = widgetOf.get(relativeTo)?.() ?? null\n const rect = node.getRect()\n if (!widget || !other || !rect) {\n onFail?.()\n return\n }\n const origin = computePointIn(widget, other, 0, 0)\n if (!origin) {\n onFail?.()\n return\n }\n onSuccess(origin.x, origin.y, rect.width, rect.height)\n },\n }\n\n widgetOf.set(handle, () => widgetRef.current)\n return handle\n}\n"]}
1
+ {"version":3,"file":"measure.js","sourceRoot":"","sources":["../../src/components/measure.ts"],"names":[],"mappings":"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","sourcesContent":["// RN's imperative geometry API (measure / measureInWindow / measureLayout),\n// shared by every component that exposes a ref.\n//\n// The size and the parent-relative position come from the Yoga rect the\n// component's layout node already holds — that is the layout truth, and it\n// is what RN reports (a rotated view still measures its own box, not its\n// axis-aligned bounding box). Only the translation into another coordinate\n// space goes through GTK, where compute_point walks the transform chain and\n// therefore already accounts for scroll offsets.\n//\n// RN's contract on failure is to not call back rather than to invent a\n// number: a view whose layout has not been committed yet (before the first\n// onLayout) or that is not in a window has nothing true to report.\nimport type { RefObject } from \"react\"\nimport type { LayoutNodeApi } from \"../contracts\"\nimport {\n computePointIn,\n computePointInWindow,\n type Gtk,\n} from \"../gtkx/bridge/index\"\n\nexport type MeasureOnSuccessCallback = (\n x: number,\n y: number,\n width: number,\n height: number,\n pageX: number,\n pageY: number,\n) => void\n\nexport type MeasureInWindowOnSuccessCallback = (\n x: number,\n y: number,\n width: number,\n height: number,\n) => void\n\nexport type MeasureLayoutOnSuccessCallback = (\n left: number,\n top: number,\n width: number,\n height: number,\n) => void\n\n/**\n * RN's opaque reference to a mounted host view — what `findNodeHandle`\n * returns and what `measureLayout` accepts as its first argument. A number,\n * as it is on every RN platform: the value crosses no boundary here, but the\n * libraries that ask for one compare it, store it in a map and hand it back,\n * and an object would only be a different type wearing the same name.\n */\nexport type NodeHandle = number\n\n/** The measurement half of a component ref, matching RN's method set. */\nexport type MeasureHandle = {\n measure(callback: MeasureOnSuccessCallback): void\n measureInWindow(callback: MeasureInWindowOnSuccessCallback): void\n measureLayout(\n relativeTo: MeasureHandle | NodeHandle,\n onSuccess: MeasureLayoutOnSuccessCallback,\n onFail?: () => void,\n ): void\n}\n\n// measureLayout needs the OTHER view's widget, and the public handle type\n// deliberately does not carry one — a portable API should not hand out a\n// Gtk.Widget. The lookup lives here instead, keyed by the handle identity.\n//\n// It is also the seam every animated component reaches through: driving\n// `opacity` and `transform` imperatively needs the widget behind a ref, and\n// this map already holds exactly that association for every component that\n// exposes a handle. Widening it beats adding a second, parallel registry.\nconst widgetOf = new WeakMap<object, () => Gtk.Widget | null>()\n\n/**\n * @internal Registers `handle` as standing for `widgetRef`'s widget.\n *\n * `createMeasureHandle` does this for the handles it builds; components that\n * COMPOSE one into a larger handle (ScrollView adds `scrollTo`/`scrollToEnd`)\n * create a new object, which is a new identity and therefore needs its own\n * entry — otherwise `measureLayout(scrollViewRef, …)` silently fails.\n */\nexport const registerHandleWidget = (\n handle: object,\n widgetRef: RefObject<Gtk.Widget | null>,\n): void => {\n widgetOf.set(handle, () => widgetRef.current)\n}\n\n/**\n * @internal The `Gtk.Widget` behind a component handle, or null when the\n * value is not a handle at all (a component that forwards no ref, or one\n * whose ref is something else entirely).\n *\n * Deliberately not exported from the package: a portable API does not hand\n * out widgets. This is how `createAnimatedComponent` reaches the widget it\n * has to write opacity and transforms to.\n */\nexport const widgetForHandle = (handle: unknown): Gtk.Widget | null => {\n if (handle === null || typeof handle !== \"object\") {\n return null\n }\n return widgetOf.get(handle)?.() ?? null\n}\n\n// --- node handles --------------------------------------------------------\n//\n// RN's `findNodeHandle` hands out an integer that stands for a mounted host\n// VIEW. On a bridge platform the integer is the native view tag and the\n// number is the only thing that can cross; here nothing has to cross, so the\n// number is minted on demand and means exactly one thing — \"the widget it\n// was minted for\".\n//\n// Keyed by the WIDGET rather than by the handle object, which is what makes\n// it behave like RN's: two refs onto the same view report the same tag, and\n// the tag survives a re-render that rebuilt the handle object. It is also why\n// this is not a second registry — `widgetOf` above is still the only thing\n// that knows what a handle stands for, and a tag is minted from its answer.\n//\n// A widget that is gone leaves a tag that resolves to null, which is what a\n// stale RN tag does too.\nconst tagOfWidget = new WeakMap<Gtk.Widget, NodeHandle>()\nconst widgetOfTag = new Map<NodeHandle, WeakRef<Gtk.Widget>>()\nlet nextTag = 1\n\n/**\n * @internal Registers `handle` as standing for whatever widget `other`\n * stands for.\n *\n * For a COMPOSITE that renders a host component and wants to be reachable as\n * that host: a windowed list owns no widget of its own, but the ScrollView it\n * renders is the thing another view measures against and the thing\n * `findNodeHandle` should answer with. RN resolves a `FlatList`'s node handle\n * through to its inner scroll view for the same reason.\n *\n * It deliberately does NOT give the composite `measure()`/`measureInWindow()`\n * — see the note on `VirtualizedListHandle`. Being measurable AGAINST is a\n * weaker claim than reporting your own geometry.\n */\nexport const registerHandleAlias = (\n handle: object,\n other: () => unknown,\n): void => {\n widgetOf.set(handle, () => widgetForHandle(other()))\n}\n\n/**\n * @internal The tag standing for the widget behind `handle`, minted on first\n * ask. Null when the value is not a component handle, or when its widget is\n * not mounted — RN returns null in both cases too.\n */\nexport const nodeHandleFor = (handle: unknown): NodeHandle | null => {\n const widget = widgetForHandle(handle)\n if (widget === null) {\n return null\n }\n const existing = tagOfWidget.get(widget)\n if (existing !== undefined) {\n return existing\n }\n const tag = nextTag\n nextTag += 1\n tagOfWidget.set(widget, tag)\n widgetOfTag.set(tag, new WeakRef(widget))\n return tag\n}\n\n/** @internal The widget a tag was minted for, or null once it is gone. */\nexport const widgetForNodeHandle = (tag: NodeHandle): Gtk.Widget | null => {\n const widget = widgetOfTag.get(tag)?.deref() ?? null\n if (widget === null) {\n widgetOfTag.delete(tag)\n }\n return widget\n}\n\n/** The widget behind either spelling of \"that other view\" that RN accepts. */\nconst widgetForTarget = (\n target: MeasureHandle | NodeHandle,\n): Gtk.Widget | null =>\n typeof target === \"number\"\n ? widgetForNodeHandle(target)\n : widgetForHandle(target)\n\nexport const createMeasureHandle = (\n widgetRef: RefObject<Gtk.Widget | null>,\n node: LayoutNodeApi,\n): MeasureHandle => {\n const handle: MeasureHandle = {\n measure(callback) {\n const widget = widgetRef.current\n const rect = node.getRect()\n if (!widget || !rect) {\n return\n }\n const page = computePointInWindow(widget, 0, 0)\n if (!page) {\n return\n }\n callback(rect.x, rect.y, rect.width, rect.height, page.x, page.y)\n },\n\n measureInWindow(callback) {\n const widget = widgetRef.current\n const rect = node.getRect()\n if (!widget || !rect) {\n return\n }\n const page = computePointInWindow(widget, 0, 0)\n if (!page) {\n return\n }\n callback(page.x, page.y, rect.width, rect.height)\n },\n\n measureLayout(relativeTo, onSuccess, onFail) {\n const widget = widgetRef.current\n const other = widgetForTarget(relativeTo)\n const rect = node.getRect()\n if (!widget || !other || !rect) {\n onFail?.()\n return\n }\n const origin = computePointIn(widget, other, 0, 0)\n if (!origin) {\n onFail?.()\n return\n }\n onSuccess(origin.x, origin.y, rect.width, rect.height)\n },\n }\n\n registerHandleWidget(handle, widgetRef)\n return handle\n}\n"]}
@@ -1,10 +1,12 @@
1
1
  import { type ReactNode } from "react";
2
2
  import type { StyleProp } from "../contracts";
3
+ import { type HitSlop } from "../gtkx/bridge/index";
3
4
  import { type PressEvent } from "./press-event";
4
5
  import { type LayoutEvent } from "./use-layout-child";
5
6
  export type PressableStateCallbackType = {
6
7
  pressed: boolean;
7
8
  hovered: boolean;
9
+ focused: boolean;
8
10
  };
9
11
  export type { NativeTouch, PressEvent } from "./press-event";
10
12
  export type PressableProps = {
@@ -16,14 +18,72 @@ export type PressableProps = {
16
18
  onLongPress?: (event: PressEvent) => void;
17
19
  onHoverIn?: () => void;
18
20
  onHoverOut?: () => void;
21
+ onFocus?: () => void;
22
+ onBlur?: () => void;
23
+ /** Whether Tab and the arrow keys can reach this pressable. Defaults to
24
+ * true when `onPress` is set, which is react-native-web's own rule — a
25
+ * control you can click and cannot reach from the keyboard is an
26
+ * accessibility bug, and on a desktop that matters more, not less. */
27
+ focusable?: boolean;
19
28
  disabled?: boolean;
20
29
  delayLongPress?: number;
30
+ /** RN's hitSlop: how far OUTSIDE its bounds this pressable still counts
31
+ * as pressed. A number is all four edges. Limited by an ancestor that
32
+ * clips — a ScrollView's viewport, say — because GTK stops picking at
33
+ * the clip, the same constraint RN documents on Android. */
34
+ hitSlop?: number | Partial<HitSlop>;
35
+ /** RN's pressRetentionOffset: how far the pointer may drift outside the
36
+ * hit rect after pressing and still activate on release. Defaults to
37
+ * RN's own {top: 20, left: 20, right: 20, bottom: 30}. */
38
+ pressRetentionOffset?: number | Partial<HitSlop>;
21
39
  onLayout?: (event: LayoutEvent) => void;
22
40
  testID?: string;
23
41
  };
24
- export declare const Pressable: ({ style, children, onPress, onPressIn, onPressOut, onLongPress, onHoverIn, onHoverOut, disabled, delayLongPress, onLayout, testID, }: PressableProps) => React.JSX.Element;
42
+ export declare const Pressable: ({ style, children, onPress, onPressIn, onPressOut, onLongPress, onHoverIn, onHoverOut, onFocus, onBlur, focusable, disabled, delayLongPress, hitSlop, pressRetentionOffset, onLayout, testID, }: PressableProps) => React.JSX.Element;
25
43
  export type TouchableOpacityProps = Omit<PressableProps, "style"> & {
26
44
  style?: StyleProp;
27
45
  activeOpacity?: number;
28
46
  };
29
47
  export declare const TouchableOpacity: ({ style, activeOpacity, ...rest }: TouchableOpacityProps) => React.JSX.Element;
48
+ export type TouchableHighlightProps = Omit<PressableProps, "style"> & {
49
+ style?: StyleProp;
50
+ /**
51
+ * RN's default is `"black"`, and its default `activeOpacity` is `0.85` — the
52
+ * underlay shows through the dimmed child rather than replacing it. Here the
53
+ * underlay IS the background, because there is no separate underlay view to
54
+ * put behind a child that may be opaque, so an app that wants RN's exact
55
+ * blend gives the child a translucent background itself.
56
+ */
57
+ underlayColor?: string;
58
+ activeOpacity?: number;
59
+ onShowUnderlay?: () => void;
60
+ onHideUnderlay?: () => void;
61
+ };
62
+ /**
63
+ * RN's `TouchableHighlight`: a background colour while held.
64
+ *
65
+ * Here because `@gorhom/bottom-sheet` re-exports it from its own public entry
66
+ * as `BottomSheetTouchable` on every platform except iOS — it is upstream's
67
+ * export, not an app's choice, so an app cannot avoid it. It is also an
68
+ * ordinary `react-native` component that this surface was simply missing.
69
+ *
70
+ * One structural difference, stated rather than papered over: RN renders a
71
+ * separate underlay VIEW behind the child and lowers the child's opacity onto
72
+ * it. Reproducing that needs a second box, and an extra box changes flex
73
+ * layout and what `measureLayout` is relative to — the same reason
74
+ * `GestureDetector` and `createAnimatedComponent` add none. So the highlight
75
+ * is this view's own `backgroundColor` while pressed.
76
+ */
77
+ export declare const TouchableHighlight: ({ style, underlayColor, activeOpacity, onShowUnderlay, onHideUnderlay, onPressIn, onPressOut, ...rest }: TouchableHighlightProps) => React.JSX.Element;
78
+ export type TouchableWithoutFeedbackProps = PressableProps;
79
+ /**
80
+ * RN's `TouchableWithoutFeedback`: the press callbacks and nothing visual.
81
+ *
82
+ * RN's own version clones its single child rather than rendering a box, and
83
+ * its documentation calls that a mistake it kept for compatibility. This one
84
+ * renders the `Pressable` box, which is what `Pressable` already is with no
85
+ * `style` callback — the difference is invisible unless the child was relying
86
+ * on being laid out by ITS parent, and RN's own docs tell you to use
87
+ * `Pressable` instead for exactly that reason.
88
+ */
89
+ export declare const TouchableWithoutFeedback: (props: PressableProps) => React.JSX.Element;
@@ -2,20 +2,46 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useLayoutEffect, useReducer, useRef, useState, } from "react";
3
3
  import { splitStyle, StyleSheet } from "../style/index";
4
4
  import { defaultCssRegistry } from "../style/registry.gtkx";
5
- import { Gtk, GtkBox } from "../gtkx/bridge/index";
5
+ import { getViewBoxComponent, Gtk, setHitSlop, } from "../gtkx/bridge/index";
6
6
  import { perfAddTime, perfCount, perfEnabled, perfNow } from "../perf";
7
7
  import { HostNodeContext } from "./host-node";
8
8
  import { createPressEvent, createTouch } from "./press-event";
9
+ import { useActivateOnKey, useFocusable, useFocusController } from "./use-focus";
9
10
  import { useLayoutChild, useRnContainer, } from "./use-layout-child";
11
+ const NO_SLOP = { top: 0, right: 0, bottom: 0, left: 0 };
12
+ /**
13
+ * RN's own DEFAULT_PRESS_RECT_OFFSETS, from Libraries/Pressability. The
14
+ * bottom edge is deliberately larger: a thumb rolls downwards off a target
15
+ * far more often than upwards.
16
+ */
17
+ const DEFAULT_PRESS_RECT = { top: 20, right: 20, bottom: 30, left: 20 };
18
+ const toRect = (value, fallback) => {
19
+ if (value === undefined) {
20
+ return fallback;
21
+ }
22
+ if (typeof value === "number") {
23
+ return { top: value, right: value, bottom: value, left: value };
24
+ }
25
+ return {
26
+ top: value.top ?? 0,
27
+ right: value.right ?? 0,
28
+ bottom: value.bottom ?? 0,
29
+ left: value.left ?? 0,
30
+ };
31
+ };
10
32
  // Coordinates arrive from GtkGestureClick in the widget's own space, which
11
33
  // is exactly RN's locationX/locationY; createTouch translates them into the
12
34
  // window for pageX/pageY.
13
35
  const pressEvent = (widget, x, y) => createPressEvent(createTouch(widget, x, y));
14
36
  // A View with a click gesture and hover tracking. State-dependent style and
15
37
  // children follow the RN Pressable function-prop contract.
16
- export const Pressable = ({ style, children, onPress, onPressIn, onPressOut, onLongPress, onHoverIn, onHoverOut, disabled = false, delayLongPress = 500, onLayout, testID, }) => {
38
+ export const Pressable = ({ style, children, onPress, onPressIn, onPressOut, onLongPress, onHoverIn, onHoverOut, onFocus, onBlur, focusable, disabled = false, delayLongPress = 500, hitSlop, pressRetentionOffset, onLayout, testID, }) => {
17
39
  const widgetRef = useRef(null);
18
40
  const [pressed, setPressed] = useState(false);
41
+ // Focus IS React state, unlike hover: it changes at human-decision rates
42
+ // (a Tab press), not at pointer-motion rates, so the fast path hover needs
43
+ // would be complexity with nothing to buy.
44
+ const [focused, setFocused] = useState(false);
19
45
  // Hover is not React state: a boundary crossing should cost what it costs
20
46
  // a native GtkListBox row to swap a CSS class, not a setState + render +
21
47
  // Yoga + allocate cycle (measured: roughly 500x the latency of a native
@@ -39,6 +65,7 @@ export const Pressable = ({ style, children, onPress, onPressIn, onPressOut, onL
39
65
  const state = {
40
66
  pressed,
41
67
  hovered: hoveredRef.current,
68
+ focused,
42
69
  };
43
70
  // Gestures are attached imperatively even though rc.3 has a declarative
44
71
  // `controllers` slot: the controllers are wired exactly once per widget and
@@ -81,6 +108,7 @@ export const Pressable = ({ style, children, onPress, onPressIn, onPressOut, onL
81
108
  const otherState = {
82
109
  pressed,
83
110
  hovered: !hoveredRef.current,
111
+ focused,
84
112
  };
85
113
  const otherFlat = StyleSheet.flatten(style(otherState));
86
114
  const otherSplit = splitStyle(otherFlat);
@@ -133,6 +161,27 @@ export const Pressable = ({ style, children, onPress, onPressIn, onPressOut, onL
133
161
  }, delayLongPress);
134
162
  }
135
163
  };
164
+ /**
165
+ * Whether a release at (x, y) — in the widget's own coordinates — still
166
+ * counts as pressing this control. RN's press rect is the hit rect plus
167
+ * pressRetentionOffset, and a release outside it is a cancel, not a
168
+ * press: dragging off a button to change your mind is how every toolkit
169
+ * works, GTK's own GtkButton included. GtkGestureClick keeps an implicit
170
+ * grab for the whole press, so `released` arrives here wherever the
171
+ * pointer ended up and the check has to be ours.
172
+ */
173
+ const withinPressRect = (x, y) => {
174
+ const widget = widgetRef.current;
175
+ if (!widget) {
176
+ return false;
177
+ }
178
+ const slop = slopRef.current;
179
+ const retention = retentionRef.current;
180
+ return (x >= -(slop.left + retention.left) &&
181
+ y >= -(slop.top + retention.top) &&
182
+ x < widget.getWidth() + slop.right + retention.right &&
183
+ y < widget.getHeight() + slop.bottom + retention.bottom);
184
+ };
136
185
  const handleReleased = (_n, x, y) => {
137
186
  if (disabled) {
138
187
  return;
@@ -140,8 +189,10 @@ export const Pressable = ({ style, children, onPress, onPressIn, onPressOut, onL
140
189
  clearLongPress();
141
190
  setPressed(false);
142
191
  const widget = widgetRef.current;
192
+ // onPressOut fires either way — RN reports the end of the press whether
193
+ // it turned into an activation or not.
143
194
  onPressOut?.(pressEvent(widget, x, y));
144
- if (!longPressFired.current) {
195
+ if (!longPressFired.current && withinPressRect(x, y)) {
145
196
  onPress?.(pressEvent(widget, x, y));
146
197
  }
147
198
  };
@@ -189,6 +240,41 @@ export const Pressable = ({ style, children, onPress, onPressIn, onPressOut, onL
189
240
  handleEnter: () => applyHover(true, onHoverIn),
190
241
  handleLeave: () => applyHover(false, onHoverOut),
191
242
  };
243
+ // A pressable that can be clicked should be reachable from the keyboard;
244
+ // one that only hovers or lays out should not join the Tab order. That is
245
+ // react-native-web's rule, and it keeps every existing Pressable in this
246
+ // repo behaving as before unless it had an onPress to begin with.
247
+ useFocusable(widgetRef, focusable ?? onPress !== undefined);
248
+ useFocusController(widgetRef, () => {
249
+ setFocused(true);
250
+ onFocus?.();
251
+ }, () => {
252
+ setFocused(false);
253
+ onBlur?.();
254
+ });
255
+ // Enter and Space activate a focused control on web and on Android, so
256
+ // they do here. The press event is synthesised at the widget's own origin
257
+ // — a keyboard press has no coordinates, and RN's own handlers read
258
+ // locationX/Y unconditionally.
259
+ useActivateOnKey(widgetRef, disabled || !onPress
260
+ ? undefined
261
+ : () => onPress(pressEvent(widgetRef.current, 0, 0)));
262
+ // Read from the gesture handlers, which are installed once and must not
263
+ // close over a stale prop.
264
+ const slopRef = useRef(NO_SLOP);
265
+ const retentionRef = useRef(DEFAULT_PRESS_RECT);
266
+ slopRef.current = toRect(hitSlop, NO_SLOP);
267
+ retentionRef.current = toRect(pressRetentionOffset, DEFAULT_PRESS_RECT);
268
+ const slop = slopRef.current;
269
+ useLayoutEffect(() => {
270
+ const widget = widgetRef.current;
271
+ if (!widget) {
272
+ return;
273
+ }
274
+ const empty = slop.top === 0 && slop.right === 0 && slop.bottom === 0 && slop.left === 0;
275
+ setHitSlop(widget, empty ? null : slop);
276
+ // eslint-disable-next-line react-hooks/exhaustive-deps
277
+ }, [slop.top, slop.right, slop.bottom, slop.left]);
192
278
  useLayoutEffect(() => {
193
279
  const widget = widgetRef.current;
194
280
  if (!widget) {
@@ -199,6 +285,24 @@ export const Pressable = ({ style, children, onPress, onPressIn, onPressOut, onL
199
285
  click.on("released", (n, x, y) => handlersRef.current.handleReleased(n, x, y));
200
286
  click.on("cancel", () => handlersRef.current.handleCancel());
201
287
  widget.addController(click);
288
+ // Hover fires from touch as well as from a mouse, and that is left
289
+ // alone deliberately. react-native-web filters it — `useHover` drops
290
+ // any event whose pointerType is "touch", because on a phone every tap
291
+ // would otherwise leave a view looking hovered. Three measurements say
292
+ // not to copy it here. GTK gives a crossing event no device at all:
293
+ // inside `enter` and `leave` both `get_current_event()` and
294
+ // `get_current_event_device()` are null, because GTK routes crossings
295
+ // through a path that never sets the controller's current event, so the
296
+ // filter would have to come from somewhere else entirely — a raw event
297
+ // tap on the toplevel recording the last input source, which is
298
+ // per-event JS work on every window for a filter nobody can check.
299
+ // GTK also sends a matching leave when a touch sequence ends, so the
300
+ // stuck phantom hover that motivates RNW's filter does not arise, and
301
+ // GTK's own CSS `:hover` lights up on touch — filtering would make this
302
+ // platform's Pressable behave unlike every widget beside it. And it
303
+ // cannot be verified either way here: there is no way to inject a touch
304
+ // on this rig (docs/research/gestures.md). Revisit with a touchscreen
305
+ // and a reason, not before.
202
306
  const motion = new Gtk.EventControllerMotion();
203
307
  motion.on("enter", () => handlersRef.current.handleEnter());
204
308
  motion.on("leave", () => handlersRef.current.handleLeave());
@@ -208,8 +312,51 @@ export const Pressable = ({ style, children, onPress, onPressIn, onPressOut, onL
208
312
  widget.removeController(motion);
209
313
  };
210
314
  }, []);
211
- return (_jsx(GtkBox, { ref: widgetRef, name: testID, cssClasses: cssClass ? [cssClass] : [], children: _jsx(HostNodeContext.Provider, { value: { engine: host.engine, node, widgetRef }, children: resolvedChildren }) }));
315
+ // The same GtkBox subclass a View renders, for its contains() override:
316
+ // hitSlop is a picking change and nothing in JS can substitute for one,
317
+ // because a press outside the widget is never delivered to it at all.
318
+ const PressableBox = getViewBoxComponent();
319
+ return (_jsx(PressableBox, { ref: widgetRef, name: testID, cssClasses: cssClass ? [cssClass] : [], children: _jsx(HostNodeContext.Provider, { value: { engine: host.engine, node, widgetRef }, children: resolvedChildren }) }));
212
320
  };
213
321
  // Classic RN touchable: dims itself while pressed via widget opacity.
214
322
  export const TouchableOpacity = ({ style, activeOpacity = 0.5, ...rest }) => (_jsx(Pressable, { ...rest, style: ({ pressed }) => [style, pressed && { opacity: activeOpacity }] }));
323
+ /**
324
+ * RN's `TouchableHighlight`: a background colour while held.
325
+ *
326
+ * Here because `@gorhom/bottom-sheet` re-exports it from its own public entry
327
+ * as `BottomSheetTouchable` on every platform except iOS — it is upstream's
328
+ * export, not an app's choice, so an app cannot avoid it. It is also an
329
+ * ordinary `react-native` component that this surface was simply missing.
330
+ *
331
+ * One structural difference, stated rather than papered over: RN renders a
332
+ * separate underlay VIEW behind the child and lowers the child's opacity onto
333
+ * it. Reproducing that needs a second box, and an extra box changes flex
334
+ * layout and what `measureLayout` is relative to — the same reason
335
+ * `GestureDetector` and `createAnimatedComponent` add none. So the highlight
336
+ * is this view's own `backgroundColor` while pressed.
337
+ */
338
+ export const TouchableHighlight = ({ style, underlayColor = "black", activeOpacity, onShowUnderlay, onHideUnderlay, onPressIn, onPressOut, ...rest }) => (_jsx(Pressable, { ...rest, onPressIn: (event) => {
339
+ onShowUnderlay?.();
340
+ onPressIn?.(event);
341
+ }, onPressOut: (event) => {
342
+ onHideUnderlay?.();
343
+ onPressOut?.(event);
344
+ }, style: ({ pressed }) => [
345
+ style,
346
+ pressed && {
347
+ backgroundColor: underlayColor,
348
+ ...(activeOpacity === undefined ? null : { opacity: activeOpacity }),
349
+ },
350
+ ] }));
351
+ /**
352
+ * RN's `TouchableWithoutFeedback`: the press callbacks and nothing visual.
353
+ *
354
+ * RN's own version clones its single child rather than rendering a box, and
355
+ * its documentation calls that a mistake it kept for compatibility. This one
356
+ * renders the `Pressable` box, which is what `Pressable` already is with no
357
+ * `style` callback — the difference is invisible unless the child was relying
358
+ * on being laid out by ITS parent, and RN's own docs tell you to use
359
+ * `Pressable` instead for exactly that reason.
360
+ */
361
+ export const TouchableWithoutFeedback = (props) => (_jsx(Pressable, { ...props }));
215
362
  //# sourceMappingURL=pressable.js.map