@expo/ui 57.0.21 → 57.0.22

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 (92) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/ui/DatePickerView.kt +1 -0
  4. package/android/src/main/java/expo/modules/ui/HostView.kt +7 -1
  5. package/android/src/main/java/expo/modules/ui/ModifierRegistry.kt +23 -2
  6. package/build/community/datetime-picker/DateTimePicker.android.d.ts.map +1 -1
  7. package/build/community/datetime-picker/utils.d.ts +11 -0
  8. package/build/community/datetime-picker/utils.d.ts.map +1 -0
  9. package/build/community/picker/Picker.android.d.ts.map +1 -1
  10. package/build/jetpack-compose/modifiers/index.d.ts +18 -3
  11. package/build/jetpack-compose/modifiers/index.d.ts.map +1 -1
  12. package/build/swift-ui/ArrangementView/index.d.ts +49 -0
  13. package/build/swift-ui/ArrangementView/index.d.ts.map +1 -0
  14. package/build/swift-ui/index.d.ts +1 -0
  15. package/build/swift-ui/index.d.ts.map +1 -1
  16. package/build/swift-ui/modifiers/animation/index.d.ts +6 -1
  17. package/build/swift-ui/modifiers/animation/index.d.ts.map +1 -1
  18. package/build/swift-ui/modifiers/animation/types.d.ts +15 -1
  19. package/build/swift-ui/modifiers/animation/types.d.ts.map +1 -1
  20. package/build/swift-ui/modifiers/arrangementModifiers.d.ts +110 -0
  21. package/build/swift-ui/modifiers/arrangementModifiers.d.ts.map +1 -0
  22. package/build/swift-ui/modifiers/containerBackground.d.ts +2 -2
  23. package/build/swift-ui/modifiers/index.d.ts +40 -2
  24. package/build/swift-ui/modifiers/index.d.ts.map +1 -1
  25. package/build/universal/Switch/index.android.d.ts.map +1 -1
  26. package/expo-module.config.json +1 -1
  27. package/ios/ArrangementViewView.swift +40 -0
  28. package/ios/ExpoUIModule.swift +1 -1
  29. package/ios/Modifiers/AnimationConfig.swift +20 -0
  30. package/ios/Modifiers/ArrangementModifiers.swift +157 -0
  31. package/ios/Modifiers/ContainerBackgroundModifier.swift +26 -13
  32. package/ios/Modifiers/PreferredColorSchemeModifier.swift +12 -0
  33. package/ios/Modifiers/View+ModifierArray.swift +3 -3
  34. package/ios/Modifiers/ViewModifierRegistry.swift +116 -9
  35. package/ios/Modifiers/WidgetKitModifiers.swift +13 -0
  36. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.21/expo.modules.ui-57.0.21-sources.jar → 57.0.22/expo.modules.ui-57.0.22-sources.jar} +0 -0
  37. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22-sources.jar.md5 +1 -0
  38. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22-sources.jar.sha1 +1 -0
  39. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22-sources.jar.sha256 +1 -0
  40. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22-sources.jar.sha512 +1 -0
  41. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.aar +0 -0
  42. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.aar.md5 +1 -0
  43. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.aar.sha1 +1 -0
  44. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.aar.sha256 +1 -0
  45. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.aar.sha512 +1 -0
  46. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.21/expo.modules.ui-57.0.21.module → 57.0.22/expo.modules.ui-57.0.22.module} +22 -22
  47. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.module.md5 +1 -0
  48. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.module.sha1 +1 -0
  49. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.module.sha256 +1 -0
  50. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.module.sha512 +1 -0
  51. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.21/expo.modules.ui-57.0.21.pom → 57.0.22/expo.modules.ui-57.0.22.pom} +1 -1
  52. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.pom.md5 +1 -0
  53. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.pom.sha1 +1 -0
  54. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.pom.sha256 +1 -0
  55. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.pom.sha512 +1 -0
  56. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
  57. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
  58. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
  59. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
  60. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
  61. package/package.json +4 -4
  62. package/src/community/datetime-picker/DateTimePicker.android.tsx +14 -4
  63. package/src/community/datetime-picker/utils.ts +21 -0
  64. package/src/community/picker/Picker.android.tsx +5 -0
  65. package/src/jetpack-compose/modifiers/index.ts +17 -3
  66. package/src/swift-ui/ArrangementView/index.tsx +70 -0
  67. package/src/swift-ui/index.tsx +1 -0
  68. package/src/swift-ui/modifiers/animation/index.ts +24 -11
  69. package/src/swift-ui/modifiers/animation/types.ts +18 -0
  70. package/src/swift-ui/modifiers/arrangementModifiers.ts +142 -0
  71. package/src/swift-ui/modifiers/containerBackground.ts +2 -2
  72. package/src/swift-ui/modifiers/index.ts +51 -1
  73. package/src/universal/Switch/index.android.tsx +11 -2
  74. package/ios/AccessoryWidgetBackgroundView.swift +0 -27
  75. package/ios/Modifiers/WidgetModifiers.swift +0 -70
  76. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21-sources.jar.md5 +0 -1
  77. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21-sources.jar.sha1 +0 -1
  78. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21-sources.jar.sha256 +0 -1
  79. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21-sources.jar.sha512 +0 -1
  80. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.aar +0 -0
  81. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.aar.md5 +0 -1
  82. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.aar.sha1 +0 -1
  83. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.aar.sha256 +0 -1
  84. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.aar.sha512 +0 -1
  85. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.module.md5 +0 -1
  86. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.module.sha1 +0 -1
  87. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.module.sha256 +0 -1
  88. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.module.sha512 +0 -1
  89. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.pom.md5 +0 -1
  90. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.pom.sha1 +0 -1
  91. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.pom.sha256 +0 -1
  92. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.21/expo.modules.ui-57.0.21.pom.sha512 +0 -1
@@ -0,0 +1 @@
1
+ 81d467c2d81c5fb4545160a5b5563fcf0f6eb3fbb191a507382ad6b0abde41d6c5506edc2281c1e98dee29eb2c861856f8e34d4208972a2dbf2b547c77143627
@@ -0,0 +1 @@
1
+ d581a4836a4dd119bfc57aca7152c5f7a45911b8
@@ -0,0 +1 @@
1
+ a869c8586462b852b75439dbfeaa7caef538db6eeff7bac5aee0026215a61a06
@@ -0,0 +1 @@
1
+ 34080b16453bc36824a34471ee76e7da22af80c63cc419ea34d8c2e1e562f72f968ce8faefd5672f33a4c899c0cdf85c2e711318d859ba4d4562b7e0a61482d8
@@ -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.22",
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.22.aar",
28
+ "url": "expo.modules.ui-57.0.22.aar",
29
+ "size": 2080513,
30
+ "sha512": "34080b16453bc36824a34471ee76e7da22af80c63cc419ea34d8c2e1e562f72f968ce8faefd5672f33a4c899c0cdf85c2e711318d859ba4d4562b7e0a61482d8",
31
+ "sha256": "a869c8586462b852b75439dbfeaa7caef538db6eeff7bac5aee0026215a61a06",
32
+ "sha1": "d581a4836a4dd119bfc57aca7152c5f7a45911b8",
33
+ "md5": "7220f1074490e12c04ff057048d86124"
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.22.aar",
145
+ "url": "expo.modules.ui-57.0.22.aar",
146
+ "size": 2080513,
147
+ "sha512": "34080b16453bc36824a34471ee76e7da22af80c63cc419ea34d8c2e1e562f72f968ce8faefd5672f33a4c899c0cdf85c2e711318d859ba4d4562b7e0a61482d8",
148
+ "sha256": "a869c8586462b852b75439dbfeaa7caef538db6eeff7bac5aee0026215a61a06",
149
+ "sha1": "d581a4836a4dd119bfc57aca7152c5f7a45911b8",
150
+ "md5": "7220f1074490e12c04ff057048d86124"
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.22-sources.jar",
165
+ "url": "expo.modules.ui-57.0.22-sources.jar",
166
+ "size": 105727,
167
+ "sha512": "81d467c2d81c5fb4545160a5b5563fcf0f6eb3fbb191a507382ad6b0abde41d6c5506edc2281c1e98dee29eb2c861856f8e34d4208972a2dbf2b547c77143627",
168
+ "sha256": "e1ff6f3760b8699263fd244601e146335a9f853109153f91be6c98d092a9302e",
169
+ "sha1": "b9f56fabf01aea58b15172683c4a748b8dc3cf55",
170
+ "md5": "67ccc30c75819937df5e850cb742a4ba"
171
171
  }
172
172
  ]
173
173
  }
@@ -0,0 +1 @@
1
+ 14b81e92a813dd3ff42d0b57bc819fe6fe45dbe9
@@ -0,0 +1 @@
1
+ 4f7022f3602a1162d857c67860c42f26d80c57f0955e815776e0d69da62a6b89
@@ -0,0 +1 @@
1
+ f4323dcdf2bd04112993e148d47b98df0245f0679aedb4965f45646c987da2d513b3a312aba6ca5802a411cc07b8260c3b3a944a30da7e4b9c2d2140e9cc0b78
@@ -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.22</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
+ 64719d73cd6c6e4410f220586d1b900553d8636f
@@ -0,0 +1 @@
1
+ b1893b9a45c11ca23be9b083040c6c8e42e5dbf2f83388fb2ecb46ebb759ef43
@@ -0,0 +1 @@
1
+ 2e7e5260dc6cae8eb8555c1614f8e50394413bd3cc98d8c34ffb9831458a6079516da7c302bac741da5f578dac28c7772d1cf5efd111f007f15639876db47768
@@ -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.22</latest>
7
+ <release>57.0.22</release>
8
8
  <versions>
9
- <version>57.0.21</version>
9
+ <version>57.0.22</version>
10
10
  </versions>
11
- <lastUpdated>20260929104945</lastUpdated>
11
+ <lastUpdated>20261006120050</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- d9951eb0ffdbd1f3b4e8c66a9506881d
1
+ ec005e8760fa18717c30f9efdbaf8407
@@ -1 +1 @@
1
- ee273f19364a6847e08cbe5eb1b5daadf787040f
1
+ 213f89fcaff64a6fdd6b446eda846a2de8851a2e
@@ -1 +1 @@
1
- 950f75c93b0ef32cc69e20471f3a68ac9088427130a66ded938e0c3ded940478
1
+ fd6986f721f0b9289418efa80805a6cf05ffcaccc5f74b409b7953f92f5a053e
@@ -1 +1 @@
1
- ecc49926b4fd4296bc3b844a0f9a313ef93474eeb921d900d082366cb28c80c466c6dc4c5fa1b3445072b1e1bedb4b8cdf62022039209423a27b5d5c9a381a3e
1
+ 9461340626636adffd749d7a45d2b9ee7741281f8c1507b97ca59fcf2c1a9cdb97cede810b8aa5dbe7f8d22d6076a512501797a90eb796b321ec3a39624f4241
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/ui",
3
- "version": "57.0.21",
3
+ "version": "57.0.22",
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.27",
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": "50ac74f1ab5682c8e32b24da6e5e97dd4dbbb80f",
125
125
  "scripts": {
126
126
  "build": "expo-module build",
127
127
  "clean": "expo-module clean",
@@ -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}
@@ -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
@@ -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
+ }
@@ -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';
@@ -5,6 +5,7 @@ import type {
5
5
  ChainableAnimationType,
6
6
  InterpolatingSpringAnimationParams,
7
7
  SpringAnimationParams,
8
+ SpringPresetAnimationParams,
8
9
  TimingAnimationParams,
9
10
  } from './types';
10
11
 
@@ -16,6 +17,8 @@ import type {
16
17
  * - `spring` accepts [`SpringAnimationParams`](#springanimationparams).
17
18
  * - `interpolatingSpring` accepts
18
19
  * [`InterpolatingSpringAnimationParams`](#interpolatingspringanimationparams).
20
+ * - Spring presets (`smooth`, `snappy`, `bouncy`) accept
21
+ * [`SpringPresetAnimationParams`](#springpresetanimationparams).
19
22
  * - Chaining returns [`ChainableAnimationType`](#chainableanimationtype).
20
23
  *
21
24
  * @example
@@ -80,23 +83,33 @@ export const Animation = {
80
83
  duration: params?.duration,
81
84
  bounce: params?.bounce,
82
85
  }),
86
+ smooth: (params?: SpringPresetAnimationParams) =>
87
+ ChainableAnimation({
88
+ type: 'smooth',
89
+ duration: params?.duration,
90
+ extraBounce: params?.extraBounce,
91
+ }),
92
+ snappy: (params?: SpringPresetAnimationParams) =>
93
+ ChainableAnimation({
94
+ type: 'snappy',
95
+ duration: params?.duration,
96
+ extraBounce: params?.extraBounce,
97
+ }),
98
+ bouncy: (params?: SpringPresetAnimationParams) =>
99
+ ChainableAnimation({
100
+ type: 'bouncy',
101
+ duration: params?.duration,
102
+ extraBounce: params?.extraBounce,
103
+ }),
83
104
 
84
105
  default: ChainableAnimation({ type: 'default' }),
85
106
  };
86
107
 
87
108
  function ChainableAnimation(animation: AnimationObject): ChainableAnimationType {
88
- let _animation: AnimationObject = animation;
89
-
90
109
  return {
91
- delay: (delay) => {
92
- _animation = { ..._animation, delay };
93
- return ChainableAnimation(_animation);
94
- },
95
- repeat: (params) => {
96
- _animation = { ..._animation, ...params };
97
- return ChainableAnimation(_animation);
98
- },
99
- [VALUE_SYMBOL]: () => _animation,
110
+ delay: (delay) => ChainableAnimation({ ...animation, delay }),
111
+ repeat: (params) => ChainableAnimation({ ...animation, ...params }),
112
+ [VALUE_SYMBOL]: () => animation,
100
113
  };
101
114
  }
102
115
 
@@ -12,6 +12,9 @@ export type AnimationObject = {
12
12
  | 'linear'
13
13
  | 'spring'
14
14
  | 'interpolatingSpring'
15
+ | 'smooth'
16
+ | 'snappy'
17
+ | 'bouncy'
15
18
  | 'default';
16
19
  duration?: number;
17
20
  response?: number;
@@ -22,6 +25,7 @@ export type AnimationObject = {
22
25
  stiffness?: number;
23
26
  damping?: number;
24
27
  initialVelocity?: number;
28
+ extraBounce?: number;
25
29
  delay?: number;
26
30
  repeatCount?: number;
27
31
  autoreverses?: boolean;
@@ -84,6 +88,20 @@ export type InterpolatingSpringAnimationParams = {
84
88
  bounce?: number;
85
89
  };
86
90
 
91
+ export type SpringPresetAnimationParams = {
92
+ /**
93
+ * The perceptual duration, which defines the pace of the spring (in seconds). This is
94
+ * approximately equal to the settling duration, but for very bouncy springs, it is the period of
95
+ * oscillation of the spring.
96
+ */
97
+ duration?: number;
98
+ /**
99
+ * Bounce added to the base bounce of the preset: 0 for `smooth`, 0.15 for `snappy`, and 0.3 for
100
+ * `bouncy`. Keep the total below 1: at 1 and above, the spring oscillates without settling.
101
+ */
102
+ extraBounce?: number;
103
+ };
104
+
87
105
  export type ChainableAnimationType = {
88
106
  /** Adds a delay before the animation starts (in seconds). */
89
107
  delay: (delay: number) => ChainableAnimationType;
@@ -0,0 +1,142 @@
1
+ import { createModifier } from './createModifier';
2
+
3
+ /**
4
+ * A style that configures an `ArrangementView` with an arrangement.
5
+ * - `'automatic'`: The default style, which resolves to `'split'`.
6
+ * - `'split'`: An arrangement view style that places the primary and secondary views side by side along one or more axes.
7
+ * - `'overlay'`: An arrangement view style that layers the primary view over the secondary view in z-order.
8
+ */
9
+ export type ArrangementViewStyle = 'automatic' | 'split' | 'overlay';
10
+
11
+ /**
12
+ * Sets the style for arrangement views within this view.
13
+ * @param style - The style to apply.
14
+ * @param options - The `axes` the arrangement supports. With `'split'`, creates a split arrangement
15
+ * that supports the given axes. With `'overlay'`, creates an overlay arrangement that supports
16
+ * laying out its views along the given axes.
17
+ * @platform ios 27.1+
18
+ * @platform tvos 27.1+
19
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/arrangementviewstyle(_:)).
20
+ */
21
+ export function arrangementViewStyle(style: 'automatic'): ReturnType<typeof createModifier>;
22
+ export function arrangementViewStyle(
23
+ style: 'split' | 'overlay',
24
+ options?: { axes?: 'horizontal' | 'vertical' | 'both' }
25
+ ): ReturnType<typeof createModifier>;
26
+ export function arrangementViewStyle(
27
+ style: ArrangementViewStyle,
28
+ options?: { axes?: 'horizontal' | 'vertical' | 'both' }
29
+ ) {
30
+ return createModifier('arrangementViewStyle', { style, axes: options?.axes });
31
+ }
32
+
33
+ /**
34
+ * The minimum, ideal, and maximum ratios for `splitArrangementLayoutRatio`.
35
+ */
36
+ export type SplitArrangementLayoutRatioParams = {
37
+ minHorizontal?: number;
38
+ idealHorizontal?: number;
39
+ maxHorizontal?: number;
40
+ minVertical?: number;
41
+ idealVertical?: number;
42
+ maxVertical?: number;
43
+ };
44
+
45
+ /**
46
+ * Sets the preferred size ratio for the content of `ArrangementView.Primary` or
47
+ * `ArrangementView.Secondary` in a split arrangement.
48
+ * @platform ios 27.1+
49
+ * @platform tvos 27.1+
50
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/splitarrangementlayoutratio(_:)).
51
+ */
52
+ export function splitArrangementLayoutRatio(ratio: number): ReturnType<typeof createModifier>;
53
+ /**
54
+ * Sets the size ratio for the content of `ArrangementView.Primary` or `ArrangementView.Secondary`
55
+ * in a split arrangement.
56
+ * @platform ios 27.1+
57
+ * @platform tvos 27.1+
58
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/splitarrangementlayoutratio(minhorizontal:idealhorizontal:maxhorizontal:minvertical:idealvertical:maxvertical:)).
59
+ */
60
+ export function splitArrangementLayoutRatio(
61
+ ratios: SplitArrangementLayoutRatioParams
62
+ ): ReturnType<typeof createModifier>;
63
+ export function splitArrangementLayoutRatio(
64
+ ratioOrParams: number | SplitArrangementLayoutRatioParams
65
+ ) {
66
+ return createModifier(
67
+ 'splitArrangementLayoutRatio',
68
+ typeof ratioOrParams === 'number' ? { ratio: ratioOrParams } : ratioOrParams
69
+ );
70
+ }
71
+
72
+ /**
73
+ * The minimum, ideal, and maximum sizes for `splitArrangementLayoutSize`.
74
+ */
75
+ export type SplitArrangementLayoutSizeParams = {
76
+ minWidth?: number;
77
+ idealWidth?: number;
78
+ maxWidth?: number;
79
+ minHeight?: number;
80
+ idealHeight?: number;
81
+ maxHeight?: number;
82
+ };
83
+
84
+ /**
85
+ * Sets the size constraints for the content of `ArrangementView.Primary` or
86
+ * `ArrangementView.Secondary` in a split arrangement.
87
+ * @platform ios 27.1+
88
+ * @platform tvos 27.1+
89
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/splitarrangementlayoutsize(minwidth:idealwidth:maxwidth:minheight:idealheight:maxheight:)).
90
+ */
91
+ export const splitArrangementLayoutSize = (constraints: SplitArrangementLayoutSizeParams) =>
92
+ createModifier('splitArrangementLayoutSize', constraints);
93
+
94
+ /**
95
+ * The split axes on which `splitArrangementFixedLayoutSize` prefers the ideal size of the view.
96
+ */
97
+ export type SplitArrangementFixedLayoutSizeParams = {
98
+ /**
99
+ * Whether to prefer a fixed width for the view in a horizontal split.
100
+ * @default true
101
+ */
102
+ horizontal?: boolean;
103
+ /**
104
+ * Whether to prefer a fixed height for the view in a vertical split.
105
+ * @default true
106
+ */
107
+ vertical?: boolean;
108
+ };
109
+
110
+ /**
111
+ * Sets the preferred size constraint for the content of `ArrangementView.Primary` or
112
+ * `ArrangementView.Secondary` in a split arrangement to the ideal size of the view within its
113
+ * container. The arrangement view prefers this size, but may resize to a smaller size depending on
114
+ * the priority of the view.
115
+ * @platform ios 27.1+
116
+ * @platform tvos 27.1+
117
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/splitarrangementfixedlayoutsize(horizontal:vertical:)).
118
+ */
119
+ export const splitArrangementFixedLayoutSize = (options?: SplitArrangementFixedLayoutSizeParams) =>
120
+ createModifier('splitArrangementFixedLayoutSize', options);
121
+
122
+ /**
123
+ * Sets the horizontal edge that a view in an overlay arrangement occupies when the arrangement
124
+ * transitions to a horizontal layout.
125
+ * @platform ios 27.1+
126
+ * @platform tvos 27.1+
127
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/overlayarrangementedge(_:)).
128
+ */
129
+ export function overlayArrangementEdge(
130
+ edge: 'leading' | 'trailing'
131
+ ): ReturnType<typeof createModifier>;
132
+ /**
133
+ * Sets the vertical edge that a view in an overlay arrangement occupies when the arrangement
134
+ * transitions to a vertical layout.
135
+ * @platform ios 27.1+
136
+ * @platform tvos 27.1+
137
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/overlayarrangementedge(_:)-4tjwn).
138
+ */
139
+ export function overlayArrangementEdge(edge: 'top' | 'bottom'): ReturnType<typeof createModifier>;
140
+ export function overlayArrangementEdge(edge: 'top' | 'bottom' | 'leading' | 'trailing') {
141
+ return createModifier('overlayArrangementEdge', { edge });
142
+ }
@@ -6,8 +6,8 @@ export type ContainerBackgroundPlacement = 'widget' | 'navigation' | 'navigation
6
6
  /**
7
7
  * Sets the container background of the enclosing container.
8
8
  *
9
- * > **Note:** `navigation` and `navigationSplitView` require iOS 18. On iOS 17 they fall back to
10
- * > the `widget` placement.
9
+ * > **Note:** `navigation` and `navigationSplitView` require iOS 18. The `widget` placement works
10
+ * > only in `expo-widgets` widgets, where the other placements fall back to it on iOS 17.
11
11
  *
12
12
  * @param style - Any [`ShapeStyle`](#shapestyle): a color, a hierarchical style, a material, or a gradient.
13
13
  * @param container - The type of container to apply the background to.