@expo/ui 57.0.11 → 57.0.13

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 (93) hide show
  1. package/CHANGELOG.md +28 -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/ModalBottomSheetView.kt +50 -0
  5. package/android/src/main/java/expo/modules/ui/graphics/DrawablePainter.kt +43 -0
  6. package/android/src/main/java/expo/modules/ui/{icon/VectorIconLoader.kt → graphics/ImageLoader.kt} +122 -87
  7. package/android/src/main/java/expo/modules/ui/graphics/ImageSource.kt +28 -0
  8. package/android/src/main/java/expo/modules/ui/{icon → graphics}/ResourceIdHelper.kt +1 -1
  9. package/android/src/main/java/expo/modules/ui/icon/IconView.kt +7 -78
  10. package/android/src/main/java/expo/modules/ui/image/ImageView.kt +136 -0
  11. package/build/jetpack-compose/Image/index.d.ts +107 -0
  12. package/build/jetpack-compose/Image/index.d.ts.map +1 -0
  13. package/build/jetpack-compose/index.d.ts +1 -0
  14. package/build/jetpack-compose/index.d.ts.map +1 -1
  15. package/build/swift-ui/Alert/index.d.ts.map +1 -1
  16. package/build/swift-ui/ConfirmationDialog/index.d.ts.map +1 -1
  17. package/build/swift-ui/Overlay/index.d.ts.map +1 -1
  18. package/build/swift-ui/Popover/index.d.ts.map +1 -1
  19. package/build/swift-ui/Slider/index.d.ts.map +1 -1
  20. package/build/swift-ui/modifiers/index.d.ts +37 -9
  21. package/build/swift-ui/modifiers/index.d.ts.map +1 -1
  22. package/build/universal/BottomSheet/index.android.d.ts +1 -1
  23. package/build/universal/BottomSheet/index.android.d.ts.map +1 -1
  24. package/build/universal/BottomSheet/index.d.ts +1 -1
  25. package/build/universal/BottomSheet/index.d.ts.map +1 -1
  26. package/build/universal/BottomSheet/index.ios.d.ts +1 -1
  27. package/build/universal/BottomSheet/index.ios.d.ts.map +1 -1
  28. package/build/universal/BottomSheet/types.d.ts +42 -0
  29. package/build/universal/BottomSheet/types.d.ts.map +1 -1
  30. package/build/universal/BottomSheet/utils.d.ts +13 -0
  31. package/build/universal/BottomSheet/utils.d.ts.map +1 -0
  32. package/expo-module.config.json +1 -1
  33. package/ios/Convertibles/PaddingValue.swift +57 -0
  34. package/ios/Modifiers/ViewModifierRegistry.swift +110 -18
  35. package/ios/RNHostView.swift +5 -0
  36. package/ios/SliderView.swift +11 -5
  37. package/ios/Toggle/ToggleView.swift +16 -18
  38. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.11/expo.modules.ui-57.0.11-sources.jar → 57.0.13/expo.modules.ui-57.0.13-sources.jar} +0 -0
  39. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13-sources.jar.md5 +1 -0
  40. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13-sources.jar.sha1 +1 -0
  41. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13-sources.jar.sha256 +1 -0
  42. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13-sources.jar.sha512 +1 -0
  43. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13.aar +0 -0
  44. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13.aar.md5 +1 -0
  45. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13.aar.sha1 +1 -0
  46. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13.aar.sha256 +1 -0
  47. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13.aar.sha512 +1 -0
  48. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.11/expo.modules.ui-57.0.11.module → 57.0.13/expo.modules.ui-57.0.13.module} +22 -22
  49. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13.module.md5 +1 -0
  50. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13.module.sha1 +1 -0
  51. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13.module.sha256 +1 -0
  52. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13.module.sha512 +1 -0
  53. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.11/expo.modules.ui-57.0.11.pom → 57.0.13/expo.modules.ui-57.0.13.pom} +1 -1
  54. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13.pom.md5 +1 -0
  55. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13.pom.sha1 +1 -0
  56. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13.pom.sha256 +1 -0
  57. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.13/expo.modules.ui-57.0.13.pom.sha512 +1 -0
  58. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
  59. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
  60. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
  61. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
  62. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
  63. package/package.json +3 -3
  64. package/src/jetpack-compose/Image/index.tsx +149 -0
  65. package/src/jetpack-compose/index.ts +1 -0
  66. package/src/swift-ui/Alert/index.tsx +1 -0
  67. package/src/swift-ui/ConfirmationDialog/index.tsx +1 -0
  68. package/src/swift-ui/Overlay/index.tsx +1 -0
  69. package/src/swift-ui/Popover/index.tsx +1 -0
  70. package/src/swift-ui/Slider/index.tsx +14 -8
  71. package/src/swift-ui/modifiers/index.ts +41 -8
  72. package/src/universal/BottomSheet/index.android.tsx +16 -2
  73. package/src/universal/BottomSheet/index.ios.tsx +9 -1
  74. package/src/universal/BottomSheet/index.tsx +17 -2
  75. package/src/universal/BottomSheet/types.ts +50 -0
  76. package/src/universal/BottomSheet/utils.ts +35 -0
  77. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11-sources.jar.md5 +0 -1
  78. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11-sources.jar.sha1 +0 -1
  79. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11-sources.jar.sha256 +0 -1
  80. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11-sources.jar.sha512 +0 -1
  81. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.aar +0 -0
  82. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.aar.md5 +0 -1
  83. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.aar.sha1 +0 -1
  84. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.aar.sha256 +0 -1
  85. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.aar.sha512 +0 -1
  86. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.module.md5 +0 -1
  87. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.module.sha1 +0 -1
  88. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.module.sha256 +0 -1
  89. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.module.sha512 +0 -1
  90. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.pom.md5 +0 -1
  91. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.pom.sha1 +0 -1
  92. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.pom.sha256 +0 -1
  93. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.11/expo.modules.ui-57.0.11.pom.sha512 +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.android.d.ts","sourceRoot":"","sources":["../../../src/universal/BottomSheet/index.android.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,SAAS,CAAC;AAuB3D,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,WAAW,EACX,SAAS,EACT,iBAAwB,EACxB,UAAU,EACV,MAAM,EACN,SAAS,GACV,EAAE,gBAAgB,kDAuClB;AAED,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.android.d.ts","sourceRoot":"","sources":["../../../src/universal/BottomSheet/index.android.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,SAAS,CAAC;AAwB3D,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,WAAW,EACX,SAAS,EACT,iBAAwB,EACxB,UAAU,EACV,MAAM,EACN,SAAS,EACT,wBAA+B,EAC/B,2BAAkC,EAClC,UAAU,EACV,cAAc,GACf,EAAE,gBAAgB,kDAgDlB;AAED,cAAc,SAAS,CAAC"}
@@ -2,6 +2,6 @@ import type { BottomSheetProps } from './types';
2
2
  /**
3
3
  * A modal sheet that slides up from the bottom of the screen.
4
4
  */
5
- export declare function BottomSheet({ children, isPresented, onDismiss, showDragIndicator, snapPoints, testID, }: BottomSheetProps): import("react/jsx-runtime").JSX.Element;
5
+ export declare function BottomSheet({ children, isPresented, onDismiss, showDragIndicator, snapPoints, testID, contentPadding, }: BottomSheetProps): import("react/jsx-runtime").JSX.Element;
6
6
  export * from './types';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/universal/BottomSheet/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,SAAS,CAAC;AAsB3D;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,WAAW,EACX,SAAS,EACT,iBAAwB,EACxB,UAAU,EACV,MAAM,GACP,EAAE,gBAAgB,2CAkClB;AAwCD,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/universal/BottomSheet/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,SAAS,CAAC;AAuB3D;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,WAAW,EACX,SAAS,EACT,iBAAwB,EACxB,UAAU,EACV,MAAM,EACN,cAAc,GACf,EAAE,gBAAgB,2CAgDlB;AAuCD,cAAc,SAAS,CAAC"}
@@ -1,4 +1,4 @@
1
1
  import type { BottomSheetProps } from './types';
2
- export declare function BottomSheet({ children, isPresented, onDismiss, showDragIndicator, snapPoints, testID, modifiers, }: BottomSheetProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function BottomSheet({ children, isPresented, onDismiss, showDragIndicator, snapPoints, testID, modifiers, contentPadding, }: BottomSheetProps): import("react/jsx-runtime").JSX.Element;
3
3
  export * from './types';
4
4
  //# sourceMappingURL=index.ios.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.ios.d.ts","sourceRoot":"","sources":["../../../src/universal/BottomSheet/index.ios.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,SAAS,CAAC;AAQ3D,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,WAAW,EACX,SAAS,EACT,iBAAwB,EACxB,UAAU,EACV,MAAM,EACN,SAAS,GACV,EAAE,gBAAgB,2CA0BlB;AAED,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.ios.d.ts","sourceRoot":"","sources":["../../../src/universal/BottomSheet/index.ios.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,SAAS,CAAC;AAS3D,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,WAAW,EACX,SAAS,EACT,iBAAwB,EACxB,UAAU,EACV,MAAM,EACN,SAAS,EACT,cAAc,GACf,EAAE,gBAAgB,2CAgClB;AAED,cAAc,SAAS,CAAC"}
@@ -1,3 +1,4 @@
1
+ import type { ColorValue } from 'react-native';
1
2
  import type { ModifierConfig } from '../../types';
2
3
  /**
3
4
  * A snap point describing one of the heights a [`BottomSheet`](#bottomsheet) can rest at.
@@ -17,6 +18,16 @@ export type SnapPoint = 'half' | 'full' | {
17
18
  } | {
18
19
  height: number;
19
20
  };
21
+ /**
22
+ * Padding between a [`BottomSheet`](#bottomsheet) and its content — a single value applied to every
23
+ * edge, or per-edge values where an edge that is left out is `0`.
24
+ */
25
+ export type BottomSheetContentPadding = number | {
26
+ top?: number;
27
+ bottom?: number;
28
+ left?: number;
29
+ right?: number;
30
+ };
20
31
  /**
21
32
  * Props for the [`BottomSheet`](#bottomsheet) component, a modal sheet that slides up from the bottom of the screen.
22
33
  */
@@ -47,10 +58,41 @@ export interface BottomSheetProps {
47
58
  * @example `['full']` — always full height
48
59
  */
49
60
  snapPoints?: SnapPoint[];
61
+ /**
62
+ * Padding between the sheet and [`children`](#children), in dp on Android, points on iOS, and
63
+ * CSS pixels on web. Pass `0` for content that reaches the sheet's edges.
64
+ *
65
+ * When omitted, each platform keeps the inset it applies by default.
66
+ *
67
+ * @example `contentPadding={0}` — full-bleed content
68
+ * @example `contentPadding={{ top: 8, bottom: 24 }}` — no horizontal inset
69
+ */
70
+ contentPadding?: BottomSheetContentPadding;
50
71
  /**
51
72
  * Identifier used to locate the component in end-to-end tests.
52
73
  */
53
74
  testID?: string;
75
+ /**
76
+ * Whether pressing the Android hardware back button (or back gesture) dismisses the bottom sheet.
77
+ * When `false`, the back press does not dismiss the sheet (note: the press still does not reach
78
+ * React Native's `BackHandler`).
79
+ * @default true
80
+ * @platform android
81
+ */
82
+ shouldDismissOnBackPress?: boolean;
83
+ /**
84
+ * Whether tapping the backdrop (scrim) dismisses the bottom sheet.
85
+ * When `false`, the sheet stays open until the user explicitly closes it (e.g. via a button).
86
+ * @default true
87
+ * @platform android
88
+ */
89
+ shouldDismissOnClickOutside?: boolean;
90
+ /**
91
+ * The color of the scrim overlay rendered behind the bottom sheet.
92
+ * Pass `'transparent'` to make the backdrop invisible while still blocking touches.
93
+ * @platform android
94
+ */
95
+ scrimColor?: ColorValue;
54
96
  /**
55
97
  * Platform-specific modifier escape hatch. Pass an array of modifier configs
56
98
  * from `@expo/ui/swift-ui/modifiers` or `@expo/ui/jetpack-compose/modifiers`.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/universal/BottomSheet/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpF;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE3B;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,SAAS,EAAE,MAAM,IAAI,CAAC;IAEtB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IAEzB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;CAC9B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/universal/BottomSheet/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpF;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GACjC,MAAM,GACN;IACE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEN;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE3B;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,SAAS,EAAE,MAAM,IAAI,CAAC;IAEtB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IAEzB;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,yBAAyB,CAAC;IAE3C;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;;OAMG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAEnC;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC;;;;OAIG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IAExB;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;CAC9B"}
@@ -0,0 +1,13 @@
1
+ import type { BottomSheetContentPadding } from './types';
2
+ export type ResolvedContentPadding = {
3
+ top: number;
4
+ bottom: number;
5
+ left: number;
6
+ right: number;
7
+ };
8
+ /**
9
+ * Resolves the `contentPadding` prop against the inset the platform applies when the prop is
10
+ * omitted. A number applies to every edge, and an edge left out of an object is `0`.
11
+ */
12
+ export declare function resolveContentPadding(contentPadding: BottomSheetContentPadding | undefined, platformDefault: ResolvedContentPadding): ResolvedContentPadding;
13
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/universal/BottomSheet/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AAEzD,MAAM,MAAM,sBAAsB,GAAG;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,cAAc,EAAE,yBAAyB,GAAG,SAAS,EACrD,eAAe,EAAE,sBAAsB,GACtC,sBAAsB,CAkBxB"}
@@ -10,7 +10,7 @@
10
10
  "publication": {
11
11
  "groupId": "expo.modules.ui",
12
12
  "artifactId": "expo.modules.ui",
13
- "version": "57.0.11",
13
+ "version": "57.0.13",
14
14
  "repository": "local-maven-repo"
15
15
  }
16
16
  }
@@ -0,0 +1,57 @@
1
+ // Copyright 2015-present 650 Industries. All rights reserved.
2
+
3
+ import ExpoModulesCore
4
+ import SwiftUI
5
+
6
+ /**
7
+ The amount of padding applied to a single edge. The system default padding has no fixed length —
8
+ SwiftUI resolves it at layout time — so it is kept as a separate case instead of a number.
9
+ */
10
+ internal enum PaddingValue: Convertible {
11
+ case `default`
12
+ case points(CGFloat)
13
+
14
+ private static let defaultKeyword = "default"
15
+
16
+ static func convert(from value: Any?, appContext: AppContext) throws -> PaddingValue {
17
+ if let value = value as? String {
18
+ guard value == defaultKeyword else {
19
+ throw InvalidPaddingValueException(value)
20
+ }
21
+ return .default
22
+ }
23
+
24
+ if let value = value as? Double {
25
+ return .points(CGFloat(value))
26
+ }
27
+
28
+ if let value = value as? Int {
29
+ return .points(CGFloat(value))
30
+ }
31
+ throw InvalidPaddingValueException(String(describing: value))
32
+ }
33
+
34
+ /**
35
+ The explicit length in points, or `nil` when the edge uses the system default padding.
36
+ */
37
+ var length: CGFloat? {
38
+ if case .points(let length) = self {
39
+ return length
40
+ }
41
+ return nil
42
+ }
43
+
44
+ var isDefault: Bool {
45
+ if case .default = self {
46
+ return true
47
+ }
48
+ return false
49
+ }
50
+ }
51
+
52
+ internal final class InvalidPaddingValueException: GenericException<String>, @unchecked Sendable {
53
+ override var reason: String {
54
+ "Padding edge value '\(param)' is neither a length nor a keyword, so the padding modifier cannot be applied. "
55
+ + "Pass a number of points, such as padding({ top: 16 }), or 'default' to use the system default padding for that edge."
56
+ }
57
+ }
@@ -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
  }
@@ -990,6 +1034,50 @@ internal struct ListRowSpacing: ViewModifier, Record {
990
1034
  }
991
1035
  }
992
1036
 
1037
+ internal enum AlignmentGuideOptions: String, Enumerable {
1038
+ case leading
1039
+ case center
1040
+ case trailing
1041
+ case listRowSeparatorLeading
1042
+ case listRowSeparatorTrailing
1043
+
1044
+ var horizontalAlignment: HorizontalAlignment? {
1045
+ switch self {
1046
+ case .leading:
1047
+ return .leading
1048
+ case .center:
1049
+ return .center
1050
+ case .trailing:
1051
+ return .trailing
1052
+ case .listRowSeparatorLeading:
1053
+ #if os(tvOS)
1054
+ return nil
1055
+ #else
1056
+ return .listRowSeparatorLeading
1057
+ #endif
1058
+ case .listRowSeparatorTrailing:
1059
+ #if os(tvOS)
1060
+ return nil
1061
+ #else
1062
+ return .listRowSeparatorTrailing
1063
+ #endif
1064
+ }
1065
+ }
1066
+ }
1067
+
1068
+ internal struct AlignmentGuideModifier: ViewModifier, Record {
1069
+ @Field var guide: AlignmentGuideOptions = .leading
1070
+ @Field var value: Double = 0
1071
+
1072
+ func body(content: Content) -> some View {
1073
+ if let alignment = guide.horizontalAlignment {
1074
+ content.alignmentGuide(alignment) { _ in CGFloat(value) }
1075
+ } else {
1076
+ content
1077
+ }
1078
+ }
1079
+ }
1080
+
993
1081
  internal enum TextTruncationModeTypes: String, Enumerable {
994
1082
  case head
995
1083
  case middle
@@ -1998,6 +2086,10 @@ extension ViewModifierRegistry {
1998
2086
  return try ListRowSpacing(from: params, appContext: appContext)
1999
2087
  }
2000
2088
 
2089
+ register("alignmentGuide") { params, appContext, _ in
2090
+ return try AlignmentGuideModifier(from: params, appContext: appContext)
2091
+ }
2092
+
2001
2093
  register("truncationMode") { params, appContext, _ in
2002
2094
  return try TextTruncationMode(from: params, appContext: appContext)
2003
2095
  }
@@ -30,6 +30,11 @@ struct RNHostView: ExpoSwiftUI.View {
30
30
  // natural size instead of falling into the fill branch below, which would
31
31
  // stretch a self-sizing SwiftUI view to fill its container.
32
32
  Children()
33
+ } else if props.children?.isEmpty ?? true {
34
+ // Nothing is mounted yet (e.g. a hosted RN `Modal` renders null until `visible` is true).
35
+ // Render nothing instead of an empty fill frame, which would take up space in the
36
+ // surrounding SwiftUI container - e.g. a spurious empty row in a `Form`'s `Section`.
37
+ EmptyView()
33
38
  } else {
34
39
  Children()
35
40
  .frame(maxWidth: .infinity, maxHeight: .infinity)
@@ -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
+ 202b4f6d1b483d93f4a457a0c2823fb597e90e2ceb05a355e35bbd2a0f847097
@@ -0,0 +1 @@
1
+ e5168296d77aefce39432efe6ebece0da6c78ee8dfcde914ae0166912b335b277f482bd0a347c52fc02d95a4f1bab27c004d0fd46b5aa90c3e047b036b2b316f
@@ -0,0 +1 @@
1
+ bd3b99b6985648ac5a8b5250422386cb9777482e
@@ -0,0 +1 @@
1
+ 8ba276c06e3fda532a8966a0adc15f3c5e32067ffea21c69b9bf91c449cef93a
@@ -0,0 +1 @@
1
+ faa66634546960f551adaa7cda25a99fc7cff82c44a44f9ff7e6e272d562fa26bea6d54c54f0135e50c7cfab38cf0eee9496ab9ddb8f2c704a9a11a690568817
@@ -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.13",
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.13.aar",
28
+ "url": "expo.modules.ui-57.0.13.aar",
29
+ "size": 1992502,
30
+ "sha512": "faa66634546960f551adaa7cda25a99fc7cff82c44a44f9ff7e6e272d562fa26bea6d54c54f0135e50c7cfab38cf0eee9496ab9ddb8f2c704a9a11a690568817",
31
+ "sha256": "8ba276c06e3fda532a8966a0adc15f3c5e32067ffea21c69b9bf91c449cef93a",
32
+ "sha1": "bd3b99b6985648ac5a8b5250422386cb9777482e",
33
+ "md5": "64fd0f1ca916ebe5cb6d23da5899df6c"
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.13.aar",
145
+ "url": "expo.modules.ui-57.0.13.aar",
146
+ "size": 1992502,
147
+ "sha512": "faa66634546960f551adaa7cda25a99fc7cff82c44a44f9ff7e6e272d562fa26bea6d54c54f0135e50c7cfab38cf0eee9496ab9ddb8f2c704a9a11a690568817",
148
+ "sha256": "8ba276c06e3fda532a8966a0adc15f3c5e32067ffea21c69b9bf91c449cef93a",
149
+ "sha1": "bd3b99b6985648ac5a8b5250422386cb9777482e",
150
+ "md5": "64fd0f1ca916ebe5cb6d23da5899df6c"
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.13-sources.jar",
165
+ "url": "expo.modules.ui-57.0.13-sources.jar",
166
+ "size": 99038,
167
+ "sha512": "e5168296d77aefce39432efe6ebece0da6c78ee8dfcde914ae0166912b335b277f482bd0a347c52fc02d95a4f1bab27c004d0fd46b5aa90c3e047b036b2b316f",
168
+ "sha256": "202b4f6d1b483d93f4a457a0c2823fb597e90e2ceb05a355e35bbd2a0f847097",
169
+ "sha1": "477d48b6fb609e6e83752cf761439f3432207248",
170
+ "md5": "28e3a694241e4bc5167c6a9ff2470b87"
171
171
  }
172
172
  ]
173
173
  }
@@ -0,0 +1 @@
1
+ 2ca889048dabe7adaf8e995c1b6ee7cb264db4af
@@ -0,0 +1 @@
1
+ 53956f3eaea9d27b0d6ba5966fe3bd89e250c09c3f3bf784b0d53d4c2c89e66d
@@ -0,0 +1 @@
1
+ fb51c628e57517d5458762c91701328fafd546397314e4b8236495dc9b8743b214cc6d46f050456e191b679eb6f21d04d28572857e3a390afa7a4b8a2c07fe3d
@@ -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.13</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
+ d9ebd441c6cd433c6510bf06e5178731f611bdd7
@@ -0,0 +1 @@
1
+ 06ccdd8caa1ed60c7f57d7e76019d10f19ff59a0e63843d4ee2341c366ba3789
@@ -0,0 +1 @@
1
+ 74ece0b7565cf001deeeac9eaa0dd2d23aae23e5c9822574e61242c21978a11e0ce7e9d9ddb4a13f2353d071d1351ce72e029a64c530f3941da5c18b2b196074
@@ -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.13</latest>
7
+ <release>57.0.13</release>
8
8
  <versions>
9
- <version>57.0.11</version>
9
+ <version>57.0.13</version>
10
10
  </versions>
11
- <lastUpdated>20260814141310</lastUpdated>
11
+ <lastUpdated>20260824074615</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- 2ed3d013ca9421b5e75ada4e2b67957b
1
+ c5687c59b58e66b61d7ad8422409a52b
@@ -1 +1 @@
1
- 6b30a9bd2542ddada62f0ff1896eb038fd533890
1
+ 19e37e7626a16f1bed2cb5e7e532fe5b2849156f
@@ -1 +1 @@
1
- 019b45348b534e778d6357dc29bfa9809f79c3c7cb60fb6e84110996f71b6336
1
+ 53945cd66292791187c0bc9fab8427ab497726954b09a946a1b4324dc85ac04f
@@ -1 +1 @@
1
- 60f8a5217ca4b39641e51f92c3c8361bc0fdb2a155bfc557599fe074cebcf02ee525f49fce24c510a4309c0c29cc0a5430b01d72d43749956deba5332ad54230
1
+ e3b22c7838747c4ad21b1a89b65060b12b1511e30770682da53e9056895af8cbad35096654e090e29bc57b794de2f6b0390f70db5c4d3b75187edbbf36f321cb