@expo/ui 57.0.18 → 57.0.20

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 (72) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/ui/HostView.kt +6 -4
  4. package/build/jetpack-compose/colors.d.ts.map +1 -1
  5. package/build/swift-ui/NavigationSplitView/index.d.ts +76 -0
  6. package/build/swift-ui/NavigationSplitView/index.d.ts.map +1 -0
  7. package/build/swift-ui/Toolbar/index.d.ts +50 -0
  8. package/build/swift-ui/Toolbar/index.d.ts.map +1 -1
  9. package/build/swift-ui/index.d.ts +1 -0
  10. package/build/swift-ui/index.d.ts.map +1 -1
  11. package/build/swift-ui/modifiers/index.d.ts +16 -1
  12. package/build/swift-ui/modifiers/index.d.ts.map +1 -1
  13. package/build/swift-ui/modifiers/navigationModifiers.d.ts +28 -0
  14. package/build/swift-ui/modifiers/navigationModifiers.d.ts.map +1 -0
  15. package/expo-module.config.json +1 -1
  16. package/ios/Convertibles/ToolbarItemPlacementOptions.swift +110 -0
  17. package/ios/Convertibles/ToolbarItemVisibilityPriorityOptions.swift +35 -0
  18. package/ios/ExpoUIModule.swift +1 -0
  19. package/ios/Modifiers/NavigationModifiers.swift +44 -0
  20. package/ios/Modifiers/ScrollEdgeEffectStyleModifier.swift +34 -0
  21. package/ios/Modifiers/ViewModifierRegistry.swift +12 -0
  22. package/ios/NavigationSplitViewView.swift +180 -0
  23. package/ios/ToolbarView.swift +88 -4
  24. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.18/expo.modules.ui-57.0.18-sources.jar → 57.0.20/expo.modules.ui-57.0.20-sources.jar} +0 -0
  25. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20-sources.jar.md5 +1 -0
  26. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20-sources.jar.sha1 +1 -0
  27. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20-sources.jar.sha256 +1 -0
  28. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20-sources.jar.sha512 +1 -0
  29. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.aar +0 -0
  30. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.aar.md5 +1 -0
  31. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.aar.sha1 +1 -0
  32. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.aar.sha256 +1 -0
  33. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.aar.sha512 +1 -0
  34. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.18/expo.modules.ui-57.0.18.module → 57.0.20/expo.modules.ui-57.0.20.module} +22 -22
  35. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.module.md5 +1 -0
  36. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.module.sha1 +1 -0
  37. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.module.sha256 +1 -0
  38. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.module.sha512 +1 -0
  39. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.18/expo.modules.ui-57.0.18.pom → 57.0.20/expo.modules.ui-57.0.20.pom} +1 -1
  40. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.pom.md5 +1 -0
  41. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.pom.sha1 +1 -0
  42. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.pom.sha256 +1 -0
  43. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.pom.sha512 +1 -0
  44. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
  45. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
  46. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
  47. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
  48. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
  49. package/package.json +4 -4
  50. package/src/jetpack-compose/colors.ts +23 -1
  51. package/src/swift-ui/NavigationSplitView/index.tsx +122 -0
  52. package/src/swift-ui/Toolbar/index.tsx +79 -0
  53. package/src/swift-ui/index.tsx +1 -0
  54. package/src/swift-ui/modifiers/index.ts +20 -0
  55. package/src/swift-ui/modifiers/navigationModifiers.ts +42 -0
  56. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18-sources.jar.md5 +0 -1
  57. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18-sources.jar.sha1 +0 -1
  58. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18-sources.jar.sha256 +0 -1
  59. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18-sources.jar.sha512 +0 -1
  60. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.aar +0 -0
  61. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.aar.md5 +0 -1
  62. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.aar.sha1 +0 -1
  63. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.aar.sha256 +0 -1
  64. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.aar.sha512 +0 -1
  65. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.module.md5 +0 -1
  66. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.module.sha1 +0 -1
  67. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.module.sha256 +0 -1
  68. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.module.sha512 +0 -1
  69. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.pom.md5 +0 -1
  70. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.pom.sha1 +0 -1
  71. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.pom.sha256 +0 -1
  72. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.pom.sha512 +0 -1
@@ -0,0 +1,44 @@
1
+ // Copyright 2025-present 650 Industries. All rights reserved.
2
+
3
+ import ExpoModulesCore
4
+ import SwiftUI
5
+
6
+ internal enum NavigationSplitViewStyleOptions: String, Enumerable {
7
+ case automatic
8
+ case balanced
9
+ case prominentDetail
10
+ }
11
+
12
+ internal struct NavigationSplitViewStyleModifier: ViewModifier, Record {
13
+ @Field var style: NavigationSplitViewStyleOptions = .automatic
14
+
15
+ @ViewBuilder
16
+ func body(content: Content) -> some View {
17
+ switch style {
18
+ case .automatic:
19
+ content.navigationSplitViewStyle(.automatic)
20
+ case .balanced:
21
+ content.navigationSplitViewStyle(.balanced)
22
+ case .prominentDetail:
23
+ content.navigationSplitViewStyle(.prominentDetail)
24
+ }
25
+ }
26
+ }
27
+
28
+ internal struct NavigationSplitViewColumnWidthModifier: ViewModifier, Record {
29
+ @Field var width: CGFloat?
30
+ @Field var min: CGFloat?
31
+ @Field var ideal: CGFloat?
32
+ @Field var max: CGFloat?
33
+
34
+ @ViewBuilder
35
+ func body(content: Content) -> some View {
36
+ if let width {
37
+ content.navigationSplitViewColumnWidth(width)
38
+ } else if let ideal {
39
+ content.navigationSplitViewColumnWidth(min: min, ideal: ideal, max: max)
40
+ } else {
41
+ content
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,34 @@
1
+ // Copyright 2015-present 650 Industries. All rights reserved.
2
+
3
+ import ExpoModulesCore
4
+ import SwiftUI
5
+
6
+ internal enum ScrollEdgeEffectStyleOptions: String, Enumerable {
7
+ case automatic
8
+ case hard
9
+ case soft
10
+ }
11
+
12
+ internal struct ScrollEdgeEffectStyleModifier: ViewModifier, Record {
13
+ @Field var style: ScrollEdgeEffectStyleOptions = .automatic
14
+ @Field var edges: EdgeOptions = .all
15
+
16
+ func body(content: Content) -> some View {
17
+ #if compiler(>=6.2) && !os(tvOS) && !os(macOS) // Xcode 26
18
+ if #available(iOS 26.0, *) {
19
+ switch style {
20
+ case .automatic:
21
+ content.scrollEdgeEffectStyle(.automatic, for: edges.toEdge())
22
+ case .hard:
23
+ content.scrollEdgeEffectStyle(.hard, for: edges.toEdge())
24
+ case .soft:
25
+ content.scrollEdgeEffectStyle(.soft, for: edges.toEdge())
26
+ }
27
+ } else {
28
+ content
29
+ }
30
+ #else
31
+ content
32
+ #endif
33
+ }
34
+ }
@@ -1989,6 +1989,14 @@ extension ViewModifierRegistry {
1989
1989
  return try NavigationTitleModifier(from: params, appContext: appContext)
1990
1990
  }
1991
1991
 
1992
+ register("navigationSplitViewStyle") { params, appContext, _ in
1993
+ return try NavigationSplitViewStyleModifier(from: params, appContext: appContext)
1994
+ }
1995
+
1996
+ register("navigationSplitViewColumnWidth") { params, appContext, _ in
1997
+ return try NavigationSplitViewColumnWidthModifier(from: params, appContext: appContext)
1998
+ }
1999
+
1992
2000
  register("accessibilityLabel") { params, appContext, _ in
1993
2001
  return try AccessibilityLabelModifier(from: params, appContext: appContext)
1994
2002
  }
@@ -2305,6 +2313,10 @@ extension ViewModifierRegistry {
2305
2313
  return try ScrollIndicatorsModifier(from: params, appContext: appContext)
2306
2314
  }
2307
2315
 
2316
+ register("scrollEdgeEffectStyle") { params, appContext, _ in
2317
+ return try ScrollEdgeEffectStyleModifier(from: params, appContext: appContext)
2318
+ }
2319
+
2308
2320
  register("tabViewStyle") { params, appContext, _ in
2309
2321
  return try TabViewStyleModifier(from: params, appContext: appContext)
2310
2322
  }
@@ -0,0 +1,180 @@
1
+ // Copyright 2025-present 650 Industries. All rights reserved.
2
+
3
+ import ExpoModulesCore
4
+ import SwiftUI
5
+
6
+ internal enum NavigationSplitViewVisibilityOptions: String, Enumerable {
7
+ case automatic
8
+ case all
9
+ case doubleColumn
10
+ case detailOnly
11
+
12
+ func toVisibility() -> NavigationSplitViewVisibility {
13
+ switch self {
14
+ case .automatic:
15
+ return .automatic
16
+ case .all:
17
+ return .all
18
+ case .doubleColumn:
19
+ return .doubleColumn
20
+ case .detailOnly:
21
+ return .detailOnly
22
+ }
23
+ }
24
+
25
+ static func from(_ visibility: NavigationSplitViewVisibility) -> NavigationSplitViewVisibilityOptions {
26
+ switch visibility {
27
+ case .all:
28
+ return .all
29
+ case .doubleColumn:
30
+ return .doubleColumn
31
+ case .detailOnly:
32
+ return .detailOnly
33
+ default:
34
+ return .automatic
35
+ }
36
+ }
37
+ }
38
+
39
+ internal enum NavigationSplitViewColumnOptions: String, Enumerable {
40
+ case sidebar
41
+ case content
42
+ case detail
43
+
44
+ @available(iOS 17.0, tvOS 17.0, *)
45
+ func toColumn() -> NavigationSplitViewColumn {
46
+ switch self {
47
+ case .sidebar:
48
+ return .sidebar
49
+ case .content:
50
+ return .content
51
+ case .detail:
52
+ return .detail
53
+ }
54
+ }
55
+
56
+ @available(iOS 17.0, tvOS 17.0, *)
57
+ static func from(_ column: NavigationSplitViewColumn) -> NavigationSplitViewColumnOptions {
58
+ switch column {
59
+ case .content:
60
+ return .content
61
+ case .detail:
62
+ return .detail
63
+ default:
64
+ return .sidebar
65
+ }
66
+ }
67
+ }
68
+
69
+ internal final class NavigationSplitViewProps: UIBaseViewProps {
70
+ @Field var columnVisibility: NavigationSplitViewVisibilityOptions?
71
+ @Field var preferredCompactColumn: NavigationSplitViewColumnOptions?
72
+ var onColumnVisibilityChange = EventDispatcher()
73
+ var onPreferredCompactColumnChange = EventDispatcher()
74
+ }
75
+
76
+ internal struct NavigationSplitViewView: ExpoSwiftUI.View {
77
+ @ObservedObject var props: NavigationSplitViewProps
78
+
79
+ // Only used while the matching prop is unset. While it is set, JS is the sole source
80
+ // of truth, so it stays in control of the columns and can refuse a change the user
81
+ // made by dragging.
82
+ @State private var uncontrolledVisibility: NavigationSplitViewVisibilityOptions = .automatic
83
+ @State private var uncontrolledCompactColumn: NavigationSplitViewColumnOptions = .sidebar
84
+
85
+ init(props: NavigationSplitViewProps) {
86
+ self.props = props
87
+ }
88
+
89
+ private var columnVisibilityBinding: Binding<NavigationSplitViewVisibility> {
90
+ let props = props
91
+ let uncontrolled = $uncontrolledVisibility
92
+ return Binding(
93
+ get: { (props.columnVisibility ?? uncontrolled.wrappedValue).toVisibility() },
94
+ set: { newValue in
95
+ let resolved = NavigationSplitViewVisibilityOptions.from(newValue)
96
+ guard (props.columnVisibility ?? uncontrolled.wrappedValue) != resolved else {
97
+ return
98
+ }
99
+ if props.columnVisibility == nil {
100
+ uncontrolled.wrappedValue = resolved
101
+ }
102
+ props.onColumnVisibilityChange(["visibility": resolved.rawValue])
103
+ }
104
+ )
105
+ }
106
+
107
+ @available(iOS 17.0, tvOS 17.0, *)
108
+ private var compactColumnBinding: Binding<NavigationSplitViewColumn> {
109
+ let props = props
110
+ let uncontrolled = $uncontrolledCompactColumn
111
+ return Binding(
112
+ get: { (props.preferredCompactColumn ?? uncontrolled.wrappedValue).toColumn() },
113
+ set: { newValue in
114
+ let resolved = NavigationSplitViewColumnOptions.from(newValue)
115
+ guard (props.preferredCompactColumn ?? uncontrolled.wrappedValue) != resolved else {
116
+ return
117
+ }
118
+ if props.preferredCompactColumn == nil {
119
+ uncontrolled.wrappedValue = resolved
120
+ }
121
+ props.onPreferredCompactColumnChange(["column": resolved.rawValue])
122
+ }
123
+ )
124
+ }
125
+
126
+ @ViewBuilder
127
+ var body: some View {
128
+ if #available(iOS 17.0, tvOS 17.0, *) {
129
+ if let contentColumn {
130
+ NavigationSplitView(
131
+ columnVisibility: columnVisibilityBinding,
132
+ preferredCompactColumn: compactColumnBinding
133
+ ) {
134
+ sidebarColumn
135
+ } content: {
136
+ contentColumn
137
+ } detail: {
138
+ detailColumn
139
+ }
140
+ } else {
141
+ NavigationSplitView(
142
+ columnVisibility: columnVisibilityBinding,
143
+ preferredCompactColumn: compactColumnBinding
144
+ ) {
145
+ sidebarColumn
146
+ } detail: {
147
+ detailColumn
148
+ }
149
+ }
150
+ } else {
151
+ if let contentColumn {
152
+ NavigationSplitView(columnVisibility: columnVisibilityBinding) {
153
+ sidebarColumn
154
+ } content: {
155
+ contentColumn
156
+ } detail: {
157
+ detailColumn
158
+ }
159
+ } else {
160
+ NavigationSplitView(columnVisibility: columnVisibilityBinding) {
161
+ sidebarColumn
162
+ } detail: {
163
+ detailColumn
164
+ }
165
+ }
166
+ }
167
+ }
168
+
169
+ private var sidebarColumn: SlotView? {
170
+ props.children?.slot("sidebar")
171
+ }
172
+
173
+ private var contentColumn: SlotView? {
174
+ props.children?.slot("content")
175
+ }
176
+
177
+ private var detailColumn: SlotView? {
178
+ props.children?.slot("detail")
179
+ }
180
+ }
@@ -5,6 +5,42 @@ import ExpoModulesCore
5
5
 
6
6
  internal final class ToolbarViewProps: UIBaseViewProps {}
7
7
 
8
+ private struct ToolbarContentView: View {
9
+ @ObservedObject var props: SlotViewProps
10
+ let content: SlotView
11
+ let base: AnyView
12
+
13
+ @ViewBuilder
14
+ var body: some View {
15
+ let children = props.children ?? []
16
+
17
+ if children.contains(where: isItem) {
18
+ children.reduce(base) { view, child in
19
+ let childView: any View = child.childView
20
+
21
+ guard let slot = child.childView as? SlotView, slot.props.name == "item" else {
22
+ return AnyView(placed(AnyView(childView), on: view, placement: .automatic, visibilityPriority: nil))
23
+ }
24
+ return AnyView(ToolbarItemLayer(props: slot.props, base: view, content: AnyView(childView)))
25
+ }
26
+ } else {
27
+ base.toolbar {
28
+ content
29
+ }
30
+ }
31
+ }
32
+ }
33
+
34
+ private struct ToolbarItemLayer: View {
35
+ @ObservedObject var props: SlotViewProps
36
+ let base: AnyView
37
+ let content: AnyView
38
+
39
+ var body: some View {
40
+ placed(content, on: base, placement: placement(from: props), visibilityPriority: visibilityPriority(from: props))
41
+ }
42
+ }
43
+
8
44
  internal struct ToolbarView: ExpoSwiftUI.View {
9
45
  @ObservedObject var props: ToolbarViewProps
10
46
 
@@ -14,10 +50,7 @@ internal struct ToolbarView: ExpoSwiftUI.View {
14
50
 
15
51
  var body: some View {
16
52
  if let content = props.children?.slot("content") {
17
- baseContent
18
- .toolbar {
19
- content
20
- }
53
+ ToolbarContentView(props: content.props, content: content, base: AnyView(baseContent))
21
54
  } else {
22
55
  baseContent
23
56
  }
@@ -31,3 +64,54 @@ internal struct ToolbarView: ExpoSwiftUI.View {
31
64
  }
32
65
  }
33
66
  }
67
+
68
+ @ViewBuilder
69
+ private func placed(
70
+ _ content: AnyView,
71
+ on base: AnyView,
72
+ placement: ToolbarItemPlacement,
73
+ visibilityPriority: ToolbarItemVisibilityPriorityOptions?
74
+ ) -> some View {
75
+ #if compiler(>=6.4) // Xcode 27
76
+ if #available(iOS 27.0, macOS 26.1, tvOS 27.0, visionOS 27.0, *),
77
+ let visibilityPriority {
78
+ base.toolbar {
79
+ ToolbarItem(placement: placement) {
80
+ content
81
+ }
82
+ .visibilityPriority(visibilityPriority.toPriority())
83
+ }
84
+ } else {
85
+ base.toolbar {
86
+ ToolbarItem(placement: placement) {
87
+ content
88
+ }
89
+ }
90
+ }
91
+ #else
92
+ base.toolbar {
93
+ ToolbarItem(placement: placement) {
94
+ content
95
+ }
96
+ }
97
+ #endif
98
+ }
99
+
100
+ private func isItem(_ child: any ExpoSwiftUI.AnyChild) -> Bool {
101
+ return (child.childView as? SlotView)?.props.name == "item"
102
+ }
103
+
104
+ private func placement(from props: SlotViewProps) -> ToolbarItemPlacement {
105
+ guard let rawPlacement = props.extraProps?["placement"] as? String,
106
+ let placement = ToolbarItemPlacementOptions(rawValue: rawPlacement) else {
107
+ return .automatic
108
+ }
109
+ return placement.toPlacement()
110
+ }
111
+
112
+ private func visibilityPriority(from props: SlotViewProps) -> ToolbarItemVisibilityPriorityOptions? {
113
+ guard let rawPriority = props.extraProps?["visibilityPriority"] as? String else {
114
+ return nil
115
+ }
116
+ return ToolbarItemVisibilityPriorityOptions(rawValue: rawPriority)
117
+ }
@@ -0,0 +1 @@
1
+ 27ca3d4c9580433a6848cb86719f6d488b13cafbbd2ae1cef5069f077a626e39
@@ -0,0 +1 @@
1
+ 78e4b35259e3faf890bbff4274c97f944b4c2c7993ddc0610db65d951caa792d9c1570edab47b86d887916b0b4255935b8581a9470d218b7a2bc611a5be71e33
@@ -0,0 +1 @@
1
+ db54ddd285099815385b8d9e4a385d28be8b60e0
@@ -0,0 +1 @@
1
+ 9b7ca89ceb5c49b9295de22b70afe86f4b486b10a7616d07b11c4b2f09becc54
@@ -0,0 +1 @@
1
+ 2f82464d9f3dd57fb4b970df07874ec5c213304ee02d311370ec67aab02914698c9bac90e1efa9caf649699ffd72e476c9c6f85893e478e9a395a6f460710cfc
@@ -3,7 +3,7 @@
3
3
  "component": {
4
4
  "group": "expo.modules.ui",
5
5
  "module": "expo.modules.ui",
6
- "version": "57.0.18",
6
+ "version": "57.0.20",
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.18.aar",
28
- "url": "expo.modules.ui-57.0.18.aar",
29
- "size": 2073510,
30
- "sha512": "d1c36be4bda31ef4d9df2b222c12ab6ee240523984bb7c550ede0186ac99aebb95f31695f76b74a8ad68c34615fa3c0d5ef15ee8c5f58c5e8e90e766a6f4d1d2",
31
- "sha256": "69f99c64824f782c36b1e44617e59fd5f5ddb13f92d906007918534cc8a29dfe",
32
- "sha1": "aad7ad5ee2eae34a4143404fa774449f0dc7f6a0",
33
- "md5": "b3a59c37f58880f20a32caa6a69c8c42"
27
+ "name": "expo.modules.ui-57.0.20.aar",
28
+ "url": "expo.modules.ui-57.0.20.aar",
29
+ "size": 2073794,
30
+ "sha512": "2f82464d9f3dd57fb4b970df07874ec5c213304ee02d311370ec67aab02914698c9bac90e1efa9caf649699ffd72e476c9c6f85893e478e9a395a6f460710cfc",
31
+ "sha256": "9b7ca89ceb5c49b9295de22b70afe86f4b486b10a7616d07b11c4b2f09becc54",
32
+ "sha1": "db54ddd285099815385b8d9e4a385d28be8b60e0",
33
+ "md5": "f64ef3618626725f3f307b6fef52a26c"
34
34
  }
35
35
  ]
36
36
  },
@@ -141,13 +141,13 @@
141
141
  ],
142
142
  "files": [
143
143
  {
144
- "name": "expo.modules.ui-57.0.18.aar",
145
- "url": "expo.modules.ui-57.0.18.aar",
146
- "size": 2073510,
147
- "sha512": "d1c36be4bda31ef4d9df2b222c12ab6ee240523984bb7c550ede0186ac99aebb95f31695f76b74a8ad68c34615fa3c0d5ef15ee8c5f58c5e8e90e766a6f4d1d2",
148
- "sha256": "69f99c64824f782c36b1e44617e59fd5f5ddb13f92d906007918534cc8a29dfe",
149
- "sha1": "aad7ad5ee2eae34a4143404fa774449f0dc7f6a0",
150
- "md5": "b3a59c37f58880f20a32caa6a69c8c42"
144
+ "name": "expo.modules.ui-57.0.20.aar",
145
+ "url": "expo.modules.ui-57.0.20.aar",
146
+ "size": 2073794,
147
+ "sha512": "2f82464d9f3dd57fb4b970df07874ec5c213304ee02d311370ec67aab02914698c9bac90e1efa9caf649699ffd72e476c9c6f85893e478e9a395a6f460710cfc",
148
+ "sha256": "9b7ca89ceb5c49b9295de22b70afe86f4b486b10a7616d07b11c4b2f09becc54",
149
+ "sha1": "db54ddd285099815385b8d9e4a385d28be8b60e0",
150
+ "md5": "f64ef3618626725f3f307b6fef52a26c"
151
151
  }
152
152
  ]
153
153
  },
@@ -161,13 +161,13 @@
161
161
  },
162
162
  "files": [
163
163
  {
164
- "name": "expo.modules.ui-57.0.18-sources.jar",
165
- "url": "expo.modules.ui-57.0.18-sources.jar",
166
- "size": 105192,
167
- "sha512": "5cdf850cb3e0dd28112d6a77eead05862cd9d3e5a75b0e1da56a032b872378b05770bc5640f69fc904bd58383e1c4c24933da4702029e6f8dba9f9ab000ef4ac",
168
- "sha256": "6b32ef025930afd41b632295e3d20bed5d52b29001680721148abc18b7dbf3c8",
169
- "sha1": "6b806f321f975d6caff272f29bc91464e74acbb2",
170
- "md5": "10a87f7e5b9322022e3579f88cee7441"
164
+ "name": "expo.modules.ui-57.0.20-sources.jar",
165
+ "url": "expo.modules.ui-57.0.20-sources.jar",
166
+ "size": 105215,
167
+ "sha512": "78e4b35259e3faf890bbff4274c97f944b4c2c7993ddc0610db65d951caa792d9c1570edab47b86d887916b0b4255935b8581a9470d218b7a2bc611a5be71e33",
168
+ "sha256": "27ca3d4c9580433a6848cb86719f6d488b13cafbbd2ae1cef5069f077a626e39",
169
+ "sha1": "27def103f0d8bd59436344ef6e64c338dcb49d2a",
170
+ "md5": "e90510f84fd38fb8a7bd77c4a4b16ce0"
171
171
  }
172
172
  ]
173
173
  }
@@ -0,0 +1 @@
1
+ 241eb62cd53bfda1c4883fc1e3a9c972f2beead6
@@ -0,0 +1 @@
1
+ 28357022d94d12ff78dbc28545b3197adca9a9d97990f52b5f04e726f77ae8e1
@@ -0,0 +1 @@
1
+ 8ec575c6a23b219980ff38475398532a5113e03e592c806bf064c0897b4f021712080b690a44603d2915eaf532dbaede70a30dd3a92fbde86692a1746cf28b59
@@ -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.18</version>
12
+ <version>57.0.20</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
+ e44cde53a66ad0b8cb771225f7fd0b30247034a9
@@ -0,0 +1 @@
1
+ 215f6bbb2ba68f9ed7aa190d3b92e9ee373548a90b5978638ca34829bc91a5a6
@@ -0,0 +1 @@
1
+ d4ae4b895695c7811964fc77007db9cb594c01f5b676af9e98598fd18111c954a77268e315c3b516704870d9bb81d1e91ce28cedd06af56e03782e63ea815a0f
@@ -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.18</latest>
7
- <release>57.0.18</release>
6
+ <latest>57.0.20</latest>
7
+ <release>57.0.20</release>
8
8
  <versions>
9
- <version>57.0.18</version>
9
+ <version>57.0.20</version>
10
10
  </versions>
11
- <lastUpdated>20260911111656</lastUpdated>
11
+ <lastUpdated>20260924100600</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- 04e4bbda95115c882497c79e219dae7e
1
+ b0f5d41a0846b3dfe21ad3670dca256b
@@ -1 +1 @@
1
- e192dcc8dd2efc7b7e7cc064e4e76462e87c4e97
1
+ 0da35804f95ba70d9ddd7634bca46c59c03a88a2
@@ -1 +1 @@
1
- 6154ba7267f0b402f8af16a924de1329c7a15afe7b0a945cbc8a275698ad03c0
1
+ 24ab2f0670c5032cddc11479196d1c37ca62c00553dd61e91adcf9fa8e4b6cdd
@@ -1 +1 @@
1
- 3b107556159f09e7d3ec09e1b3c39a2dc00ee3a2567bbca3918dbe8dbc030ce5557870c68fe708808310b78b4f1b43316f10d2f6760a45ae7e2797015a9553d5
1
+ 2eeaec75ff3371d3acdff5a2c6fe9aa40845808d62682a5359dcf291fcc765c2e64d36822cd67820eeb896b573cfab204e20a028e82f3d7d1e21f0f141e8315e
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/ui",
3
- "version": "57.0.18",
3
+ "version": "57.0.20",
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": "57.0.22",
100
- "expo-module-scripts": "56.0.3"
99
+ "expo-module-scripts": "56.0.3",
100
+ "expo": "57.0.25"
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": "9e5319c0f821a27b7924841903abae50e2b41790",
124
+ "gitHead": "9349d1457178dd9cccb8bdd3aed47473c49134e1",
125
125
  "scripts": {
126
126
  "build": "expo-module build",
127
127
  "clean": "expo-module clean",
@@ -183,11 +183,33 @@ export const isDynamicColorAvailable: boolean = ExpoUIModule.isDynamicColorAvail
183
183
  */
184
184
  export const HostPaletteContext = createContext<MaterialColors | null>(null);
185
185
 
186
+ // Cache the `scheme` + `seedColor` keyed palette to prevent sync calls to `getMaterialColors`.
187
+ // https://github.com/expo/expo/issues/50477
188
+ const seededPalettes = new Map<string, MaterialColors>();
189
+ const MAX_SEEDED_PALETTES = 32;
190
+
186
191
  /**
187
192
  * Get the Material 3 color palette.
188
193
  */
189
194
  export function getMaterialColors(options?: MaterialColorsOptions): MaterialColors {
190
- return ExpoUIModule.getMaterialColors(options ?? null);
195
+ const scheme = options?.scheme;
196
+ const seedColor = options?.seedColor;
197
+ const isCacheable =
198
+ (scheme === 'light' || scheme === 'dark') &&
199
+ (typeof seedColor === 'string' || typeof seedColor === 'number');
200
+ if (!isCacheable) {
201
+ return ExpoUIModule.getMaterialColors(options ?? null);
202
+ }
203
+ const key = `${scheme}:${seedColor}`;
204
+ let palette = seededPalettes.get(key);
205
+ if (!palette) {
206
+ palette = ExpoUIModule.getMaterialColors(options) as MaterialColors;
207
+ if (seededPalettes.size >= MAX_SEEDED_PALETTES) {
208
+ seededPalettes.delete(seededPalettes.keys().next().value!);
209
+ }
210
+ seededPalettes.set(key, palette);
211
+ }
212
+ return palette;
191
213
  }
192
214
 
193
215
  /**