@expo/ui 56.0.8 → 56.0.10

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 (252) hide show
  1. package/CHANGELOG.md +35 -1
  2. package/CLAUDE.md +1 -1
  3. package/android/build.gradle +2 -2
  4. package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +49 -6
  5. package/android/src/main/java/expo/modules/ui/HorizontalPagerView.kt +97 -16
  6. package/android/src/main/java/expo/modules/ui/LoadingView.kt +80 -0
  7. package/android/src/main/java/expo/modules/ui/ModifierRegistry.kt +31 -3
  8. package/android/src/main/java/expo/modules/ui/SnackbarView.kt +126 -0
  9. package/android/src/main/java/expo/modules/ui/colors/MaterialColors.kt +2 -0
  10. package/android/src/main/java/expo/modules/ui/state/ObservableState.kt +10 -0
  11. package/assets/keyboard_arrow_down.xml +10 -0
  12. package/build/State/index.d.ts +6 -0
  13. package/build/State/index.d.ts.map +1 -0
  14. package/build/State/useNativeState.d.ts +32 -3
  15. package/build/State/useNativeState.d.ts.map +1 -1
  16. package/build/community/bottom-sheet/BottomSheet.ios.d.ts.map +1 -1
  17. package/build/community/pager-view/PagerView.android.d.ts +7 -0
  18. package/build/community/pager-view/PagerView.android.d.ts.map +1 -0
  19. package/build/community/pager-view/PagerView.d.ts +8 -0
  20. package/build/community/pager-view/PagerView.d.ts.map +1 -0
  21. package/build/community/pager-view/PagerView.ios.d.ts +15 -0
  22. package/build/community/pager-view/PagerView.ios.d.ts.map +1 -0
  23. package/build/community/pager-view/index.d.ts +3 -0
  24. package/build/community/pager-view/index.d.ts.map +1 -0
  25. package/build/community/pager-view/types.d.ts +128 -0
  26. package/build/community/pager-view/types.d.ts.map +1 -0
  27. package/build/community/segmented-control/vendor/SegmentsSeparators.d.ts.map +1 -1
  28. package/build/jetpack-compose/HorizontalPager/index.d.ts +27 -0
  29. package/build/jetpack-compose/HorizontalPager/index.d.ts.map +1 -1
  30. package/build/jetpack-compose/Host/index.d.ts +1 -0
  31. package/build/jetpack-compose/Host/index.d.ts.map +1 -1
  32. package/build/jetpack-compose/LoadingIndicator/index.d.ts +41 -0
  33. package/build/jetpack-compose/LoadingIndicator/index.d.ts.map +1 -0
  34. package/build/jetpack-compose/Snackbar/index.d.ts +94 -0
  35. package/build/jetpack-compose/Snackbar/index.d.ts.map +1 -0
  36. package/build/jetpack-compose/SyncSwitch/index.d.ts +1 -1
  37. package/build/jetpack-compose/SyncSwitch/index.d.ts.map +1 -1
  38. package/build/jetpack-compose/TextField/index.d.ts +1 -1
  39. package/build/jetpack-compose/TextField/index.d.ts.map +1 -1
  40. package/build/jetpack-compose/index.d.ts +3 -2
  41. package/build/jetpack-compose/index.d.ts.map +1 -1
  42. package/build/jetpack-compose/modifiers/index.d.ts +6 -2
  43. package/build/jetpack-compose/modifiers/index.d.ts.map +1 -1
  44. package/build/swift-ui/BottomSheet/index.d.ts +5 -1
  45. package/build/swift-ui/BottomSheet/index.d.ts.map +1 -1
  46. package/build/swift-ui/Host/index.d.ts +1 -0
  47. package/build/swift-ui/Host/index.d.ts.map +1 -1
  48. package/build/swift-ui/ScrollView/index.d.ts +30 -0
  49. package/build/swift-ui/ScrollView/index.d.ts.map +1 -1
  50. package/build/swift-ui/SecureField/index.d.ts +1 -1
  51. package/build/swift-ui/SecureField/index.d.ts.map +1 -1
  52. package/build/swift-ui/SyncToggle/index.d.ts +1 -1
  53. package/build/swift-ui/SyncToggle/index.d.ts.map +1 -1
  54. package/build/swift-ui/TextField/index.d.ts +1 -1
  55. package/build/swift-ui/TextField/index.d.ts.map +1 -1
  56. package/build/swift-ui/index.d.ts +2 -2
  57. package/build/swift-ui/index.d.ts.map +1 -1
  58. package/build/swift-ui/modifiers/index.d.ts +25 -15
  59. package/build/swift-ui/modifiers/index.d.ts.map +1 -1
  60. package/build/swift-ui/modifiers/scrollObservation.d.ts +52 -0
  61. package/build/swift-ui/modifiers/scrollObservation.d.ts.map +1 -0
  62. package/build/swift-ui/modifiers/scrollPosition.d.ts +1 -1
  63. package/build/swift-ui/modifiers/scrollPosition.d.ts.map +1 -1
  64. package/build/swift-ui/modifiers/symbolEffect.d.ts +1 -1
  65. package/build/swift-ui/modifiers/symbolEffect.d.ts.map +1 -1
  66. package/build/swift-ui/withAnimation.d.ts +26 -0
  67. package/build/swift-ui/withAnimation.d.ts.map +1 -0
  68. package/build/universal/BottomSheet/index.android.d.ts +1 -1
  69. package/build/universal/BottomSheet/index.android.d.ts.map +1 -1
  70. package/build/universal/BottomSheet/index.d.ts +1 -1
  71. package/build/universal/BottomSheet/index.d.ts.map +1 -1
  72. package/build/universal/BottomSheet/index.ios.d.ts +1 -1
  73. package/build/universal/BottomSheet/index.ios.d.ts.map +1 -1
  74. package/build/universal/BottomSheet/types.d.ts +27 -0
  75. package/build/universal/BottomSheet/types.d.ts.map +1 -1
  76. package/build/universal/Checkbox/index.d.ts.map +1 -1
  77. package/build/universal/Collapsible/index.android.d.ts +8 -0
  78. package/build/universal/Collapsible/index.android.d.ts.map +1 -0
  79. package/build/universal/Collapsible/index.d.ts +8 -0
  80. package/build/universal/Collapsible/index.d.ts.map +1 -0
  81. package/build/universal/Collapsible/index.ios.d.ts +7 -0
  82. package/build/universal/Collapsible/index.ios.d.ts.map +1 -0
  83. package/build/universal/Collapsible/types.d.ts +23 -0
  84. package/build/universal/Collapsible/types.d.ts.map +1 -0
  85. package/build/universal/Column/index.d.ts.map +1 -1
  86. package/build/universal/Host/index.d.ts +5 -18
  87. package/build/universal/Host/index.d.ts.map +1 -1
  88. package/build/universal/Host/types.d.ts +72 -0
  89. package/build/universal/Host/types.d.ts.map +1 -0
  90. package/build/universal/List/index.android.d.ts +9 -0
  91. package/build/universal/List/index.android.d.ts.map +1 -0
  92. package/build/universal/List/index.d.ts +8 -0
  93. package/build/universal/List/index.d.ts.map +1 -0
  94. package/build/universal/List/index.ios.d.ts +8 -0
  95. package/build/universal/List/index.ios.d.ts.map +1 -0
  96. package/build/universal/List/types.d.ts +26 -0
  97. package/build/universal/List/types.d.ts.map +1 -0
  98. package/build/universal/ListItem/ListItem.android.d.ts +8 -0
  99. package/build/universal/ListItem/ListItem.android.d.ts.map +1 -0
  100. package/build/universal/ListItem/ListItem.d.ts +9 -0
  101. package/build/universal/ListItem/ListItem.d.ts.map +1 -0
  102. package/build/universal/ListItem/ListItem.ios.d.ts +8 -0
  103. package/build/universal/ListItem/ListItem.ios.d.ts.map +1 -0
  104. package/build/universal/ListItem/ListItemSlots.d.ts +21 -0
  105. package/build/universal/ListItem/ListItemSlots.d.ts.map +1 -0
  106. package/build/universal/ListItem/index.d.ts +10 -0
  107. package/build/universal/ListItem/index.d.ts.map +1 -0
  108. package/build/universal/ListItem/types.d.ts +59 -0
  109. package/build/universal/ListItem/types.d.ts.map +1 -0
  110. package/build/universal/Picker/Picker.android.d.ts +9 -0
  111. package/build/universal/Picker/Picker.android.d.ts.map +1 -0
  112. package/build/universal/Picker/Picker.d.ts +8 -0
  113. package/build/universal/Picker/Picker.d.ts.map +1 -0
  114. package/build/universal/Picker/Picker.ios.d.ts +9 -0
  115. package/build/universal/Picker/Picker.ios.d.ts.map +1 -0
  116. package/build/universal/Picker/PickerItem.d.ts +9 -0
  117. package/build/universal/Picker/PickerItem.d.ts.map +1 -0
  118. package/build/universal/Picker/index.d.ts +8 -0
  119. package/build/universal/Picker/index.d.ts.map +1 -0
  120. package/build/universal/Picker/types.d.ts +69 -0
  121. package/build/universal/Picker/types.d.ts.map +1 -0
  122. package/build/universal/RNHostView/index.android.d.ts +7 -0
  123. package/build/universal/RNHostView/index.android.d.ts.map +1 -0
  124. package/build/universal/RNHostView/index.d.ts +7 -0
  125. package/build/universal/RNHostView/index.d.ts.map +1 -0
  126. package/build/universal/RNHostView/index.ios.d.ts +7 -0
  127. package/build/universal/RNHostView/index.ios.d.ts.map +1 -0
  128. package/build/universal/RNHostView/types.d.ts +23 -0
  129. package/build/universal/RNHostView/types.d.ts.map +1 -0
  130. package/build/universal/Switch/index.d.ts.map +1 -1
  131. package/build/universal/TextInput/index.d.ts.map +1 -1
  132. package/build/universal/index.d.ts +5 -0
  133. package/build/universal/index.d.ts.map +1 -1
  134. package/expo-module.config.json +1 -1
  135. package/ios/BottomSheetView.swift +4 -1
  136. package/ios/ExpoUIModule.swift +47 -4
  137. package/ios/HostView.swift +21 -18
  138. package/ios/Modifiers/AnimationConfig.swift +109 -0
  139. package/ios/Modifiers/FontModifier.swift +72 -20
  140. package/ios/Modifiers/ScrollObservationModifiers.swift +107 -0
  141. package/ios/Modifiers/ViewModifierRegistry.swift +9 -112
  142. package/ios/State/ObservableState.swift +12 -1
  143. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{56.0.8/expo.modules.ui-56.0.8-sources.jar → 56.0.10/expo.modules.ui-56.0.10-sources.jar} +0 -0
  144. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10-sources.jar.md5 +1 -0
  145. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10-sources.jar.sha1 +1 -0
  146. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10-sources.jar.sha256 +1 -0
  147. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10-sources.jar.sha512 +1 -0
  148. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10.aar +0 -0
  149. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10.aar.md5 +1 -0
  150. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10.aar.sha1 +1 -0
  151. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10.aar.sha256 +1 -0
  152. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10.aar.sha512 +1 -0
  153. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{56.0.8/expo.modules.ui-56.0.8.module → 56.0.10/expo.modules.ui-56.0.10.module} +22 -22
  154. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10.module.md5 +1 -0
  155. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10.module.sha1 +1 -0
  156. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10.module.sha256 +1 -0
  157. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10.module.sha512 +1 -0
  158. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{56.0.8/expo.modules.ui-56.0.8.pom → 56.0.10/expo.modules.ui-56.0.10.pom} +1 -1
  159. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10.pom.md5 +1 -0
  160. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10.pom.sha1 +1 -0
  161. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10.pom.sha256 +1 -0
  162. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.10/expo.modules.ui-56.0.10.pom.sha512 +1 -0
  163. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
  164. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
  165. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
  166. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
  167. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
  168. package/package.json +7 -3
  169. package/src/State/index.ts +10 -0
  170. package/src/State/useNativeState.ts +71 -3
  171. package/src/community/bottom-sheet/BottomSheet.ios.tsx +0 -17
  172. package/src/community/pager-view/PagerView.android.tsx +223 -0
  173. package/src/community/pager-view/PagerView.ios.tsx +267 -0
  174. package/src/community/pager-view/PagerView.tsx +14 -0
  175. package/src/community/pager-view/index.tsx +13 -0
  176. package/src/community/pager-view/types.tsx +137 -0
  177. package/src/community/picker/Picker.android.tsx +1 -1
  178. package/src/community/segmented-control/vendor/SegmentsSeparators.tsx +3 -6
  179. package/src/jetpack-compose/HorizontalPager/index.tsx +89 -18
  180. package/src/jetpack-compose/Host/index.tsx +1 -0
  181. package/src/jetpack-compose/LoadingIndicator/index.tsx +91 -0
  182. package/src/jetpack-compose/Snackbar/index.tsx +135 -0
  183. package/src/jetpack-compose/SyncSwitch/index.tsx +1 -3
  184. package/src/jetpack-compose/TextField/index.tsx +1 -4
  185. package/src/jetpack-compose/index.ts +3 -2
  186. package/src/jetpack-compose/modifiers/index.ts +5 -2
  187. package/src/swift-ui/BottomSheet/index.tsx +32 -15
  188. package/src/swift-ui/Host/index.tsx +1 -0
  189. package/src/swift-ui/ScrollView/index.tsx +33 -0
  190. package/src/swift-ui/SecureField/index.tsx +1 -4
  191. package/src/swift-ui/SyncToggle/index.tsx +1 -3
  192. package/src/swift-ui/TextField/index.tsx +1 -4
  193. package/src/swift-ui/index.tsx +2 -3
  194. package/src/swift-ui/modifiers/index.ts +37 -14
  195. package/src/swift-ui/modifiers/scrollObservation.ts +80 -0
  196. package/src/swift-ui/modifiers/scrollPosition.ts +1 -2
  197. package/src/swift-ui/modifiers/symbolEffect.ts +1 -2
  198. package/src/swift-ui/withAnimation.ts +71 -0
  199. package/src/ts-declarations/react-native-web.d.ts +7 -0
  200. package/src/universal/BottomSheet/index.android.tsx +58 -11
  201. package/src/universal/BottomSheet/index.ios.tsx +40 -20
  202. package/src/universal/BottomSheet/index.tsx +49 -4
  203. package/src/universal/BottomSheet/types.ts +25 -0
  204. package/src/universal/Checkbox/index.tsx +14 -2
  205. package/src/universal/Collapsible/index.android.tsx +72 -0
  206. package/src/universal/Collapsible/index.ios.tsx +16 -0
  207. package/src/universal/Collapsible/index.tsx +71 -0
  208. package/src/universal/Collapsible/types.ts +25 -0
  209. package/src/universal/Column/index.tsx +3 -1
  210. package/src/universal/Host/index.tsx +9 -10
  211. package/src/universal/Host/types.ts +70 -0
  212. package/src/universal/List/index.android.tsx +44 -0
  213. package/src/universal/List/index.ios.tsx +19 -0
  214. package/src/universal/List/index.tsx +26 -0
  215. package/src/universal/List/types.ts +28 -0
  216. package/src/universal/ListItem/ListItem.android.tsx +52 -0
  217. package/src/universal/ListItem/ListItem.ios.tsx +58 -0
  218. package/src/universal/ListItem/ListItem.tsx +77 -0
  219. package/src/universal/ListItem/ListItemSlots.tsx +66 -0
  220. package/src/universal/ListItem/index.ts +15 -0
  221. package/src/universal/ListItem/types.ts +67 -0
  222. package/src/universal/Picker/Picker.android.tsx +69 -0
  223. package/src/universal/Picker/Picker.ios.tsx +45 -0
  224. package/src/universal/Picker/Picker.tsx +52 -0
  225. package/src/universal/Picker/PickerItem.tsx +27 -0
  226. package/src/universal/Picker/index.ts +11 -0
  227. package/src/universal/Picker/types.ts +79 -0
  228. package/src/universal/RNHostView/index.android.tsx +33 -0
  229. package/src/universal/RNHostView/index.ios.tsx +12 -0
  230. package/src/universal/RNHostView/index.tsx +39 -0
  231. package/src/universal/RNHostView/types.ts +25 -0
  232. package/src/universal/Switch/index.tsx +7 -2
  233. package/src/universal/TextInput/index.tsx +12 -2
  234. package/src/universal/index.ts +5 -0
  235. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8-sources.jar.md5 +0 -1
  236. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8-sources.jar.sha1 +0 -1
  237. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8-sources.jar.sha256 +0 -1
  238. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8-sources.jar.sha512 +0 -1
  239. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8.aar +0 -0
  240. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8.aar.md5 +0 -1
  241. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8.aar.sha1 +0 -1
  242. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8.aar.sha256 +0 -1
  243. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8.aar.sha512 +0 -1
  244. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8.module.md5 +0 -1
  245. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8.module.sha1 +0 -1
  246. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8.module.sha256 +0 -1
  247. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8.module.sha512 +0 -1
  248. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8.pom.md5 +0 -1
  249. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8.pom.sha1 +0 -1
  250. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8.pom.sha256 +0 -1
  251. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.8/expo.modules.ui-56.0.8.pom.sha512 +0 -1
  252. package/src/community/bottom-sheet/CLAUDE.md +0 -55
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/universal/RNHostView/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,kBAAkB;IACzD;;;;;;;;;OASG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,QAAQ,EAAE,YAAY,CAAC;CACxB"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/universal/Switch/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAc3C;;GAEG;AACH,wBAAgB,MAAM,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,QAAgB,EAAE,MAAM,EAAE,EAAE,WAAW,2CAa5F;AAED,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/universal/Switch/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAiB3C;;GAEG;AACH,wBAAgB,MAAM,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,QAAgB,EAAE,MAAM,EAAE,EAAE,WAAW,2CAe5F;AAED,cAAc,SAAS,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/universal/TextInput/index.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,wBAAgB,SAAS,CAAC,EACxB,GAAG,EACH,KAAK,EACL,YAAY,EACZ,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,aAAa,EACb,eAAe,EACf,OAAO,EACP,MAAM,EACN,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,IAAI,EACJ,MAAM,EACN,oBAAoB,EACpB,KAAK,EACL,SAAS,EACT,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,SAAS,EACT,WAAW,EACX,cAAc,EACd,SAAS,EACT,iBAAiB,EACjB,iBAAiB,GAClB,EAAE,cAAc,2CAiFhB;AAED,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/universal/TextInput/index.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAM9C,wBAAgB,SAAS,CAAC,EACxB,GAAG,EACH,KAAK,EACL,YAAY,EACZ,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,aAAa,EACb,eAAe,EACf,OAAO,EACP,MAAM,EACN,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,IAAI,EACJ,MAAM,EACN,oBAAoB,EACpB,KAAK,EACL,SAAS,EACT,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,SAAS,EACT,WAAW,EACX,cAAc,EACd,SAAS,EACT,iBAAiB,EACjB,iBAAiB,GAClB,EAAE,cAAc,2CAuFhB;AAED,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC"}
@@ -8,8 +8,13 @@ export * from './Switch';
8
8
  export * from './Slider';
9
9
  export * from './Checkbox';
10
10
  export * from './BottomSheet';
11
+ export * from './Collapsible';
11
12
  export * from './FieldGroup';
12
13
  export * from './Icon';
14
+ export * from './List';
15
+ export * from './ListItem';
16
+ export * from './Picker';
17
+ export * from './RNHostView';
13
18
  export * from './Spacer';
14
19
  export * from './State';
15
20
  export { TextInput, type TextInputProps, type TextInputRef } from './TextInput';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/universal/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhF,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/universal/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhF,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC"}
@@ -10,7 +10,7 @@
10
10
  "publication": {
11
11
  "groupId": "expo.modules.ui",
12
12
  "artifactId": "expo.modules.ui",
13
- "version": "56.0.8",
13
+ "version": "56.0.10",
14
14
  "repository": "local-maven-repo"
15
15
  }
16
16
  }
@@ -7,6 +7,7 @@ final class BottomSheetProps: UIBaseViewProps {
7
7
  @Field var isPresented: Bool = false
8
8
  @Field var fitToContents: Bool = false
9
9
  var onIsPresentedChange = EventDispatcher()
10
+ var onDismiss = EventDispatcher()
10
11
  }
11
12
 
12
13
  struct SizePreferenceKey: PreferenceKey {
@@ -86,7 +87,9 @@ struct BottomSheetView: ExpoSwiftUI.View {
86
87
 
87
88
  var body: some View {
88
89
  Rectangle().hidden()
89
- .sheet(isPresented: $isPresented) {
90
+ .sheet(isPresented: $isPresented, onDismiss: {
91
+ props.onDismiss()
92
+ }) {
90
93
  sheetContent
91
94
  }
92
95
  .onChange(of: isPresented, perform: { newIsPresented in
@@ -1,6 +1,7 @@
1
1
  // Copyright 2025-present 650 Industries. All rights reserved.
2
2
 
3
3
  import ExpoModulesCore
4
+ import SwiftUI
4
5
 
5
6
  public final class ExpoUIModule: Module {
6
7
  public func definition() -> ModuleDefinition {
@@ -28,7 +29,19 @@ public final class ExpoUIModule: Module {
28
29
  }
29
30
 
30
31
  Function("setValue") { (state: ObservableState, wrapper: [String: Any]) in
31
- state.value = wrapper["value"]
32
+ let newValue = wrapper["value"]
33
+ // Update state on the UI thread
34
+ if Thread.isMainThread {
35
+ state.value = newValue
36
+ } else {
37
+ DispatchQueue.main.async {
38
+ state.value = newValue
39
+ }
40
+ }
41
+ }
42
+
43
+ Function("setOnChange") { (state: ObservableState, callback: WorkletCallback?) in
44
+ state.onChange = callback
32
45
  }
33
46
  }
34
47
 
@@ -38,6 +51,33 @@ public final class ExpoUIModule: Module {
38
51
  RefreshableManager.shared.completeRefresh(id: id)
39
52
  }
40
53
 
54
+ AsyncFunction("withAnimation") { (
55
+ animation: AnimationConfig?,
56
+ body: WorkletCallback,
57
+ completion: WorkletCallback?,
58
+ completionCriteria: AnimationCompletionCriteriaType?
59
+ ) in
60
+ let swiftUIAnimation = animation?.toSwiftUIAnimation()
61
+
62
+ if let completion {
63
+ if #available(iOS 17.0, tvOS 17.0, *) {
64
+ let criteria: SwiftUI.AnimationCompletionCriteria =
65
+ completionCriteria == .removed ? .removed : .logicallyComplete
66
+ withAnimation(swiftUIAnimation, completionCriteria: criteria) {
67
+ body.invoke()
68
+ } completion: {
69
+ completion.invoke()
70
+ }
71
+ return
72
+ }
73
+ }
74
+
75
+ withAnimation(swiftUIAnimation) {
76
+ body.invoke()
77
+ }
78
+ }
79
+ .runOnQueue(.main)
80
+
41
81
  // MARK: - Expo UI Views with AsyncFunctions
42
82
 
43
83
  ExpoUIView(SecureFieldView.self) {
@@ -81,13 +121,16 @@ public final class ExpoUIModule: Module {
81
121
  }
82
122
  }
83
123
 
84
- // MARK: - Views don't support common view modifiers
124
+ // MARK: - Views that apply common view modifiers internally
125
+
126
+ View(HostView.self)
127
+ View(TextView.self)
128
+
129
+ // MARK: - Views that don't support common view modifiers
85
130
 
86
131
  View(SlotView.self)
87
132
  View(NamespaceView.self)
88
133
  View(GridRowView.self)
89
- View(HostView.self)
90
- View(TextView.self)
91
134
 
92
135
  // MARK: - Expo UI Views
93
136
 
@@ -38,6 +38,7 @@ internal final class HostViewProps: ExpoSwiftUI.ViewProps, ExpoSwiftUI.SafeAreaC
38
38
  @Field var matchContentsHorizontal = false
39
39
  @Field var matchContentsVertical = false
40
40
  @Field var ignoreSafeArea: ExpoSwiftUI.IgnoreSafeArea?
41
+ @Field var modifiers: ModifierArray?
41
42
  var onLayoutContent = EventDispatcher()
42
43
  }
43
44
 
@@ -45,38 +46,40 @@ struct HostView: ExpoSwiftUI.View, ExpoSwiftUI.WithHostingView {
45
46
  @ObservedObject var props: HostViewProps
46
47
 
47
48
  var body: some View {
48
- var useViewportSizeMeasurement: Bool = props.useViewportSizeMeasurement
49
- if #available(iOS 16.0, tvOS 16.0, macOS 13.0, *) {
50
- useViewportSizeMeasurement = props.useViewportSizeMeasurement
51
- } else {
52
- log.warn("useViewportSizeMeasurement is not supported on iOS/tvOS < 16.0")
53
- useViewportSizeMeasurement = false
54
- }
55
-
56
49
  let layoutDirection = props.layoutDirection.toLayoutDirection()
57
50
  let alignment: Alignment = layoutDirection == .rightToLeft ? .topTrailing : .topLeading
58
51
 
59
52
  if #available(iOS 16.0, tvOS 16.0, macOS 13.0, *) {
60
53
  // swiftlint:disable:next identifier_name
61
- let HostLayout = useViewportSizeMeasurement
54
+ let HostLayout = props.useViewportSizeMeasurement
62
55
  ? AnyLayout(ViewportSizeMeasurementLayout(layoutDirection: layoutDirection))
63
56
  : AnyLayout(ZStackLayout(alignment: alignment))
64
- return HostLayout {
57
+ HostLayout {
65
58
  Children()
66
59
  }
67
60
  .fixedSize(horizontal: props.matchContentsHorizontal, vertical: props.matchContentsVertical)
68
61
  .modifier(LayoutDirectionModifier(layoutDirection: layoutDirection))
69
62
  .modifier(ColorSchemeModifier(colorScheme: props.colorScheme?.toColorScheme()))
63
+ .applyModifiers(
64
+ props.modifiers,
65
+ appContext: props.appContext,
66
+ globalEventDispatcher: props.globalEventDispatcher
67
+ )
68
+ .modifier(GeometryChangeModifier(props: props))
69
+ } else {
70
+ ZStack(alignment: alignment) {
71
+ Children()
72
+ }
73
+ .fixedSize(horizontal: props.matchContentsHorizontal, vertical: props.matchContentsVertical)
74
+ .modifier(LayoutDirectionModifier(layoutDirection: layoutDirection))
75
+ .modifier(ColorSchemeModifier(colorScheme: props.colorScheme?.toColorScheme()))
76
+ .applyModifiers(
77
+ props.modifiers,
78
+ appContext: props.appContext,
79
+ globalEventDispatcher: props.globalEventDispatcher
80
+ )
70
81
  .modifier(GeometryChangeModifier(props: props))
71
82
  }
72
-
73
- return ZStack(alignment: alignment) {
74
- Children()
75
- }
76
- .fixedSize(horizontal: props.matchContentsHorizontal, vertical: props.matchContentsVertical)
77
- .modifier(LayoutDirectionModifier(layoutDirection: layoutDirection))
78
- .modifier(ColorSchemeModifier(colorScheme: props.colorScheme?.toColorScheme()))
79
- .modifier(GeometryChangeModifier(props: props))
80
83
  }
81
84
 
82
85
  private func safeAreaSize() -> CGSize {
@@ -0,0 +1,109 @@
1
+ // Copyright 2025-present 650 Industries. All rights reserved.
2
+
3
+ import ExpoModulesCore
4
+ import SwiftUI
5
+
6
+ internal enum AnimationType: String, Enumerable {
7
+ case easeInOut
8
+ case easeIn
9
+ case easeOut
10
+ case linear
11
+ case spring
12
+ case interpolatingSpring
13
+ case `default`
14
+ }
15
+
16
+ internal enum AnimationCompletionCriteriaType: String, Enumerable {
17
+ case logicallyComplete
18
+ case removed
19
+ }
20
+
21
+ /**
22
+ Describes a SwiftUI `Animation` value over the JS bridge. Consumed by both
23
+ the `animation(_:value:)` view modifier and the `withAnimation(_:_:)`
24
+ function so they accept the same JS shape.
25
+ */
26
+ internal struct AnimationConfig: Record {
27
+ // Shared fallbacks used when the JS side omits a parameter. Mirrors
28
+ // SwiftUI's own defaults so each animation variant resolves the same way.
29
+ private static let defaultDuration: Double = 0.5
30
+ private static let defaultResponse: Double = 0.5
31
+ private static let defaultDampingFraction: Double = 0.825
32
+ private static let defaultBlendDuration: Double = 0.0
33
+ private static let defaultBounce: Double = 0.0
34
+
35
+ @Field var type: AnimationType = .default
36
+ @Field var duration: Double?
37
+ @Field var response: Double?
38
+ @Field var dampingFraction: Double?
39
+ @Field var blendDuration: Double?
40
+ @Field var bounce: Double?
41
+ @Field var mass: Double = 1.0
42
+ @Field var stiffness: Double?
43
+ @Field var damping: Double?
44
+ @Field var initialVelocity: Double = 0.0
45
+ @Field var delay: Double?
46
+ @Field var repeatCount: Int?
47
+ @Field var autoreverses: Bool = true
48
+
49
+ func toSwiftUIAnimation() -> Animation {
50
+ var animation: Animation
51
+
52
+ switch type {
53
+ case .easeIn:
54
+ animation = duration.map { Animation.easeIn(duration: $0) } ?? .easeIn
55
+ case .easeOut:
56
+ animation = duration.map { Animation.easeOut(duration: $0) } ?? .easeOut
57
+ case .linear:
58
+ animation = duration.map { Animation.linear(duration: $0) } ?? .linear
59
+ case .easeInOut:
60
+ animation = duration.map { Animation.easeInOut(duration: $0) } ?? .easeInOut
61
+ case .spring:
62
+ if response != nil || dampingFraction != nil {
63
+ animation = .spring(
64
+ response: response ?? Self.defaultResponse,
65
+ dampingFraction: dampingFraction ?? Self.defaultDampingFraction,
66
+ blendDuration: blendDuration ?? Self.defaultBlendDuration
67
+ )
68
+ } else if duration != nil || bounce != nil {
69
+ animation = .spring(
70
+ duration: duration ?? Self.defaultDuration,
71
+ bounce: bounce ?? Self.defaultBounce,
72
+ blendDuration: blendDuration ?? Self.defaultBlendDuration
73
+ )
74
+ } else if let blendDuration {
75
+ animation = .spring(blendDuration: blendDuration)
76
+ } else {
77
+ animation = .spring
78
+ }
79
+ case .interpolatingSpring:
80
+ if duration != nil || bounce != nil {
81
+ animation = .interpolatingSpring(
82
+ duration: duration ?? Self.defaultDuration,
83
+ bounce: bounce ?? Self.defaultBounce,
84
+ initialVelocity: initialVelocity
85
+ )
86
+ } else if let stiffness, let damping {
87
+ animation = .interpolatingSpring(
88
+ mass: mass,
89
+ stiffness: stiffness,
90
+ damping: damping,
91
+ initialVelocity: initialVelocity
92
+ )
93
+ } else {
94
+ animation = .interpolatingSpring
95
+ }
96
+ default:
97
+ animation = .default
98
+ }
99
+
100
+ if let delay {
101
+ animation = animation.delay(delay)
102
+ }
103
+ if let repeatCount {
104
+ animation = animation.repeatCount(repeatCount, autoreverses: autoreverses)
105
+ }
106
+
107
+ return animation
108
+ }
109
+ }
@@ -16,15 +16,15 @@ internal enum FontWeight: String, Enumerable {
16
16
 
17
17
  func toSwiftUI() -> Font.Weight {
18
18
  switch self {
19
- case .ultraLight: return .ultraLight
20
- case .thin: return .thin
21
- case .light: return .light
22
- case .regular: return .regular
23
- case .medium: return .medium
24
- case .semibold: return .semibold
25
- case .bold: return .bold
26
- case .heavy: return .heavy
27
- case .black: return .black
19
+ case .ultraLight: .ultraLight
20
+ case .thin: .thin
21
+ case .light: .light
22
+ case .regular: .regular
23
+ case .medium: .medium
24
+ case .semibold: .semibold
25
+ case .bold: .bold
26
+ case .heavy: .heavy
27
+ case .black: .black
28
28
  }
29
29
  }
30
30
  }
@@ -37,10 +37,40 @@ internal enum FontDesign: String, Enumerable {
37
37
 
38
38
  func toSwiftUI() -> Font.Design {
39
39
  switch self {
40
- case .default: return .default
41
- case .rounded: return .rounded
42
- case .serif: return .serif
43
- case .monospaced: return .monospaced
40
+ case .default: .default
41
+ case .rounded: .rounded
42
+ case .serif: .serif
43
+ case .monospaced: .monospaced
44
+ }
45
+ }
46
+ }
47
+
48
+ internal enum FontTextStyle: String, Enumerable {
49
+ case largeTitle
50
+ case title
51
+ case title2
52
+ case title3
53
+ case headline
54
+ case subheadline
55
+ case body
56
+ case callout
57
+ case footnote
58
+ case caption
59
+ case caption2
60
+
61
+ func toSwiftUI() -> Font.TextStyle {
62
+ switch self {
63
+ case .largeTitle: .largeTitle
64
+ case .title: .title
65
+ case .title2: .title2
66
+ case .title3: .title3
67
+ case .headline: .headline
68
+ case .subheadline: .subheadline
69
+ case .body: .body
70
+ case .callout: .callout
71
+ case .footnote: .footnote
72
+ case .caption: .caption
73
+ case .caption2: .caption2
44
74
  }
45
75
  }
46
76
  }
@@ -50,16 +80,38 @@ internal struct FontModifier: ViewModifier, Record {
50
80
  @Field var size: CGFloat?
51
81
  @Field var weight: FontWeight?
52
82
  @Field var design: FontDesign?
83
+ @Field var textStyle: FontTextStyle?
53
84
 
54
85
  func body(content: Content) -> some View {
86
+ content.font(resolveFont())
87
+ }
88
+
89
+ private func resolveFont() -> Font {
55
90
  if let family = family {
56
- content.font(Font.custom(family, size: size ?? 17))
57
- } else {
58
- content.font(.system(
59
- size: size ?? 17,
60
- weight: weight?.toSwiftUI() ?? .regular,
61
- design: design?.toSwiftUI() ?? .default
62
- ))
91
+ let baseSize = size ?? 17
92
+ var font: Font = if let textStyle = textStyle {
93
+ Font.custom(family, size: baseSize, relativeTo: textStyle.toSwiftUI())
94
+ } else {
95
+ Font.custom(family, size: baseSize)
96
+ }
97
+ if let weight = weight {
98
+ font = font.weight(weight.toSwiftUI())
99
+ }
100
+ return font
63
101
  }
102
+
103
+ if let textStyle = textStyle {
104
+ var font = Font.system(textStyle.toSwiftUI(), design: design?.toSwiftUI() ?? .default)
105
+ if let weight = weight {
106
+ font = font.weight(weight.toSwiftUI())
107
+ }
108
+ return font
109
+ }
110
+
111
+ return .system(
112
+ size: size ?? 17,
113
+ weight: weight?.toSwiftUI() ?? .regular,
114
+ design: design?.toSwiftUI() ?? .default
115
+ )
64
116
  }
65
117
  }
@@ -0,0 +1,107 @@
1
+ // Copyright 2026-present 650 Industries. All rights reserved.
2
+
3
+ import ExpoModulesCore
4
+ import SwiftUI
5
+
6
+ internal struct OnScrollGeometryChangeModifier: ViewModifier, Record {
7
+ // Worklet path: synchronous invocation on the UI runtime (no JS-thread dispatch).
8
+ @Field var workletCallback: WorkletCallback?
9
+ // JS-thread path: async event via the global modifier event dispatcher.
10
+ var eventDispatcher: EventDispatcher?
11
+
12
+ init() {}
13
+
14
+ init(from params: Dict, appContext: AppContext, eventDispatcher: EventDispatcher) throws {
15
+ try self = .init(from: params, appContext: appContext)
16
+ self.eventDispatcher = eventDispatcher
17
+ }
18
+
19
+ func body(content: Content) -> some View {
20
+ if #available(iOS 18.0, tvOS 18.0, *) {
21
+ content
22
+ .onScrollGeometryChange(for: ScrollGeometryPayload.self) { ScrollGeometryPayload($0) }
23
+ action: { [workletCallback, eventDispatcher] _, payload in
24
+ let geometry = payload.dictionary
25
+ if let workletCallback {
26
+ workletCallback.invoke(arguments: [geometry])
27
+ } else {
28
+ eventDispatcher?(["onScrollGeometryChange": geometry])
29
+ }
30
+ }
31
+ } else {
32
+ content
33
+ }
34
+ }
35
+ }
36
+
37
+ internal struct OnScrollPhaseChangeModifier: ViewModifier, Record {
38
+ var eventDispatcher: EventDispatcher?
39
+
40
+ init() {}
41
+
42
+ init(from params: Dict, appContext: AppContext, eventDispatcher: EventDispatcher) throws {
43
+ try self = .init(from: params, appContext: appContext)
44
+ self.eventDispatcher = eventDispatcher
45
+ }
46
+
47
+ func body(content: Content) -> some View {
48
+ if #available(iOS 18.0, tvOS 18.0, *) {
49
+ content.onScrollPhaseChange { [eventDispatcher] _, newPhase, context in
50
+ eventDispatcher?([
51
+ "onScrollPhaseChange": [
52
+ "phase": Self.phaseString(newPhase),
53
+ "geometry": ScrollGeometryPayload(context.geometry).dictionary
54
+ ]
55
+ ])
56
+ }
57
+ } else {
58
+ content
59
+ }
60
+ }
61
+
62
+ @available(iOS 18.0, tvOS 18.0, *)
63
+ private static func phaseString(_ phase: ScrollPhase) -> String {
64
+ return switch phase {
65
+ case .idle: "idle"
66
+ case .tracking: "tracking"
67
+ case .interacting: "interacting"
68
+ case .animating: "animating"
69
+ case .decelerating: "decelerating"
70
+ @unknown default: "idle"
71
+ }
72
+ }
73
+ }
74
+
75
+ internal struct ScrollGeometryPayload: Equatable {
76
+ let contentOffsetX: CGFloat
77
+ let contentOffsetY: CGFloat
78
+ let containerWidth: CGFloat
79
+ let containerHeight: CGFloat
80
+ let contentWidth: CGFloat
81
+ let contentHeight: CGFloat
82
+
83
+ var dictionary: [String: Any] {
84
+ [
85
+ "contentOffsetX": contentOffsetX,
86
+ "contentOffsetY": contentOffsetY,
87
+ "containerWidth": containerWidth,
88
+ "containerHeight": containerHeight,
89
+ "contentWidth": contentWidth,
90
+ "contentHeight": contentHeight
91
+ ]
92
+ }
93
+ }
94
+
95
+ @available(iOS 18.0, tvOS 18.0, *)
96
+ extension ScrollGeometryPayload {
97
+ init(_ geometry: ScrollGeometry) {
98
+ self.init(
99
+ contentOffsetX: geometry.contentOffset.x,
100
+ contentOffsetY: geometry.contentOffset.y,
101
+ containerWidth: geometry.containerSize.width,
102
+ containerHeight: geometry.containerSize.height,
103
+ contentWidth: geometry.contentSize.width,
104
+ contentHeight: geometry.contentSize.height
105
+ )
106
+ }
107
+ }
@@ -621,38 +621,12 @@ internal struct AnyViewModifier: ViewModifier {
621
621
  }
622
622
  }
623
623
 
624
- internal enum AnimationType: String, Enumerable {
625
- case easeInOut
626
- case easeIn
627
- case easeOut
628
- case linear
629
- case spring
630
- case interpolatingSpring
631
- case `default`
632
- }
633
-
634
- internal struct AnimationConfig: Record {
635
- @Field var type: AnimationType = .default
636
- @Field var duration: Double?
637
- @Field var response: Double?
638
- @Field var dampingFraction: Double?
639
- @Field var blendDuration: Double?
640
- @Field var bounce: Double?
641
- @Field var mass: Double?
642
- @Field var stiffness: Double?
643
- @Field var damping: Double?
644
- @Field var initialVelocity: Double?
645
- @Field var delay: Double?
646
- @Field var repeatCount: Int?
647
- @Field var autoreverses: Bool?
648
- }
649
-
650
624
  internal struct AnimationModifier: ViewModifier, Record {
651
625
  @Field var animation: AnimationConfig
652
626
  @Field var animatedValue: Either<Double, Bool>?
653
627
 
654
628
  func body(content: Content) -> some View {
655
- let animationValue = parseAnimation(animation)
629
+ let animationValue = animation.toSwiftUIAnimation()
656
630
  if let value: Bool = animatedValue?.get() {
657
631
  content.animation(animationValue, value: value)
658
632
  } else if let value: Double = animatedValue?.get() {
@@ -661,91 +635,6 @@ internal struct AnimationModifier: ViewModifier, Record {
661
635
  content
662
636
  }
663
637
  }
664
-
665
- private func parseAnimation(_ config: AnimationConfig) -> Animation {
666
- let type = config.type
667
-
668
- var animation: Animation
669
-
670
- switch type {
671
- case .easeIn:
672
- if let duration = config.duration {
673
- animation = .easeIn(duration: duration)
674
- } else {
675
- animation = .easeIn
676
- }
677
-
678
- case .easeOut:
679
- if let duration = config.duration {
680
- animation = .easeOut(duration: duration)
681
- } else {
682
- animation = .easeOut
683
- }
684
-
685
- case .linear:
686
- if let duration = config.duration {
687
- animation = .linear(duration: duration)
688
- } else {
689
- animation = .linear
690
- }
691
-
692
- case .easeInOut:
693
- if let duration = config.duration {
694
- animation = .easeInOut(duration: duration)
695
- } else {
696
- animation = .easeInOut
697
- }
698
-
699
- case .spring:
700
- let duration = config.duration
701
- let bounce = config.bounce
702
- let response = config.response
703
- let dampingFraction = config.dampingFraction
704
- let blendDuration = config.blendDuration
705
-
706
- if response != nil || dampingFraction != nil {
707
- // default values are 0.5, 0.825, 0.0
708
- animation = .spring(response: response ?? 0.5, dampingFraction: dampingFraction ?? 0.825, blendDuration: blendDuration ?? 0.0)
709
- } else if duration != nil || bounce != nil {
710
- // default values are 0.5, 0.0, 0.0
711
- animation = .spring(duration: duration ?? 0.5, bounce: bounce ?? 0.0, blendDuration: blendDuration ?? 0.0)
712
- } else if let blendDuration = blendDuration {
713
- animation = .spring(blendDuration: blendDuration)
714
- } else {
715
- animation = .spring
716
- }
717
-
718
- case .interpolatingSpring:
719
- let duration = config.duration
720
- let bounce = config.bounce
721
- let mass = config.mass
722
- let stiffness = config.stiffness
723
- let damping = config.damping
724
- let initialVelocity = config.initialVelocity
725
-
726
- if duration != nil || bounce != nil {
727
- animation = .interpolatingSpring(duration: duration ?? 0.5, bounce: bounce ?? 0.0, initialVelocity: initialVelocity ?? 0.0)
728
- } else if let stiffness, let damping {
729
- animation = .interpolatingSpring(mass: mass ?? 1.0, stiffness: stiffness, damping: damping, initialVelocity: initialVelocity ?? 0.0)
730
- } else {
731
- animation = .interpolatingSpring
732
- }
733
-
734
- default:
735
- animation = .default
736
- }
737
-
738
- if let delay = config.delay {
739
- animation = animation.delay(delay)
740
- }
741
-
742
- if let repeatCount = config.repeatCount {
743
- let autoreverses = config.autoreverses ?? false
744
- animation = animation.repeatCount(repeatCount, autoreverses: autoreverses)
745
- }
746
-
747
- return animation
748
- }
749
638
  }
750
639
 
751
640
  internal enum ScrollContentBackgroundTypes: String, Enumerable {
@@ -1961,5 +1850,13 @@ extension ViewModifierRegistry {
1961
1850
  register("symbolEffect") { params, appContext, _ in
1962
1851
  return try SymbolEffectModifier(from: params, appContext: appContext)
1963
1852
  }
1853
+
1854
+ register("onScrollPhaseChange") { params, appContext, eventDispatcher in
1855
+ return try OnScrollPhaseChangeModifier(from: params, appContext: appContext, eventDispatcher: eventDispatcher)
1856
+ }
1857
+
1858
+ register("onScrollGeometryChange") { params, appContext, eventDispatcher in
1859
+ return try OnScrollGeometryChangeModifier(from: params, appContext: appContext, eventDispatcher: eventDispatcher)
1860
+ }
1964
1861
  }
1965
1862
  }