@expo/ui 57.0.11 → 57.0.12

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 (91) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +14 -1
  4. package/android/src/main/java/expo/modules/ui/graphics/DrawablePainter.kt +43 -0
  5. package/android/src/main/java/expo/modules/ui/{icon/VectorIconLoader.kt → graphics/ImageLoader.kt} +122 -87
  6. package/android/src/main/java/expo/modules/ui/graphics/ImageSource.kt +28 -0
  7. package/android/src/main/java/expo/modules/ui/{icon → graphics}/ResourceIdHelper.kt +1 -1
  8. package/android/src/main/java/expo/modules/ui/icon/IconView.kt +7 -78
  9. package/android/src/main/java/expo/modules/ui/image/ImageView.kt +136 -0
  10. package/build/jetpack-compose/Image/index.d.ts +107 -0
  11. package/build/jetpack-compose/Image/index.d.ts.map +1 -0
  12. package/build/jetpack-compose/index.d.ts +1 -0
  13. package/build/jetpack-compose/index.d.ts.map +1 -1
  14. package/build/swift-ui/Alert/index.d.ts.map +1 -1
  15. package/build/swift-ui/ConfirmationDialog/index.d.ts.map +1 -1
  16. package/build/swift-ui/Overlay/index.d.ts.map +1 -1
  17. package/build/swift-ui/Popover/index.d.ts.map +1 -1
  18. package/build/swift-ui/Slider/index.d.ts.map +1 -1
  19. package/build/swift-ui/modifiers/index.d.ts +16 -8
  20. package/build/swift-ui/modifiers/index.d.ts.map +1 -1
  21. package/build/universal/BottomSheet/index.android.d.ts +1 -1
  22. package/build/universal/BottomSheet/index.android.d.ts.map +1 -1
  23. package/build/universal/BottomSheet/index.d.ts +1 -1
  24. package/build/universal/BottomSheet/index.d.ts.map +1 -1
  25. package/build/universal/BottomSheet/index.ios.d.ts +1 -1
  26. package/build/universal/BottomSheet/index.ios.d.ts.map +1 -1
  27. package/build/universal/BottomSheet/types.d.ts +28 -0
  28. package/build/universal/BottomSheet/types.d.ts.map +1 -1
  29. package/build/universal/BottomSheet/utils.d.ts +13 -0
  30. package/build/universal/BottomSheet/utils.d.ts.map +1 -0
  31. package/expo-module.config.json +1 -1
  32. package/ios/Convertibles/PaddingValue.swift +57 -0
  33. package/ios/Modifiers/ViewModifierRegistry.swift +62 -18
  34. package/ios/SliderView.swift +11 -5
  35. package/ios/Toggle/ToggleView.swift +16 -18
  36. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.11/expo.modules.ui-57.0.11-sources.jar → 57.0.12/expo.modules.ui-57.0.12-sources.jar} +0 -0
  37. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12-sources.jar.md5 +1 -0
  38. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12-sources.jar.sha1 +1 -0
  39. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12-sources.jar.sha256 +1 -0
  40. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12-sources.jar.sha512 +1 -0
  41. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12.aar +0 -0
  42. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12.aar.md5 +1 -0
  43. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12.aar.sha1 +1 -0
  44. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12.aar.sha256 +1 -0
  45. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12.aar.sha512 +1 -0
  46. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.11/expo.modules.ui-57.0.11.module → 57.0.12/expo.modules.ui-57.0.12.module} +22 -22
  47. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12.module.md5 +1 -0
  48. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12.module.sha1 +1 -0
  49. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12.module.sha256 +1 -0
  50. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12.module.sha512 +1 -0
  51. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.11/expo.modules.ui-57.0.11.pom → 57.0.12/expo.modules.ui-57.0.12.pom} +1 -1
  52. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12.pom.md5 +1 -0
  53. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12.pom.sha1 +1 -0
  54. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12.pom.sha256 +1 -0
  55. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.12/expo.modules.ui-57.0.12.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 +3 -3
  62. package/src/jetpack-compose/Image/index.tsx +149 -0
  63. package/src/jetpack-compose/index.ts +1 -0
  64. package/src/swift-ui/Alert/index.tsx +1 -0
  65. package/src/swift-ui/ConfirmationDialog/index.tsx +1 -0
  66. package/src/swift-ui/Overlay/index.tsx +1 -0
  67. package/src/swift-ui/Popover/index.tsx +1 -0
  68. package/src/swift-ui/Slider/index.tsx +14 -8
  69. package/src/swift-ui/modifiers/index.ts +16 -8
  70. package/src/universal/BottomSheet/index.android.tsx +13 -2
  71. package/src/universal/BottomSheet/index.ios.tsx +9 -1
  72. package/src/universal/BottomSheet/index.tsx +17 -2
  73. package/src/universal/BottomSheet/types.ts +33 -0
  74. package/src/universal/BottomSheet/utils.ts +35 -0
  75. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11-sources.jar.md5 +0 -1
  76. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11-sources.jar.sha1 +0 -1
  77. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11-sources.jar.sha256 +0 -1
  78. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11-sources.jar.sha512 +0 -1
  79. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.aar +0 -0
  80. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.aar.md5 +0 -1
  81. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.aar.sha1 +0 -1
  82. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.aar.sha256 +0 -1
  83. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.aar.sha512 +0 -1
  84. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.module.md5 +0 -1
  85. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.module.sha1 +0 -1
  86. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.module.sha256 +0 -1
  87. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.module.sha512 +0 -1
  88. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.pom.md5 +0 -1
  89. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.pom.sha1 +0 -1
  90. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.pom.sha256 +0 -1
  91. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.pom.sha512 +0 -1
@@ -83,31 +83,75 @@ internal struct FrameModifier: ViewModifier, Record {
83
83
  }
84
84
 
85
85
  internal struct PaddingModifier: ViewModifier, Record {
86
- @Field var all: CGFloat?
87
- @Field var horizontal: CGFloat?
88
- @Field var vertical: CGFloat?
86
+ @Field var all: PaddingValue?
87
+ @Field var horizontal: PaddingValue?
88
+ @Field var vertical: PaddingValue?
89
89
 
90
- @Field var top: CGFloat?
91
- @Field var leading: CGFloat?
92
- @Field var bottom: CGFloat?
93
- @Field var trailing: CGFloat?
90
+ @Field var top: PaddingValue?
91
+ @Field var leading: PaddingValue?
92
+ @Field var bottom: PaddingValue?
93
+ @Field var trailing: PaddingValue?
94
+
95
+ /**
96
+ The value of each edge, where a value set for a specific edge wins over the shorthands
97
+ covering that edge. A `nil` edge was not set at all and gets no padding.
98
+ */
99
+ private var resolvedEdges: (top: PaddingValue?, leading: PaddingValue?, bottom: PaddingValue?, trailing: PaddingValue?) {
100
+ (
101
+ top: top ?? vertical ?? all,
102
+ leading: leading ?? horizontal ?? all,
103
+ bottom: bottom ?? vertical ?? all,
104
+ trailing: trailing ?? horizontal ?? all
105
+ )
106
+ }
107
+
108
+ /**
109
+ The edges left to the system, which `EdgeInsets` cannot express.
110
+ */
111
+ private var defaultEdges: Edge.Set {
112
+ let edges = resolvedEdges
113
+ var result: Edge.Set = []
114
+
115
+ if edges.top?.isDefault == true {
116
+ result.insert(.top)
117
+ }
118
+ if edges.leading?.isDefault == true {
119
+ result.insert(.leading)
120
+ }
121
+ if edges.bottom?.isDefault == true {
122
+ result.insert(.bottom)
123
+ }
124
+ if edges.trailing?.isDefault == true {
125
+ result.insert(.trailing)
126
+ }
127
+ return result
128
+ }
129
+
130
+ private var insets: EdgeInsets {
131
+ let edges = resolvedEdges
132
+
133
+ return EdgeInsets(
134
+ top: edges.top?.length ?? 0,
135
+ leading: edges.leading?.length ?? 0,
136
+ bottom: edges.bottom?.length ?? 0,
137
+ trailing: edges.trailing?.length ?? 0
138
+ )
139
+ }
94
140
 
95
141
  func body(content: Content) -> some View {
96
- let hasCustomPadding = [
97
- all, horizontal, vertical, top, leading, bottom, trailing
98
- ].contains { $0 != nil }
142
+ let edges = resolvedEdges
99
143
 
100
- if !hasCustomPadding {
144
+ if edges.top == nil && edges.leading == nil && edges.bottom == nil && edges.trailing == nil {
101
145
  // Default SwiftUI padding (system spacing)
102
146
  content.padding()
103
147
  } else {
104
- let insets = EdgeInsets(
105
- top: top ?? vertical ?? all ?? 0,
106
- leading: leading ?? horizontal ?? all ?? 0,
107
- bottom: bottom ?? vertical ?? all ?? 0,
108
- trailing: trailing ?? horizontal ?? all ?? 0
109
- )
110
- content.padding(insets)
148
+ // `EdgeInsets` can only carry lengths, so the edges left to the system are applied by a
149
+ // second call. Padding modifiers add up and these two cover disjoint edges.
150
+ if defaultEdges.isEmpty {
151
+ content.padding(insets)
152
+ } else {
153
+ content.padding(insets).padding(defaultEdges)
154
+ }
111
155
  }
112
156
  }
113
157
  }
@@ -6,8 +6,8 @@ import ExpoModulesCore
6
6
  struct SliderView: ExpoSwiftUI.View {
7
7
  @ObservedObject var props: SliderProps
8
8
  @State var value: Float = 0.0
9
- @State var isEditing: Bool = false
10
-
9
+ @State private var eventCount: Int = 0
10
+
11
11
  init(props: SliderProps) {
12
12
  self.props = props
13
13
  }
@@ -19,13 +19,19 @@ struct SliderView: ExpoSwiftUI.View {
19
19
  value = clamp(props.value ?? 0.0)
20
20
  }
21
21
  .onChange(of: props.value) { newValue in
22
- guard !isEditing else { return }
22
+ // A prop JS produced before our newest change is a stale echo of a drag that has
23
+ // since moved on, so applying it would pull the thumb back from under the finger.
24
+ if let seenCount = props.mostRecentEventCount, seenCount < eventCount {
25
+ return
26
+ }
23
27
  value = clamp(newValue ?? 0.0)
24
28
  }
25
29
  .onChange(of: value) { newValue in
26
30
  if props.value != newValue {
31
+ eventCount += 1
27
32
  props.onValueChanged([
28
- "value": newValue
33
+ "value": newValue,
34
+ "eventCount": eventCount
29
35
  ])
30
36
  }
31
37
  }
@@ -56,7 +62,6 @@ struct SliderView: ExpoSwiftUI.View {
56
62
  let hasAnyLabel = label != nil || minimumValueLabel != nil || maximumValueLabel != nil
57
63
 
58
64
  let handleEditingChanged: (Bool) -> Void = { isEditing in
59
- self.isEditing = isEditing
60
65
  props.onEditingChanged(["isEditing": isEditing])
61
66
  }
62
67
 
@@ -142,6 +147,7 @@ final class SliderProps: UIBaseViewProps {
142
147
  @Field var max: Float?
143
148
  @Field var lowerLimit: Float?
144
149
  @Field var upperLimit: Float?
150
+ @Field var mostRecentEventCount: Int?
145
151
  var onValueChanged = EventDispatcher()
146
152
  var onEditingChanged = EventDispatcher()
147
153
  }
@@ -12,38 +12,36 @@ internal final class ToggleProps: UIBaseViewProps {
12
12
 
13
13
  internal struct ToggleView: ExpoSwiftUI.View {
14
14
  @ObservedObject var props: ToggleProps
15
- @State var checked: Bool = false
15
+ // Only used when `isOn` isn't passed. While the prop is set it is the sole source of
16
+ // truth, so JS stays in control of what the toggle shows and can refuse a change.
17
+ @State private var uncontrolled = false
16
18
 
17
19
  init(props: ToggleProps) {
18
20
  self.props = props
19
21
  }
20
22
 
21
23
  var body: some View {
22
- makeToggle()
23
- .onChange(of: checked) { newValue in
24
- if props.isOn == newValue {
25
- return
24
+ makeToggle(isOn: Binding(
25
+ get: { props.isOn ?? uncontrolled },
26
+ set: { newValue in
27
+ uncontrolled = newValue
28
+ if props.isOn != newValue {
29
+ props.onIsOnChange([
30
+ "isOn": newValue
31
+ ])
26
32
  }
27
- props.onIsOnChange([
28
- "isOn": newValue
29
- ])
30
- }
31
- .onChange(of: props.isOn) { newValue in
32
- checked = newValue ?? false
33
- }
34
- .onAppear {
35
- checked = props.isOn ?? false
36
33
  }
34
+ ))
37
35
  }
38
36
 
39
37
  @ViewBuilder
40
- private func makeToggle() -> some View {
38
+ private func makeToggle(isOn: Binding<Bool>) -> some View {
41
39
  if let systemImage = props.systemImage, let label = props.label {
42
- Toggle(label, systemImage: systemImage, isOn: $checked)
40
+ Toggle(label, systemImage: systemImage, isOn: isOn)
43
41
  } else if let label = props.label {
44
- Toggle(label, isOn: $checked)
42
+ Toggle(label, isOn: isOn)
45
43
  } else {
46
- Toggle(isOn: $checked) { Children() }
44
+ Toggle(isOn: isOn) { Children() }
47
45
  }
48
46
  }
49
47
  }
@@ -0,0 +1 @@
1
+ 3f5266c79c694c7d3ae5a885827d2dfb4ae922a9f66fceca406cd7556b753ac0
@@ -0,0 +1 @@
1
+ bee3386af6f699916c5f3b09c72510621403743e5e887bf0e60d13142304a97964289f39f1fe79355ca9127cc02dfc88cf2d21bbfa4638ed4b9446de05030856
@@ -0,0 +1 @@
1
+ 2ba19351886430ec818130eab431ce8143a56693
@@ -0,0 +1 @@
1
+ cdc531cad279eabcfce2c71e778614be0e16c45c77222fe4fa51fcbd7991e30b
@@ -0,0 +1 @@
1
+ 8feb6c5213343355b543cddfedde01251c5a8a9067aa01efb89fe663b2a0e04f3284ab62ed2c9a2f8e65305691f61dd248ba2fdbc3dc7415c5d09ced6425edd1
@@ -3,7 +3,7 @@
3
3
  "component": {
4
4
  "group": "expo.modules.ui",
5
5
  "module": "expo.modules.ui",
6
- "version": "57.0.11",
6
+ "version": "57.0.12",
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.11.aar",
28
- "url": "expo.modules.ui-57.0.11.aar",
29
- "size": 1951651,
30
- "sha512": "aaa731134a933ce7a2606140fc2655b2ed4967ca072ed210cd24192ee1316e2aace1d21d5c63660ee67888cdfddf86092f690a5d54767644eb6a40c9e64713f7",
31
- "sha256": "36d7de508b797671c51d35fc849b3ccee089a15a6bb8852a335d0af13338c78f",
32
- "sha1": "89971894361a24c8a79097da2beeb18acde639c8",
33
- "md5": "12d490bd19c2a43cc53f7f0b0c47a456"
27
+ "name": "expo.modules.ui-57.0.12.aar",
28
+ "url": "expo.modules.ui-57.0.12.aar",
29
+ "size": 1988885,
30
+ "sha512": "8feb6c5213343355b543cddfedde01251c5a8a9067aa01efb89fe663b2a0e04f3284ab62ed2c9a2f8e65305691f61dd248ba2fdbc3dc7415c5d09ced6425edd1",
31
+ "sha256": "cdc531cad279eabcfce2c71e778614be0e16c45c77222fe4fa51fcbd7991e30b",
32
+ "sha1": "2ba19351886430ec818130eab431ce8143a56693",
33
+ "md5": "4508cfcae86a661e2c66bbf15b5909b0"
34
34
  }
35
35
  ]
36
36
  },
@@ -141,13 +141,13 @@
141
141
  ],
142
142
  "files": [
143
143
  {
144
- "name": "expo.modules.ui-57.0.11.aar",
145
- "url": "expo.modules.ui-57.0.11.aar",
146
- "size": 1951651,
147
- "sha512": "aaa731134a933ce7a2606140fc2655b2ed4967ca072ed210cd24192ee1316e2aace1d21d5c63660ee67888cdfddf86092f690a5d54767644eb6a40c9e64713f7",
148
- "sha256": "36d7de508b797671c51d35fc849b3ccee089a15a6bb8852a335d0af13338c78f",
149
- "sha1": "89971894361a24c8a79097da2beeb18acde639c8",
150
- "md5": "12d490bd19c2a43cc53f7f0b0c47a456"
144
+ "name": "expo.modules.ui-57.0.12.aar",
145
+ "url": "expo.modules.ui-57.0.12.aar",
146
+ "size": 1988885,
147
+ "sha512": "8feb6c5213343355b543cddfedde01251c5a8a9067aa01efb89fe663b2a0e04f3284ab62ed2c9a2f8e65305691f61dd248ba2fdbc3dc7415c5d09ced6425edd1",
148
+ "sha256": "cdc531cad279eabcfce2c71e778614be0e16c45c77222fe4fa51fcbd7991e30b",
149
+ "sha1": "2ba19351886430ec818130eab431ce8143a56693",
150
+ "md5": "4508cfcae86a661e2c66bbf15b5909b0"
151
151
  }
152
152
  ]
153
153
  },
@@ -161,13 +161,13 @@
161
161
  },
162
162
  "files": [
163
163
  {
164
- "name": "expo.modules.ui-57.0.11-sources.jar",
165
- "url": "expo.modules.ui-57.0.11-sources.jar",
166
- "size": 95171,
167
- "sha512": "938426b2ed24a041a9cc2ab04e9fe12fac0bdf6556b6daadc5f14907395625122c9cb4d77e2aae78780413995cedc71c97d59f003da45a702af6328b0f4312d6",
168
- "sha256": "1c278284d86a0c256802d5c4bc4e8780650313dfca9cd372f11270677138f9fb",
169
- "sha1": "ff3268099478cd30644b24d64f739ca622826811",
170
- "md5": "ea5f349d6e792bbbab810a13446845b0"
164
+ "name": "expo.modules.ui-57.0.12-sources.jar",
165
+ "url": "expo.modules.ui-57.0.12-sources.jar",
166
+ "size": 98169,
167
+ "sha512": "bee3386af6f699916c5f3b09c72510621403743e5e887bf0e60d13142304a97964289f39f1fe79355ca9127cc02dfc88cf2d21bbfa4638ed4b9446de05030856",
168
+ "sha256": "3f5266c79c694c7d3ae5a885827d2dfb4ae922a9f66fceca406cd7556b753ac0",
169
+ "sha1": "dabe60c8f675eb6123187ef607915dccbeb79789",
170
+ "md5": "46f030ed2d5faa9fc07df319df125512"
171
171
  }
172
172
  ]
173
173
  }
@@ -0,0 +1 @@
1
+ 64563430ecb895ad72e936b019402ccd7c9e6c89
@@ -0,0 +1 @@
1
+ a615e1f0a09d6a7e76aba8b907fde6ffae9af29c50e411d880ba36a30908ccdb
@@ -0,0 +1 @@
1
+ fab8c1e40a8d6e25b66e77c977f415a05a3c4f6b5dcafb461c3a1be165b8db57f21b6cce4b46446a7855090b367fd38ff678b6d48e807dc22712d5e207cd9336
@@ -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.11</version>
12
+ <version>57.0.12</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
+ dcf4640e9a602afa20af004bae13cdcb182d7cc6
@@ -0,0 +1 @@
1
+ 3f88190776e8ff18c8b42b46ee0b8b4e2a827cf671160966b6a3e1e62301f913
@@ -0,0 +1 @@
1
+ 62c5c2b27746a876d4db64eef13f596835a2f876c0808457d1a82b38fc93e7e5e667a11a5cbcb603efa58ff10b9001981bb347f99b6bd009e452445c80299689
@@ -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.11</latest>
7
- <release>57.0.11</release>
6
+ <latest>57.0.12</latest>
7
+ <release>57.0.12</release>
8
8
  <versions>
9
- <version>57.0.11</version>
9
+ <version>57.0.12</version>
10
10
  </versions>
11
- <lastUpdated>20260814141310</lastUpdated>
11
+ <lastUpdated>20260820103851</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- 2ed3d013ca9421b5e75ada4e2b67957b
1
+ 990a1e6f470f0ae61d641c01c2510f97
@@ -1 +1 @@
1
- 6b30a9bd2542ddada62f0ff1896eb038fd533890
1
+ a6d138ba3ecd66801bb35f9d23a69cef22d0b0e8
@@ -1 +1 @@
1
- 019b45348b534e778d6357dc29bfa9809f79c3c7cb60fb6e84110996f71b6336
1
+ d98cea313be8b245d8c8b9dd4455ddaa2f5259a8e9a55b19079afd698133e01e
@@ -1 +1 @@
1
- 60f8a5217ca4b39641e51f92c3c8361bc0fdb2a155bfc557599fe074cebcf02ee525f49fce24c510a4309c0c29cc0a5430b01d72d43749956deba5332ad54230
1
+ 6d33dd52cf942431a652c01906b58f2765c791f457597f8757a98d8d6dfa2a2af5ed9715aca0c28ceb9ab615b01198d6126dd48f1745762560d41d845507f374
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/ui",
3
- "version": "57.0.11",
3
+ "version": "57.0.12",
4
4
  "description": "A collection of UI components",
5
5
  "sideEffects": [
6
6
  "*.fx.js",
@@ -96,7 +96,7 @@
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": "57.0.13",
99
+ "expo": "57.0.15",
100
100
  "expo-module-scripts": "56.0.3"
101
101
  },
102
102
  "jest": {
@@ -121,7 +121,7 @@
121
121
  "optional": true
122
122
  }
123
123
  },
124
- "gitHead": "125b8d4472432db3dc4ae047730432d7bd5bd30c",
124
+ "gitHead": "499024a441d67293aa60afcbe02051999a54f1bb",
125
125
  "scripts": {
126
126
  "build": "expo-module build",
127
127
  "clean": "expo-module clean",
@@ -0,0 +1,149 @@
1
+ import { requireNativeView } from 'expo';
2
+ import {
3
+ Image as ReactNativeImage,
4
+ type ColorValue,
5
+ type ImageResolvedAssetSource,
6
+ } from 'react-native';
7
+
8
+ import { type ViewEvent } from '../../types';
9
+ import { type ContentAlignment, type PrimitiveBaseProps, transformProps } from '../layout-types';
10
+
11
+ /** Controls how an image is scaled inside its bounds. */
12
+ export type ImageContentScale =
13
+ | 'fit'
14
+ | 'crop'
15
+ | 'fillBounds'
16
+ | 'fillWidth'
17
+ | 'fillHeight'
18
+ | 'inside'
19
+ | 'none';
20
+
21
+ /** A bundled image or a single URI-based image source. */
22
+ export type ImageSource =
23
+ | number
24
+ | {
25
+ uri: string;
26
+ width?: number;
27
+ height?: number;
28
+ scale?: number;
29
+ };
30
+
31
+ export interface ImageProps extends PrimitiveBaseProps {
32
+ /**
33
+ * A bundled image or an object containing a single local or remote URI.
34
+ *
35
+ * @example
36
+ * ```tsx
37
+ * <Image source={require('./photo.png')} />
38
+ * <Image source={{ uri: 'file:///path/to/photo.png' }} />
39
+ * ```
40
+ */
41
+ source: ImageSource;
42
+
43
+ /**
44
+ * How the image should be scaled to fit its bounds.
45
+ * @default 'fit'
46
+ *
47
+ * @example
48
+ * ```tsx
49
+ * <Image source={require('./photo.png')} contentScale="crop" />
50
+ * ```
51
+ */
52
+ contentScale?: ImageContentScale;
53
+
54
+ /**
55
+ * How the image should be aligned within its bounds.
56
+ * @default 'center'
57
+ */
58
+ alignment?: ContentAlignment;
59
+
60
+ /**
61
+ * Accessibility label for the image.
62
+ * Used by screen readers to describe the image to users.
63
+ * Use `null` for decorative images.
64
+ *
65
+ * @example
66
+ * ```tsx
67
+ * <Image
68
+ * source={require('./photo.png')}
69
+ * contentDescription="A mountain at sunset"
70
+ * />
71
+ * ```
72
+ */
73
+ contentDescription?: string | null;
74
+
75
+ /**
76
+ * Optional color applied to every non-transparent image pixel.
77
+ *
78
+ * @example
79
+ * ```tsx
80
+ * <Image source={require('./icon.png')} tint="#007AFF" />
81
+ * <Image source={require('./icon.png')} tint="blue" />
82
+ * ```
83
+ */
84
+ tint?: ColorValue;
85
+
86
+ /**
87
+ * Opacity of the image between `0` and `1`.
88
+ * @default 1
89
+ *
90
+ * @example
91
+ * ```tsx
92
+ * <Image source={require('./icon.png')} alpha={0.5} />
93
+ * ```
94
+ */
95
+ alpha?: number;
96
+
97
+ /**
98
+ * Callback that is called when the image loads successfully.
99
+ */
100
+ onLoad?: () => void;
101
+
102
+ /**
103
+ * Callback that is called when the image fails to load.
104
+ */
105
+ onError?: (error: string) => void;
106
+ }
107
+
108
+ /** @hidden */
109
+ export type NativeImageProps = Omit<ImageProps, 'source' | 'onLoad' | 'onError'> &
110
+ ViewEvent<'onLoad', void> &
111
+ ViewEvent<'onError', { error: string }> & {
112
+ source: ImageResolvedAssetSource | null;
113
+ };
114
+
115
+ const ImageNativeView: React.ComponentType<NativeImageProps> = requireNativeView(
116
+ 'ExpoUI',
117
+ 'ImageView'
118
+ );
119
+
120
+ /**
121
+ * Displays an image using Jetpack Compose.
122
+ *
123
+ * Size the image with modifiers such as `size`, `width`, `height`, or `fillMaxSize`.
124
+ *
125
+ * @example
126
+ * ```tsx
127
+ * import { Image } from '@expo/ui/jetpack-compose';
128
+ * import { size } from '@expo/ui/jetpack-compose/modifiers';
129
+ *
130
+ * <Image
131
+ * source={require('./photo.png')}
132
+ * contentScale="crop"
133
+ * contentDescription="A mountain at sunset"
134
+ * modifiers={[size(160, 100)]}
135
+ * />
136
+ * ```
137
+ */
138
+ export function Image(props: ImageProps) {
139
+ const { source, onLoad, onError, ...restProps } = props;
140
+
141
+ return (
142
+ <ImageNativeView
143
+ {...transformProps(restProps)}
144
+ source={ReactNativeImage.resolveAssetSource(source)}
145
+ onLoad={onLoad}
146
+ onError={onError ? ({ nativeEvent }) => onError(nativeEvent.error) : undefined}
147
+ />
148
+ );
149
+ }
@@ -10,6 +10,7 @@ export * from './Chip';
10
10
  export * from './Button';
11
11
  export * from './colors';
12
12
  export * from './Icon';
13
+ export * from './Image';
13
14
  export * from './IconButton';
14
15
  export * from './DropdownMenu';
15
16
  export * from './ExposedDropdownMenuBox';
@@ -73,6 +73,7 @@ function Alert(props: AlertProps) {
73
73
  return (
74
74
  <AlertNativeView
75
75
  {...(modifiers ? createViewModifierEventListener(modifiers) : undefined)}
76
+ modifiers={modifiers}
76
77
  {...restProps}
77
78
  onIsPresentedChange={handleIsPresentedChange}>
78
79
  {children}
@@ -76,6 +76,7 @@ function ConfirmationDialog(props: ConfirmationDialogProps) {
76
76
  return (
77
77
  <ConfirmationDialogNativeView
78
78
  {...(modifiers ? createViewModifierEventListener(modifiers) : undefined)}
79
+ modifiers={modifiers}
79
80
  {...restProps}
80
81
  onIsPresentedChange={handleIsPresentedChange}>
81
82
  {children}
@@ -30,6 +30,7 @@ export function Overlay(props: OverlayProps) {
30
30
  return (
31
31
  <OverlayNativeView
32
32
  {...(modifiers ? createViewModifierEventListener(modifiers) : undefined)}
33
+ modifiers={modifiers}
33
34
  {...restProps}>
34
35
  {children}
35
36
  </OverlayNativeView>
@@ -56,6 +56,7 @@ export function Popover(props: PopoverViewProps) {
56
56
  return (
57
57
  <PopoverNativeView
58
58
  {...(modifiers ? createViewModifierEventListener(modifiers) : undefined)}
59
+ modifiers={modifiers}
59
60
  {...restProps}
60
61
  isPresented={isPresented}
61
62
  onIsPresentedChange={handleIsPresentedChange}>
@@ -1,4 +1,5 @@
1
1
  import { requireNativeView } from 'expo';
2
+ import { useRef } from 'react';
2
3
  import type { NativeSyntheticEvent } from 'react-native';
3
4
 
4
5
  import { Slot } from '../SlotView';
@@ -57,7 +58,8 @@ type NativeSliderProps = Omit<
57
58
  SliderProps,
58
59
  'onValueChange' | 'onEditingChanged' | 'label' | 'minimumValueLabel' | 'maximumValueLabel'
59
60
  > & {
60
- onValueChanged?: (event: NativeSyntheticEvent<{ value: number }>) => void;
61
+ mostRecentEventCount?: number;
62
+ onValueChanged?: (event: NativeSyntheticEvent<{ value: number; eventCount: number }>) => void;
61
63
  onEditingChanged?: (event: NativeSyntheticEvent<{ isEditing: boolean }>) => void;
62
64
  children?: React.ReactNode;
63
65
  };
@@ -67,7 +69,10 @@ const SliderNativeView: React.ComponentType<NativeSliderProps> = requireNativeVi
67
69
  'SliderView'
68
70
  );
69
71
 
70
- function transformSliderProps(props: SliderProps): NativeSliderProps {
72
+ function transformSliderProps(
73
+ props: SliderProps,
74
+ eventCount: { current: number }
75
+ ): NativeSliderProps {
71
76
  const {
72
77
  label,
73
78
  minimumValueLabel,
@@ -78,11 +83,11 @@ function transformSliderProps(props: SliderProps): NativeSliderProps {
78
83
  } = props;
79
84
  return {
80
85
  ...restProps,
81
- onValueChanged: onValueChange
82
- ? ({ nativeEvent: { value } }) => {
83
- onValueChange(value);
84
- }
85
- : undefined,
86
+ mostRecentEventCount: eventCount.current,
87
+ onValueChanged: ({ nativeEvent: { value, eventCount: nativeEventCount } }) => {
88
+ eventCount.current = nativeEventCount;
89
+ onValueChange?.(value);
90
+ },
86
91
  onEditingChanged: onEditingChanged
87
92
  ? ({ nativeEvent: { isEditing } }) => {
88
93
  onEditingChanged(isEditing);
@@ -93,9 +98,10 @@ function transformSliderProps(props: SliderProps): NativeSliderProps {
93
98
 
94
99
  export function Slider(props: SliderProps) {
95
100
  const { label, minimumValueLabel, maximumValueLabel } = props;
101
+ const eventCount = useRef(0);
96
102
 
97
103
  return (
98
- <SliderNativeView {...transformSliderProps(props)}>
104
+ <SliderNativeView {...transformSliderProps(props, eventCount)}>
99
105
  {label && <Slot name="label">{label}</Slot>}
100
106
  {minimumValueLabel && <Slot name="minimum">{minimumValueLabel}</Slot>}
101
107
  {maximumValueLabel && <Slot name="maximum">{maximumValueLabel}</Slot>}