@expo/ui 57.0.17 → 57.0.19

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 +18 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/ui/DatePickerView.kt +2 -2
  4. package/android/src/main/java/expo/modules/ui/menu/DropdownMenu.kt +2 -0
  5. package/android/src/main/java/expo/modules/ui/menu/DropdownMenuRecords.kt +2 -1
  6. package/build/jetpack-compose/DatePicker/index.d.ts +4 -0
  7. package/build/jetpack-compose/DatePicker/index.d.ts.map +1 -1
  8. package/build/jetpack-compose/DropdownMenu/index.d.ts +7 -0
  9. package/build/jetpack-compose/DropdownMenu/index.d.ts.map +1 -1
  10. package/build/swift-ui/Button/index.d.ts +3 -1
  11. package/build/swift-ui/Button/index.d.ts.map +1 -1
  12. package/build/swift-ui/NavigationDestination/index.d.ts +30 -0
  13. package/build/swift-ui/NavigationDestination/index.d.ts.map +1 -0
  14. package/build/swift-ui/NavigationLink/index.d.ts +32 -0
  15. package/build/swift-ui/NavigationLink/index.d.ts.map +1 -0
  16. package/build/swift-ui/NavigationSplitView/index.d.ts +76 -0
  17. package/build/swift-ui/NavigationSplitView/index.d.ts.map +1 -0
  18. package/build/swift-ui/NavigationStack/index.d.ts +45 -0
  19. package/build/swift-ui/NavigationStack/index.d.ts.map +1 -0
  20. package/build/swift-ui/Toolbar/index.d.ts +40 -0
  21. package/build/swift-ui/Toolbar/index.d.ts.map +1 -0
  22. package/build/swift-ui/index.d.ts +5 -0
  23. package/build/swift-ui/index.d.ts.map +1 -1
  24. package/build/swift-ui/modifiers/index.d.ts +8 -1
  25. package/build/swift-ui/modifiers/index.d.ts.map +1 -1
  26. package/build/swift-ui/modifiers/navigationModifiers.d.ts +28 -0
  27. package/build/swift-ui/modifiers/navigationModifiers.d.ts.map +1 -0
  28. package/expo-module.config.json +1 -1
  29. package/ios/Button/Button.swift +13 -0
  30. package/ios/Button/ButtonProps.swift +6 -0
  31. package/ios/ExpoUIModule.swift +5 -0
  32. package/ios/Modifiers/NavigationModifiers.swift +44 -0
  33. package/ios/Modifiers/ViewModifierRegistry.swift +25 -0
  34. package/ios/NavigationLinkView.swift +22 -0
  35. package/ios/NavigationSplitViewView.swift +180 -0
  36. package/ios/NavigationStackView.swift +63 -0
  37. package/ios/SlotView.swift +5 -0
  38. package/ios/ToolbarView.swift +33 -0
  39. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.17/expo.modules.ui-57.0.17-sources.jar → 57.0.19/expo.modules.ui-57.0.19-sources.jar} +0 -0
  40. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19-sources.jar.md5 +1 -0
  41. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19-sources.jar.sha1 +1 -0
  42. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19-sources.jar.sha256 +1 -0
  43. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19-sources.jar.sha512 +1 -0
  44. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19.aar +0 -0
  45. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19.aar.md5 +1 -0
  46. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19.aar.sha1 +1 -0
  47. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19.aar.sha256 +1 -0
  48. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19.aar.sha512 +1 -0
  49. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.17/expo.modules.ui-57.0.17.module → 57.0.19/expo.modules.ui-57.0.19.module} +22 -22
  50. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19.module.md5 +1 -0
  51. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19.module.sha1 +1 -0
  52. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19.module.sha256 +1 -0
  53. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19.module.sha512 +1 -0
  54. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.17/expo.modules.ui-57.0.17.pom → 57.0.19/expo.modules.ui-57.0.19.pom} +1 -1
  55. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19.pom.md5 +1 -0
  56. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19.pom.sha1 +1 -0
  57. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19.pom.sha256 +1 -0
  58. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.19/expo.modules.ui-57.0.19.pom.sha512 +1 -0
  59. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
  60. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
  61. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
  62. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
  63. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
  64. package/package.json +3 -3
  65. package/src/jetpack-compose/DatePicker/index.tsx +4 -0
  66. package/src/jetpack-compose/DropdownMenu/index.tsx +9 -0
  67. package/src/swift-ui/Button/index.tsx +3 -1
  68. package/src/swift-ui/NavigationDestination/index.tsx +39 -0
  69. package/src/swift-ui/NavigationLink/index.tsx +51 -0
  70. package/src/swift-ui/NavigationSplitView/index.tsx +122 -0
  71. package/src/swift-ui/NavigationStack/index.tsx +75 -0
  72. package/src/swift-ui/Toolbar/index.tsx +64 -0
  73. package/src/swift-ui/index.tsx +5 -0
  74. package/src/swift-ui/modifiers/index.ts +10 -1
  75. package/src/swift-ui/modifiers/navigationModifiers.ts +42 -0
  76. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17-sources.jar.md5 +0 -1
  77. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17-sources.jar.sha1 +0 -1
  78. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17-sources.jar.sha256 +0 -1
  79. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17-sources.jar.sha512 +0 -1
  80. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.aar +0 -0
  81. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.aar.md5 +0 -1
  82. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.aar.sha1 +0 -1
  83. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.aar.sha256 +0 -1
  84. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.aar.sha512 +0 -1
  85. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.module.md5 +0 -1
  86. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.module.sha1 +0 -1
  87. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.module.sha256 +0 -1
  88. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.module.sha512 +0 -1
  89. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.pom.md5 +0 -1
  90. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.pom.sha1 +0 -1
  91. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.pom.sha256 +0 -1
  92. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.pom.sha512 +0 -1
@@ -0,0 +1,28 @@
1
+ import { createModifier } from './createModifier';
2
+ export type NavigationSplitViewStyle = 'automatic' | 'balanced' | 'prominentDetail';
3
+ /**
4
+ * Sets the style of a `NavigationSplitView`.
5
+ * @param style - The style to apply.
6
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/navigationsplitviewstyle(_:)).
7
+ */
8
+ export declare const navigationSplitViewStyle: (style: NavigationSplitViewStyle) => import("./createModifier").ModifierConfig;
9
+ /**
10
+ * The resizable form of `navigationSplitViewColumnWidth`.
11
+ */
12
+ export type NavigationSplitViewColumnWidthParams = {
13
+ min?: number;
14
+ ideal: number;
15
+ max?: number;
16
+ };
17
+ /**
18
+ * Sets the width of a column of a `NavigationSplitView`.
19
+ *
20
+ * Pass a number for a fixed column, or an `ideal` width with optional `min` and `max` for a
21
+ * column that resizes with the window. Prefer the resizable form: a hardcoded sidebar width
22
+ * does not survive every window size.
23
+ *
24
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/navigationsplitviewcolumnwidth(_:)).
25
+ */
26
+ export declare function navigationSplitViewColumnWidth(width: number): ReturnType<typeof createModifier>;
27
+ export declare function navigationSplitViewColumnWidth(params: NavigationSplitViewColumnWidthParams): ReturnType<typeof createModifier>;
28
+ //# sourceMappingURL=navigationModifiers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigationModifiers.d.ts","sourceRoot":"","sources":["../../../src/swift-ui/modifiers/navigationModifiers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,MAAM,wBAAwB,GAAG,WAAW,GAAG,UAAU,GAAG,iBAAiB,CAAC;AAEpF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GAAI,OAAO,wBAAwB,8CACjB,CAAC;AAExD;;GAEG;AACH,MAAM,MAAM,oCAAoC,GAAG;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACjG,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,oCAAoC,GAC3C,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC"}
@@ -10,7 +10,7 @@
10
10
  "publication": {
11
11
  "groupId": "expo.modules.ui",
12
12
  "artifactId": "expo.modules.ui",
13
- "version": "57.0.17",
13
+ "version": "57.0.19",
14
14
  "repository": "local-maven-repo"
15
15
  }
16
16
  }
@@ -21,6 +21,19 @@ public struct Button: ExpoSwiftUI.View {
21
21
  props.onButtonPress()
22
22
  }
23
23
  }
24
+ } else {
25
+ labelLessButton
26
+ }
27
+ }
28
+
29
+ @ViewBuilder
30
+ private var labelLessButton: some View {
31
+ if #available(iOS 26.0, tvOS 26.0, macOS 26.0, *),
32
+ props.children?.isEmpty ?? true,
33
+ let role = props.role?.toNativeRole() {
34
+ SwiftUI.Button(role: role) {
35
+ props.onButtonPress()
36
+ }
24
37
  } else {
25
38
  SwiftUI.Button(role: props.role?.toNativeRole(), action: {
26
39
  props.onButtonPress()
@@ -7,6 +7,7 @@ public enum ButtonRole: String, Enumerable {
7
7
  case `default`
8
8
  case destructive
9
9
  case cancel
10
+ case close
10
11
 
11
12
  public func toNativeRole() -> SwiftUI.ButtonRole? {
12
13
  switch self {
@@ -16,6 +17,11 @@ public enum ButtonRole: String, Enumerable {
16
17
  return SwiftUI.ButtonRole.destructive
17
18
  case .cancel:
18
19
  return SwiftUI.ButtonRole.cancel
20
+ case .close:
21
+ if #available(iOS 26.0, tvOS 26.0, macOS 26.0, *) {
22
+ return SwiftUI.ButtonRole.close
23
+ }
24
+ return nil
19
25
  }
20
26
  }
21
27
  }
@@ -156,6 +156,11 @@ public final class ExpoUIModule: Module {
156
156
 
157
157
  ExpoUIView(MenuView.self)
158
158
 
159
+ ExpoUIView(NavigationStackView.self)
160
+ ExpoUIView(NavigationLinkView.self)
161
+ ExpoUIView(NavigationSplitViewView.self)
162
+ ExpoUIView(ToolbarView.self)
163
+
159
164
  ExpoUIView(FormView.self)
160
165
  ExpoUIView(GaugeView.self)
161
166
  ExpoUIView(GroupView.self)
@@ -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
+ }
@@ -1800,6 +1800,19 @@ internal struct TextFieldStyleModifier: ViewModifier, Record {
1800
1800
  }
1801
1801
  }
1802
1802
 
1803
+ internal struct NavigationTitleModifier: ViewModifier, Record {
1804
+ @Field var title: String?
1805
+
1806
+ @ViewBuilder
1807
+ func body(content: Content) -> some View {
1808
+ if let title {
1809
+ content.navigationTitle(title)
1810
+ } else {
1811
+ content
1812
+ }
1813
+ }
1814
+ }
1815
+
1803
1816
  // MARK: - Built-in Modifier Registration
1804
1817
 
1805
1818
  // swiftlint:disable:next no_grouping_extension
@@ -1972,6 +1985,18 @@ extension ViewModifierRegistry {
1972
1985
  return try HueRotationModifier(from: params, appContext: appContext)
1973
1986
  }
1974
1987
 
1988
+ register("navigationTitle") { params, appContext, _ in
1989
+ return try NavigationTitleModifier(from: params, appContext: appContext)
1990
+ }
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
+
1975
2000
  register("accessibilityLabel") { params, appContext, _ in
1976
2001
  return try AccessibilityLabelModifier(from: params, appContext: appContext)
1977
2002
  }
@@ -0,0 +1,22 @@
1
+ // Copyright 2025-present 650 Industries. All rights reserved.
2
+
3
+ import SwiftUI
4
+ import ExpoModulesCore
5
+
6
+ internal final class NavigationLinkViewProps: UIBaseViewProps {
7
+ @Field var value: String = ""
8
+ }
9
+
10
+ internal struct NavigationLinkView: ExpoSwiftUI.View {
11
+ @ObservedObject var props: NavigationLinkViewProps
12
+
13
+ init(props: NavigationLinkViewProps) {
14
+ self.props = props
15
+ }
16
+
17
+ var body: some View {
18
+ NavigationLink(value: props.value) {
19
+ Children()
20
+ }
21
+ }
22
+ }
@@ -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
+ }
@@ -0,0 +1,63 @@
1
+ // Copyright 2025-present 650 Industries. All rights reserved.
2
+
3
+ import SwiftUI
4
+ import ExpoModulesCore
5
+
6
+ internal final class NavigationStackViewProps: UIBaseViewProps {
7
+ @Field var path: [String]?
8
+ var onPathChange = EventDispatcher()
9
+ }
10
+
11
+ private struct NavigationDestinationContent: View {
12
+ @ObservedObject var props: NavigationStackViewProps
13
+ let value: String
14
+
15
+ var body: some View {
16
+ props.children?
17
+ .slots("destination")
18
+ .first { $0.extra("value", as: String.self) == value }
19
+ }
20
+ }
21
+
22
+ internal struct NavigationStackView: ExpoSwiftUI.View {
23
+ @ObservedObject var props: NavigationStackViewProps
24
+ @State private var uncontrolledPath: [String] = []
25
+
26
+ init(props: NavigationStackViewProps) {
27
+ self.props = props
28
+ }
29
+
30
+ private var pathBinding: Binding<[String]> {
31
+ let props = props
32
+ let uncontrolled = $uncontrolledPath
33
+ return Binding(
34
+ get: { props.path ?? uncontrolled.wrappedValue },
35
+ set: { newPath in
36
+ guard (props.path ?? uncontrolled.wrappedValue) != newPath else {
37
+ return
38
+ }
39
+ if props.path == nil {
40
+ uncontrolled.wrappedValue = newPath
41
+ }
42
+ props.onPathChange(["path": newPath])
43
+ }
44
+ )
45
+ }
46
+
47
+ var body: some View {
48
+ NavigationStack(path: pathBinding) {
49
+ rootContent
50
+ .navigationDestination(for: String.self) { value in
51
+ NavigationDestinationContent(props: props, value: value)
52
+ }
53
+ }
54
+ }
55
+
56
+ @ViewBuilder
57
+ private var rootContent: some View {
58
+ ForEach(props.children?.withoutSlot("destination") ?? [], id: \.id) { child in
59
+ let view: any View = child.childView
60
+ AnyView(view)
61
+ }
62
+ }
63
+ }
@@ -30,6 +30,11 @@ extension [any ExpoSwiftUI.AnyChild] {
30
30
  .first { $0.props.name == name }
31
31
  }
32
32
 
33
+ func slots(_ name: String) -> [SlotView] {
34
+ compactMap { $0.childView as? SlotView }
35
+ .filter { $0.props.name == name }
36
+ }
37
+
33
38
  func withoutSlot(_ name: String) -> [any ExpoSwiftUI.AnyChild] {
34
39
  filter {
35
40
  guard let slot = $0.childView as? SlotView else { return true }
@@ -0,0 +1,33 @@
1
+ // Copyright 2025-present 650 Industries. All rights reserved.
2
+
3
+ import SwiftUI
4
+ import ExpoModulesCore
5
+
6
+ internal final class ToolbarViewProps: UIBaseViewProps {}
7
+
8
+ internal struct ToolbarView: ExpoSwiftUI.View {
9
+ @ObservedObject var props: ToolbarViewProps
10
+
11
+ init(props: ToolbarViewProps) {
12
+ self.props = props
13
+ }
14
+
15
+ var body: some View {
16
+ if let content = props.children?.slot("content") {
17
+ baseContent
18
+ .toolbar {
19
+ content
20
+ }
21
+ } else {
22
+ baseContent
23
+ }
24
+ }
25
+
26
+ @ViewBuilder
27
+ private var baseContent: some View {
28
+ ForEach(props.children?.withoutSlots() ?? [], id: \.id) { child in
29
+ let view: any View = child.childView
30
+ AnyView(view)
31
+ }
32
+ }
33
+ }
@@ -0,0 +1 @@
1
+ 6b32ef025930afd41b632295e3d20bed5d52b29001680721148abc18b7dbf3c8
@@ -0,0 +1 @@
1
+ 5cdf850cb3e0dd28112d6a77eead05862cd9d3e5a75b0e1da56a032b872378b05770bc5640f69fc904bd58383e1c4c24933da4702029e6f8dba9f9ab000ef4ac
@@ -0,0 +1 @@
1
+ aad7ad5ee2eae34a4143404fa774449f0dc7f6a0
@@ -0,0 +1 @@
1
+ 69f99c64824f782c36b1e44617e59fd5f5ddb13f92d906007918534cc8a29dfe
@@ -0,0 +1 @@
1
+ d1c36be4bda31ef4d9df2b222c12ab6ee240523984bb7c550ede0186ac99aebb95f31695f76b74a8ad68c34615fa3c0d5ef15ee8c5f58c5e8e90e766a6f4d1d2
@@ -3,7 +3,7 @@
3
3
  "component": {
4
4
  "group": "expo.modules.ui",
5
5
  "module": "expo.modules.ui",
6
- "version": "57.0.17",
6
+ "version": "57.0.19",
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.17.aar",
28
- "url": "expo.modules.ui-57.0.17.aar",
29
- "size": 2072906,
30
- "sha512": "10a5b1af451aa49760a4c2ca23f439feeff3ee645cef0ca3af0ef7e487efeb5d26c3ff608ce68568a005f46707a5b774e274b5ca0ffc058429d633e600c9ed1e",
31
- "sha256": "13b9babd2eaa4ed0f4ad6a09f8443eb1a4bca31cc519d29db8371cdabd6487e4",
32
- "sha1": "394fabe7251e3d947f0bbf2037e2bb065b8493d5",
33
- "md5": "87a5f6dc53fef1a3b6810eb8db0ccc6a"
27
+ "name": "expo.modules.ui-57.0.19.aar",
28
+ "url": "expo.modules.ui-57.0.19.aar",
29
+ "size": 2073510,
30
+ "sha512": "d1c36be4bda31ef4d9df2b222c12ab6ee240523984bb7c550ede0186ac99aebb95f31695f76b74a8ad68c34615fa3c0d5ef15ee8c5f58c5e8e90e766a6f4d1d2",
31
+ "sha256": "69f99c64824f782c36b1e44617e59fd5f5ddb13f92d906007918534cc8a29dfe",
32
+ "sha1": "aad7ad5ee2eae34a4143404fa774449f0dc7f6a0",
33
+ "md5": "b3a59c37f58880f20a32caa6a69c8c42"
34
34
  }
35
35
  ]
36
36
  },
@@ -141,13 +141,13 @@
141
141
  ],
142
142
  "files": [
143
143
  {
144
- "name": "expo.modules.ui-57.0.17.aar",
145
- "url": "expo.modules.ui-57.0.17.aar",
146
- "size": 2072906,
147
- "sha512": "10a5b1af451aa49760a4c2ca23f439feeff3ee645cef0ca3af0ef7e487efeb5d26c3ff608ce68568a005f46707a5b774e274b5ca0ffc058429d633e600c9ed1e",
148
- "sha256": "13b9babd2eaa4ed0f4ad6a09f8443eb1a4bca31cc519d29db8371cdabd6487e4",
149
- "sha1": "394fabe7251e3d947f0bbf2037e2bb065b8493d5",
150
- "md5": "87a5f6dc53fef1a3b6810eb8db0ccc6a"
144
+ "name": "expo.modules.ui-57.0.19.aar",
145
+ "url": "expo.modules.ui-57.0.19.aar",
146
+ "size": 2073510,
147
+ "sha512": "d1c36be4bda31ef4d9df2b222c12ab6ee240523984bb7c550ede0186ac99aebb95f31695f76b74a8ad68c34615fa3c0d5ef15ee8c5f58c5e8e90e766a6f4d1d2",
148
+ "sha256": "69f99c64824f782c36b1e44617e59fd5f5ddb13f92d906007918534cc8a29dfe",
149
+ "sha1": "aad7ad5ee2eae34a4143404fa774449f0dc7f6a0",
150
+ "md5": "b3a59c37f58880f20a32caa6a69c8c42"
151
151
  }
152
152
  ]
153
153
  },
@@ -161,13 +161,13 @@
161
161
  },
162
162
  "files": [
163
163
  {
164
- "name": "expo.modules.ui-57.0.17-sources.jar",
165
- "url": "expo.modules.ui-57.0.17-sources.jar",
166
- "size": 105126,
167
- "sha512": "6a46b6260033cfdf2fcb8cb69b966ac7dcca618a6f3e9c011819a76e42f998c2a549b1864bbbbd642b106c01d9ee184eb822019cc58d4b438103ed8d421cbb2d",
168
- "sha256": "a2eb95b5f7bc80a8406159f0cd3cc67058927f3e88d1ce5e0eed1000f47bf6e7",
169
- "sha1": "43ac02b43fa332c84dbd29354a8ffc002828927a",
170
- "md5": "cee93fd5a15e4eaab695ed3175a4949f"
164
+ "name": "expo.modules.ui-57.0.19-sources.jar",
165
+ "url": "expo.modules.ui-57.0.19-sources.jar",
166
+ "size": 105192,
167
+ "sha512": "5cdf850cb3e0dd28112d6a77eead05862cd9d3e5a75b0e1da56a032b872378b05770bc5640f69fc904bd58383e1c4c24933da4702029e6f8dba9f9ab000ef4ac",
168
+ "sha256": "6b32ef025930afd41b632295e3d20bed5d52b29001680721148abc18b7dbf3c8",
169
+ "sha1": "6b806f321f975d6caff272f29bc91464e74acbb2",
170
+ "md5": "10a87f7e5b9322022e3579f88cee7441"
171
171
  }
172
172
  ]
173
173
  }
@@ -0,0 +1 @@
1
+ 3af365b8ed7883f229ea41349e15c062f1ad7a63
@@ -0,0 +1 @@
1
+ 2a5b61f7e12f0d930fc4d9704f068ee06ff80ab5375dad6d624d0912cd6506bc
@@ -0,0 +1 @@
1
+ 174fdfa60779be5d3f06f40ceb2b5cf3f314a9fb30c86b68cd11d17b8ffd42a998995b7509f8b677ad3055437830bef80747a57e3f5c46e24b37779e552bf29e
@@ -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.17</version>
12
+ <version>57.0.19</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
+ 65fbef30690fc0cfaa52e3d42c99d013090b4afd
@@ -0,0 +1 @@
1
+ b1e83cb5f98577ef5af1bcc23b2b95500ab32360b9d0d26735f4da415377f08c
@@ -0,0 +1 @@
1
+ f712b1f0ed7ed5e98076cdc5a01320497ceb7e48189f3de78bff0f2d9614e8d86da72e048e154481b1c9d74a03bbc26a76c2776828509c94731938a7b8728d0b
@@ -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.17</latest>
7
- <release>57.0.17</release>
6
+ <latest>57.0.19</latest>
7
+ <release>57.0.19</release>
8
8
  <versions>
9
- <version>57.0.17</version>
9
+ <version>57.0.19</version>
10
10
  </versions>
11
- <lastUpdated>20260908134223</lastUpdated>
11
+ <lastUpdated>20260918080059</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- dd7d18bde7636ea29ab7549373c2f43a
1
+ 3ed6339c5c2bb9e9eb1fa4452ede025b
@@ -1 +1 @@
1
- d491c408ce08119efc695fac8f3abe210c89b66a
1
+ 6dfefad7e7a03ebb1a00756a4d68745b3aa69ed8
@@ -1 +1 @@
1
- f6eeadee99bcfa2fce76c19ec4942a74b7323cddef420a50177b3ddaf7a0a699
1
+ 6f6d20e77179ec3ab780aea4934eae56a5195426bca6ac9db6c10e22aa5e22ba