@expo/ui 56.0.15 → 56.0.17

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 (130) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +54 -6
  4. package/android/src/main/java/expo/modules/ui/HostView.kt +0 -2
  5. package/android/src/main/java/expo/modules/ui/ModifierRegistry.kt +65 -0
  6. package/android/src/main/java/expo/modules/ui/NavigationBarView.kt +95 -0
  7. package/android/src/main/java/expo/modules/ui/RNHostView.kt +182 -6
  8. package/android/src/main/java/expo/modules/ui/textfield/BasicTextField.kt +203 -0
  9. package/android/src/main/java/expo/modules/ui/{TextFieldView.kt → textfield/TextField.kt} +63 -267
  10. package/android/src/main/java/expo/modules/ui/textfield/TextFieldShared.kt +299 -0
  11. package/build/State/useNativeState.d.ts +8 -3
  12. package/build/State/useNativeState.d.ts.map +1 -1
  13. package/build/community/pager-view/PagerView.android.d.ts.map +1 -1
  14. package/build/jetpack-compose/NavigationBar/index.d.ts +101 -0
  15. package/build/jetpack-compose/NavigationBar/index.d.ts.map +1 -0
  16. package/build/jetpack-compose/TextField/BasicTextField.d.ts +36 -0
  17. package/build/jetpack-compose/TextField/BasicTextField.d.ts.map +1 -0
  18. package/build/jetpack-compose/TextField/TextField.d.ts +131 -0
  19. package/build/jetpack-compose/TextField/TextField.d.ts.map +1 -0
  20. package/build/jetpack-compose/TextField/index.d.ts +3 -244
  21. package/build/jetpack-compose/TextField/index.d.ts.map +1 -1
  22. package/build/jetpack-compose/TextField/shared.d.ts +171 -0
  23. package/build/jetpack-compose/TextField/shared.d.ts.map +1 -0
  24. package/build/jetpack-compose/index.d.ts +2 -1
  25. package/build/jetpack-compose/index.d.ts.map +1 -1
  26. package/build/jetpack-compose/modifiers/index.d.ts +42 -0
  27. package/build/jetpack-compose/modifiers/index.d.ts.map +1 -1
  28. package/build/swift-ui/DisclosureGroup/index.d.ts +11 -2
  29. package/build/swift-ui/DisclosureGroup/index.d.ts.map +1 -1
  30. package/build/swift-ui/Image/index.d.ts +7 -1
  31. package/build/swift-ui/Image/index.d.ts.map +1 -1
  32. package/build/swift-ui/Label/index.d.ts +5 -0
  33. package/build/swift-ui/Label/index.d.ts.map +1 -1
  34. package/build/swift-ui/modifiers/index.d.ts +100 -4
  35. package/build/swift-ui/modifiers/index.d.ts.map +1 -1
  36. package/build/universal/Collapsible/index.android.d.ts +1 -1
  37. package/build/universal/Collapsible/index.android.d.ts.map +1 -1
  38. package/build/universal/Collapsible/index.d.ts +1 -1
  39. package/build/universal/Collapsible/index.d.ts.map +1 -1
  40. package/build/universal/Collapsible/index.ios.d.ts +1 -1
  41. package/build/universal/Collapsible/index.ios.d.ts.map +1 -1
  42. package/build/universal/Collapsible/types.d.ts +5 -0
  43. package/build/universal/Collapsible/types.d.ts.map +1 -1
  44. package/build/universal/TextInput/index.android.d.ts.map +1 -1
  45. package/build/universal/TextInput/types.d.ts +5 -1
  46. package/build/universal/TextInput/types.d.ts.map +1 -1
  47. package/expo-module.config.json +1 -1
  48. package/ios/BottomSheetView.swift +1 -1
  49. package/ios/DisclosureGroupView.swift +36 -13
  50. package/ios/ImageView.swift +20 -14
  51. package/ios/Label.swift +26 -2
  52. package/ios/Modifiers/ButtonBorderShapeModifier.swift +46 -0
  53. package/ios/Modifiers/DynamicTypeSizeModifier.swift +56 -0
  54. package/ios/Modifiers/FontModifier.swift +4 -1
  55. package/ios/Modifiers/ImageScaleModifier.swift +29 -0
  56. package/ios/Modifiers/OnGeometryChangeModifier.swift +8 -16
  57. package/ios/Modifiers/ViewModifierRegistry.swift +89 -8
  58. package/ios/SecureFieldView.swift +17 -1
  59. package/ios/TextFieldView.swift +33 -2
  60. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{56.0.15/expo.modules.ui-56.0.15-sources.jar → 56.0.17/expo.modules.ui-56.0.17-sources.jar} +0 -0
  61. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17-sources.jar.md5 +1 -0
  62. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17-sources.jar.sha1 +1 -0
  63. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17-sources.jar.sha256 +1 -0
  64. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17-sources.jar.sha512 +1 -0
  65. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17.aar +0 -0
  66. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17.aar.md5 +1 -0
  67. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17.aar.sha1 +1 -0
  68. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17.aar.sha256 +1 -0
  69. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17.aar.sha512 +1 -0
  70. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{56.0.15/expo.modules.ui-56.0.15.module → 56.0.17/expo.modules.ui-56.0.17.module} +22 -22
  71. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17.module.md5 +1 -0
  72. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17.module.sha1 +1 -0
  73. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17.module.sha256 +1 -0
  74. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17.module.sha512 +1 -0
  75. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{56.0.15/expo.modules.ui-56.0.15.pom → 56.0.17/expo.modules.ui-56.0.17.pom} +1 -1
  76. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17.pom.md5 +1 -0
  77. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17.pom.sha1 +1 -0
  78. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17.pom.sha256 +1 -0
  79. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.17/expo.modules.ui-56.0.17.pom.sha512 +1 -0
  80. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
  81. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
  82. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
  83. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
  84. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
  85. package/package.json +4 -4
  86. package/src/State/index.fx.ts +4 -1
  87. package/src/State/useNativeState.ts +24 -13
  88. package/src/community/datetime-picker/DateTimePicker.tsx +1 -1
  89. package/src/community/menu/MenuView.ios.tsx +1 -1
  90. package/src/community/pager-view/PagerView.android.tsx +16 -2
  91. package/src/community/pager-view/PagerView.ios.tsx +1 -1
  92. package/src/community/picker/Picker.ios.tsx +1 -1
  93. package/src/community/segmented-control/SegmentedControl.ios.tsx +1 -1
  94. package/src/community/slider/Slider.ios.tsx +1 -1
  95. package/src/jetpack-compose/NavigationBar/index.tsx +174 -0
  96. package/src/jetpack-compose/TextField/BasicTextField.tsx +118 -0
  97. package/src/jetpack-compose/TextField/TextField.tsx +198 -0
  98. package/src/jetpack-compose/TextField/index.ts +19 -0
  99. package/src/jetpack-compose/TextField/{index.tsx → shared.ts} +71 -203
  100. package/src/jetpack-compose/index.ts +7 -0
  101. package/src/jetpack-compose/modifiers/index.ts +49 -0
  102. package/src/swift-ui/BottomSheet/index.tsx +1 -1
  103. package/src/swift-ui/DisclosureGroup/index.tsx +14 -2
  104. package/src/swift-ui/Image/index.tsx +16 -3
  105. package/src/swift-ui/Label/index.tsx +8 -1
  106. package/src/swift-ui/modifiers/index.ts +143 -5
  107. package/src/universal/Collapsible/index.android.tsx +10 -2
  108. package/src/universal/Collapsible/index.ios.tsx +17 -3
  109. package/src/universal/Collapsible/index.tsx +8 -2
  110. package/src/universal/Collapsible/types.ts +7 -0
  111. package/src/universal/TextInput/index.android.tsx +26 -33
  112. package/src/universal/TextInput/types.ts +5 -1
  113. package/android/src/main/java/expo/modules/ui/ShadowNodeSyncFlush.kt +0 -28
  114. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15-sources.jar.md5 +0 -1
  115. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15-sources.jar.sha1 +0 -1
  116. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15-sources.jar.sha256 +0 -1
  117. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15-sources.jar.sha512 +0 -1
  118. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15.aar +0 -0
  119. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15.aar.md5 +0 -1
  120. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15.aar.sha1 +0 -1
  121. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15.aar.sha256 +0 -1
  122. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15.aar.sha512 +0 -1
  123. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15.module.md5 +0 -1
  124. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15.module.sha1 +0 -1
  125. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15.module.sha256 +0 -1
  126. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15.module.sha512 +0 -1
  127. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15.pom.md5 +0 -1
  128. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15.pom.sha1 +0 -1
  129. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15.pom.sha256 +0 -1
  130. package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.15/expo.modules.ui-56.0.15.pom.sha512 +0 -1
@@ -0,0 +1,56 @@
1
+ // Copyright 2015-present 650 Industries. All rights reserved.
2
+
3
+ import ExpoModulesCore
4
+ import SwiftUI
5
+
6
+ internal enum DynamicTypeSizeType: String, Enumerable {
7
+ case xSmall
8
+ case small
9
+ case medium
10
+ case large
11
+ case xLarge
12
+ case xxLarge
13
+ case xxxLarge
14
+ case accessibility1
15
+ case accessibility2
16
+ case accessibility3
17
+ case accessibility4
18
+ case accessibility5
19
+
20
+ func toSwiftUI() -> SwiftUI.DynamicTypeSize {
21
+ switch self {
22
+ case .xSmall: .xSmall
23
+ case .small: .small
24
+ case .medium: .medium
25
+ case .large: .large
26
+ case .xLarge: .xLarge
27
+ case .xxLarge: .xxLarge
28
+ case .xxxLarge: .xxxLarge
29
+ case .accessibility1: .accessibility1
30
+ case .accessibility2: .accessibility2
31
+ case .accessibility3: .accessibility3
32
+ case .accessibility4: .accessibility4
33
+ case .accessibility5: .accessibility5
34
+ }
35
+ }
36
+ }
37
+
38
+ internal struct DynamicTypeSizeModifier: ViewModifier, Record {
39
+ @Field var size: DynamicTypeSizeType?
40
+ @Field var min: DynamicTypeSizeType?
41
+ @Field var max: DynamicTypeSizeType?
42
+
43
+ func body(content: Content) -> some View {
44
+ if let size {
45
+ content.dynamicTypeSize(size.toSwiftUI())
46
+ } else if let min, let max {
47
+ content.dynamicTypeSize(min.toSwiftUI()...max.toSwiftUI())
48
+ } else if let max {
49
+ content.dynamicTypeSize(...max.toSwiftUI())
50
+ } else if let min {
51
+ content.dynamicTypeSize(min.toSwiftUI()...)
52
+ } else {
53
+ content
54
+ }
55
+ }
56
+ }
@@ -86,7 +86,10 @@ internal struct FontModifier: ViewModifier, Record {
86
86
  content.font(resolveFont())
87
87
  }
88
88
 
89
- private func resolveFont() -> Font {
89
+ // Shared so the Text-concatenation path (`applyTextModifier`) resolves the
90
+ // same `Font` as the view path, instead of a fixed-size `Font.custom` that
91
+ // drops `relativeTo` (Dynamic Type) and `weight`.
92
+ func resolveFont() -> Font {
90
93
  if let family = family {
91
94
  let baseSize = size ?? 17
92
95
  var font: Font = if let textStyle = textStyle {
@@ -0,0 +1,29 @@
1
+ // Copyright 2015-present 650 Industries. All rights reserved.
2
+
3
+ import ExpoModulesCore
4
+ import SwiftUI
5
+
6
+ internal enum ImageScaleType: String, Enumerable {
7
+ case small
8
+ case medium
9
+ case large
10
+
11
+ func toNativeImageScale() -> Image.Scale {
12
+ switch self {
13
+ case .small:
14
+ return .small
15
+ case .medium:
16
+ return .medium
17
+ case .large:
18
+ return .large
19
+ }
20
+ }
21
+ }
22
+
23
+ internal struct ImageScaleModifier: ViewModifier, Record {
24
+ @Field var scale: ImageScaleType = .medium
25
+
26
+ func body(content: Content) -> some View {
27
+ content.imageScale(scale.toNativeImageScale())
28
+ }
29
+ }
@@ -13,26 +13,18 @@ internal struct OnGeometryChangeModifier: ViewModifier, Record {
13
13
  self.eventDispatcher = eventDispatcher
14
14
  }
15
15
 
16
- private func dispatch(_ size: CGSize) {
16
+ private func dispatch(_ frame: CGRect) {
17
17
  eventDispatcher?(["onGeometryChange": [
18
- "width": size.width,
19
- "height": size.height
18
+ "x": frame.origin.x,
19
+ "y": frame.origin.y,
20
+ "width": frame.size.width,
21
+ "height": frame.size.height
20
22
  ]])
21
23
  }
22
24
 
23
25
  func body(content: Content) -> some View {
24
- if #available(iOS 16.0, tvOS 16.0, macOS 13.0, *) {
25
- content.onGeometryChange(for: CGSize.self, of: { proxy in proxy.size }, action: {
26
- dispatch($0)
27
- })
28
- } else {
29
- content.background(
30
- GeometryReader { geometry in
31
- Color.clear
32
- .onAppear { dispatch(geometry.size) }
33
- .onChange(of: geometry.size) { dispatch($0) }
34
- }
35
- )
36
- }
26
+ content.onGeometryChange(for: CGRect.self, of: { proxy in proxy.frame(in: .global) }, action: {
27
+ dispatch($0)
28
+ })
37
29
  }
38
30
  }
@@ -486,6 +486,38 @@ internal struct AccessibilityValueModifier: ViewModifier, Record {
486
486
  }
487
487
  }
488
488
 
489
+ internal struct AccessibilityInputLabelsModifier: ViewModifier, Record {
490
+ @Field var inputLabels: [String]?
491
+
492
+ func body(content: Content) -> some View {
493
+ if let inputLabels = inputLabels {
494
+ content.accessibilityInputLabels(inputLabels.map { Text($0) })
495
+ } else {
496
+ content
497
+ }
498
+ }
499
+ }
500
+
501
+ internal struct AccessibilityIdentifierModifier: ViewModifier, Record {
502
+ @Field var identifier: String?
503
+
504
+ func body(content: Content) -> some View {
505
+ if let identifier = identifier {
506
+ content.accessibilityIdentifier(identifier)
507
+ } else {
508
+ content
509
+ }
510
+ }
511
+ }
512
+
513
+ internal struct AccessibilityHiddenModifier: ViewModifier, Record {
514
+ @Field var hidden: Bool = true
515
+
516
+ func body(content: Content) -> some View {
517
+ content.accessibilityHidden(hidden)
518
+ }
519
+ }
520
+
489
521
  internal struct LayoutPriorityModifier: ViewModifier, Record {
490
522
  @Field var priority: Double = 0
491
523
 
@@ -712,6 +744,22 @@ internal struct ListRowSeparator: ViewModifier, Record {
712
744
  }
713
745
  }
714
746
 
747
+ internal struct ListRowSpacing: ViewModifier, Record {
748
+ @Field var spacing: Double?
749
+
750
+ func body(content: Content) -> some View {
751
+ #if os(iOS)
752
+ if #available(iOS 15.0, *) {
753
+ content.listRowSpacing(spacing.map { CGFloat($0) })
754
+ } else {
755
+ content
756
+ }
757
+ #else
758
+ content
759
+ #endif
760
+ }
761
+ }
762
+
715
763
  internal enum TextTruncationModeTypes: String, Enumerable {
716
764
  case head
717
765
  case middle
@@ -757,6 +805,14 @@ internal struct TextAllowsTightening: ViewModifier, Record {
757
805
  }
758
806
  }
759
807
 
808
+ internal struct MinimumScaleFactorModifier: ViewModifier, Record {
809
+ @Field var factor: CGFloat = 1.0
810
+
811
+ func body(content: Content) -> some View {
812
+ content.minimumScaleFactor(factor)
813
+ }
814
+ }
815
+
760
816
  internal enum TextCaseTypes: String, Enumerable {
761
817
  case lowercase
762
818
  case uppercase
@@ -1212,14 +1268,7 @@ public class ViewModifierRegistry {
1212
1268
  return text.monospacedDigit()
1213
1269
  case "font":
1214
1270
  guard let modifier = try? FontModifier(from: params, appContext: appContext) else { return text }
1215
- if let family = modifier.family {
1216
- return text.font(Font.custom(family, size: modifier.size ?? 17))
1217
- }
1218
- return text.font(.system(
1219
- size: modifier.size ?? 17,
1220
- weight: modifier.weight?.toSwiftUI() ?? .regular,
1221
- design: modifier.design?.toSwiftUI() ?? .default
1222
- ))
1271
+ return text.font(modifier.resolveFont())
1223
1272
  case "foregroundColor":
1224
1273
  guard let modifier = try? ForegroundColorModifier(from: params, appContext: appContext),
1225
1274
  let color = modifier.color else { return text }
@@ -1535,6 +1584,18 @@ extension ViewModifierRegistry {
1535
1584
  return try AccessibilityValueModifier(from: params, appContext: appContext)
1536
1585
  }
1537
1586
 
1587
+ register("accessibilityInputLabels") { params, appContext, _ in
1588
+ return try AccessibilityInputLabelsModifier(from: params, appContext: appContext)
1589
+ }
1590
+
1591
+ register("accessibilityIdentifier") { params, appContext, _ in
1592
+ return try AccessibilityIdentifierModifier(from: params, appContext: appContext)
1593
+ }
1594
+
1595
+ register("accessibilityHidden") { params, appContext, _ in
1596
+ return try AccessibilityHiddenModifier(from: params, appContext: appContext)
1597
+ }
1598
+
1538
1599
  register("layoutPriority") { params, appContext, _ in
1539
1600
  return try LayoutPriorityModifier(from: params, appContext: appContext)
1540
1601
  }
@@ -1599,6 +1660,10 @@ extension ViewModifierRegistry {
1599
1660
  return try ButtonStyleModifier(from: params, appContext: appContext)
1600
1661
  }
1601
1662
 
1663
+ register("buttonBorderShape") { params, appContext, _ in
1664
+ return try ButtonBorderShapeModifier(from: params, appContext: appContext)
1665
+ }
1666
+
1602
1667
  register("toggleStyle") { params, appContext, _ in
1603
1668
  return try ToggleStyleModifier(from: params, appContext: appContext)
1604
1669
  }
@@ -1627,6 +1692,10 @@ extension ViewModifierRegistry {
1627
1692
  return try ListRowSeparator(from: params, appContext: appContext)
1628
1693
  }
1629
1694
 
1695
+ register("listRowSpacing") { params, appContext, _ in
1696
+ return try ListRowSpacing(from: params, appContext: appContext)
1697
+ }
1698
+
1630
1699
  register("truncationMode") { params, appContext, _ in
1631
1700
  return try TextTruncationMode(from: params, appContext: appContext)
1632
1701
  }
@@ -1639,6 +1708,10 @@ extension ViewModifierRegistry {
1639
1708
  return try TextAllowsTightening(from: params, appContext: appContext)
1640
1709
  }
1641
1710
 
1711
+ register("minimumScaleFactor") { params, appContext, _ in
1712
+ return try MinimumScaleFactorModifier(from: params, appContext: appContext)
1713
+ }
1714
+
1642
1715
  register("textCase") { params, appContext, _ in
1643
1716
  return try TextCase(from: params, appContext: appContext)
1644
1717
  }
@@ -1703,6 +1776,14 @@ extension ViewModifierRegistry {
1703
1776
  return try FontModifier(from: params, appContext: appContext)
1704
1777
  }
1705
1778
 
1779
+ register("dynamicTypeSize") { params, appContext, _ in
1780
+ return try DynamicTypeSizeModifier(from: params, appContext: appContext)
1781
+ }
1782
+
1783
+ register("imageScale") { params, appContext, _ in
1784
+ return try ImageScaleModifier(from: params, appContext: appContext)
1785
+ }
1786
+
1706
1787
  register("gridCellUnsizedAxes") { params, appContext, _ in
1707
1788
  return try GridCellUnsizedAxes(from: params, appContext: appContext)
1708
1789
  }
@@ -70,8 +70,22 @@ private struct StatefulSecureField: View {
70
70
  @FocusState.Binding var isFocused: Bool
71
71
  let promptText: Text?
72
72
 
73
+ // See `StatefulTextField.userMutatingState` in TextFieldView.swift.
74
+ @State private var userMutatingState = false
75
+
76
+ private var textBinding: Binding<String> {
77
+ Binding(
78
+ get: { (state.value as? String) ?? "" },
79
+ set: { newValue in
80
+ let current = (state.value as? String) ?? ""
81
+ guard newValue != current else { return }
82
+ userMutatingState = true
83
+ state.value = newValue
84
+ }
85
+ )
86
+ }
87
+
73
88
  var body: some View {
74
- let textBinding = state.binding("")
75
89
  SecureField(
76
90
  promptText == nil ? props.placeholder : "",
77
91
  text: textBinding,
@@ -84,10 +98,12 @@ private struct StatefulSecureField: View {
84
98
  }
85
99
  }
86
100
  .onChange(of: state.value as? String) { newValue in
101
+ guard userMutatingState else { return }
87
102
  if let max = props.maxLength, let str = newValue, str.count > max {
88
103
  state.value = String(str.prefix(max))
89
104
  return
90
105
  }
106
+ userMutatingState = false
91
107
  props.onTextChange(["value": newValue])
92
108
  props.onTextChangeSync?.invoke(arguments: [newValue])
93
109
  }
@@ -123,13 +123,27 @@ private struct StatefulTextField: View {
123
123
  @FocusState.Binding var isFocused: Bool
124
124
  let promptText: Text?
125
125
 
126
+ // True only while the current `state.value` change came from the user typing.
127
+ @State private var userMutatingState = false
128
+
126
129
  private var swiftUIAxis: Axis {
127
130
  props.axis == .vertical ? .vertical : .horizontal
128
131
  }
129
132
 
133
+ private var textBinding: Binding<String> {
134
+ Binding(
135
+ get: { (state.value as? String) ?? "" },
136
+ set: { newValue in
137
+ let current = (state.value as? String) ?? ""
138
+ guard newValue != current else { return }
139
+ userMutatingState = true
140
+ state.value = newValue
141
+ }
142
+ )
143
+ }
144
+
130
145
  @ViewBuilder
131
146
  var textField: some View {
132
- let textBinding = state.binding("")
133
147
  if #available(iOS 16.0, tvOS 16.0, *) {
134
148
  TextField(
135
149
  promptText == nil ? props.placeholder : "",
@@ -156,10 +170,12 @@ private struct StatefulTextField: View {
156
170
  }
157
171
  }
158
172
  .onChange(of: state.value as? String) { newValue in
173
+ guard userMutatingState else { return }
159
174
  if let max = props.maxLength, let str = newValue, str.count > max {
160
175
  state.value = String(str.prefix(max))
161
176
  return
162
177
  }
178
+ userMutatingState = false
163
179
  props.onTextChange(["value": newValue])
164
180
  props.onTextChangeSync?.invoke(arguments: [newValue])
165
181
  }
@@ -184,13 +200,26 @@ private struct StatefulSelectableTextField: View {
184
200
  let promptText: Text?
185
201
 
186
202
  @State private var localSelection: SwiftUI.TextSelection?
203
+ // See `StatefulTextField.userMutatingState`.
204
+ @State private var userMutatingState = false
187
205
 
188
206
  private var swiftUIAxis: Axis {
189
207
  props.axis == .vertical ? .vertical : .horizontal
190
208
  }
191
209
 
210
+ private var textBinding: Binding<String> {
211
+ Binding(
212
+ get: { (state.value as? String) ?? "" },
213
+ set: { newValue in
214
+ let current = (state.value as? String) ?? ""
215
+ guard newValue != current else { return }
216
+ userMutatingState = true
217
+ state.value = newValue
218
+ }
219
+ )
220
+ }
221
+
192
222
  var body: some View {
193
- let textBinding = state.binding("")
194
223
  TextField(
195
224
  promptText == nil ? props.placeholder : "",
196
225
  text: textBinding,
@@ -221,10 +250,12 @@ private struct StatefulSelectableTextField: View {
221
250
  props.onSelectionChange(["start": start, "end": end])
222
251
  }
223
252
  .onChange(of: state.value as? String) { newValue in
253
+ guard userMutatingState else { return }
224
254
  if let max = props.maxLength, let str = newValue, str.count > max {
225
255
  state.value = String(str.prefix(max))
226
256
  return
227
257
  }
258
+ userMutatingState = false
228
259
  props.onTextChange(["value": newValue])
229
260
  props.onTextChangeSync?.invoke(arguments: [newValue])
230
261
  }
@@ -0,0 +1 @@
1
+ bac457301e76c3dfc74a046e5d5ed7267765368e432b1762051897bcabf7cac9
@@ -0,0 +1 @@
1
+ e557d79f5242ede237b371d5f85b1567ee12961dc1f2ba434d60649842996d377086ae27ae59a4a8f131b37d536ba3d5ddf1a6d29cadd2fb0ff6ed642ce4efc5
@@ -0,0 +1 @@
1
+ 33aac01ba03ba8dca900252f3fc70770c4e03c6c
@@ -0,0 +1 @@
1
+ 866c8d63f5a18f663ce603eb908d3cdf16fb0f8dd0edfe799214cfe7f8261f0a
@@ -0,0 +1 @@
1
+ a9a4256d94715e7932f328ad004a5df0d5016275805c751a50eb9ceb370a2a522a81c9996cf0f95a10fd22e9d1eb5ddeab3a6a7f0e1e75a8ac17c3c3e7fc5d43
@@ -3,7 +3,7 @@
3
3
  "component": {
4
4
  "group": "expo.modules.ui",
5
5
  "module": "expo.modules.ui",
6
- "version": "56.0.15",
6
+ "version": "56.0.17",
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-56.0.15.aar",
28
- "url": "expo.modules.ui-56.0.15.aar",
29
- "size": 1839545,
30
- "sha512": "b0183591c16d8ba78c2d0e6aad2044b660811a5fb2126302a5f746dff169fc93fd4547d4c73ccf35bfefa083fde9819acbf3bb0fa4f6c80869e0d225880047a2",
31
- "sha256": "27c02acb624ed6593fe2380e495a636970bc9033ae9cd00132029c7b8ecf899e",
32
- "sha1": "7100e52679119435cf14936c7a715d729b763e16",
33
- "md5": "790df1c5a23dc1ac9a8521284af9bc15"
27
+ "name": "expo.modules.ui-56.0.17.aar",
28
+ "url": "expo.modules.ui-56.0.17.aar",
29
+ "size": 1941021,
30
+ "sha512": "a9a4256d94715e7932f328ad004a5df0d5016275805c751a50eb9ceb370a2a522a81c9996cf0f95a10fd22e9d1eb5ddeab3a6a7f0e1e75a8ac17c3c3e7fc5d43",
31
+ "sha256": "866c8d63f5a18f663ce603eb908d3cdf16fb0f8dd0edfe799214cfe7f8261f0a",
32
+ "sha1": "33aac01ba03ba8dca900252f3fc70770c4e03c6c",
33
+ "md5": "81713f2bd9b92dc37c26efb771e35ed8"
34
34
  }
35
35
  ]
36
36
  },
@@ -141,13 +141,13 @@
141
141
  ],
142
142
  "files": [
143
143
  {
144
- "name": "expo.modules.ui-56.0.15.aar",
145
- "url": "expo.modules.ui-56.0.15.aar",
146
- "size": 1839545,
147
- "sha512": "b0183591c16d8ba78c2d0e6aad2044b660811a5fb2126302a5f746dff169fc93fd4547d4c73ccf35bfefa083fde9819acbf3bb0fa4f6c80869e0d225880047a2",
148
- "sha256": "27c02acb624ed6593fe2380e495a636970bc9033ae9cd00132029c7b8ecf899e",
149
- "sha1": "7100e52679119435cf14936c7a715d729b763e16",
150
- "md5": "790df1c5a23dc1ac9a8521284af9bc15"
144
+ "name": "expo.modules.ui-56.0.17.aar",
145
+ "url": "expo.modules.ui-56.0.17.aar",
146
+ "size": 1941021,
147
+ "sha512": "a9a4256d94715e7932f328ad004a5df0d5016275805c751a50eb9ceb370a2a522a81c9996cf0f95a10fd22e9d1eb5ddeab3a6a7f0e1e75a8ac17c3c3e7fc5d43",
148
+ "sha256": "866c8d63f5a18f663ce603eb908d3cdf16fb0f8dd0edfe799214cfe7f8261f0a",
149
+ "sha1": "33aac01ba03ba8dca900252f3fc70770c4e03c6c",
150
+ "md5": "81713f2bd9b92dc37c26efb771e35ed8"
151
151
  }
152
152
  ]
153
153
  },
@@ -161,13 +161,13 @@
161
161
  },
162
162
  "files": [
163
163
  {
164
- "name": "expo.modules.ui-56.0.15-sources.jar",
165
- "url": "expo.modules.ui-56.0.15-sources.jar",
166
- "size": 87333,
167
- "sha512": "ba1daa456b3e0d92466af0c58b5ddd0bdd0a4c5f06c727bf7d34acd69e78c42187295b575199cefa3b2098d59eeb1ab6fcf2463c339fd6af2a186224a14f505d",
168
- "sha256": "01e5734d4e704ab1ff81ad1651eae63e0c5317dbba712328b1721270d303e0cf",
169
- "sha1": "cef9c4c1296a5c70d6a61965cba485c2dd802f47",
170
- "md5": "2cf329d52090d6202b7a70c1cb7c2a4b"
164
+ "name": "expo.modules.ui-56.0.17-sources.jar",
165
+ "url": "expo.modules.ui-56.0.17-sources.jar",
166
+ "size": 93760,
167
+ "sha512": "e557d79f5242ede237b371d5f85b1567ee12961dc1f2ba434d60649842996d377086ae27ae59a4a8f131b37d536ba3d5ddf1a6d29cadd2fb0ff6ed642ce4efc5",
168
+ "sha256": "bac457301e76c3dfc74a046e5d5ed7267765368e432b1762051897bcabf7cac9",
169
+ "sha1": "e82e406da75f0fa928868fcc7544e62b40878a6b",
170
+ "md5": "f2d5194e36c18df1298150a82ed8f885"
171
171
  }
172
172
  ]
173
173
  }
@@ -0,0 +1 @@
1
+ a96aa2d3f82455b3cd1195750e69322297f59cc2
@@ -0,0 +1 @@
1
+ 984b14af41cf6c8453c2c30f8d0198633d3a5c554380a04b919c93525d567483
@@ -0,0 +1 @@
1
+ 705123ec935a2660e4bc8e213b277405a6ebcf62c036516bcf8872df4d664b1f2fae2ed5460211f33a02af572e330a8b19a2918be92444f2a788aea50da3d989
@@ -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>56.0.15</version>
12
+ <version>56.0.17</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
+ a93ea47f7fa573055fe5b2f59334cc98f96e8ec9
@@ -0,0 +1 @@
1
+ d61c5b4603103c407b0148f4385fef3257eb3d359ec1b60b36eea1ba1e7d2c3c
@@ -0,0 +1 @@
1
+ 1023aa15d84af57f96c468156c994d6c18926d43144beb43c9e3d1c6286b9e3b4dbefb8ede3e336842d27927ad095b2f664e10507e7d4c6f13ed71bc6a566794
@@ -3,11 +3,11 @@
3
3
  <groupId>expo.modules.ui</groupId>
4
4
  <artifactId>expo.modules.ui</artifactId>
5
5
  <versioning>
6
- <latest>56.0.15</latest>
7
- <release>56.0.15</release>
6
+ <latest>56.0.17</latest>
7
+ <release>56.0.17</release>
8
8
  <versions>
9
- <version>56.0.15</version>
9
+ <version>56.0.17</version>
10
10
  </versions>
11
- <lastUpdated>20260529100208</lastUpdated>
11
+ <lastUpdated>20260610225255</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- b63599942a3f767839b2ab4661aa9f0b
1
+ 60c5694e01fc3b8dcd52745fd34646eb
@@ -1 +1 @@
1
- 5ed1689c481832ae81351f3296fa74efa0ad8104
1
+ 86afe3595463910ac648dbece60ea85603f093da
@@ -1 +1 @@
1
- 38ac5032a6f49787dcf8f493b77d9546a7d81a06288bac319a98bad6f79ec877
1
+ e33fc63e4f06dfa13f99ce5b5ceafeaf1d4045473ecbbe42799c66be3c5a1bc7
@@ -1 +1 @@
1
- 7138619d0626a7b454da7b4ffed89dcdc169737955a85beae665e23c404dae52117ae7f1857bdc186018c782c44da47e73912e80e635f2edf60a40cef085a5a9
1
+ 8a94e8065a8cf5abcbc83a6d2ce2d927133a4670a8313b921b7369f6793cede644c762fefc3807c9bc2d7bfdf15aeccc183cb4c9b383094576455cbe6d8e0fa6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/ui",
3
- "version": "56.0.15",
3
+ "version": "56.0.17",
4
4
  "description": "A collection of UI components",
5
5
  "sideEffects": [
6
6
  "*.fx.js"
@@ -95,8 +95,8 @@
95
95
  "@types/react": "~19.2.0",
96
96
  "react-native-reanimated": "4.3.1",
97
97
  "react-native-worklets": "0.8.3",
98
- "expo": "56.0.7",
99
- "expo-module-scripts": "56.0.2"
98
+ "expo": "56.0.10",
99
+ "expo-module-scripts": "56.0.3"
100
100
  },
101
101
  "jest": {
102
102
  "preset": "expo-module-scripts"
@@ -124,7 +124,7 @@
124
124
  "optional": true
125
125
  }
126
126
  },
127
- "gitHead": "a7adc95c1747db1e92655feba56d0e62660098db",
127
+ "gitHead": "b1e94a5c1c5b19472a42ca25752a3533699bc46a",
128
128
  "scripts": {
129
129
  "build": "expo-module build",
130
130
  "clean": "expo-module clean",
@@ -41,7 +41,8 @@ function registerSharedObjectSerializer(): void {
41
41
  unpack: (packed) => {
42
42
  'worklet';
43
43
  const obj = (globalThis as any).expo.SharedObject.__resolveInWorklet(packed.objectId);
44
- // Define .value property if the object has getValue/setValue (e.g. ObservableState)
44
+ // Define .value plus the get/set accessors if the object has
45
+ // getValue/setValue (e.g. ObservableState)
45
46
  if (typeof obj.getValue === 'function' && typeof obj.setValue === 'function') {
46
47
  Object.defineProperty(obj, 'value', {
47
48
  get() {
@@ -51,6 +52,8 @@ function registerSharedObjectSerializer(): void {
51
52
  obj.setValue({ value: v });
52
53
  },
53
54
  });
55
+ obj.get = () => obj.getValue();
56
+ obj.set = (v: any) => obj.setValue({ value: v });
54
57
  }
55
58
  return obj;
56
59
  },