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 +1 @@
1
- {"version":3,"file":"animated.js","sourceRoot":"","sources":["../../src/components/animated.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useLayoutEffect, useRef, type ReactNode } from \"react\"\nimport { createAnimated, type FrameScheduler } from \"../animated/index\"\nimport type { FlatStyle, StyleProp, TransformPart } from \"../contracts\"\nimport { GLib, GtkBox, queueAllocate, type Gtk } from \"../gtkx/bridge/index\"\nimport type { ResponderProps } from \"../responder/types\"\nimport { useResponder } from \"../responder/use-responder\"\nimport { HostNodeContext } from \"./host-node\"\nimport { setStoredTransform } from \"./rect-store\"\nimport {\n useLayoutChild,\n useRnContainer,\n type LayoutEvent,\n} from \"./use-layout-child\"\n\n// ~60fps one-shot ticks off the GLib main loop. A frame-clock driver (per\n// window) is a later optimization; timeouts keep the driver widget-free.\nconst glibScheduler: FrameScheduler = {\n schedule(callback) {\n let cancelled = false\n const id = GLib.timeoutAdd(GLib.PRIORITY_DEFAULT, 16, () => {\n if (!cancelled) {\n callback(Number(GLib.getMonotonicTime()) / 1000)\n }\n return false\n })\n return () => {\n if (!cancelled) {\n cancelled = true\n GLib.Source.remove(id)\n }\n }\n },\n}\n\nconst api = createAnimated(glibScheduler)\n\n// Interpolations produce suffixed strings (\"45deg\"), so a driven value is\n// not necessarily a number — `rotate` is normally an interpolate() with a\n// deg outputRange.\ntype AnimatedValue = number | string\n\ntype AnimatedNode = {\n addListener(callback: (state: { value: AnimatedValue }) => void): string\n removeListener(id: string): void\n __getValue(): AnimatedValue\n}\n\nconst isAnimatedNode = (value: unknown): value is AnimatedNode =>\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as AnimatedNode).addListener === \"function\" &&\n typeof (value as AnimatedNode).__getValue === \"function\"\n\ntype AnimatedTransformPart = { [key: string]: number | string | AnimatedNode }\n\n// One entry of the style's transform array, kept in source order. The array\n// order IS the composition order in RN, so an animated entry updates its own\n// slot in place instead of being lifted out of the list — that is what makes\n// [{rotate}, {translateX}] compose differently from the reverse, as in RN.\ntype TransformSlot = {\n key: string\n node: AnimatedNode | null\n value: AnimatedValue\n}\n\n// Stable per-node identity for the effect's dependency key: Animated nodes\n// are objects, and the bindings must be rebuilt when the node behind a slot\n// changes — not on every render that rebuilds an equal-looking array.\nlet nextNodeId = 1\nconst nodeIds = new WeakMap<object, number>()\nconst nodeId = (value: object): number => {\n let id = nodeIds.get(value)\n if (id === undefined) {\n id = nextNodeId++\n nodeIds.set(value, id)\n }\n return id\n}\n\n// Omit, not plain intersection: intersecting would AND the animated transform\n// with FlatStyle's numeric one, rejecting Animated.Value entries.\nexport type AnimatedViewStyle = Omit<FlatStyle, \"opacity\" | \"transform\"> & {\n opacity?: number | AnimatedNode\n transform?: (TransformPart | AnimatedTransformPart)[]\n}\n\n// Animated.View is where a PanResponder drag lands in idiomatic RN — the\n// dragged box is animated by definition — so it takes the responder props\n// exactly as View does.\nexport type AnimatedViewProps = ResponderProps & {\n style?: AnimatedViewStyle | AnimatedViewStyle[]\n children?: ReactNode\n onLayout?: (event: LayoutEvent) => void\n testID?: string\n}\n\nconst splitAnimated = (\n style: AnimatedViewProps[\"style\"],\n): {\n staticStyle: StyleProp\n opacity: AnimatedNode | null\n slots: TransformSlot[]\n} => {\n const flat: Record<string, unknown> = {}\n const collect = (entry: AnimatedViewProps[\"style\"]): void => {\n if (!entry) {\n return\n }\n if (Array.isArray(entry)) {\n entry.forEach(collect)\n return\n }\n Object.assign(flat, entry)\n }\n collect(style)\n\n let opacity: AnimatedNode | null = null\n const slots: TransformSlot[] = []\n\n if (isAnimatedNode(flat.opacity)) {\n opacity = flat.opacity\n delete flat.opacity\n }\n if (Array.isArray(flat.transform)) {\n for (const part of flat.transform as AnimatedTransformPart[]) {\n const key = Object.keys(part)[0]\n if (key === undefined) {\n continue\n }\n const value = part[key]\n slots.push(\n isAnimatedNode(value)\n ? { key, node: value, value: value.__getValue() }\n : { key, node: null, value: value as AnimatedValue },\n )\n }\n // The whole array is owned here from now on, static entries included:\n // leaving them in the style would make useLayoutChild write the same\n // rect-store slot from the other side, and the two would overwrite\n // each other every render.\n delete flat.transform\n }\n\n return { staticStyle: flat as StyleProp, opacity, slots }\n}\n\n// Animated values bypass React entirely: listeners write straight to the\n// widget (opacity) and to the rect store (the transform applied by the\n// parent's allocate), on top of the engine-committed base rect — the fast\n// path measured in the spike. Animation frames never touch Yoga.\nconst AnimatedView = ({\n style,\n children,\n onLayout,\n testID,\n ...responderProps\n}: AnimatedViewProps) => {\n const widgetRef = useRef<Gtk.Box | null>(null)\n const { staticStyle, opacity, slots } = splitAnimated(style)\n\n const { host, node, cssClass } = useLayoutChild(widgetRef, {\n style: staticStyle,\n onLayout,\n })\n useRnContainer(widgetRef, node)\n useResponder(widgetRef, responderProps)\n\n // The effect reads the slots of the render that (re)armed it; the values\n // inside are then owned by the listeners.\n const slotsRef = useRef<TransformSlot[]>(slots)\n slotsRef.current = slots\n\n // Rebind on a change of shape (which transforms, in which order), of the\n // node behind an animated entry, or of a static entry's value — not on\n // every render that rebuilds an equal-looking array.\n const bindingKey =\n (opacity ? `opacity#${nodeId(opacity)}` : \"\") +\n slots\n .map((slot) =>\n slot.node\n ? `|${slot.key}#${nodeId(slot.node)}`\n : `|${slot.key}=${String(slot.value)}`,\n )\n .join(\"\")\n\n useLayoutEffect(() => {\n const widget = widgetRef.current\n if (!widget) {\n return\n }\n\n // The live transform array, mutated in place: an Animated write must\n // stay one numeric store plus one queued allocation — no React render,\n // no Yoga pass, no allocation per frame beyond the composed matrix.\n //\n // RN transform semantics: this is paint-only. The result goes to the\n // rect store unclamped — the parent's measure ignores children, so a\n // transformed child draws past the boundary over its neighbors without\n // moving a single ancestor.\n const parts = slotsRef.current.map(\n (slot) => ({ [slot.key]: slot.value }) as Record<string, AnimatedValue>,\n )\n\n const flush = (): void => {\n setStoredTransform(widget, parts as unknown as TransformPart[])\n const parentWidget = host.widgetRef.current\n if (parentWidget) {\n queueAllocate(parentWidget)\n }\n }\n\n const subscriptions: { node: AnimatedNode; id: string }[] = []\n slotsRef.current.forEach((slot, index) => {\n if (!slot.node) {\n return\n }\n const part = parts[index]!\n subscriptions.push({\n node: slot.node,\n id: slot.node.addListener(({ value }) => {\n part[slot.key] = value\n flush()\n }),\n })\n })\n\n if (opacity) {\n const applyOpacity = (value: AnimatedValue): void => {\n const numeric = typeof value === \"number\" ? value : parseFloat(value)\n widgetRef.current?.setOpacity(Math.min(1, Math.max(0, numeric)))\n }\n subscriptions.push({\n node: opacity,\n id: opacity.addListener(({ value }) => {\n applyOpacity(value)\n }),\n })\n applyOpacity(opacity.__getValue())\n }\n\n flush()\n\n return () => {\n for (const { node: animated, id } of subscriptions) {\n animated.removeListener(id)\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [bindingKey, node])\n\n return (\n <GtkBox\n ref={widgetRef}\n name={testID}\n cssClasses={cssClass ? [cssClass] : []}\n >\n <HostNodeContext.Provider\n value={{ engine: host.engine, node, widgetRef }}\n >\n {children}\n </HostNodeContext.Provider>\n </GtkBox>\n )\n}\n\nexport const Animated = {\n ...api,\n View: AnimatedView,\n}\n\nexport { Easing } from \"../animated/index\"\n"]}
1
+ {"version":3,"file":"animated.js","sourceRoot":"","sources":["../../src/components/animated.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n type ComponentProps,\n type ComponentType,\n type ElementType,\n type ReactNode,\n type Ref,\n} from \"react\"\nimport type { DrivenSize } from \"../layout/driven-size\"\nimport {\n INSET_PROPERTIES,\n insetRefusalReason,\n insetTranslation,\n type InsetProperty,\n} from \"../style/absolute-insets\"\nimport {\n drivenSizeRefusal,\n SIZE_PROPERTIES,\n type SizeProperty,\n} from \"../style/animated-size\"\nimport {\n DRIVEABLE_COLOR_PROPERTIES,\n driveableColorsToCss,\n type DriveableColorProperty,\n} from \"../style/imperative-css\"\nimport { StyleSheet } from \"../style/index\"\nimport { createAnimated } from \"../animated/index\"\nimport type {\n DimensionValue,\n FlatStyle,\n PointerEventsValue,\n StyleProp,\n TransformPart,\n} from \"../contracts\"\nimport {\n createWidgetCss,\n GtkBox,\n queueAllocate,\n setBoxPassthrough,\n setPointerTarget,\n setZIndex,\n type Gtk,\n type WidgetCss,\n} from \"../gtkx/bridge/index\"\nimport type { ResponderProps } from \"../responder/types\"\nimport { useResponder } from \"../responder/use-responder\"\nimport { applyDrivenSize, releaseDrivenSize } from \"./driven-size\"\nimport { glibScheduler } from \"./frame-scheduler\"\nimport { HostNodeContext, useHostNode, type HostNode } from \"./host-node\"\nimport { Image } from \"./image\"\nimport {\n createMeasureHandle,\n widgetForHandle,\n type MeasureHandle,\n} from \"./measure\"\nimport { setStoredTransform } from \"./rect-store\"\nimport { ScrollView } from \"./scroll-view\"\nimport { Text } from \"./text\"\nimport {\n nodeForWidget,\n useLayoutChild,\n useRnContainer,\n type LayoutEvent,\n} from \"./use-layout-child\"\n\nconst api = createAnimated(glibScheduler)\n\n// Interpolations produce suffixed strings (\"45deg\"), so a driven value is\n// not necessarily a number — `rotate` is normally an interpolate() with a\n// deg outputRange.\ntype AnimatedValue = number | string\n\ntype AnimatedNode = {\n addListener(callback: (state: { value: AnimatedValue }) => void): string\n removeListener(id: string): void\n __getValue(): AnimatedValue\n}\n\nconst isAnimatedNode = (value: unknown): value is AnimatedNode =>\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as AnimatedNode).addListener === \"function\" &&\n typeof (value as AnimatedNode).__getValue === \"function\"\n\ntype AnimatedTransformPart = { [key: string]: number | string | AnimatedNode }\n\n// One entry of the style's transform array, kept in source order. The array\n// order IS the composition order in RN, so an animated entry updates its own\n// slot in place instead of being lifted out of the list — that is what makes\n// [{rotate}, {translateX}] compose differently from the reverse, as in RN.\ntype TransformSlot = {\n key: string\n node: AnimatedNode | null\n value: AnimatedValue\n // Set only on a slot DERIVED from an animated inset (`top`/`left`/`right`/\n // `bottom` on a node whose own position is absolute). The slot then carries\n // `sign * (inset - base)`, where `base` is the inset value Yoga was given at\n // the last React commit — see splitAnimated.\n inset?: { base: number; sign: 1 | -1 }\n}\n\nconst toNumber = (value: AnimatedValue): number =>\n typeof value === \"number\" ? value : Number.parseFloat(value)\n\n// What a slot actually writes into the transform array. An ordinary slot\n// writes its value; a derived inset slot writes its offset from the committed\n// base, which is what makes an absolute `top` a translation.\nconst slotValue = (\n slot: TransformSlot,\n value: AnimatedValue,\n): AnimatedValue => {\n if (!slot.inset) {\n return value\n }\n const numeric = toNumber(value)\n // A non-numeric inset (a percentage produced mid-animation) has no offset\n // from a point base. Holding the last position beats jumping to NaN, and\n // the leaf never becomes driveable in the first place unless it starts\n // numeric — see style/absolute-insets.ts and reanimated-compat/style.ts.\n return Number.isFinite(numeric)\n ? slot.inset.sign * (numeric - slot.inset.base)\n : 0\n}\n\n// Stable per-node identity for the effect's dependency key: Animated nodes\n// are objects, and the bindings must be rebuilt when the node behind a slot\n// changes — not on every render that rebuilds an equal-looking array.\nlet nextNodeId = 1\nconst nodeIds = new WeakMap<object, number>()\nconst nodeId = (value: object): number => {\n let id = nodeIds.get(value)\n if (id === undefined) {\n id = nextNodeId++\n nodeIds.set(value, id)\n }\n return id\n}\n\n// Omit, not plain intersection: intersecting would AND the animated transform\n// with FlatStyle's numeric one, rejecting Animated.Value entries.\nexport type AnimatedViewStyle = Omit<\n FlatStyle,\n | \"opacity\"\n | \"zIndex\"\n | \"transform\"\n | DriveableColorProperty\n | InsetProperty\n | SizeProperty\n> & {\n opacity?: number | AnimatedNode\n zIndex?: number | AnimatedNode\n transform?: (TransformPart | AnimatedTransformPart)[]\n} & Partial<Record<DriveableColorProperty, string | AnimatedNode>> &\n Partial<Record<InsetProperty, DimensionValue | AnimatedNode>> &\n Partial<Record<SizeProperty, DimensionValue | AnimatedNode>>\n\n/** What every animated component accepts as `style`, arrays and falsy included. */\nexport type AnimatedStyleProp =\n AnimatedViewStyle | readonly (AnimatedViewStyle | false | null | undefined)[]\n\n// Animated.View is where a PanResponder drag lands in idiomatic RN — the\n// dragged box is animated by definition — so it takes the responder props\n// exactly as View does.\nexport type AnimatedViewProps = ResponderProps & {\n style?: AnimatedStyleProp\n children?: ReactNode\n onLayout?: (event: LayoutEvent) => void\n testID?: string\n // Reanimated's `Animated.View` IS `createAnimatedComponent(View)` upstream,\n // so it takes every View prop — `pointerEvents` included. Dropping it made\n // an invisible full-screen overlay swallow every press underneath it, which\n // is exactly how `react-native-drawer-layout`'s `Overlay` is built\n // (opacity 0 plus `pointerEvents: \"none\"`): the drawer's own edge swipe\n // worked and NOTHING inside the app did.\n pointerEvents?: PointerEventsValue\n // The other half of the same parity gap. `useAnimatedProps` returns an\n // object of current values, and `createAnimatedComponent` already spreads\n // it — but `Animated.View` is written by hand here rather than produced by\n // that factory, so it has to spread it too. Upstream's `Overlay` sets\n // `pointerEvents` through THIS channel, not as a static prop.\n animatedProps?: Record<string, unknown>\n // Same handle a plain View exposes. RN gives every host component the\n // imperative geometry methods, and Reanimated's `useAnimatedRef` +\n // `measure()` is written against an Animated.View having them — without\n // this, measuring an animated view means wrapping it in a plain one.\n ref?: Ref<MeasureHandle>\n}\n\n// One driven colour property. Unlike transforms these do not compose, so each\n// is simply the latest value of its own declaration.\ntype ColorSlot = {\n property: DriveableColorProperty\n node: AnimatedNode\n}\n\n// One driven size. `base` is the value Yoga was given at the last React\n// commit, which is what the rebase moves and what the committed rect the\n// override sits on top of was laid out at.\ntype SizeSlot = {\n property: SizeProperty\n node: AnimatedNode\n base: number\n}\n\n// One warning per inset property per session, like every other channel here.\nconst warnedInsets = new Set<string>()\n\nconst insetTranslationOf = (property: InsetProperty): string =>\n property === \"top\" || property === \"bottom\" ? \"translateY\" : \"translateX\"\n\nconst warnInsetNotTranslatable = (\n property: InsetProperty,\n reason: string | null,\n): void => {\n if (warnedInsets.has(property)) {\n return\n }\n warnedInsets.add(property)\n const isProduction =\n typeof process !== \"undefined\" && process.env.NODE_ENV === \"production\"\n if (isProduction) {\n return\n }\n const spec = insetTranslationOf(property)\n console.warn(\n `react-native-gtkx: an animated \\`${property}\\` cannot be driven here. ` +\n (reason\n ? `The node IS absolutely positioned, but ${reason}, so there is no translation that reproduces it. `\n : \"`top`/`left`/`right`/`bottom` are driven at frame rate only on a node whose own `position` is \" +\n '\"absolute\", where moving it is exactly a translation and touches no sibling. Anything else needs a ' +\n \"Yoga pass over the container plus its commit walk, which costs what the CONTAINER costs (71 µs at \" +\n \"five children, 509 µs at three hundred) against a transform's 0.12 µs. \") +\n `Animate \\`transform: [{ ${spec}: … }]\\` instead. ` +\n \"The value is still applied on the next React render. See docs/api.md.\",\n )\n}\n\n/** @internal Test seam: the warning is once per property per session by design. */\nexport const resetAnimatedInsetWarnings = (): void => {\n warnedInsets.clear()\n}\n\n// Same policy for sizes: once per property per session, and the reason is the\n// actionable part — the rule refuses for one of eight named reasons and each\n// of them has a different fix.\nconst warnedSizes = new Set<string>()\n\nconst warnSizeNotDriveable = (property: SizeProperty, reason: string): void => {\n if (warnedSizes.has(property)) {\n return\n }\n warnedSizes.add(property)\n const isProduction =\n typeof process !== \"undefined\" && process.env.NODE_ENV === \"production\"\n if (isProduction) {\n return\n }\n const scale = property === \"width\" ? \"scaleX\" : \"scaleY\"\n console.warn(\n `react-native-gtkx: an animated \\`${property}\\` cannot be driven here, because ${reason}. ` +\n `\\`width\\`/\\`height\\` run at frame rate only where the change stops at the node that owns it — the ` +\n \"node's own subtree is then re-laid-out pinned to the driven value (7.1 µs for a leaf, 21.7 µs with \" +\n \"wrapped text, the same at five children and at three hundred) and one allocation puts it on screen. \" +\n \"Anything else needs a Yoga pass over the container plus its commit walk, which costs what the \" +\n \"CONTAINER costs: 71 µs at five children, 509 µs at three hundred, against a transform's 0.6 µs. \" +\n `The closest transform is \\`transform: [{ ${scale}: … }]\\`, but it is NOT the same thing — a scale ` +\n \"grows about the view's centre, so the box moves as it grows, and it scales the content with the box \" +\n \"instead of re-laying it out, so text stretches rather than re-wrapping. \" +\n \"The new value is applied on the next React render either way. See docs/api.md.\",\n )\n}\n\n/** @internal Test seam: the warning is once per property per session by design. */\nexport const resetAnimatedSizeWarnings = (): void => {\n warnedSizes.clear()\n}\n\nconst splitAnimated = (\n style: AnimatedStyleProp | false | null | undefined,\n): {\n staticStyle: StyleProp\n opacity: AnimatedNode | null\n zIndex: AnimatedNode | null\n slots: TransformSlot[]\n colors: ColorSlot[]\n sizes: SizeSlot[]\n} => {\n const flat: Record<string, unknown> = {}\n const collect = (\n entry: AnimatedStyleProp | false | null | undefined,\n ): void => {\n if (!entry) {\n return\n }\n if (Array.isArray(entry)) {\n entry.forEach(collect)\n return\n }\n Object.assign(flat, entry)\n }\n collect(style)\n\n let opacity: AnimatedNode | null = null\n let zIndex: AnimatedNode | null = null\n const slots: TransformSlot[] = []\n const colors: ColorSlot[] = []\n const sizes: SizeSlot[] = []\n\n if (isAnimatedNode(flat.opacity)) {\n opacity = flat.opacity\n delete flat.opacity\n }\n // `zIndex` is in `useSortable`'s style object on every frame and changes\n // value about twice per drag. It takes the same door opacity does — one\n // widget-level write, no Yoga, no CSS — so there is nothing to refuse.\n if (isAnimatedNode(flat.zIndex)) {\n zIndex = flat.zIndex\n delete flat.zIndex\n }\n for (const property of DRIVEABLE_COLOR_PROPERTIES) {\n const value = flat[property]\n if (isAnimatedNode(value)) {\n colors.push({ property, node: value })\n // Removed from the static style so the shared class registry never sees\n // a per-frame value: its memoisation stays keyed on styles that change\n // when React renders, which is the only thing it is good at.\n delete flat[property]\n }\n }\n if (Array.isArray(flat.transform)) {\n for (const part of flat.transform as AnimatedTransformPart[]) {\n const key = Object.keys(part)[0]\n if (key === undefined) {\n continue\n }\n const value = part[key]\n slots.push(\n isAnimatedNode(value)\n ? { key, node: value, value: value.__getValue() }\n : { key, node: null, value: value as AnimatedValue },\n )\n }\n // The whole array is owned here from now on, static entries included:\n // leaving them in the style would make useLayoutChild write the same\n // rect-store slot from the other side, and the two would overwrite\n // each other every render.\n delete flat.transform\n }\n\n // Slice 2b: an animated inset on an absolutely positioned node becomes a\n // derived translate. It is the one layout property with an exact transform\n // equivalent, because an out-of-flow node's position affects nothing but\n // where it is drawn — see src/style/absolute-insets.ts for the measured\n // rule and for the configurations where the equivalence does NOT hold.\n //\n // Three things happen here at once, and all three are load-bearing:\n //\n // - THE BASE. The inset's current value is written back into the static\n // style as a plain number, so Yoga is given a real position and the\n // committed rect the parent's allocate reads is the base the offset is\n // measured from. Nothing about the shadow tree changes.\n // - THE REBASE. This runs on every render, so when React commits a layout\n // with a different inset, the base moves and the offset is recomputed\n // against it in the SAME commit — the Yoga write and the offset write\n // are both layout effects, and the engine's flush is a microtask, so GTK\n // never gets a frame in between and there is no jump.\n // - THE ORDER. Derived slots go FIRST. The array's leftmost entry is the\n // outermost matrix (style/transform.ts), so a derived translate is\n // applied to the point LAST — it moves the already-rotated, already-\n // scaled box in the parent's coordinates, exactly as a layout position\n // does. Appending instead would put the user's scale on the OUTSIDE and\n // multiply the offset by it.\n const insetSlots: TransformSlot[] = []\n for (const property of INSET_PROPERTIES) {\n const value = flat[property]\n if (!isAnimatedNode(value)) {\n continue\n }\n const base = toNumber(value.__getValue())\n const translation = Number.isFinite(base)\n ? insetTranslation(flat, property)\n : null\n if (!translation) {\n // Not an equivalence. Resolve to the current value so the static style\n // is at least correct on this render, and keep slice 2's refusal loud.\n flat[property] = Number.isFinite(base) ? base : undefined\n warnInsetNotTranslatable(property, insetRefusalReason(flat, property))\n continue\n }\n flat[property] = base\n insetSlots.push({\n key: translation.transform,\n node: value,\n value: 0,\n inset: { base, sign: translation.sign },\n })\n }\n\n // Slice 3: an animated `width`/`height` where the change is confined to the\n // node that owns it. Unlike an inset this is NOT re-expressed as a\n // transform — there is no transform that reproduces a size change, which\n // docs/research/animated-size.md §6 measured rather than assumed — so the\n // slot carries the property itself and the view layer drives it through a\n // pinned pass over the node's own subtree.\n //\n // THE REBASE, exactly as above and for the same reason: the driven value is\n // written back into the static style as a plain number, so Yoga is given the\n // size the animation is currently showing and the committed rect the\n // override sits on catches up in the SAME commit. Both writes are layout\n // effects and the engine's flush is a microtask, so GTK never gets a frame\n // in between.\n //\n // WHETHER it can be driven is not decided here. The answer depends on the\n // CONTAINER's `flexDirection`, its `alignItems` and where its own size comes\n // from, none of which are in this style object or in this component's props\n // — it is asked of the layout tree in useAnimatedBinding, which is the only\n // place the tree exists.\n for (const property of SIZE_PROPERTIES) {\n const value = flat[property]\n if (!isAnimatedNode(value)) {\n continue\n }\n const base = toNumber(value.__getValue())\n if (!Number.isFinite(base)) {\n // A percentage produced mid-animation has no point base to lay out at.\n // Dropped rather than driven, and the leaf never becomes driveable in\n // the first place unless it starts numeric — reanimated-compat/style.ts.\n flat[property] = undefined\n continue\n }\n flat[property] = base\n sizes.push({ property, node: value, base })\n }\n\n return {\n staticStyle: flat as StyleProp,\n opacity,\n zIndex,\n slots: insetSlots.length > 0 ? [...insetSlots, ...slots] : slots,\n colors,\n sizes,\n }\n}\n\n/**\n * The imperative write path, and the whole of it.\n *\n * Animated values bypass React entirely: listeners write straight to the\n * widget (opacity), to the rect store (the transform applied by the parent's\n * allocate) on top of the engine-committed base rect, and to a CSS provider\n * private to the widget (colours). Animation frames never touch Yoga, and\n * never touch the shared stylesheet.\n *\n * Nothing here is View-specific, which is why it is a hook rather than a\n * paragraph inside `AnimatedView`: it needs the CHILD's widget (for\n * `setOpacity` and the rect store) and its PARENT's (for `queueAllocate`),\n * and any component that can produce those two can be animated. The child is\n * reached through a getter rather than a ref because a wrapper does not own\n * the widget — it reads it back out of whatever handle the wrapped component\n * exposed, which may only exist after that component's own layout effects.\n */\nconst useAnimatedBinding = (\n getWidget: () => Gtk.Widget | null,\n host: HostNode,\n opacity: AnimatedNode | null,\n zIndex: AnimatedNode | null,\n slots: TransformSlot[],\n colors: ColorSlot[],\n sizes: SizeSlot[],\n // Anything else that must force a rebind. `AnimatedView` passes its layout\n // node; the generic wrapper has nothing to add.\n rebindKey?: unknown,\n): void => {\n // The effect reads the slots of the render that (re)armed it; the values\n // inside are then owned by the listeners.\n const slotsRef = useRef<TransformSlot[]>(slots)\n slotsRef.current = slots\n const colorsRef = useRef<ColorSlot[]>(colors)\n colorsRef.current = colors\n const sizesRef = useRef<SizeSlot[]>(sizes)\n sizesRef.current = sizes\n const getWidgetRef = useRef(getWidget)\n getWidgetRef.current = getWidget\n const hostRef = useRef(host)\n hostRef.current = host\n const parentWidgetRef = host.widgetRef\n\n // Rebind on a change of shape (which transforms, in which order), of the\n // node behind an animated entry, or of a static entry's value — not on\n // every render that rebuilds an equal-looking array.\n //\n // A derived inset slot adds its BASE to the key, and that is what makes the\n // rebase happen: React committing a new `top` moves the base, which re-arms\n // this effect in the same commit that gives Yoga the new position.\n const bindingKey =\n (opacity ? `opacity#${nodeId(opacity)}` : \"\") +\n (zIndex ? `zIndex#${nodeId(zIndex)}` : \"\") +\n slots\n .map((slot) => {\n const inset = slot.inset ? `~${slot.inset.sign}:${slot.inset.base}` : \"\"\n return slot.node\n ? `|${slot.key}#${nodeId(slot.node)}${inset}`\n : `|${slot.key}=${String(slot.value)}`\n })\n .join(\"\") +\n colors.map((slot) => `|${slot.property}#${nodeId(slot.node)}`).join(\"\") +\n // The base is in the key for the same reason a derived inset's is: React\n // committing a new size moves it, and re-arming here is what hands the\n // override back to the engine in the same commit that gives Yoga the new\n // value.\n sizes\n .map((slot) => `|${slot.property}#${nodeId(slot.node)}~${slot.base}`)\n .join(\"\")\n\n useLayoutEffect(() => {\n const widget = getWidgetRef.current()\n if (!widget) {\n return\n }\n // Captured for the CLEANUP only: by then the ref may already have been\n // detached, and the container to re-allocate is the one this binding was\n // made against. Every live write below re-reads the ref instead.\n const boundParentWidget = parentWidgetRef.current\n\n // The live transform array, mutated in place: an Animated write must\n // stay one numeric store plus one queued allocation — no React render,\n // no Yoga pass, no allocation per frame beyond the composed matrix.\n //\n // RN transform semantics: this is paint-only. The result goes to the\n // rect store unclamped — the parent's measure ignores children, so a\n // transformed child draws past the boundary over its neighbors without\n // moving a single ancestor.\n const parts = slotsRef.current.map(\n (slot) =>\n ({\n [slot.key]: slot.node\n ? slotValue(slot, slot.node.__getValue())\n : slot.value,\n }) as Record<string, AnimatedValue>,\n )\n\n const flush = (): void => {\n const widget = getWidgetRef.current()\n if (!widget) {\n return\n }\n setStoredTransform(widget, parts as unknown as TransformPart[])\n const parentWidget = parentWidgetRef.current\n if (parentWidget) {\n queueAllocate(parentWidget)\n }\n }\n\n const subscriptions: { node: AnimatedNode; id: string }[] = []\n slotsRef.current.forEach((slot, index) => {\n if (!slot.node) {\n return\n }\n const part = parts[index]!\n subscriptions.push({\n node: slot.node,\n id: slot.node.addListener(({ value }) => {\n part[slot.key] = slotValue(slot, value)\n flush()\n }),\n })\n })\n\n if (opacity) {\n const applyOpacity = (value: AnimatedValue): void => {\n const numeric = typeof value === \"number\" ? value : parseFloat(value)\n getWidgetRef.current()?.setOpacity(Math.min(1, Math.max(0, numeric)))\n }\n subscriptions.push({\n node: opacity,\n id: opacity.addListener(({ value }) => {\n applyOpacity(value)\n }),\n })\n applyOpacity(opacity.__getValue())\n }\n\n // The container's paint and pick order (gtkx/bridge/view-box.ts). The\n // write drops the container's cached order and queues a redraw; nothing\n // is re-measured and nothing is re-allocated, because zIndex changes\n // neither.\n if (zIndex) {\n const applyZIndex = (value: AnimatedValue): void => {\n const widget = getWidgetRef.current()\n if (!widget) {\n return\n }\n const numeric = typeof value === \"number\" ? value : parseFloat(value)\n setZIndex(widget, Number.isFinite(numeric) ? Math.round(numeric) : 0)\n }\n subscriptions.push({\n node: zIndex,\n id: zIndex.addListener(({ value }) => {\n applyZIndex(value)\n }),\n })\n applyZIndex(zIndex.__getValue())\n }\n\n // Colours take the other imperative door: a CSS provider private to this\n // widget, replaced in place. Deliberately NOT the shared class registry —\n // that one memoises by CSS text, so a driven colour would mint a class per\n // frame into a document GTK re-parses whole and that is never pruned\n // (docs/research/animated-colors.md). All driven colours share one\n // provider and one declaration block: two properties animating together\n // are one write, not two.\n const colorSlots = colorsRef.current\n let widgetCss: WidgetCss | null = null\n if (colorSlots.length > 0) {\n const css = createWidgetCss(widget)\n widgetCss = css\n const values: Record<string, unknown> = {}\n const writeColors = (): void => {\n css.set(driveableColorsToCss(values))\n }\n for (const slot of colorSlots) {\n values[slot.property] = slot.node.__getValue()\n subscriptions.push({\n node: slot.node,\n id: slot.node.addListener(({ value }) => {\n values[slot.property] = value\n writeColors()\n }),\n })\n }\n writeColors()\n }\n\n // Sizes take the third door, and it is the only one that runs Yoga.\n //\n // Nothing is written at BIND time on purpose: the render that armed this\n // effect put the current value into the static style, so the engine is\n // already committing exactly this size and an override would be a copy of\n // it. The first write happens when a frame asks for something else.\n const sizeSlots = sizesRef.current\n const drivenWidgets: Gtk.Widget[] = []\n if (sizeSlots.length > 0) {\n const layoutNode = nodeForWidget(widget)\n const driven: DrivenSize = {}\n const driveable = new Set<SizeProperty>()\n let decided = false\n // Deferred to the first frame that actually asks for a new size, and\n // that is not laziness: the rule is asked of the CONTAINER's Yoga node,\n // and on a first mount a container's own layout effects run AFTER its\n // children's — so at bind time the container may still be carrying the\n // defaults rather than its style. By the first frame the tree has been\n // laid out at least once and the answer is the real one.\n const decide = (): void => {\n decided = true\n if (!layoutNode) {\n return\n }\n const context = {\n node: layoutNode,\n rootIsContentSized: hostRef.current.engine.contentSized,\n }\n for (const slot of sizeSlots) {\n const reason = drivenSizeRefusal(context, slot.property)\n if (reason === null) {\n driveable.add(slot.property)\n } else {\n warnSizeNotDriveable(slot.property, reason)\n }\n }\n }\n for (const slot of sizeSlots) {\n subscriptions.push({\n node: slot.node,\n id: slot.node.addListener(({ value }) => {\n const numeric = toNumber(value)\n if (!Number.isFinite(numeric)) {\n return\n }\n if (!decided) {\n decide()\n }\n if (!driveable.has(slot.property) || !layoutNode) {\n return\n }\n driven[slot.property] = numeric\n const target = getWidgetRef.current()\n if (target) {\n applyDrivenSize(\n layoutNode,\n target,\n parentWidgetRef.current,\n driven,\n drivenWidgets,\n )\n }\n }),\n })\n }\n }\n\n flush()\n\n return () => {\n for (const { node: animated, id } of subscriptions) {\n animated.removeListener(id)\n }\n widgetCss?.dispose()\n // Every widget this binding was driving goes back to the rect the\n // engine committed. On a REBASE that is the whole point: the render\n // that re-armed this effect handed Yoga the size the animation is\n // showing, so the committed rect is about to become the driven one and\n // holding an override on top of it would be holding a stale copy.\n if (drivenWidgets.length > 0) {\n releaseDrivenSize(drivenWidgets)\n if (boundParentWidget) {\n queueAllocate(boundParentWidget)\n }\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [bindingKey, rebindKey])\n}\n\nconst AnimatedView = ({\n style,\n children,\n onLayout,\n testID,\n ref,\n pointerEvents,\n animatedProps,\n ...responderProps\n}: AnimatedViewProps) => {\n const widgetRef = useRef<Gtk.Box | null>(null)\n const { staticStyle, opacity, zIndex, slots, colors, sizes } =\n splitAnimated(style)\n\n const { host, node, cssClass } = useLayoutChild(widgetRef, {\n style: staticStyle,\n onLayout,\n })\n useRnContainer(widgetRef, node)\n useResponder(widgetRef, responderProps)\n\n // `animatedProps` LAST, matching `createAnimatedComponent`'s\n // `{ ...rest, ...animatedProps }` — a value produced by the updater is the\n // live one and wins over the static prop. Only the picking mode is read\n // here: a numeric animated prop has no meaning on a View, and the SVG\n // shapes that do take them go through `createAnimatedComponent` already.\n const mode: PointerEventsValue =\n (animatedProps?.pointerEvents as PointerEventsValue | undefined) ??\n pointerEvents ??\n StyleSheet.flatten(staticStyle)?.pointerEvents ??\n \"auto\"\n\n useLayoutEffect(() => {\n const widget = widgetRef.current\n if (!widget) {\n return\n }\n setPointerTarget(widget, mode !== \"none\")\n setBoxPassthrough(widget, mode === \"box-none\")\n }, [mode])\n\n useImperativeHandle(ref, () => createMeasureHandle(widgetRef, node), [node])\n\n useAnimatedBinding(\n () => widgetRef.current,\n host,\n opacity,\n zIndex,\n slots,\n colors,\n sizes,\n node,\n )\n\n return (\n <GtkBox\n ref={widgetRef}\n name={testID}\n cssClasses={cssClass ? [cssClass] : []}\n >\n <HostNodeContext.Provider\n value={{ engine: host.engine, node, widgetRef }}\n >\n {children}\n </HostNodeContext.Provider>\n </GtkBox>\n )\n}\n\n// --- createAnimatedComponent ---------------------------------------------\n\n/** Node-backed props from `useAnimatedProps`, spread onto the wrapped component. */\nexport type AnimatedPropsProp = Record<string, unknown>\n\n/** The props an animated wrapper adds on top of the component's own. */\nexport type AnimatedComponentExtraProps = {\n style?: AnimatedStyleProp\n animatedProps?: AnimatedPropsProp\n}\n\n// `Partial`, as upstream's own `AnimatedProps<Props>` effectively is: a prop\n// supplied through `animatedProps` is invisible to the type system here, so\n// insisting on the wrapped component's required props would reject exactly\n// the call the feature exists for (`<AnimatedCircle animatedProps={{ r }} />`).\nexport type AnimatedComponent<C extends ElementType> = (\n props: Partial<Omit<ComponentProps<C>, \"style\">> &\n AnimatedComponentExtraProps,\n) => ReactNode\n\nconst displayNameOf = (component: unknown): string => {\n if (typeof component === \"string\") {\n return component\n }\n const named = component as { displayName?: string; name?: string }\n return named?.displayName ?? named?.name ?? \"Component\"\n}\n\n// One warning per wrapped component per session — a mapper runs at frame\n// rate, and the name is the actionable part.\nconst warnedWithoutWidget = new Set<string>()\n\nconst warnNoWidget = (name: string): void => {\n if (warnedWithoutWidget.has(name)) {\n return\n }\n warnedWithoutWidget.add(name)\n const isProduction =\n typeof process !== \"undefined\" && process.env.NODE_ENV === \"production\"\n if (!isProduction) {\n console.warn(\n `react-native-gtkx: createAnimatedComponent(${name}) was given an animated \\`opacity\\`, ` +\n \"`transform`, colour or size, but the component exposed no ref carrying a widget, so there is nothing to write \" +\n \"to. Give it a `ref?: Ref<MeasureHandle>` built with the platform's own measure handle, or wrap \" +\n \"it in an `Animated.View`. See docs/api.md.\",\n )\n }\n}\n\n/** @internal Test seam: the warning is once per component per session by design. */\nexport const resetAnimatedComponentWarnings = (): void => {\n warnedWithoutWidget.clear()\n}\n\n/**\n * Wraps a component so its `style`'s `opacity`/`transform` and its\n * `animatedProps` can be driven imperatively — RN's own\n * `Animated.createAnimatedComponent`.\n *\n * IT ADDS NO WIDGET. Wrapping in an `Animated.View` would have been three\n * lines and would have been wrong: an extra box changes flex layout, changes\n * what `measureLayout` is relative to, and changes which widget a parent's\n * allocate walks. That is not a shim, it is a different tree. Instead the\n * wrapper renders the component itself and reaches the widget through the\n * handle the component already exposes (see measure.ts's `widgetOf`), so the\n * rendered output is byte-for-byte what the unwrapped component produces.\n *\n * `animatedProps` are passed straight through as animated NODES rather than\n * resolved to numbers, because the components that take them already accept\n * one: the SVG shapes duck-type an animated node on every numeric geometry\n * and paint prop and subscribe to it themselves (svg/animated-support.ts),\n * redrawing through `queueDraw`. Nothing is resolved here that the receiver\n * can resolve better.\n */\nexport const createAnimatedComponent = <C extends ElementType>(\n component: C,\n): AnimatedComponent<C> => {\n const name = displayNameOf(component)\n\n const AnimatedWrapper = ({\n style,\n animatedProps,\n ref,\n ...rest\n }: AnimatedComponentExtraProps & {\n ref?: Ref<unknown>\n [key: string]: unknown\n }) => {\n // The PARENT's widget, for `queueAllocate` — the wrapper is not a host\n // node itself, so this is the container the wrapped component is laid out\n // by, exactly as it would be without the wrapper.\n const host = useHostNode()\n const handleRef = useRef<unknown>(null)\n const { staticStyle, opacity, zIndex, slots, colors, sizes } =\n splitAnimated(style)\n const driven =\n opacity !== null ||\n zIndex !== null ||\n slots.length > 0 ||\n colors.length > 0 ||\n sizes.length > 0\n\n // Stable identity: a fresh callback ref every render would detach and\n // reattach the wrapped component's handle on every render.\n const forwardedRef = useRef<Ref<unknown> | undefined>(ref)\n forwardedRef.current = ref\n const [assignHandle] = useState(() => (instance: unknown) => {\n handleRef.current = instance\n const target = forwardedRef.current\n if (typeof target === \"function\") {\n target(instance)\n } else if (target) {\n ;(target as { current: unknown }).current = instance\n }\n // No return value: React 19 reads one as a callback-ref cleanup.\n })\n\n useAnimatedBinding(\n () => widgetForHandle(handleRef.current),\n host,\n opacity,\n zIndex,\n slots,\n colors,\n sizes,\n )\n\n // A silent no-op is the failure this repo refuses. Checked after the\n // wrapped component's own layout effects have run, which is where its\n // `useImperativeHandle` publishes the handle.\n useLayoutEffect(() => {\n if (driven && widgetForHandle(handleRef.current) === null) {\n warnNoWidget(name)\n }\n })\n\n const targetProps: Record<string, unknown> = { ...rest, ...animatedProps }\n // Only when there is something to attach: a component that takes no ref\n // (the SVG shapes) would otherwise get one in its rest props.\n if (driven || ref) {\n targetProps.ref = assignHandle\n }\n // Likewise `style`: passing `{}` to a component that has no style prop\n // would push an empty object into whatever collects its rest props.\n if (style !== undefined) {\n targetProps.style = staticStyle\n }\n\n const Target = component as ComponentType<Record<string, unknown>>\n return <Target {...targetProps} />\n }\n AnimatedWrapper.displayName = `Animated(${name})`\n\n return AnimatedWrapper as AnimatedComponent<C>\n}\n\n/**\n * `Animated.FlatList` is deliberately absent, and this is the refusal.\n *\n * FlatList is a COMPOSITE, not a host component: it renders the windowed\n * VirtualizedList core, which renders a ScrollView, which is the only thing\n * in that chain owning a widget. Its ref is a scroll API by contract\n * (`scrollToIndex`/`scrollToItem`/`scrollToOffset`), so there is no handle to\n * read a widget back out of — and giving it one would mean publishing the\n * scrolled window through two layers that exist to hide it.\n *\n * Upstream's `Animated.FlatList` mostly exists so `onScroll` can be an\n * `Animated.event`/`useAnimatedScrollHandler`, and neither of those is\n * implemented here either. So this throws where it is used, naming itself and\n * naming the two things that do work.\n */\nconst AnimatedFlatList = (): never => {\n throw new Error(\n \"react-native-gtkx: `Animated.FlatList` is not implemented. FlatList is a composite — the windowed \" +\n \"core over a ScrollView — and its ref is a scroll API, so there is no host widget for an animated \" +\n \"style to write to. Put the animated style on an `Animated.View` wrapping the list, or use \" +\n \"`Animated.ScrollView` if the list does not need virtualization. See docs/api.md.\",\n )\n}\nAnimatedFlatList.displayName = \"Animated.FlatList\"\n\n/**\n * `Text`, `Image` and `ScrollView` are the generic wrapper over the\n * platform's own components — no subclass, no special case, and no widget\n * added to the tree. They are animatable at all because those three now\n * expose a ref carrying their widget, which is RN parity in its own right.\n */\nconst AnimatedText = createAnimatedComponent(Text)\nconst AnimatedImage = createAnimatedComponent(Image)\nconst AnimatedScrollView = createAnimatedComponent(ScrollView)\n\nexport const Animated = {\n ...api,\n View: AnimatedView,\n Text: AnimatedText,\n Image: AnimatedImage,\n ScrollView: AnimatedScrollView,\n // Typed as taking the props it refuses, so the failure is at RUNTIME with\n // the message above rather than at compile time with \"no overload matches\n // this call\" — an app porting from mobile deserves the sentence, not a\n // type puzzle.\n FlatList: AnimatedFlatList as (props: Record<string, unknown>) => never,\n createAnimatedComponent,\n}\n\nexport { Easing } from \"../animated/index\"\n"]}
@@ -0,0 +1,27 @@
1
+ import { type DrivenSize } from "../layout/driven-size";
2
+ import type { LayoutNode } from "../layout/node";
3
+ import { type Gtk } from "../gtkx/bridge/index";
4
+ /**
5
+ * Drives `widget` to `size` and puts it on screen.
6
+ *
7
+ * `touched` is the caller's record of every widget currently carrying an
8
+ * override, rewritten in place on each frame so that unbinding — or a React
9
+ * render, which rebases onto a freshly committed layout — can hand every one
10
+ * of them back to the engine.
11
+ *
12
+ * The node itself overrides ONLY the axis being driven. Its origin and its
13
+ * other axis keep coming from the committed rect, which is both the claim of
14
+ * the carve-out (neither moved) and what keeps a window resize mid-animation
15
+ * from leaving the node behind at a stale position.
16
+ *
17
+ * The driven axis is read back OUT of Yoga rather than written straight
18
+ * through, and that is not ceremony. Yoga floors a box at its own padding and
19
+ * border, so a node with `padding: "10%"` driven below that floor is 80 px
20
+ * wide in a real pass and would have been allocated 60 by a value written
21
+ * straight through — a divergence the engine probe caught
22
+ * (tests/unit/style/animated-size.test.ts). Asking Yoga what the size became
23
+ * reproduces its arithmetic instead of re-deriving it here.
24
+ */
25
+ export declare const applyDrivenSize: (node: LayoutNode, widget: Gtk.Widget, parentWidget: Gtk.Widget | null, size: DrivenSize, touched: Gtk.Widget[]) => void;
26
+ /** Hands every driven widget back to whatever the engine last committed. */
27
+ export declare const releaseDrivenSize: (touched: Gtk.Widget[]) => void;
@@ -0,0 +1,85 @@
1
+ // The write half of an animated size: one pinned Yoga pass over the animated
2
+ // node's own subtree, its results into the rect store as OVERRIDES, and one
3
+ // queued allocation on the parent. No engine flush, no commit walk, no
4
+ // `queueResize`, and nothing above the node is visited.
5
+ //
6
+ // Why the descendants are written too, and why that is not optional: a rect
7
+ // write alone — the node's own box and nothing else — is 0.9 µs and beautifully
8
+ // flat, and it is wrong. It makes the BOX the right size and leaves everything
9
+ // inside it on its old layout: a label stayed 100 px wide and three lines tall
10
+ // inside a 260 px box (docs/research/animated-size.md §5). Re-wrapping is what
11
+ // a size change MEANS, and it is the difference between this and a `scaleX`.
12
+ import { layoutSubtreeAtSize } from "../layout/driven-size";
13
+ import { queueAllocate } from "../gtkx/bridge/index";
14
+ import { clearStoredDrivenBox, getStoredRect, setStoredDrivenBox, } from "./rect-store";
15
+ import { nodeForWidget } from "./use-layout-child";
16
+ const writeSubtree = (node, widget, touched) => {
17
+ let child = widget.getFirstChild();
18
+ while (child !== null) {
19
+ const childNode = nodeForWidget(child);
20
+ // Only this container's own layout children: a nested layout root belongs
21
+ // to a different engine and lays itself out, and a raw GTK widget in a
22
+ // slot has no node at all.
23
+ if (childNode !== undefined &&
24
+ childNode.parent === node &&
25
+ getStoredRect(child) !== undefined) {
26
+ const yoga = childNode.yoga;
27
+ setStoredDrivenBox(child, {
28
+ x: yoga.getComputedLeft(),
29
+ y: yoga.getComputedTop(),
30
+ width: yoga.getComputedWidth(),
31
+ height: yoga.getComputedHeight(),
32
+ });
33
+ touched.push(child);
34
+ writeSubtree(childNode, child, touched);
35
+ }
36
+ child = child.getNextSibling();
37
+ }
38
+ };
39
+ /**
40
+ * Drives `widget` to `size` and puts it on screen.
41
+ *
42
+ * `touched` is the caller's record of every widget currently carrying an
43
+ * override, rewritten in place on each frame so that unbinding — or a React
44
+ * render, which rebases onto a freshly committed layout — can hand every one
45
+ * of them back to the engine.
46
+ *
47
+ * The node itself overrides ONLY the axis being driven. Its origin and its
48
+ * other axis keep coming from the committed rect, which is both the claim of
49
+ * the carve-out (neither moved) and what keeps a window resize mid-animation
50
+ * from leaving the node behind at a stale position.
51
+ *
52
+ * The driven axis is read back OUT of Yoga rather than written straight
53
+ * through, and that is not ceremony. Yoga floors a box at its own padding and
54
+ * border, so a node with `padding: "10%"` driven below that floor is 80 px
55
+ * wide in a real pass and would have been allocated 60 by a value written
56
+ * straight through — a divergence the engine probe caught
57
+ * (tests/unit/style/animated-size.test.ts). Asking Yoga what the size became
58
+ * reproduces its arithmetic instead of re-deriving it here.
59
+ */
60
+ export const applyDrivenSize = (node, widget, parentWidget, size, touched) => {
61
+ if (getStoredRect(widget) === undefined) {
62
+ return;
63
+ }
64
+ layoutSubtreeAtSize(node, size);
65
+ releaseDrivenSize(touched);
66
+ setStoredDrivenBox(widget, {
67
+ x: null,
68
+ y: null,
69
+ width: size.width === undefined ? null : node.yoga.getComputedWidth(),
70
+ height: size.height === undefined ? null : node.yoga.getComputedHeight(),
71
+ });
72
+ touched.push(widget);
73
+ writeSubtree(node, widget, touched);
74
+ if (parentWidget) {
75
+ queueAllocate(parentWidget);
76
+ }
77
+ };
78
+ /** Hands every driven widget back to whatever the engine last committed. */
79
+ export const releaseDrivenSize = (touched) => {
80
+ for (const widget of touched) {
81
+ clearStoredDrivenBox(widget);
82
+ }
83
+ touched.length = 0;
84
+ };
85
+ //# sourceMappingURL=driven-size.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driven-size.js","sourceRoot":"","sources":["../../src/components/driven-size.ts"],"names":[],"mappings":"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","sourcesContent":["// The write half of an animated size: one pinned Yoga pass over the animated\n// node's own subtree, its results into the rect store as OVERRIDES, and one\n// queued allocation on the parent. No engine flush, no commit walk, no\n// `queueResize`, and nothing above the node is visited.\n//\n// Why the descendants are written too, and why that is not optional: a rect\n// write alone — the node's own box and nothing else — is 0.9 µs and beautifully\n// flat, and it is wrong. It makes the BOX the right size and leaves everything\n// inside it on its old layout: a label stayed 100 px wide and three lines tall\n// inside a 260 px box (docs/research/animated-size.md §5). Re-wrapping is what\n// a size change MEANS, and it is the difference between this and a `scaleX`.\nimport { layoutSubtreeAtSize, type DrivenSize } from \"../layout/driven-size\"\nimport type { LayoutNode } from \"../layout/node\"\nimport { queueAllocate, type Gtk } from \"../gtkx/bridge/index\"\nimport {\n clearStoredDrivenBox,\n getStoredRect,\n setStoredDrivenBox,\n} from \"./rect-store\"\nimport { nodeForWidget } from \"./use-layout-child\"\n\nconst writeSubtree = (\n node: LayoutNode,\n widget: Gtk.Widget,\n touched: Gtk.Widget[],\n): void => {\n let child = widget.getFirstChild()\n while (child !== null) {\n const childNode = nodeForWidget(child)\n // Only this container's own layout children: a nested layout root belongs\n // to a different engine and lays itself out, and a raw GTK widget in a\n // slot has no node at all.\n if (\n childNode !== undefined &&\n childNode.parent === node &&\n getStoredRect(child) !== undefined\n ) {\n const yoga = childNode.yoga\n setStoredDrivenBox(child, {\n x: yoga.getComputedLeft(),\n y: yoga.getComputedTop(),\n width: yoga.getComputedWidth(),\n height: yoga.getComputedHeight(),\n })\n touched.push(child)\n writeSubtree(childNode, child, touched)\n }\n child = child.getNextSibling()\n }\n}\n\n/**\n * Drives `widget` to `size` and puts it on screen.\n *\n * `touched` is the caller's record of every widget currently carrying an\n * override, rewritten in place on each frame so that unbinding — or a React\n * render, which rebases onto a freshly committed layout — can hand every one\n * of them back to the engine.\n *\n * The node itself overrides ONLY the axis being driven. Its origin and its\n * other axis keep coming from the committed rect, which is both the claim of\n * the carve-out (neither moved) and what keeps a window resize mid-animation\n * from leaving the node behind at a stale position.\n *\n * The driven axis is read back OUT of Yoga rather than written straight\n * through, and that is not ceremony. Yoga floors a box at its own padding and\n * border, so a node with `padding: \"10%\"` driven below that floor is 80 px\n * wide in a real pass and would have been allocated 60 by a value written\n * straight through — a divergence the engine probe caught\n * (tests/unit/style/animated-size.test.ts). Asking Yoga what the size became\n * reproduces its arithmetic instead of re-deriving it here.\n */\nexport const applyDrivenSize = (\n node: LayoutNode,\n widget: Gtk.Widget,\n parentWidget: Gtk.Widget | null,\n size: DrivenSize,\n touched: Gtk.Widget[],\n): void => {\n if (getStoredRect(widget) === undefined) {\n return\n }\n layoutSubtreeAtSize(node, size)\n releaseDrivenSize(touched)\n setStoredDrivenBox(widget, {\n x: null,\n y: null,\n width: size.width === undefined ? null : node.yoga.getComputedWidth(),\n height: size.height === undefined ? null : node.yoga.getComputedHeight(),\n })\n touched.push(widget)\n writeSubtree(node, widget, touched)\n if (parentWidget) {\n queueAllocate(parentWidget)\n }\n}\n\n/** Hands every driven widget back to whatever the engine last committed. */\nexport const releaseDrivenSize = (touched: Gtk.Widget[]): void => {\n for (const widget of touched) {\n clearStoredDrivenBox(widget)\n }\n touched.length = 0\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import { type NodeHandle } from "./measure";
2
+ /**
3
+ * RN's `findNodeHandle`: the node handle for a mounted component, or null.
4
+ *
5
+ * Accepts what RN accepts — a component handle (what a ref holds here), a
6
+ * node handle (returned unchanged), or null/undefined. Anything else,
7
+ * including a ref to something this platform never registered as a host
8
+ * view, returns null rather than inventing a tag for it.
9
+ */
10
+ export declare const findNodeHandle: (componentOrHandle: unknown) => NodeHandle | null;
11
+ export type { NodeHandle };
@@ -0,0 +1,53 @@
1
+ // RN's escape hatch from a ref to a native view handle.
2
+ //
3
+ // On a bridge platform the returned integer is the native view tag, and it
4
+ // exists because a JS ref cannot cross to native — the number can. There is
5
+ // no boundary here: a widget call is a synchronous C call on this same
6
+ // stack, and `widgetForHandle` already resolves a component handle straight
7
+ // to its `Gtk.Widget`. So the honest question is not "what is a native
8
+ // handle here" but "what do the callers do with the number", and measured
9
+ // against the libraries that ask for one, they do exactly two things:
10
+ //
11
+ // - compare it. `@gorhom/bottom-sheet` reads it in `useScrollableSetter`
12
+ // and `useScrollable` to decide whether the scrollable that just mounted
13
+ // is the one it already tracks (`id !== ref.id`). It never dereferences
14
+ // it — the ref itself travels alongside, in the same record.
15
+ // - hand it back to `measureLayout`. `react-native-draggable-flatlist`
16
+ // takes a handle for its outer scroll container in
17
+ // `NestableDraggableFlatList` and passes it as the first argument of
18
+ // `containerRef.current.measureLayout(...)`, which is RN's other
19
+ // spelling of "relative to that view".
20
+ //
21
+ // Both are satisfied by an integer that is stable per mounted WIDGET and
22
+ // resolvable back to it, which is what `nodeHandleFor` mints and what
23
+ // `measureLayout` now accepts. Returning the handle OBJECT instead would
24
+ // satisfy them too and would be a lie about the type: `NodeHandle` is a
25
+ // number on every platform RN runs on, and a library that stores one in a
26
+ // `Map<number, …>` or logs it would get something else. Keying by the widget
27
+ // rather than by the handle is what makes the tag survive a re-render — a
28
+ // `useImperativeHandle` builds a fresh handle object each time, and a tag
29
+ // that changed with it would tell `@gorhom/bottom-sheet` its scrollable had
30
+ // been replaced on every render.
31
+ //
32
+ // What it does NOT do is reach anything native. There is no `UIManager` here
33
+ // to pass a tag to, so a tag is worth exactly what this platform can resolve
34
+ // it to and no more — see docs/api.md.
35
+ import { nodeHandleFor } from "./measure";
36
+ /**
37
+ * RN's `findNodeHandle`: the node handle for a mounted component, or null.
38
+ *
39
+ * Accepts what RN accepts — a component handle (what a ref holds here), a
40
+ * node handle (returned unchanged), or null/undefined. Anything else,
41
+ * including a ref to something this platform never registered as a host
42
+ * view, returns null rather than inventing a tag for it.
43
+ */
44
+ export const findNodeHandle = (componentOrHandle) => {
45
+ if (componentOrHandle === null || componentOrHandle === undefined) {
46
+ return null;
47
+ }
48
+ if (typeof componentOrHandle === "number") {
49
+ return componentOrHandle;
50
+ }
51
+ return nodeHandleFor(componentOrHandle);
52
+ };
53
+ //# sourceMappingURL=find-node-handle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-node-handle.js","sourceRoot":"","sources":["../../src/components/find-node-handle.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,uEAAuE;AACvE,4EAA4E;AAC5E,uEAAuE;AACvE,0EAA0E;AAC1E,sEAAsE;AACtE,EAAE;AACF,2EAA2E;AAC3E,6EAA6E;AAC7E,4EAA4E;AAC5E,iEAAiE;AACjE,yEAAyE;AACzE,uDAAuD;AACvD,yEAAyE;AACzE,qEAAqE;AACrE,2CAA2C;AAC3C,EAAE;AACF,yEAAyE;AACzE,sEAAsE;AACtE,yEAAyE;AACzE,wEAAwE;AACxE,0EAA0E;AAC1E,6EAA6E;AAC7E,0EAA0E;AAC1E,0EAA0E;AAC1E,4EAA4E;AAC5E,iCAAiC;AACjC,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,uCAAuC;AACvC,OAAO,EAAE,aAAa,EAAmB,MAAM,WAAW,CAAA;AAE1D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,iBAA0B,EACP,EAAE;IACrB,IAAI,iBAAiB,KAAK,IAAI,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;QAClE,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,OAAO,iBAAiB,KAAK,QAAQ,EAAE,CAAC;QAC1C,OAAO,iBAAiB,CAAA;IAC1B,CAAC;IACD,OAAO,aAAa,CAAC,iBAAiB,CAAC,CAAA;AACzC,CAAC,CAAA","sourcesContent":["// RN's escape hatch from a ref to a native view handle.\n//\n// On a bridge platform the returned integer is the native view tag, and it\n// exists because a JS ref cannot cross to native — the number can. There is\n// no boundary here: a widget call is a synchronous C call on this same\n// stack, and `widgetForHandle` already resolves a component handle straight\n// to its `Gtk.Widget`. So the honest question is not \"what is a native\n// handle here\" but \"what do the callers do with the number\", and measured\n// against the libraries that ask for one, they do exactly two things:\n//\n// - compare it. `@gorhom/bottom-sheet` reads it in `useScrollableSetter`\n// and `useScrollable` to decide whether the scrollable that just mounted\n// is the one it already tracks (`id !== ref.id`). It never dereferences\n// it — the ref itself travels alongside, in the same record.\n// - hand it back to `measureLayout`. `react-native-draggable-flatlist`\n// takes a handle for its outer scroll container in\n// `NestableDraggableFlatList` and passes it as the first argument of\n// `containerRef.current.measureLayout(...)`, which is RN's other\n// spelling of \"relative to that view\".\n//\n// Both are satisfied by an integer that is stable per mounted WIDGET and\n// resolvable back to it, which is what `nodeHandleFor` mints and what\n// `measureLayout` now accepts. Returning the handle OBJECT instead would\n// satisfy them too and would be a lie about the type: `NodeHandle` is a\n// number on every platform RN runs on, and a library that stores one in a\n// `Map<number, …>` or logs it would get something else. Keying by the widget\n// rather than by the handle is what makes the tag survive a re-render — a\n// `useImperativeHandle` builds a fresh handle object each time, and a tag\n// that changed with it would tell `@gorhom/bottom-sheet` its scrollable had\n// been replaced on every render.\n//\n// What it does NOT do is reach anything native. There is no `UIManager` here\n// to pass a tag to, so a tag is worth exactly what this platform can resolve\n// it to and no more — see docs/api.md.\nimport { nodeHandleFor, type NodeHandle } from \"./measure\"\n\n/**\n * RN's `findNodeHandle`: the node handle for a mounted component, or null.\n *\n * Accepts what RN accepts — a component handle (what a ref holds here), a\n * node handle (returned unchanged), or null/undefined. Anything else,\n * including a ref to something this platform never registered as a host\n * view, returns null rather than inventing a tag for it.\n */\nexport const findNodeHandle = (\n componentOrHandle: unknown,\n): NodeHandle | null => {\n if (componentOrHandle === null || componentOrHandle === undefined) {\n return null\n }\n if (typeof componentOrHandle === \"number\") {\n return componentOrHandle\n }\n return nodeHandleFor(componentOrHandle)\n}\n\nexport type { NodeHandle }\n"]}
@@ -1,13 +1,14 @@
1
1
  import { type ComponentType, type ReactElement } from "react";
2
2
  import type { StyleProp } from "../contracts";
3
3
  import type { ScrollViewProps } from "./scroll-view";
4
- import { type ItemLayout, type ListRenderItemInfo, type ViewabilityConfig, type ViewToken, type VirtualizedListHandle } from "./virtualized-list";
4
+ import { type ItemLayout, type ListRenderItemInfo, type ViewabilityConfig, type ViewToken, type VirtualizedListHandle, type VirtualizedListProps } from "./virtualized-list";
5
5
  export type { ListRenderItemInfo, ViewabilityConfig, ViewToken, } from "./virtualized-list";
6
6
  export type { VirtualizedListHandle as FlatListHandle } from "./virtualized-list";
7
7
  export type FlatListProps<T> = Omit<ScrollViewProps, "children"> & {
8
8
  data: readonly T[];
9
9
  renderItem: (info: ListRenderItemInfo<T>) => ReactElement | null;
10
10
  keyExtractor?: (item: T, index: number) => string;
11
+ CellRendererComponent?: VirtualizedListProps<T>["CellRendererComponent"];
11
12
  ItemSeparatorComponent?: ComponentType | null;
12
13
  ListHeaderComponent?: ComponentType | ReactElement | null;
13
14
  ListFooterComponent?: ComponentType | ReactElement | null;
@@ -38,7 +39,7 @@ export type SectionListData<T> = {
38
39
  title: string;
39
40
  data: readonly T[];
40
41
  };
41
- export type SectionListProps<T> = Omit<FlatListProps<T>, "data" | "renderItem" | "getItemLayout" | "onViewableItemsChanged" | "viewabilityConfig"> & {
42
+ export type SectionListProps<T> = Omit<FlatListProps<T>, "CellRendererComponent" | "data" | "renderItem" | "getItemLayout" | "onViewableItemsChanged" | "viewabilityConfig"> & {
42
43
  sections: readonly SectionListData<T>[];
43
44
  renderItem: (info: ListRenderItemInfo<T>) => ReactElement | null;
44
45
  renderSectionHeader?: (info: {
@@ -1 +1 @@
1
- {"version":3,"file":"flat-list.js","sourceRoot":"","sources":["../../src/components/flat-list.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAyC,MAAM,OAAO,CAAA;AAGzE,OAAO,EACL,eAAe,GAMhB,MAAM,oBAAoB,CAAA;AAuC3B,6EAA6E;AAC7E,mEAAmE;AACnE,MAAM,aAAa,GAAG,UAAU,CAC9B,CAAK,KAAuB,EAAE,GAAqC,EAAE,EAAE,CAAC,CACtE,KAAC,eAAe,OACV,KAAK,EACT,GAAG,EAAE,GAAG,GACR,CACH,CACF,CAAA;AACD,aAAa,CAAC,WAAW,GAAG,UAAU,CAAA;AAEtC,MAAM,CAAC,MAAM,QAAQ,GAAG,aAEP,CAAA;AA+BjB,MAAM,CAAC,MAAM,WAAW,GAAG,CAAK,EAC9B,QAAQ,EACR,UAAU,EACV,mBAAmB,EACnB,2BAA2B,GAAG,IAAI,EAClC,GAAG,EACH,GAAG,IAAI,EACa,EAAgB,EAAE;IACtC,MAAM,IAAI,GAAoB,EAAE,CAAA;IAChC,MAAM,aAAa,GAAa,EAAE,CAAA;IAClC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC/B,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAA;QACtC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACnC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAC1C,CAAC,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,CACL,KAAC,QAAQ,OACH,IAAI,EACR,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,IAAI,EACV,mBAAmB,EACjB,2BAA2B,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,EAEzD,YAAY,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAC5C,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,CAC5B,GAAG,CAAC,IAAI,KAAK,QAAQ;YACnB,CAAC,CAAC,CAAC,mBAAmB,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,IAAI,IAAI,CAAC;YAC3D,CAAC,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,GAEtD,CACH,CAAA;AACH,CAAC,CAAA","sourcesContent":["import { forwardRef, type ComponentType, type ReactElement } from \"react\"\nimport type { StyleProp } from \"../contracts\"\nimport type { ScrollViewProps } from \"./scroll-view\"\nimport {\n VirtualizedList,\n type ItemLayout,\n type ListRenderItemInfo,\n type ViewabilityConfig,\n type ViewToken,\n type VirtualizedListHandle,\n} from \"./virtualized-list\"\n\nexport type {\n ListRenderItemInfo,\n ViewabilityConfig,\n ViewToken,\n} from \"./virtualized-list\"\n// The FlatList ref exposes the full scroll surface of the windowed core\n// (scrollTo, scrollToEnd, scrollToIndex, scrollToItem, scrollToOffset).\nexport type { VirtualizedListHandle as FlatListHandle } from \"./virtualized-list\"\n\nexport type FlatListProps<T> = Omit<ScrollViewProps, \"children\"> & {\n data: readonly T[]\n renderItem: (info: ListRenderItemInfo<T>) => ReactElement | null\n keyExtractor?: (item: T, index: number) => string\n ItemSeparatorComponent?: ComponentType | null\n ListHeaderComponent?: ComponentType | ReactElement | null\n ListFooterComponent?: ComponentType | ReactElement | null\n ListEmptyComponent?: ComponentType | ReactElement | null\n onEndReached?: () => void\n onEndReachedThreshold?: number\n onViewableItemsChanged?: (info: {\n viewableItems: ViewToken<T>[]\n changed: ViewToken<T>[]\n }) => void\n viewabilityConfig?: ViewabilityConfig\n estimatedItemSize?: number\n getItemLayout?: (data: readonly T[], index: number) => ItemLayout\n windowSize?: number\n initialNumToRender?: number\n maxToRenderPerBatch?: number\n updateCellsBatchingPeriod?: number\n extraData?: unknown\n inverted?: boolean\n refreshing?: boolean\n onRefresh?: () => void\n style?: StyleProp\n}\n\n// FlatList is a thin veneer over the windowed VirtualizedList core: only the\n// rows around the viewport are mounted (see virtualized-list.tsx).\nconst FlatListInner = forwardRef(\n <T,>(props: FlatListProps<T>, ref: React.Ref<VirtualizedListHandle>) => (\n <VirtualizedList\n {...props}\n ref={ref}\n />\n ),\n)\nFlatListInner.displayName = \"FlatList\"\n\nexport const FlatList = FlatListInner as <T>(\n props: FlatListProps<T> & { ref?: React.Ref<VirtualizedListHandle> },\n) => ReactElement\n\nexport type SectionListData<T> = { title: string; data: readonly T[] }\n\n// Viewability props are excluded: SectionList flattens sections into private\n// row records, so ViewTokens would leak that internal row type instead of T —\n// section-aware tokens are not implemented yet.\nexport type SectionListProps<T> = Omit<\n FlatListProps<T>,\n | \"data\"\n | \"renderItem\"\n | \"getItemLayout\"\n | \"onViewableItemsChanged\"\n | \"viewabilityConfig\"\n> & {\n sections: readonly SectionListData<T>[]\n renderItem: (info: ListRenderItemInfo<T>) => ReactElement | null\n renderSectionHeader?: (info: {\n section: SectionListData<T>\n }) => ReactElement | null\n // RN default on iOS; ours defaults to true too — section headers pin to\n // the top and get pushed out by the next section's header.\n stickySectionHeadersEnabled?: boolean\n // React 19 ref-as-prop: the same scroll surface FlatList exposes.\n ref?: React.Ref<VirtualizedListHandle>\n}\n\ntype SectionRow<T> =\n | { kind: \"header\"; section: SectionListData<T> }\n | { kind: \"item\"; item: T; index: number }\n\nexport const SectionList = <T,>({\n sections,\n renderItem,\n renderSectionHeader,\n stickySectionHeadersEnabled = true,\n ref,\n ...rest\n}: SectionListProps<T>): ReactElement => {\n const rows: SectionRow<T>[] = []\n const headerIndices: number[] = []\n for (const section of sections) {\n headerIndices.push(rows.length)\n rows.push({ kind: \"header\", section })\n section.data.forEach((item, index) => {\n rows.push({ kind: \"item\", item, index })\n })\n }\n return (\n <FlatList\n {...rest}\n ref={ref}\n data={rows}\n stickyHeaderIndices={\n stickySectionHeadersEnabled ? headerIndices : undefined\n }\n keyExtractor={(_row, index) => String(index)}\n renderItem={({ item: row }) =>\n row.kind === \"header\"\n ? (renderSectionHeader?.({ section: row.section }) ?? null)\n : renderItem({ item: row.item, index: row.index })\n }\n />\n )\n}\n"]}
1
+ {"version":3,"file":"flat-list.js","sourceRoot":"","sources":["../../src/components/flat-list.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAyC,MAAM,OAAO,CAAA;AAGzE,OAAO,EACL,eAAe,GAOhB,MAAM,oBAAoB,CAAA;AA0C3B,6EAA6E;AAC7E,mEAAmE;AACnE,MAAM,aAAa,GAAG,UAAU,CAC9B,CAAK,KAAuB,EAAE,GAAqC,EAAE,EAAE,CAAC,CACtE,KAAC,eAAe,OACV,KAAK,EACT,GAAG,EAAE,GAAG,GACR,CACH,CACF,CAAA;AACD,aAAa,CAAC,WAAW,GAAG,UAAU,CAAA;AAEtC,MAAM,CAAC,MAAM,QAAQ,GAAG,aAEP,CAAA;AAkCjB,MAAM,CAAC,MAAM,WAAW,GAAG,CAAK,EAC9B,QAAQ,EACR,UAAU,EACV,mBAAmB,EACnB,2BAA2B,GAAG,IAAI,EAClC,GAAG,EACH,GAAG,IAAI,EACa,EAAgB,EAAE;IACtC,MAAM,IAAI,GAAoB,EAAE,CAAA;IAChC,MAAM,aAAa,GAAa,EAAE,CAAA;IAClC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC/B,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAA;QACtC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACnC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAC1C,CAAC,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,CACL,KAAC,QAAQ,OACH,IAAI,EACR,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,IAAI,EACV,mBAAmB,EACjB,2BAA2B,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,EAEzD,YAAY,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAC5C,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,CAC5B,GAAG,CAAC,IAAI,KAAK,QAAQ;YACnB,CAAC,CAAC,CAAC,mBAAmB,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,IAAI,IAAI,CAAC;YAC3D,CAAC,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,GAEtD,CACH,CAAA;AACH,CAAC,CAAA","sourcesContent":["import { forwardRef, type ComponentType, type ReactElement } from \"react\"\nimport type { StyleProp } from \"../contracts\"\nimport type { ScrollViewProps } from \"./scroll-view\"\nimport {\n VirtualizedList,\n type ItemLayout,\n type ListRenderItemInfo,\n type ViewabilityConfig,\n type ViewToken,\n type VirtualizedListHandle,\n type VirtualizedListProps,\n} from \"./virtualized-list\"\n\nexport type {\n ListRenderItemInfo,\n ViewabilityConfig,\n ViewToken,\n} from \"./virtualized-list\"\n// The FlatList ref exposes the full scroll surface of the windowed core\n// (scrollTo, scrollToEnd, scrollToIndex, scrollToItem, scrollToOffset).\nexport type { VirtualizedListHandle as FlatListHandle } from \"./virtualized-list\"\n\nexport type FlatListProps<T> = Omit<ScrollViewProps, \"children\"> & {\n data: readonly T[]\n renderItem: (info: ListRenderItemInfo<T>) => ReactElement | null\n keyExtractor?: (item: T, index: number) => string\n // RN's per-cell wrapper — see virtualized-list.tsx for what the list hands\n // it and what it must apply.\n CellRendererComponent?: VirtualizedListProps<T>[\"CellRendererComponent\"]\n ItemSeparatorComponent?: ComponentType | null\n ListHeaderComponent?: ComponentType | ReactElement | null\n ListFooterComponent?: ComponentType | ReactElement | null\n ListEmptyComponent?: ComponentType | ReactElement | null\n onEndReached?: () => void\n onEndReachedThreshold?: number\n onViewableItemsChanged?: (info: {\n viewableItems: ViewToken<T>[]\n changed: ViewToken<T>[]\n }) => void\n viewabilityConfig?: ViewabilityConfig\n estimatedItemSize?: number\n getItemLayout?: (data: readonly T[], index: number) => ItemLayout\n windowSize?: number\n initialNumToRender?: number\n maxToRenderPerBatch?: number\n updateCellsBatchingPeriod?: number\n extraData?: unknown\n inverted?: boolean\n refreshing?: boolean\n onRefresh?: () => void\n style?: StyleProp\n}\n\n// FlatList is a thin veneer over the windowed VirtualizedList core: only the\n// rows around the viewport are mounted (see virtualized-list.tsx).\nconst FlatListInner = forwardRef(\n <T,>(props: FlatListProps<T>, ref: React.Ref<VirtualizedListHandle>) => (\n <VirtualizedList\n {...props}\n ref={ref}\n />\n ),\n)\nFlatListInner.displayName = \"FlatList\"\n\nexport const FlatList = FlatListInner as <T>(\n props: FlatListProps<T> & { ref?: React.Ref<VirtualizedListHandle> },\n) => ReactElement\n\nexport type SectionListData<T> = { title: string; data: readonly T[] }\n\n// Viewability props are excluded: SectionList flattens sections into private\n// row records, so ViewTokens would leak that internal row type instead of T —\n// section-aware tokens are not implemented yet. `CellRendererComponent` is\n// excluded for exactly the same reason: its `item` would be one of those\n// records, not a T.\nexport type SectionListProps<T> = Omit<\n FlatListProps<T>,\n | \"CellRendererComponent\"\n | \"data\"\n | \"renderItem\"\n | \"getItemLayout\"\n | \"onViewableItemsChanged\"\n | \"viewabilityConfig\"\n> & {\n sections: readonly SectionListData<T>[]\n renderItem: (info: ListRenderItemInfo<T>) => ReactElement | null\n renderSectionHeader?: (info: {\n section: SectionListData<T>\n }) => ReactElement | null\n // RN default on iOS; ours defaults to true too — section headers pin to\n // the top and get pushed out by the next section's header.\n stickySectionHeadersEnabled?: boolean\n // React 19 ref-as-prop: the same scroll surface FlatList exposes.\n ref?: React.Ref<VirtualizedListHandle>\n}\n\ntype SectionRow<T> =\n | { kind: \"header\"; section: SectionListData<T> }\n | { kind: \"item\"; item: T; index: number }\n\nexport const SectionList = <T,>({\n sections,\n renderItem,\n renderSectionHeader,\n stickySectionHeadersEnabled = true,\n ref,\n ...rest\n}: SectionListProps<T>): ReactElement => {\n const rows: SectionRow<T>[] = []\n const headerIndices: number[] = []\n for (const section of sections) {\n headerIndices.push(rows.length)\n rows.push({ kind: \"header\", section })\n section.data.forEach((item, index) => {\n rows.push({ kind: \"item\", item, index })\n })\n }\n return (\n <FlatList\n {...rest}\n ref={ref}\n data={rows}\n stickyHeaderIndices={\n stickySectionHeadersEnabled ? headerIndices : undefined\n }\n keyExtractor={(_row, index) => String(index)}\n renderItem={({ item: row }) =>\n row.kind === \"header\"\n ? (renderSectionHeader?.({ section: row.section }) ?? null)\n : renderItem({ item: row.item, index: row.index })\n }\n />\n )\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import type { FrameScheduler } from "../animated/index";
2
+ /** What a frame driver has to answer: when is it now, and call me next frame. */
3
+ export type FrameDriver = {
4
+ schedule(callback: (timeMs: number) => void): () => void;
5
+ /** The same clock the frame stamps come from, readable off-frame. */
6
+ now(): number;
7
+ };
8
+ export declare const glibScheduler: FrameScheduler;
9
+ /**
10
+ * @internal Swaps the clock every animation on this platform runs on. Null
11
+ * restores the GLib one. Only `withReanimatedTimer` should call it — a driver
12
+ * left installed stops every animation in the process.
13
+ */
14
+ export declare const installFrameDriver: (next: FrameDriver | null) => void;
15
+ /** @internal The real clock, for a manual driver that continues from it. */
16
+ export declare const realFrameClock: () => number;
@@ -0,0 +1,37 @@
1
+ import { GLib } from "../gtkx/bridge/index";
2
+ const glibDriver = {
3
+ now() {
4
+ return Number(GLib.getMonotonicTime()) / 1000;
5
+ },
6
+ schedule(callback) {
7
+ let cancelled = false;
8
+ const id = GLib.timeoutAdd(GLib.PRIORITY_DEFAULT, 16, () => {
9
+ if (!cancelled) {
10
+ callback(Number(GLib.getMonotonicTime()) / 1000);
11
+ }
12
+ return false;
13
+ });
14
+ return () => {
15
+ if (!cancelled) {
16
+ cancelled = true;
17
+ GLib.Source.remove(id);
18
+ }
19
+ };
20
+ },
21
+ };
22
+ let driver = glibDriver;
23
+ export const glibScheduler = {
24
+ now: () => driver.now(),
25
+ schedule: (callback) => driver.schedule(callback),
26
+ };
27
+ /**
28
+ * @internal Swaps the clock every animation on this platform runs on. Null
29
+ * restores the GLib one. Only `withReanimatedTimer` should call it — a driver
30
+ * left installed stops every animation in the process.
31
+ */
32
+ export const installFrameDriver = (next) => {
33
+ driver = next ?? glibDriver;
34
+ };
35
+ /** @internal The real clock, for a manual driver that continues from it. */
36
+ export const realFrameClock = () => glibDriver.now();
37
+ //# sourceMappingURL=frame-scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-scheduler.js","sourceRoot":"","sources":["../../src/components/frame-scheduler.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAS3C,MAAM,UAAU,GAAgB;IAC9B,GAAG;QACD,OAAO,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,GAAG,IAAI,CAAA;IAC/C,CAAC;IACD,QAAQ,CAAC,QAAQ;QACf,IAAI,SAAS,GAAG,KAAK,CAAA;QACrB,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,EAAE,GAAG,EAAE;YACzD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;YAClD,CAAC;YACD,OAAO,KAAK,CAAA;QACd,CAAC,CAAC,CAAA;QACF,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,SAAS,GAAG,IAAI,CAAA;gBAChB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YACxB,CAAC;QACH,CAAC,CAAA;IACH,CAAC;CACF,CAAA;AAED,IAAI,MAAM,GAAgB,UAAU,CAAA;AAEpC,MAAM,CAAC,MAAM,aAAa,GAAmB;IAC3C,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE;IACvB,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;CAClD,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAwB,EAAQ,EAAE;IACnE,MAAM,GAAG,IAAI,IAAI,UAAU,CAAA;AAC7B,CAAC,CAAA;AAED,4EAA4E;AAC5E,MAAM,CAAC,MAAM,cAAc,GAAG,GAAW,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAA","sourcesContent":["// The one frame driver on this platform: ~60fps one-shot ticks off the GLib\n// main loop. A frame-clock driver (per window) is a later optimization;\n// timeouts keep the driver widget-free.\n//\n// Its own module because two things now inject it — `Animated` in\n// components/animated.tsx and the Reanimated compat surface in\n// reanimated-compat/ — and the point of both is that they share ONE clock.\n// A second scheduler would be a second timer competing for the same main\n// loop, which is exactly what neither layer is allowed to add.\n//\n// `glibScheduler` is a façade over a swappable DRIVER rather than the driver\n// itself, and that indirection buys exactly one thing: a test can take the\n// clock. Every consumer captured the object at import time and calls through\n// it per frame, so replacing what is behind it replaces the clock for\n// everything at once — which is what makes `advanceAnimationByTime()` (see\n// src/reanimated-compat/test-timers.ts) drive the platform's real animations\n// deterministically instead of sleeping and hoping.\nimport type { FrameScheduler } from \"../animated/index\"\nimport { GLib } from \"../gtkx/bridge/index\"\n\n/** What a frame driver has to answer: when is it now, and call me next frame. */\nexport type FrameDriver = {\n schedule(callback: (timeMs: number) => void): () => void\n /** The same clock the frame stamps come from, readable off-frame. */\n now(): number\n}\n\nconst glibDriver: FrameDriver = {\n now() {\n return Number(GLib.getMonotonicTime()) / 1000\n },\n schedule(callback) {\n let cancelled = false\n const id = GLib.timeoutAdd(GLib.PRIORITY_DEFAULT, 16, () => {\n if (!cancelled) {\n callback(Number(GLib.getMonotonicTime()) / 1000)\n }\n return false\n })\n return () => {\n if (!cancelled) {\n cancelled = true\n GLib.Source.remove(id)\n }\n }\n },\n}\n\nlet driver: FrameDriver = glibDriver\n\nexport const glibScheduler: FrameScheduler = {\n now: () => driver.now(),\n schedule: (callback) => driver.schedule(callback),\n}\n\n/**\n * @internal Swaps the clock every animation on this platform runs on. Null\n * restores the GLib one. Only `withReanimatedTimer` should call it — a driver\n * left installed stops every animation in the process.\n */\nexport const installFrameDriver = (next: FrameDriver | null): void => {\n driver = next ?? glibDriver\n}\n\n/** @internal The real clock, for a manual driver that continues from it. */\nexport const realFrameClock = (): number => glibDriver.now()\n"]}
@@ -1,8 +1,12 @@
1
+ import { type Ref } from "react";
1
2
  import type { StyleProp } from "../contracts";
3
+ import { type MeasureHandle } from "./measure";
2
4
  import { type LayoutEvent } from "./use-layout-child";
3
5
  export type ImageSource = {
4
6
  uri: string;
5
7
  } | string;
8
+ /** RN's imperative geometry methods, on an `Image` ref. */
9
+ export type ImageHandle = MeasureHandle;
6
10
  export type ImageProps = {
7
11
  source: ImageSource;
8
12
  style?: StyleProp;
@@ -15,5 +19,6 @@ export type ImageProps = {
15
19
  };
16
20
  }) => void;
17
21
  testID?: string;
22
+ ref?: Ref<ImageHandle>;
18
23
  };
19
- export declare const Image: ({ source, style, resizeMode, onLayout, onLoad, onError, testID, }: ImageProps) => React.JSX.Element;
24
+ export declare const Image: ({ source, style, resizeMode, onLayout, onLoad, onError, testID, ref, }: ImageProps) => React.JSX.Element;
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { existsSync } from "node:fs";
3
- import { useEffect, useRef } from "react";
4
- import { Gdk, Gtk, GtkPicture } from "../gtkx/bridge/index";
3
+ import { useEffect, useImperativeHandle, useLayoutEffect, useRef, } from "react";
4
+ import { Gdk, Gtk, GtkPicture, setPaintOnlyLeaf } from "../gtkx/bridge/index";
5
5
  import { isRemoteUri, loadRemoteImage } from "./image-loader";
6
+ import { createMeasureHandle } from "./measure";
6
7
  import { useLayoutChild } from "./use-layout-child";
7
8
  const CONTENT_FIT = {
8
9
  cover: Gtk.ContentFit.COVER,
@@ -20,9 +21,19 @@ const toPath = (source) => {
20
21
  // formats — e.g. ICO favicons), so onError is honest instead of showing
21
22
  // an empty picture. Sizing comes from the style (width/height or flex) —
22
23
  // like RN, which also cannot infer remote image sizes synchronously.
23
- export const Image = ({ source, style, resizeMode = "cover", onLayout, onLoad, onError, testID, }) => {
24
+ export const Image = ({ source, style, resizeMode = "cover", onLayout, onLoad, onError, testID, ref, }) => {
24
25
  const widgetRef = useRef(null);
25
- useLayoutChild(widgetRef, { style, onLayout });
26
+ const { node } = useLayoutChild(widgetRef, { style, onLayout });
27
+ useImperativeHandle(ref, () => createMeasureHandle(widgetRef, node), [node]);
28
+ // Paint-only for picking, exactly as `Text`'s label is: `Image` has no press
29
+ // prop, so a targetable GtkPicture only ever shadowed its own container —
30
+ // see the zIndex block in gtkx/bridge/view-box.ts.
31
+ useLayoutEffect(() => {
32
+ const picture = widgetRef.current;
33
+ if (picture) {
34
+ setPaintOnlyLeaf(picture);
35
+ }
36
+ }, []);
26
37
  const path = toPath(source);
27
38
  useEffect(() => {
28
39
  const widget = widgetRef.current;
@@ -1 +1 @@
1
- {"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/components/image.tsx"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\"\nimport { useEffect, useRef } from \"react\"\nimport type { StyleProp } from \"../contracts\"\nimport { Gdk, Gtk, GtkPicture } from \"../gtkx/bridge/index\"\nimport { isRemoteUri, loadRemoteImage } from \"./image-loader\"\nimport { useLayoutChild, type LayoutEvent } from \"./use-layout-child\"\n\nexport type ImageSource = { uri: string } | string\n\nexport type ImageProps = {\n source: ImageSource\n style?: StyleProp\n resizeMode?: \"cover\" | \"contain\" | \"stretch\" | \"center\"\n onLayout?: (event: LayoutEvent) => void\n onLoad?: () => void\n onError?: (error: { nativeEvent: { error: string } }) => void\n testID?: string\n}\n\nconst CONTENT_FIT = {\n cover: Gtk.ContentFit.COVER,\n contain: Gtk.ContentFit.CONTAIN,\n stretch: Gtk.ContentFit.FILL,\n center: Gtk.ContentFit.SCALE_DOWN,\n} as const\n\nconst toPath = (source: ImageSource): string => {\n const uri = typeof source === \"string\" ? source : source.uri\n return uri.startsWith(\"file://\") ? uri.slice(\"file://\".length) : uri\n}\n\n// Local files load synchronously; http(s) URIs download through the\n// on-disk cache (image-loader.ts) and set the picture when ready. The\n// texture is decoded explicitly (Gdk.Texture throws on unsupported\n// formats — e.g. ICO favicons), so onError is honest instead of showing\n// an empty picture. Sizing comes from the style (width/height or flex) —\n// like RN, which also cannot infer remote image sizes synchronously.\nexport const Image = ({\n source,\n style,\n resizeMode = \"cover\",\n onLayout,\n onLoad,\n onError,\n testID,\n}: ImageProps) => {\n const widgetRef = useRef<Gtk.Picture | null>(null)\n useLayoutChild(widgetRef, { style, onLayout })\n\n const path = toPath(source)\n\n useEffect(() => {\n const widget = widgetRef.current\n if (!widget) {\n return\n }\n const show = (file: string): void => {\n const target = widgetRef.current\n if (!target) {\n return\n }\n try {\n // Decode explicitly: setFilename fails silently on formats the\n // texture loader does not support, newFromFilename throws.\n target.setPaintable(Gdk.Texture.newFromFilename(file))\n onLoad?.()\n } catch (error) {\n onError?.({ nativeEvent: { error: String(error) } })\n }\n }\n if (isRemoteUri(path)) {\n let cancelled = false\n loadRemoteImage(path).then(\n (file) => {\n // Unmount (or a source change) during the download must not touch\n // the widget or fire stale callbacks.\n if (!cancelled) {\n show(file)\n }\n },\n (error: unknown) => {\n if (!cancelled) {\n onError?.({ nativeEvent: { error: String(error) } })\n }\n },\n )\n return () => {\n cancelled = true\n }\n }\n if (!existsSync(path)) {\n onError?.({ nativeEvent: { error: `Image not found: ${path}` } })\n return\n }\n show(path)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [path])\n\n return (\n <GtkPicture\n ref={widgetRef}\n name={testID}\n contentFit={CONTENT_FIT[resizeMode]}\n />\n )\n}\n"]}
1
+ {"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/components/image.tsx"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\"\nimport {\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n type Ref,\n} from \"react\"\nimport type { StyleProp } from \"../contracts\"\nimport { Gdk, Gtk, GtkPicture, setPaintOnlyLeaf } from \"../gtkx/bridge/index\"\nimport { isRemoteUri, loadRemoteImage } from \"./image-loader\"\nimport { createMeasureHandle, type MeasureHandle } from \"./measure\"\nimport { useLayoutChild, type LayoutEvent } from \"./use-layout-child\"\n\nexport type ImageSource = { uri: string } | string\n\n/** RN's imperative geometry methods, on an `Image` ref. */\nexport type ImageHandle = MeasureHandle\n\nexport type ImageProps = {\n source: ImageSource\n style?: StyleProp\n resizeMode?: \"cover\" | \"contain\" | \"stretch\" | \"center\"\n onLayout?: (event: LayoutEvent) => void\n onLoad?: () => void\n onError?: (error: { nativeEvent: { error: string } }) => void\n testID?: string\n // The same handle every other host component exposes — RN parity, and the\n // seam `Animated.Image` reads its widget back through.\n ref?: Ref<ImageHandle>\n}\n\nconst CONTENT_FIT = {\n cover: Gtk.ContentFit.COVER,\n contain: Gtk.ContentFit.CONTAIN,\n stretch: Gtk.ContentFit.FILL,\n center: Gtk.ContentFit.SCALE_DOWN,\n} as const\n\nconst toPath = (source: ImageSource): string => {\n const uri = typeof source === \"string\" ? source : source.uri\n return uri.startsWith(\"file://\") ? uri.slice(\"file://\".length) : uri\n}\n\n// Local files load synchronously; http(s) URIs download through the\n// on-disk cache (image-loader.ts) and set the picture when ready. The\n// texture is decoded explicitly (Gdk.Texture throws on unsupported\n// formats — e.g. ICO favicons), so onError is honest instead of showing\n// an empty picture. Sizing comes from the style (width/height or flex) —\n// like RN, which also cannot infer remote image sizes synchronously.\nexport const Image = ({\n source,\n style,\n resizeMode = \"cover\",\n onLayout,\n onLoad,\n onError,\n testID,\n ref,\n}: ImageProps) => {\n const widgetRef = useRef<Gtk.Picture | null>(null)\n const { node } = useLayoutChild(widgetRef, { style, onLayout })\n\n useImperativeHandle(ref, () => createMeasureHandle(widgetRef, node), [node])\n\n // Paint-only for picking, exactly as `Text`'s label is: `Image` has no press\n // prop, so a targetable GtkPicture only ever shadowed its own container —\n // see the zIndex block in gtkx/bridge/view-box.ts.\n useLayoutEffect(() => {\n const picture = widgetRef.current\n if (picture) {\n setPaintOnlyLeaf(picture)\n }\n }, [])\n\n const path = toPath(source)\n\n useEffect(() => {\n const widget = widgetRef.current\n if (!widget) {\n return\n }\n const show = (file: string): void => {\n const target = widgetRef.current\n if (!target) {\n return\n }\n try {\n // Decode explicitly: setFilename fails silently on formats the\n // texture loader does not support, newFromFilename throws.\n target.setPaintable(Gdk.Texture.newFromFilename(file))\n onLoad?.()\n } catch (error) {\n onError?.({ nativeEvent: { error: String(error) } })\n }\n }\n if (isRemoteUri(path)) {\n let cancelled = false\n loadRemoteImage(path).then(\n (file) => {\n // Unmount (or a source change) during the download must not touch\n // the widget or fire stale callbacks.\n if (!cancelled) {\n show(file)\n }\n },\n (error: unknown) => {\n if (!cancelled) {\n onError?.({ nativeEvent: { error: String(error) } })\n }\n },\n )\n return () => {\n cancelled = true\n }\n }\n if (!existsSync(path)) {\n onError?.({ nativeEvent: { error: `Image not found: ${path}` } })\n return\n }\n show(path)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [path])\n\n return (\n <GtkPicture\n ref={widgetRef}\n name={testID}\n contentFit={CONTENT_FIT[resizeMode]}\n />\n )\n}\n"]}