@expo/ui 57.0.21 → 57.0.23

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 (128) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/ui/DatePickerView.kt +36 -2
  4. package/android/src/main/java/expo/modules/ui/DateRangePickerView.kt +35 -2
  5. package/android/src/main/java/expo/modules/ui/HostView.kt +28 -1
  6. package/android/src/main/java/expo/modules/ui/ModifierRegistry.kt +23 -2
  7. package/android/src/main/java/expo/modules/ui/RNHostView.kt +124 -17
  8. package/build/community/bottom-sheet/BottomSheet.ios.d.ts.map +1 -1
  9. package/build/community/datetime-picker/DateTimePicker.android.d.ts.map +1 -1
  10. package/build/community/datetime-picker/utils.d.ts +11 -0
  11. package/build/community/datetime-picker/utils.d.ts.map +1 -0
  12. package/build/community/picker/Picker.android.d.ts.map +1 -1
  13. package/build/jetpack-compose/DatePicker/index.d.ts +38 -0
  14. package/build/jetpack-compose/DatePicker/index.d.ts.map +1 -1
  15. package/build/jetpack-compose/RNHostView/index.d.ts +6 -1
  16. package/build/jetpack-compose/RNHostView/index.d.ts.map +1 -1
  17. package/build/jetpack-compose/modifiers/index.d.ts +18 -3
  18. package/build/jetpack-compose/modifiers/index.d.ts.map +1 -1
  19. package/build/swift-ui/ArrangementView/index.d.ts +49 -0
  20. package/build/swift-ui/ArrangementView/index.d.ts.map +1 -0
  21. package/build/swift-ui/Chart/index.d.ts +10 -0
  22. package/build/swift-ui/Chart/index.d.ts.map +1 -1
  23. package/build/swift-ui/RNHostView.d.ts +7 -2
  24. package/build/swift-ui/RNHostView.d.ts.map +1 -1
  25. package/build/swift-ui/index.d.ts +1 -0
  26. package/build/swift-ui/index.d.ts.map +1 -1
  27. package/build/swift-ui/modifiers/animation/index.d.ts +6 -1
  28. package/build/swift-ui/modifiers/animation/index.d.ts.map +1 -1
  29. package/build/swift-ui/modifiers/animation/types.d.ts +15 -1
  30. package/build/swift-ui/modifiers/animation/types.d.ts.map +1 -1
  31. package/build/swift-ui/modifiers/arrangementModifiers.d.ts +110 -0
  32. package/build/swift-ui/modifiers/arrangementModifiers.d.ts.map +1 -0
  33. package/build/swift-ui/modifiers/containerBackground.d.ts +2 -2
  34. package/build/swift-ui/modifiers/index.d.ts +41 -2
  35. package/build/swift-ui/modifiers/index.d.ts.map +1 -1
  36. package/build/swift-ui/modifiers/presentationModifiers.d.ts +17 -1
  37. package/build/swift-ui/modifiers/presentationModifiers.d.ts.map +1 -1
  38. package/build/swift-ui/modifiers/searchable.d.ts +84 -0
  39. package/build/swift-ui/modifiers/searchable.d.ts.map +1 -0
  40. package/build/universal/RNHostView/index.d.ts.map +1 -1
  41. package/build/universal/RNHostView/types.d.ts +9 -4
  42. package/build/universal/RNHostView/types.d.ts.map +1 -1
  43. package/build/universal/Switch/index.android.d.ts.map +1 -1
  44. package/build/utils/matchContents.d.ts +11 -0
  45. package/build/utils/matchContents.d.ts.map +1 -0
  46. package/expo-module.config.json +1 -1
  47. package/ios/ArrangementViewView.swift +40 -0
  48. package/ios/ChartView.swift +15 -10
  49. package/ios/ExpoUIModule.swift +1 -1
  50. package/ios/Modifiers/AnimationConfig.swift +20 -0
  51. package/ios/Modifiers/ArrangementModifiers.swift +157 -0
  52. package/ios/Modifiers/ContainerBackgroundModifier.swift +26 -13
  53. package/ios/Modifiers/PreferredColorSchemeModifier.swift +12 -0
  54. package/ios/Modifiers/PresentationModifiers.swift +20 -4
  55. package/ios/Modifiers/SearchToolbarBehaviorModifier.swift +35 -0
  56. package/ios/Modifiers/SearchableModifier.swift +94 -0
  57. package/ios/Modifiers/View+ModifierArray.swift +3 -3
  58. package/ios/Modifiers/ViewModifierRegistry.swift +124 -9
  59. package/ios/Modifiers/WidgetKitModifiers.swift +13 -0
  60. package/ios/Picker/PickerView.swift +9 -7
  61. package/ios/RNHostView.swift +55 -9
  62. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.21/expo.modules.ui-57.0.21-sources.jar → 57.0.23/expo.modules.ui-57.0.23-sources.jar} +0 -0
  63. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23-sources.jar.md5 +1 -0
  64. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23-sources.jar.sha1 +1 -0
  65. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23-sources.jar.sha256 +1 -0
  66. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23-sources.jar.sha512 +1 -0
  67. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23.aar +0 -0
  68. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23.aar.md5 +1 -0
  69. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23.aar.sha1 +1 -0
  70. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23.aar.sha256 +1 -0
  71. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23.aar.sha512 +1 -0
  72. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.21/expo.modules.ui-57.0.21.module → 57.0.23/expo.modules.ui-57.0.23.module} +22 -22
  73. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23.module.md5 +1 -0
  74. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23.module.sha1 +1 -0
  75. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23.module.sha256 +1 -0
  76. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23.module.sha512 +1 -0
  77. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.21/expo.modules.ui-57.0.21.pom → 57.0.23/expo.modules.ui-57.0.23.pom} +1 -1
  78. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23.pom.md5 +1 -0
  79. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23.pom.sha1 +1 -0
  80. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23.pom.sha256 +1 -0
  81. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.23/expo.modules.ui-57.0.23.pom.sha512 +1 -0
  82. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
  83. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
  84. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
  85. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
  86. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
  87. package/package.json +4 -4
  88. package/src/community/bottom-sheet/BottomSheet.ios.tsx +7 -6
  89. package/src/community/datetime-picker/DateTimePicker.android.tsx +18 -4
  90. package/src/community/datetime-picker/utils.ts +21 -0
  91. package/src/community/picker/Picker.android.tsx +5 -0
  92. package/src/jetpack-compose/DatePicker/index.tsx +38 -0
  93. package/src/jetpack-compose/RNHostView/index.tsx +17 -6
  94. package/src/jetpack-compose/modifiers/index.ts +17 -3
  95. package/src/swift-ui/ArrangementView/index.tsx +70 -0
  96. package/src/swift-ui/Chart/index.tsx +10 -0
  97. package/src/swift-ui/RNHostView.tsx +11 -4
  98. package/src/swift-ui/index.tsx +1 -0
  99. package/src/swift-ui/modifiers/animation/index.ts +24 -11
  100. package/src/swift-ui/modifiers/animation/types.ts +18 -0
  101. package/src/swift-ui/modifiers/arrangementModifiers.ts +142 -0
  102. package/src/swift-ui/modifiers/containerBackground.ts +2 -2
  103. package/src/swift-ui/modifiers/index.ts +52 -1
  104. package/src/swift-ui/modifiers/presentationModifiers.ts +18 -2
  105. package/src/swift-ui/modifiers/searchable.ts +107 -0
  106. package/src/universal/RNHostView/index.tsx +9 -4
  107. package/src/universal/RNHostView/types.ts +6 -4
  108. package/src/universal/Switch/index.android.tsx +11 -2
  109. package/src/utils/matchContents.ts +14 -0
  110. package/ios/AccessoryWidgetBackgroundView.swift +0 -27
  111. package/ios/Modifiers/WidgetModifiers.swift +0 -70
  112. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21-sources.jar.md5 +0 -1
  113. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21-sources.jar.sha1 +0 -1
  114. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21-sources.jar.sha256 +0 -1
  115. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21-sources.jar.sha512 +0 -1
  116. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.aar +0 -0
  117. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.aar.md5 +0 -1
  118. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.aar.sha1 +0 -1
  119. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.aar.sha256 +0 -1
  120. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.aar.sha512 +0 -1
  121. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.module.md5 +0 -1
  122. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.module.sha1 +0 -1
  123. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.module.sha256 +0 -1
  124. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.module.sha512 +0 -1
  125. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.pom.md5 +0 -1
  126. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.pom.sha1 +0 -1
  127. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.pom.sha256 +0 -1
  128. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.pom.sha512 +0 -1
@@ -3,7 +3,7 @@
3
3
  "component": {
4
4
  "group": "expo.modules.ui",
5
5
  "module": "expo.modules.ui",
6
- "version": "57.0.21",
6
+ "version": "57.0.23",
7
7
  "attributes": {
8
8
  "org.gradle.status": "release"
9
9
  }
@@ -24,13 +24,13 @@
24
24
  },
25
25
  "files": [
26
26
  {
27
- "name": "expo.modules.ui-57.0.21.aar",
28
- "url": "expo.modules.ui-57.0.21.aar",
29
- "size": 2074203,
30
- "sha512": "894745399f2255f02b84f664c1e62ab66d71daf4a24e3ce48ecfb7e60d0ba9abfbe31a5d9517953e2d365b786ba9da8ba8f476361777fd57006eb7fb7522c32c",
31
- "sha256": "edfc30f6ff0935cee758638ea4443ec247e3628ba4a088f44f58becfca185b6e",
32
- "sha1": "b8495e88a2dd3b3386885867acede44c5a99186f",
33
- "md5": "8b8ece627534269af4e6dfa665f46f6c"
27
+ "name": "expo.modules.ui-57.0.23.aar",
28
+ "url": "expo.modules.ui-57.0.23.aar",
29
+ "size": 2087870,
30
+ "sha512": "7ba6b0ca0e41c0aeaea90cfc7d49664bb88531a251ba79b1124009eba0b724b48ba1c306744111a40871213cdf5767638b931803dc2229c4ba1850b6cc87ca15",
31
+ "sha256": "45594b39ac8f0c6eb37b663d40160b8e93b6d5f56b985a739c8a03c6780d910f",
32
+ "sha1": "bc99884c9e5f484800ffb10156cc8b50fa4d31c8",
33
+ "md5": "53230bb5c7cc2bcc0d717bc544974f6c"
34
34
  }
35
35
  ]
36
36
  },
@@ -141,13 +141,13 @@
141
141
  ],
142
142
  "files": [
143
143
  {
144
- "name": "expo.modules.ui-57.0.21.aar",
145
- "url": "expo.modules.ui-57.0.21.aar",
146
- "size": 2074203,
147
- "sha512": "894745399f2255f02b84f664c1e62ab66d71daf4a24e3ce48ecfb7e60d0ba9abfbe31a5d9517953e2d365b786ba9da8ba8f476361777fd57006eb7fb7522c32c",
148
- "sha256": "edfc30f6ff0935cee758638ea4443ec247e3628ba4a088f44f58becfca185b6e",
149
- "sha1": "b8495e88a2dd3b3386885867acede44c5a99186f",
150
- "md5": "8b8ece627534269af4e6dfa665f46f6c"
144
+ "name": "expo.modules.ui-57.0.23.aar",
145
+ "url": "expo.modules.ui-57.0.23.aar",
146
+ "size": 2087870,
147
+ "sha512": "7ba6b0ca0e41c0aeaea90cfc7d49664bb88531a251ba79b1124009eba0b724b48ba1c306744111a40871213cdf5767638b931803dc2229c4ba1850b6cc87ca15",
148
+ "sha256": "45594b39ac8f0c6eb37b663d40160b8e93b6d5f56b985a739c8a03c6780d910f",
149
+ "sha1": "bc99884c9e5f484800ffb10156cc8b50fa4d31c8",
150
+ "md5": "53230bb5c7cc2bcc0d717bc544974f6c"
151
151
  }
152
152
  ]
153
153
  },
@@ -161,13 +161,13 @@
161
161
  },
162
162
  "files": [
163
163
  {
164
- "name": "expo.modules.ui-57.0.21-sources.jar",
165
- "url": "expo.modules.ui-57.0.21-sources.jar",
166
- "size": 105285,
167
- "sha512": "bd014a7ec6f4940b753de1ef54b686c8316d45a4242893e9a508948dd22fc893063a285538d30a3fa943deedbf32915697892ff4a739e17fcb2b194a79f71d8d",
168
- "sha256": "352b556c7e482ce79471552b5d73a5f29d92e9a339fd3edecf327c7df9e6576b",
169
- "sha1": "ca977e2408458c690c3555514485a6a8e7fade24",
170
- "md5": "711eb23ebb503bc13f871f580afcbcf0"
164
+ "name": "expo.modules.ui-57.0.23-sources.jar",
165
+ "url": "expo.modules.ui-57.0.23-sources.jar",
166
+ "size": 107457,
167
+ "sha512": "0a89146da34d837d01eb682540df3405b70f6b1d18c50bedc2ecc1d0dee3188df777de03a5b629100950a0f6d3c2d9f89f52416641cb22d8f3a715c8e841ff18",
168
+ "sha256": "5f4063182b296fa0028d945a2621f9d8a86eb5219b0ad88492a18dfe4d737978",
169
+ "sha1": "04332c3498b6b2a56dfb4cbefe592c11f4a8f36a",
170
+ "md5": "9e119ee5a1c2c38e6d69d4f866341e7a"
171
171
  }
172
172
  ]
173
173
  }
@@ -0,0 +1 @@
1
+ 0f57bae59c7621092ebe1c14bfb8c87cc5b7273c
@@ -0,0 +1 @@
1
+ 0b119d47d60446499106b77dc5f2c57ceec7eba851a407248935ad6e2ecc3539
@@ -0,0 +1 @@
1
+ 7f583d3b3219882068aec8344ed3dc1018dd834668efb13abb894a7f40383e29d5927b3831e05e6fdeb563cc88c4dfbc7755f2cd1c196f7f94944a7952e43b70
@@ -9,7 +9,7 @@
9
9
  <modelVersion>4.0.0</modelVersion>
10
10
  <groupId>expo.modules.ui</groupId>
11
11
  <artifactId>expo.modules.ui</artifactId>
12
- <version>57.0.21</version>
12
+ <version>57.0.23</version>
13
13
  <packaging>aar</packaging>
14
14
  <name>expo.modules.ui</name>
15
15
  <url>https://github.com/expo/expo</url>
@@ -0,0 +1 @@
1
+ 62243ce65c64f455e89ce81503d756d2e527d796
@@ -0,0 +1 @@
1
+ 44a4eede4dc8a4bded07f608acb42e408ce8f348f356b2da8c9d59e213cd7211
@@ -0,0 +1 @@
1
+ cf1da141b64a97372daa7bd1c5df1e9b385ad5fcc99a1bc61405fe63cbdee68ac487cfd7a034fb6a2b103e9be2559c3f8366cdbec67826b71ccb6718ff31ee4c
@@ -3,11 +3,11 @@
3
3
  <groupId>expo.modules.ui</groupId>
4
4
  <artifactId>expo.modules.ui</artifactId>
5
5
  <versioning>
6
- <latest>57.0.21</latest>
7
- <release>57.0.21</release>
6
+ <latest>57.0.23</latest>
7
+ <release>57.0.23</release>
8
8
  <versions>
9
- <version>57.0.21</version>
9
+ <version>57.0.23</version>
10
10
  </versions>
11
- <lastUpdated>20260929104945</lastUpdated>
11
+ <lastUpdated>20261012142026</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- d9951eb0ffdbd1f3b4e8c66a9506881d
1
+ 24ee94a25190ebaeb53918c5209d4321
@@ -1 +1 @@
1
- ee273f19364a6847e08cbe5eb1b5daadf787040f
1
+ 19abdc5ee5d92e4d98095aba33600fd7d66cdd9a
@@ -1 +1 @@
1
- 950f75c93b0ef32cc69e20471f3a68ac9088427130a66ded938e0c3ded940478
1
+ d5851aa26d95ed5105d695c05844f6188c86f45a8320f41d9e135463fa0294b0
@@ -1 +1 @@
1
- ecc49926b4fd4296bc3b844a0f9a313ef93474eeb921d900d082366cb28c80c466c6dc4c5fa1b3445072b1e1bedb4b8cdf62022039209423a27b5d5c9a381a3e
1
+ 5ed30451f94f10e9f83d081992d999c14cca93e46c5d37296d2634c82ae630e4c5cc264158a9de4df3db398c3afa42f99f9b4fb64d19f6c432d0919950274cbc
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/ui",
3
- "version": "57.0.21",
3
+ "version": "57.0.23",
4
4
  "description": "A collection of UI components",
5
5
  "sideEffects": [
6
6
  "*.fx.js",
@@ -96,8 +96,8 @@
96
96
  "@types/react": "~19.2.0",
97
97
  "react-native-reanimated": "4.5.1",
98
98
  "react-native-worklets": "0.10.1",
99
- "expo-module-scripts": "56.0.3",
100
- "expo": "57.0.26"
99
+ "expo": "57.0.28",
100
+ "expo-module-scripts": "56.0.3"
101
101
  },
102
102
  "jest": {
103
103
  "preset": "expo-module-scripts"
@@ -121,7 +121,7 @@
121
121
  "optional": true
122
122
  }
123
123
  },
124
- "gitHead": "ad1efa3fa5802156660198ba5d787f91014d8df3",
124
+ "gitHead": "58da4edafcb043872c3ed9bf8f5957e6544d0a9c",
125
125
  "scripts": {
126
126
  "build": "expo-module build",
127
127
  "clean": "expo-module clean",
@@ -199,8 +199,9 @@ export function BottomSheet(props: BottomSheetProps) {
199
199
  const bg = extractBackgroundColor(backgroundStyle);
200
200
  return [
201
201
  ...(fitToContents
202
- ? // Makes the iPad sheet size to that content instead of opening near full height.
203
- [presentationSizing('fitted')]
202
+ ? // Fits the sheet height to the content (iPad opens near full height otherwise) and lets
203
+ // the system choose the width.
204
+ [presentationSizing('automatic', { fitted: { horizontal: false, vertical: true } })]
204
205
  : [
205
206
  presentationDetents(detents, {
206
207
  selection: selectedDetent,
@@ -231,16 +232,16 @@ export function BottomSheet(props: BottomSheetProps) {
231
232
  onDismiss={fireCloseCallbacks}
232
233
  fitToContents={fitToContents}>
233
234
  <Group modifiers={modifiers}>
234
- <RNHostView matchContents={fitToContents}>
235
+ <RNHostView matchContents={fitToContents ? { vertical: true } : false}>
235
236
  {/* paddingTop compensates for tighter spacing between native drag indicator and content
236
237
  compared to gorhom's handle. flexGrow:1 + height:0 (flex-basis 0) fills the snap-point
237
238
  height without inheriting the scrollable child's intrinsic content height. With matchContents,
238
- RNHostView lays the hosted view out at its own size, so `width` gives it the sheet width
239
- while its height stays content-sized. */}
239
+ RNHostView takes the width from the sheet, which can be narrower than the window, and
240
+ the height from the content. */}
240
241
  <View
241
242
  style={
242
243
  fitToContents
243
- ? { width, paddingTop: handleComponent !== null ? 16 : 0 }
244
+ ? { paddingTop: handleComponent !== null ? 16 : 0 }
244
245
  : { flexGrow: 1, height: 0, paddingTop: handleComponent !== null ? 16 : 0 }
245
246
  }>
246
247
  <SheetScrollContextReset>{children}</SheetScrollContextReset>
@@ -1,4 +1,5 @@
1
1
  import { buildEvent, buildChangeEvent, type DateTimePickerProps } from './types';
2
+ import { localDateToUtcDayISOString, utcDayToLocalDate } from './utils';
2
3
  import {
3
4
  DateTimePicker as AndroidPicker,
4
5
  DatePickerDialog as AndroidDatePickerDialog,
@@ -52,6 +53,14 @@ export function DateTimePicker(props: DateTimePickerProps) {
52
53
  negativeButton,
53
54
  } = props;
54
55
 
56
+ // Material3 date pickers work in UTC days, while `value` and the reported date are local —
57
+ // matching `@react-native-community/datetimepicker`. Send `value`'s local calendar day as a UTC
58
+ // day and convert the picked UTC day back, keeping `value`'s time of day. The native side
59
+ // already converts `minimumDate`/`maximumDate` by their local calendar day. Time pickers read
60
+ // local hours from the instant, so they take `value` unchanged.
61
+ const usesDateComponents = mode !== 'time';
62
+ const initialDate = usesDateComponents ? localDateToUtcDayISOString(value) : value.toISOString();
63
+
55
64
  const onDismissed = () => {
56
65
  if (onDismissProp) {
57
66
  onDismissProp();
@@ -70,10 +79,11 @@ export function DateTimePicker(props: DateTimePickerProps) {
70
79
  };
71
80
 
72
81
  const onDateSelected = (date: Date) => {
82
+ const selected = usesDateComponents ? utcDayToLocalDate(date, value) : date;
73
83
  if (onValueChange) {
74
- onValueChange(buildChangeEvent(date), date);
84
+ onValueChange(buildChangeEvent(selected), selected);
75
85
  } else {
76
- onChange?.(buildEvent(date), date);
86
+ onChange?.(buildEvent(selected), selected);
77
87
  }
78
88
  };
79
89
 
@@ -81,7 +91,7 @@ export function DateTimePicker(props: DateTimePickerProps) {
81
91
  minimumDate || maximumDate ? { start: minimumDate, end: maximumDate } : undefined;
82
92
 
83
93
  const dialogProps = {
84
- initialDate: value.toISOString(),
94
+ initialDate,
85
95
  color: accentColor,
86
96
  confirmButtonLabel: positiveButton?.label,
87
97
  dismissButtonLabel: negativeButton?.label,
@@ -111,7 +121,7 @@ export function DateTimePicker(props: DateTimePickerProps) {
111
121
  return (
112
122
  <Host matchContents={{ vertical: true }} style={style}>
113
123
  <AndroidPicker
114
- initialDate={value.toISOString()}
124
+ initialDate={initialDate}
115
125
  displayedComponents={modeToDisplayedComponents(mode)}
116
126
  variant={displayToAndroidVariant(display)}
117
127
  selectableDates={selectableDates}
@@ -119,6 +129,10 @@ export function DateTimePicker(props: DateTimePickerProps) {
119
129
  color={accentColor}
120
130
  onDateSelected={onDateSelected}
121
131
  showVariantToggle={false}
132
+ // Match iOS, where the inline picker has no label: hide Material 3's "Select date" title
133
+ // and its selected-date headline.
134
+ showTitle={false}
135
+ showHeadline={false}
122
136
  {...(testID ? { testID } : undefined)}
123
137
  />
124
138
  </Host>
@@ -0,0 +1,21 @@
1
+ // Material3's DatePicker (and the native side's `toUtcDayMillis` bounds conversion) works in UTC
2
+ // days, while `value`, `minimumDate`, and `maximumDate` are local dates — matching
3
+ // `@react-native-community/datetimepicker`. These helpers convert between the two.
4
+
5
+ /**
6
+ * Returns the ISO string of the UTC midnight of `value`'s local calendar day, so Material3 shows
7
+ * the same day the user sees locally.
8
+ */
9
+ export function localDateToUtcDayISOString(value: Date): string {
10
+ return new Date(Date.UTC(value.getFullYear(), value.getMonth(), value.getDate())).toISOString();
11
+ }
12
+
13
+ /**
14
+ * Converts the UTC-midnight day reported by Material3 back into a local date, keeping the time of
15
+ * day from `timeOfDay`.
16
+ */
17
+ export function utcDayToLocalDate(utcDay: Date, timeOfDay: Date): Date {
18
+ const result = new Date(timeOfDay);
19
+ result.setFullYear(utcDay.getUTCFullYear(), utcDay.getUTCMonth(), utcDay.getUTCDate());
20
+ return result;
21
+ }
@@ -36,6 +36,11 @@ export function Picker<T extends PickerItemValue>(props: PickerProps<T>) {
36
36
  const selectedLabel = selectedItem?.label ?? '';
37
37
  const labelState = useNativeState(selectedLabel);
38
38
 
39
+ // `useNativeState` only captures its initial value, so push later changes to the field.
40
+ React.useEffect(() => {
41
+ labelState.set(selectedLabel);
42
+ }, [labelState, selectedLabel]);
43
+
39
44
  return (
40
45
  <Host style={style} matchContents={{ vertical: true }}>
41
46
  <ExposedDropdownMenuBox
@@ -131,6 +131,20 @@ export interface DateTimePickerProps {
131
131
  * @default true
132
132
  */
133
133
  showVariantToggle?: boolean;
134
+ /**
135
+ * Whether the picker shows its title, such as "Select date". When `false`, the picker passes
136
+ * `null` to Material 3's `title` slot. This prop has no effect when `displayedComponents` is
137
+ * `'hourAndMinute'`.
138
+ * @default true
139
+ */
140
+ showTitle?: boolean;
141
+ /**
142
+ * Whether the picker shows its headline, which displays the current selection. When `false`,
143
+ * the picker passes `null` to Material 3's `headline` slot. This prop has no effect when
144
+ * `displayedComponents` is `'hourAndMinute'`.
145
+ * @default true
146
+ */
147
+ showHeadline?: boolean;
134
148
  /**
135
149
  * The components that the picker should display.
136
150
  * On Android, you can have a picker that selects just the date or just the time.
@@ -252,6 +266,18 @@ export interface DateRangePickerProps {
252
266
  * @default true
253
267
  */
254
268
  showVariantToggle?: boolean;
269
+ /**
270
+ * Whether the picker shows its title, such as "Select date". When `false`, the picker passes
271
+ * `null` to Material 3's `title` slot.
272
+ * @default true
273
+ */
274
+ showTitle?: boolean;
275
+ /**
276
+ * Whether the picker shows its headline, which displays the current selection. When `false`,
277
+ * the picker passes `null` to Material 3's `headline` slot.
278
+ * @default true
279
+ */
280
+ showHeadline?: boolean;
255
281
  /**
256
282
  * The tint color to use on the picker elements.
257
283
  */
@@ -332,6 +358,18 @@ export interface DatePickerDialogProps {
332
358
  initialDate?: string | null;
333
359
  variant?: AndroidVariant;
334
360
  showVariantToggle?: boolean;
361
+ /**
362
+ * Whether the picker shows its title, such as "Select date". When `false`, the picker passes
363
+ * `null` to Material 3's `title` slot.
364
+ * @default true
365
+ */
366
+ showTitle?: boolean;
367
+ /**
368
+ * Whether the picker shows its headline, which displays the current selection. When `false`,
369
+ * the picker passes `null` to Material 3's `headline` slot.
370
+ * @default true
371
+ */
372
+ showHeadline?: boolean;
335
373
  confirmButtonLabel?: string;
336
374
  dismissButtonLabel?: string;
337
375
  color?: ColorValue;
@@ -4,6 +4,7 @@ import type { LayoutChangeEvent } from 'react-native';
4
4
 
5
5
  import { PresentedContentContext, useIsPresentedInOwnWindow } from '../../PresentedContentContext';
6
6
  import type { ModifierConfig } from '../../types';
7
+ import { resolveMatchContents } from '../../utils/matchContents';
7
8
  import type { PrimitiveBaseProps } from '../layout';
8
9
  import { createViewModifierEventListener } from '../modifiers/utils';
9
10
 
@@ -11,10 +12,12 @@ export interface RNHostProps extends PrimitiveBaseProps {
11
12
  /**
12
13
  * When `true`, the RNHost will update its size in the Jetpack Compose view tree to match the children's size.
13
14
  * When `false`, the RNHost will use the size of the parent Jetpack Compose View.
15
+ * Pass an object to choose per axis. For example, `{ vertical: true }` takes the width from the
16
+ * parent and the height from the children, so text wraps and grows vertically.
14
17
  * Can be only set once on mount.
15
18
  * @default false
16
19
  */
17
- matchContents?: boolean;
20
+ matchContents?: boolean | { vertical?: boolean; horizontal?: boolean };
18
21
  /**
19
22
  * Called on mount and whenever this view's layout in the React Native view tree changes.
20
23
  * With `matchContents`, the reported size is the one measured from the hosted view.
@@ -30,8 +33,10 @@ export interface RNHostProps extends PrimitiveBaseProps {
30
33
  modifiers?: ModifierConfig[];
31
34
  }
32
35
 
33
- type NativeRNHostProps = RNHostProps & {
36
+ type NativeRNHostProps = Omit<RNHostProps, 'matchContents'> & {
34
37
  layoutRoot: boolean;
38
+ matchContentsHorizontal: boolean;
39
+ matchContentsVertical: boolean;
35
40
  /**
36
41
  * Internal. Drives the shadow node's content measurement, see
37
42
  * `ExpoViewShadowNode::sizesToContent`.
@@ -44,13 +49,17 @@ const NativeRNHostView: ComponentType<NativeRNHostProps> = requireNativeView(
44
49
  );
45
50
 
46
51
  function transformProps(props: RNHostProps, layoutRoot: boolean): NativeRNHostProps {
47
- const { modifiers, ...restProps } = props;
52
+ const { modifiers, matchContents, ...restProps } = props;
53
+ const { horizontal: matchContentsHorizontal, vertical: matchContentsVertical } =
54
+ resolveMatchContents(matchContents);
48
55
  return {
49
56
  modifiers,
50
57
  ...(modifiers ? createViewModifierEventListener(modifiers) : undefined),
51
58
  ...restProps,
52
59
  layoutRoot,
53
- expoInternalSizeFromChildren: props.matchContents,
60
+ matchContentsHorizontal,
61
+ matchContentsVertical,
62
+ expoInternalSizeFromChildren: matchContentsHorizontal || matchContentsVertical,
54
63
  };
55
64
  }
56
65
 
@@ -61,12 +70,14 @@ export function RNHostView(props: RNHostProps) {
61
70
  // is what makes a `Pressable` drop its press on the first finger movement.
62
71
  const layoutRoot = useIsPresentedInOwnWindow();
63
72
 
73
+ const nativeProps = transformProps(props, layoutRoot);
74
+
64
75
  return (
65
76
  <NativeRNHostView
66
- {...transformProps(props, layoutRoot)}
77
+ {...nativeProps}
67
78
  // `matchContents` can only be used once on mount
68
79
  // So we force unmount when it changes to prevent unexpected layout
69
- key={props.matchContents ? 'matchContents' : 'noMatchContents'}>
80
+ key={`${nativeProps.matchContentsHorizontal}-${nativeProps.matchContentsVertical}`}>
70
81
  {/* Reset context here so only nearest RNHostView becomes the layout root for its children, and not any other RNHostView above it in the tree. */}
71
82
  <PresentedContentContext.Provider value={false}>
72
83
  {props.children}
@@ -79,10 +79,24 @@ export const fillMaxWidth = (fraction?: number) => createModifier('fillMaxWidth'
79
79
  export const fillMaxHeight = (fraction?: number) => createModifier('fillMaxHeight', { fraction });
80
80
 
81
81
  /**
82
- * Sets the exact width of the view.
83
- * @param value - Width in dp.
82
+ * Intrinsic width values for the `width` modifier. `Min` is the smallest width at which the content
83
+ * still draws correctly, and `Max` is the width the content needs when nothing limits it.
84
84
  */
85
- export const width = (value: number) => createModifier('width', { width: value });
85
+ export const IntrinsicSize = { Min: 'min', Max: 'max' } as const;
86
+ // eslint-disable-next-line @typescript-eslint/no-redeclare -- value and type share the name, like an enum
87
+ export type IntrinsicSize = (typeof IntrinsicSize)[keyof typeof IntrinsicSize];
88
+
89
+ /**
90
+ * Sets the width of the view to an exact value, or to the minimum or maximum intrinsic width of its
91
+ * content. The incoming constraints can still make the view narrower or wider than that width.
92
+ * @param value - Width in dp, or an `IntrinsicSize`. `IntrinsicSize.Min` uses the minimum intrinsic
93
+ * width, the smallest width at which the content still draws correctly (for a text, its widest word).
94
+ * `IntrinsicSize.Max` uses the maximum intrinsic width, the width the content needs when nothing
95
+ * limits it (for a text, a single line).
96
+ * @see [Compose `width(IntrinsicSize)` modifier](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/width.modifier#(androidx.compose.ui.Modifier).width(androidx.compose.foundation.layout.IntrinsicSize))
97
+ * @see [Intrinsic measurements in Compose layouts](https://developer.android.com/develop/ui/compose/layouts/intrinsic-measurements)
98
+ */
99
+ export const width = (value: number | IntrinsicSize) => createModifier('width', { width: value });
86
100
 
87
101
  /**
88
102
  * Sets the exact height of the view.
@@ -0,0 +1,70 @@
1
+ import { requireNativeView } from 'expo';
2
+
3
+ import { Slot } from '../SlotView';
4
+ import { createViewModifierEventListener } from '../modifiers/utils';
5
+ import { type CommonViewModifierProps } from '../types';
6
+
7
+ export interface ArrangementViewProps extends CommonViewModifierProps {
8
+ /**
9
+ * The views to arrange. Provide `ArrangementView.Primary` and `ArrangementView.Secondary`.
10
+ */
11
+ children: React.ReactNode;
12
+ }
13
+
14
+ const ArrangementViewNativeView: React.ComponentType<ArrangementViewProps> = requireNativeView(
15
+ 'ExpoUI',
16
+ 'ArrangementViewView'
17
+ );
18
+
19
+ /**
20
+ * The primary view of the arrangement.
21
+ */
22
+ function ArrangementViewPrimary(props: { children: React.ReactNode }) {
23
+ return <Slot name="primary">{props.children}</Slot>;
24
+ }
25
+
26
+ /**
27
+ * The secondary view of the arrangement.
28
+ */
29
+ function ArrangementViewSecondary(props: { children: React.ReactNode }) {
30
+ return <Slot name="secondary">{props.children}</Slot>;
31
+ }
32
+
33
+ ArrangementView.Primary = ArrangementViewPrimary;
34
+ ArrangementView.Secondary = ArrangementViewSecondary;
35
+
36
+ /**
37
+ * ArrangementView uses the native [ArrangementView](https://developer.apple.com/documentation/swiftui/arrangementview) view.
38
+ *
39
+ * A view that arranges primary and secondary content using an adaptive layout that responds to
40
+ * the environment.
41
+ *
42
+ * > **Note:** Below iOS 27.1, the children render without a container.
43
+ * @example
44
+ * ```tsx
45
+ * <Host style={{ flex: 1 }}>
46
+ * <ArrangementView modifiers={[arrangementViewStyle('split')]}>
47
+ * <ArrangementView.Primary>
48
+ * <NowPlaying />
49
+ * </ArrangementView.Primary>
50
+ * <ArrangementView.Secondary>
51
+ * <Lyrics />
52
+ * </ArrangementView.Secondary>
53
+ * </ArrangementView>
54
+ * </Host>
55
+ * ```
56
+ * @platform ios 27.1+
57
+ * @platform tvos 27.1+
58
+ */
59
+ export function ArrangementView(props: ArrangementViewProps) {
60
+ const { modifiers, children, ...restProps } = props;
61
+
62
+ return (
63
+ <ArrangementViewNativeView
64
+ modifiers={modifiers}
65
+ {...(modifiers ? createViewModifierEventListener(modifiers) : undefined)}
66
+ {...restProps}>
67
+ {children}
68
+ </ArrangementViewNativeView>
69
+ );
70
+ }
@@ -102,6 +102,16 @@ export type PieChartStyle = {
102
102
  * Space between slices in points.
103
103
  */
104
104
  angularInset?: number;
105
+ /**
106
+ * Corner radius of each slice in points. On a donut, half the ring's thickness gives fully rounded ends.
107
+ * @default 0
108
+ */
109
+ cornerRadius?: number;
110
+ /**
111
+ * Opacity of each slice, from 0 to 1.
112
+ * @default 0.8
113
+ */
114
+ opacity?: number;
105
115
  };
106
116
 
107
117
  /**
@@ -2,6 +2,7 @@ import { requireNativeView } from 'expo';
2
2
  import type { LayoutChangeEvent } from 'react-native';
3
3
 
4
4
  import { PresentedContentContext, useIsPresentedInOwnWindow } from '../PresentedContentContext';
5
+ import { resolveMatchContents } from '../utils/matchContents';
5
6
 
6
7
  const RNHostNativeView: React.ComponentType<any> = requireNativeView('ExpoUI', 'RNHostView');
7
8
 
@@ -10,10 +11,12 @@ export interface RNHostViewProps {
10
11
  * When `true`, the RNHost will update its size in the React Native view tree to match the
11
12
  * children's size.
12
13
  * When `false`, the RNHost will use the size of the parent SwiftUI View.
14
+ * Pass an object to choose per axis. For example, `{ vertical: true }` takes the width from the
15
+ * parent and the height from the children, so text wraps and grows vertically.
13
16
  * Can be only set once on mount.
14
17
  * @default false
15
18
  */
16
- matchContents?: boolean;
19
+ matchContents?: boolean | { vertical?: boolean; horizontal?: boolean };
17
20
  onLayout?: (event: LayoutChangeEvent) => void;
18
21
  /**
19
22
  * The RN View to be hosted.
@@ -21,21 +24,25 @@ export interface RNHostViewProps {
21
24
  children: React.ReactElement;
22
25
  }
23
26
 
24
- export function RNHostView(props: RNHostViewProps) {
27
+ export function RNHostView({ matchContents, ...props }: RNHostViewProps) {
25
28
  // A sheet or popover presents its content in its own view controller, where the React Native
26
29
  // surface root is not an ancestor and so touch dispatches don't work.
27
30
  // Hosted content there owns its touches and is the origin it is measured from; native reads
28
31
  // this one prop for both.
29
32
  const layoutRoot = useIsPresentedInOwnWindow();
33
+ const { horizontal: matchContentsHorizontal, vertical: matchContentsVertical } =
34
+ resolveMatchContents(matchContents);
30
35
 
31
36
  return (
32
37
  <RNHostNativeView
33
38
  {...props}
34
39
  layoutRoot={layoutRoot}
35
- expoInternalSizeFromChildren={props.matchContents}
40
+ matchContentsHorizontal={matchContentsHorizontal}
41
+ matchContentsVertical={matchContentsVertical}
42
+ expoInternalSizeFromChildren={matchContentsHorizontal || matchContentsVertical}
36
43
  // `matchContents` can only be used once on mount
37
44
  // So we force unmount when it changes to prevent unexpected layout
38
- key={props.matchContents ? 'matchContents' : 'noMatchContents'}>
45
+ key={`${matchContentsHorizontal}-${matchContentsVertical}`}>
39
46
  {/* Reset context here so only nearest RNHostView becomes the layout root for its children, and not any other RNHostView above it in the tree. */}
40
47
  <PresentedContentContext.Provider value={false}>
41
48
  {props.children}
@@ -28,6 +28,7 @@ export * from './Menu';
28
28
  export * from './NavigationDestination';
29
29
  export * from './NavigationLink';
30
30
  export * from './NavigationSplitView';
31
+ export * from './ArrangementView';
31
32
  export * from './NavigationStack';
32
33
  export * from './Picker';
33
34
  export * from './ProgressView';