@expo/ui 57.0.20 → 57.0.22

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 (111) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/ui/DatePickerView.kt +1 -0
  4. package/android/src/main/java/expo/modules/ui/HostView.kt +7 -1
  5. package/android/src/main/java/expo/modules/ui/ModifierRegistry.kt +34 -5
  6. package/android/src/main/java/expo/modules/ui/SemanticsModifier.kt +2 -1
  7. package/build/community/datetime-picker/DateTimePicker.android.d.ts.map +1 -1
  8. package/build/community/datetime-picker/utils.d.ts +11 -0
  9. package/build/community/datetime-picker/utils.d.ts.map +1 -0
  10. package/build/community/picker/Picker.android.d.ts.map +1 -1
  11. package/build/jetpack-compose/modifiers/index.d.ts +33 -6
  12. package/build/jetpack-compose/modifiers/index.d.ts.map +1 -1
  13. package/build/swift-ui/ArrangementView/index.d.ts +49 -0
  14. package/build/swift-ui/ArrangementView/index.d.ts.map +1 -0
  15. package/build/swift-ui/index.d.ts +1 -0
  16. package/build/swift-ui/index.d.ts.map +1 -1
  17. package/build/swift-ui/modifiers/animation/index.d.ts +6 -1
  18. package/build/swift-ui/modifiers/animation/index.d.ts.map +1 -1
  19. package/build/swift-ui/modifiers/animation/types.d.ts +15 -1
  20. package/build/swift-ui/modifiers/animation/types.d.ts.map +1 -1
  21. package/build/swift-ui/modifiers/arrangementModifiers.d.ts +110 -0
  22. package/build/swift-ui/modifiers/arrangementModifiers.d.ts.map +1 -0
  23. package/build/swift-ui/modifiers/containerBackground.d.ts +2 -2
  24. package/build/swift-ui/modifiers/index.d.ts +40 -2
  25. package/build/swift-ui/modifiers/index.d.ts.map +1 -1
  26. package/build/swift-ui/modifiers/presentationModifiers.d.ts +8 -0
  27. package/build/swift-ui/modifiers/presentationModifiers.d.ts.map +1 -1
  28. package/build/universal/State.android.d.ts +1 -3
  29. package/build/universal/State.android.d.ts.map +1 -1
  30. package/build/universal/State.d.ts +2 -3
  31. package/build/universal/State.d.ts.map +1 -1
  32. package/build/universal/State.ios.d.ts +1 -3
  33. package/build/universal/State.ios.d.ts.map +1 -1
  34. package/build/universal/Switch/index.android.d.ts.map +1 -1
  35. package/build/universal/transformStyle.ios.d.ts.map +1 -1
  36. package/build/universal/types.d.ts +24 -0
  37. package/build/universal/types.d.ts.map +1 -1
  38. package/expo-module.config.json +1 -1
  39. package/ios/ArrangementViewView.swift +40 -0
  40. package/ios/ExpoUIModule.swift +1 -1
  41. package/ios/Modifiers/AnimationConfig.swift +20 -0
  42. package/ios/Modifiers/ArrangementModifiers.swift +157 -0
  43. package/ios/Modifiers/ContainerBackgroundModifier.swift +26 -13
  44. package/ios/Modifiers/PreferredColorSchemeModifier.swift +12 -0
  45. package/ios/Modifiers/PresentationModifiers.swift +10 -0
  46. package/ios/Modifiers/View+ModifierArray.swift +3 -3
  47. package/ios/Modifiers/ViewModifierRegistry.swift +120 -9
  48. package/ios/Modifiers/WidgetKitModifiers.swift +13 -0
  49. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.20/expo.modules.ui-57.0.20-sources.jar → 57.0.22/expo.modules.ui-57.0.22-sources.jar} +0 -0
  50. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22-sources.jar.md5 +1 -0
  51. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22-sources.jar.sha1 +1 -0
  52. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22-sources.jar.sha256 +1 -0
  53. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22-sources.jar.sha512 +1 -0
  54. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.aar +0 -0
  55. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.aar.md5 +1 -0
  56. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.aar.sha1 +1 -0
  57. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.aar.sha256 +1 -0
  58. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.aar.sha512 +1 -0
  59. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.20/expo.modules.ui-57.0.20.module → 57.0.22/expo.modules.ui-57.0.22.module} +22 -22
  60. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.module.md5 +1 -0
  61. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.module.sha1 +1 -0
  62. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.module.sha256 +1 -0
  63. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.module.sha512 +1 -0
  64. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.20/expo.modules.ui-57.0.20.pom → 57.0.22/expo.modules.ui-57.0.22.pom} +1 -1
  65. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.pom.md5 +1 -0
  66. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.pom.sha1 +1 -0
  67. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.pom.sha256 +1 -0
  68. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.22/expo.modules.ui-57.0.22.pom.sha512 +1 -0
  69. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
  70. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
  71. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
  72. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
  73. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
  74. package/package.json +4 -4
  75. package/src/community/datetime-picker/DateTimePicker.android.tsx +14 -4
  76. package/src/community/datetime-picker/utils.ts +21 -0
  77. package/src/community/picker/Picker.android.tsx +5 -0
  78. package/src/jetpack-compose/modifiers/index.ts +33 -4
  79. package/src/swift-ui/ArrangementView/index.tsx +70 -0
  80. package/src/swift-ui/index.tsx +1 -0
  81. package/src/swift-ui/modifiers/animation/index.ts +24 -11
  82. package/src/swift-ui/modifiers/animation/types.ts +18 -0
  83. package/src/swift-ui/modifiers/arrangementModifiers.ts +142 -0
  84. package/src/swift-ui/modifiers/containerBackground.ts +2 -2
  85. package/src/swift-ui/modifiers/index.ts +51 -1
  86. package/src/swift-ui/modifiers/presentationModifiers.ts +10 -0
  87. package/src/universal/State.android.ts +1 -1
  88. package/src/universal/State.ios.ts +1 -1
  89. package/src/universal/State.ts +12 -4
  90. package/src/universal/Switch/index.android.tsx +11 -2
  91. package/src/universal/transformStyle.ios.ts +5 -2
  92. package/src/universal/types.ts +27 -0
  93. package/ios/AccessoryWidgetBackgroundView.swift +0 -27
  94. package/ios/Modifiers/WidgetModifiers.swift +0 -70
  95. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20-sources.jar.md5 +0 -1
  96. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20-sources.jar.sha1 +0 -1
  97. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20-sources.jar.sha256 +0 -1
  98. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20-sources.jar.sha512 +0 -1
  99. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.aar +0 -0
  100. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.aar.md5 +0 -1
  101. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.aar.sha1 +0 -1
  102. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.aar.sha256 +0 -1
  103. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.aar.sha512 +0 -1
  104. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.module.md5 +0 -1
  105. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.module.sha1 +0 -1
  106. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.module.sha256 +0 -1
  107. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.module.sha512 +0 -1
  108. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.pom.md5 +0 -1
  109. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.pom.sha1 +0 -1
  110. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.pom.sha256 +0 -1
  111. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.20/expo.modules.ui-57.0.20.pom.sha512 +0 -1
@@ -79,10 +79,24 @@ export const fillMaxWidth = (fraction?: number) => createModifier('fillMaxWidth'
79
79
  export const fillMaxHeight = (fraction?: number) => createModifier('fillMaxHeight', { fraction });
80
80
 
81
81
  /**
82
- * Sets the exact width of the view.
83
- * @param value - Width in dp.
82
+ * Intrinsic width values for the `width` modifier. `Min` is the smallest width at which the content
83
+ * still draws correctly, and `Max` is the width the content needs when nothing limits it.
84
84
  */
85
- export const width = (value: number) => createModifier('width', { width: value });
85
+ export const IntrinsicSize = { Min: 'min', Max: 'max' } as const;
86
+ // eslint-disable-next-line @typescript-eslint/no-redeclare -- value and type share the name, like an enum
87
+ export type IntrinsicSize = (typeof IntrinsicSize)[keyof typeof IntrinsicSize];
88
+
89
+ /**
90
+ * Sets the width of the view to an exact value, or to the minimum or maximum intrinsic width of its
91
+ * content. The incoming constraints can still make the view narrower or wider than that width.
92
+ * @param value - Width in dp, or an `IntrinsicSize`. `IntrinsicSize.Min` uses the minimum intrinsic
93
+ * width, the smallest width at which the content still draws correctly (for a text, its widest word).
94
+ * `IntrinsicSize.Max` uses the maximum intrinsic width, the width the content needs when nothing
95
+ * limits it (for a text, a single line).
96
+ * @see [Compose `width(IntrinsicSize)` modifier](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/width.modifier#(androidx.compose.ui.Modifier).width(androidx.compose.foundation.layout.IntrinsicSize))
97
+ * @see [Intrinsic measurements in Compose layouts](https://developer.android.com/develop/ui/compose/layouts/intrinsic-measurements)
98
+ */
99
+ export const width = (value: number | IntrinsicSize) => createModifier('width', { width: value });
86
100
 
87
101
  /**
88
102
  * Sets the exact height of the view.
@@ -443,10 +457,25 @@ export const onGloballyPositioned = (
443
457
  */
444
458
  export const testID = (tag: string) => createModifier('testID', { testID: tag });
445
459
 
460
+ /**
461
+ * Options for the `semantics` modifier.
462
+ */
463
+ export type SemanticsConfig = {
464
+ /**
465
+ * An autofill hint, such as `'email'` or `'password'`.
466
+ */
467
+ contentType?: string;
468
+ /**
469
+ * What accessibility services such as TalkBack announce for the element. Useful when the visible
470
+ * content does not read well aloud, as with an abbreviation or a glyph.
471
+ */
472
+ contentDescription?: string;
473
+ };
474
+
446
475
  /**
447
476
  * Applies semantic properties. Wraps `Modifier.semantics { ... }`.
448
477
  */
449
- export const semantics = (params: { contentType?: string }) => createModifier('semantics', params);
478
+ export const semantics = (params: SemanticsConfig) => createModifier('semantics', params);
450
479
 
451
480
  // =============================================================================
452
481
  // Clip Modifier & Shapes
@@ -0,0 +1,70 @@
1
+ import { requireNativeView } from 'expo';
2
+
3
+ import { Slot } from '../SlotView';
4
+ import { createViewModifierEventListener } from '../modifiers/utils';
5
+ import { type CommonViewModifierProps } from '../types';
6
+
7
+ export interface ArrangementViewProps extends CommonViewModifierProps {
8
+ /**
9
+ * The views to arrange. Provide `ArrangementView.Primary` and `ArrangementView.Secondary`.
10
+ */
11
+ children: React.ReactNode;
12
+ }
13
+
14
+ const ArrangementViewNativeView: React.ComponentType<ArrangementViewProps> = requireNativeView(
15
+ 'ExpoUI',
16
+ 'ArrangementViewView'
17
+ );
18
+
19
+ /**
20
+ * The primary view of the arrangement.
21
+ */
22
+ function ArrangementViewPrimary(props: { children: React.ReactNode }) {
23
+ return <Slot name="primary">{props.children}</Slot>;
24
+ }
25
+
26
+ /**
27
+ * The secondary view of the arrangement.
28
+ */
29
+ function ArrangementViewSecondary(props: { children: React.ReactNode }) {
30
+ return <Slot name="secondary">{props.children}</Slot>;
31
+ }
32
+
33
+ ArrangementView.Primary = ArrangementViewPrimary;
34
+ ArrangementView.Secondary = ArrangementViewSecondary;
35
+
36
+ /**
37
+ * ArrangementView uses the native [ArrangementView](https://developer.apple.com/documentation/swiftui/arrangementview) view.
38
+ *
39
+ * A view that arranges primary and secondary content using an adaptive layout that responds to
40
+ * the environment.
41
+ *
42
+ * > **Note:** Below iOS 27.1, the children render without a container.
43
+ * @example
44
+ * ```tsx
45
+ * <Host style={{ flex: 1 }}>
46
+ * <ArrangementView modifiers={[arrangementViewStyle('split')]}>
47
+ * <ArrangementView.Primary>
48
+ * <NowPlaying />
49
+ * </ArrangementView.Primary>
50
+ * <ArrangementView.Secondary>
51
+ * <Lyrics />
52
+ * </ArrangementView.Secondary>
53
+ * </ArrangementView>
54
+ * </Host>
55
+ * ```
56
+ * @platform ios 27.1+
57
+ * @platform tvos 27.1+
58
+ */
59
+ export function ArrangementView(props: ArrangementViewProps) {
60
+ const { modifiers, children, ...restProps } = props;
61
+
62
+ return (
63
+ <ArrangementViewNativeView
64
+ modifiers={modifiers}
65
+ {...(modifiers ? createViewModifierEventListener(modifiers) : undefined)}
66
+ {...restProps}>
67
+ {children}
68
+ </ArrangementViewNativeView>
69
+ );
70
+ }
@@ -28,6 +28,7 @@ export * from './Menu';
28
28
  export * from './NavigationDestination';
29
29
  export * from './NavigationLink';
30
30
  export * from './NavigationSplitView';
31
+ export * from './ArrangementView';
31
32
  export * from './NavigationStack';
32
33
  export * from './Picker';
33
34
  export * from './ProgressView';
@@ -5,6 +5,7 @@ import type {
5
5
  ChainableAnimationType,
6
6
  InterpolatingSpringAnimationParams,
7
7
  SpringAnimationParams,
8
+ SpringPresetAnimationParams,
8
9
  TimingAnimationParams,
9
10
  } from './types';
10
11
 
@@ -16,6 +17,8 @@ import type {
16
17
  * - `spring` accepts [`SpringAnimationParams`](#springanimationparams).
17
18
  * - `interpolatingSpring` accepts
18
19
  * [`InterpolatingSpringAnimationParams`](#interpolatingspringanimationparams).
20
+ * - Spring presets (`smooth`, `snappy`, `bouncy`) accept
21
+ * [`SpringPresetAnimationParams`](#springpresetanimationparams).
19
22
  * - Chaining returns [`ChainableAnimationType`](#chainableanimationtype).
20
23
  *
21
24
  * @example
@@ -80,23 +83,33 @@ export const Animation = {
80
83
  duration: params?.duration,
81
84
  bounce: params?.bounce,
82
85
  }),
86
+ smooth: (params?: SpringPresetAnimationParams) =>
87
+ ChainableAnimation({
88
+ type: 'smooth',
89
+ duration: params?.duration,
90
+ extraBounce: params?.extraBounce,
91
+ }),
92
+ snappy: (params?: SpringPresetAnimationParams) =>
93
+ ChainableAnimation({
94
+ type: 'snappy',
95
+ duration: params?.duration,
96
+ extraBounce: params?.extraBounce,
97
+ }),
98
+ bouncy: (params?: SpringPresetAnimationParams) =>
99
+ ChainableAnimation({
100
+ type: 'bouncy',
101
+ duration: params?.duration,
102
+ extraBounce: params?.extraBounce,
103
+ }),
83
104
 
84
105
  default: ChainableAnimation({ type: 'default' }),
85
106
  };
86
107
 
87
108
  function ChainableAnimation(animation: AnimationObject): ChainableAnimationType {
88
- let _animation: AnimationObject = animation;
89
-
90
109
  return {
91
- delay: (delay) => {
92
- _animation = { ..._animation, delay };
93
- return ChainableAnimation(_animation);
94
- },
95
- repeat: (params) => {
96
- _animation = { ..._animation, ...params };
97
- return ChainableAnimation(_animation);
98
- },
99
- [VALUE_SYMBOL]: () => _animation,
110
+ delay: (delay) => ChainableAnimation({ ...animation, delay }),
111
+ repeat: (params) => ChainableAnimation({ ...animation, ...params }),
112
+ [VALUE_SYMBOL]: () => animation,
100
113
  };
101
114
  }
102
115
 
@@ -12,6 +12,9 @@ export type AnimationObject = {
12
12
  | 'linear'
13
13
  | 'spring'
14
14
  | 'interpolatingSpring'
15
+ | 'smooth'
16
+ | 'snappy'
17
+ | 'bouncy'
15
18
  | 'default';
16
19
  duration?: number;
17
20
  response?: number;
@@ -22,6 +25,7 @@ export type AnimationObject = {
22
25
  stiffness?: number;
23
26
  damping?: number;
24
27
  initialVelocity?: number;
28
+ extraBounce?: number;
25
29
  delay?: number;
26
30
  repeatCount?: number;
27
31
  autoreverses?: boolean;
@@ -84,6 +88,20 @@ export type InterpolatingSpringAnimationParams = {
84
88
  bounce?: number;
85
89
  };
86
90
 
91
+ export type SpringPresetAnimationParams = {
92
+ /**
93
+ * The perceptual duration, which defines the pace of the spring (in seconds). This is
94
+ * approximately equal to the settling duration, but for very bouncy springs, it is the period of
95
+ * oscillation of the spring.
96
+ */
97
+ duration?: number;
98
+ /**
99
+ * Bounce added to the base bounce of the preset: 0 for `smooth`, 0.15 for `snappy`, and 0.3 for
100
+ * `bouncy`. Keep the total below 1: at 1 and above, the spring oscillates without settling.
101
+ */
102
+ extraBounce?: number;
103
+ };
104
+
87
105
  export type ChainableAnimationType = {
88
106
  /** Adds a delay before the animation starts (in seconds). */
89
107
  delay: (delay: number) => ChainableAnimationType;
@@ -0,0 +1,142 @@
1
+ import { createModifier } from './createModifier';
2
+
3
+ /**
4
+ * A style that configures an `ArrangementView` with an arrangement.
5
+ * - `'automatic'`: The default style, which resolves to `'split'`.
6
+ * - `'split'`: An arrangement view style that places the primary and secondary views side by side along one or more axes.
7
+ * - `'overlay'`: An arrangement view style that layers the primary view over the secondary view in z-order.
8
+ */
9
+ export type ArrangementViewStyle = 'automatic' | 'split' | 'overlay';
10
+
11
+ /**
12
+ * Sets the style for arrangement views within this view.
13
+ * @param style - The style to apply.
14
+ * @param options - The `axes` the arrangement supports. With `'split'`, creates a split arrangement
15
+ * that supports the given axes. With `'overlay'`, creates an overlay arrangement that supports
16
+ * laying out its views along the given axes.
17
+ * @platform ios 27.1+
18
+ * @platform tvos 27.1+
19
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/arrangementviewstyle(_:)).
20
+ */
21
+ export function arrangementViewStyle(style: 'automatic'): ReturnType<typeof createModifier>;
22
+ export function arrangementViewStyle(
23
+ style: 'split' | 'overlay',
24
+ options?: { axes?: 'horizontal' | 'vertical' | 'both' }
25
+ ): ReturnType<typeof createModifier>;
26
+ export function arrangementViewStyle(
27
+ style: ArrangementViewStyle,
28
+ options?: { axes?: 'horizontal' | 'vertical' | 'both' }
29
+ ) {
30
+ return createModifier('arrangementViewStyle', { style, axes: options?.axes });
31
+ }
32
+
33
+ /**
34
+ * The minimum, ideal, and maximum ratios for `splitArrangementLayoutRatio`.
35
+ */
36
+ export type SplitArrangementLayoutRatioParams = {
37
+ minHorizontal?: number;
38
+ idealHorizontal?: number;
39
+ maxHorizontal?: number;
40
+ minVertical?: number;
41
+ idealVertical?: number;
42
+ maxVertical?: number;
43
+ };
44
+
45
+ /**
46
+ * Sets the preferred size ratio for the content of `ArrangementView.Primary` or
47
+ * `ArrangementView.Secondary` in a split arrangement.
48
+ * @platform ios 27.1+
49
+ * @platform tvos 27.1+
50
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/splitarrangementlayoutratio(_:)).
51
+ */
52
+ export function splitArrangementLayoutRatio(ratio: number): ReturnType<typeof createModifier>;
53
+ /**
54
+ * Sets the size ratio for the content of `ArrangementView.Primary` or `ArrangementView.Secondary`
55
+ * in a split arrangement.
56
+ * @platform ios 27.1+
57
+ * @platform tvos 27.1+
58
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/splitarrangementlayoutratio(minhorizontal:idealhorizontal:maxhorizontal:minvertical:idealvertical:maxvertical:)).
59
+ */
60
+ export function splitArrangementLayoutRatio(
61
+ ratios: SplitArrangementLayoutRatioParams
62
+ ): ReturnType<typeof createModifier>;
63
+ export function splitArrangementLayoutRatio(
64
+ ratioOrParams: number | SplitArrangementLayoutRatioParams
65
+ ) {
66
+ return createModifier(
67
+ 'splitArrangementLayoutRatio',
68
+ typeof ratioOrParams === 'number' ? { ratio: ratioOrParams } : ratioOrParams
69
+ );
70
+ }
71
+
72
+ /**
73
+ * The minimum, ideal, and maximum sizes for `splitArrangementLayoutSize`.
74
+ */
75
+ export type SplitArrangementLayoutSizeParams = {
76
+ minWidth?: number;
77
+ idealWidth?: number;
78
+ maxWidth?: number;
79
+ minHeight?: number;
80
+ idealHeight?: number;
81
+ maxHeight?: number;
82
+ };
83
+
84
+ /**
85
+ * Sets the size constraints for the content of `ArrangementView.Primary` or
86
+ * `ArrangementView.Secondary` in a split arrangement.
87
+ * @platform ios 27.1+
88
+ * @platform tvos 27.1+
89
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/splitarrangementlayoutsize(minwidth:idealwidth:maxwidth:minheight:idealheight:maxheight:)).
90
+ */
91
+ export const splitArrangementLayoutSize = (constraints: SplitArrangementLayoutSizeParams) =>
92
+ createModifier('splitArrangementLayoutSize', constraints);
93
+
94
+ /**
95
+ * The split axes on which `splitArrangementFixedLayoutSize` prefers the ideal size of the view.
96
+ */
97
+ export type SplitArrangementFixedLayoutSizeParams = {
98
+ /**
99
+ * Whether to prefer a fixed width for the view in a horizontal split.
100
+ * @default true
101
+ */
102
+ horizontal?: boolean;
103
+ /**
104
+ * Whether to prefer a fixed height for the view in a vertical split.
105
+ * @default true
106
+ */
107
+ vertical?: boolean;
108
+ };
109
+
110
+ /**
111
+ * Sets the preferred size constraint for the content of `ArrangementView.Primary` or
112
+ * `ArrangementView.Secondary` in a split arrangement to the ideal size of the view within its
113
+ * container. The arrangement view prefers this size, but may resize to a smaller size depending on
114
+ * the priority of the view.
115
+ * @platform ios 27.1+
116
+ * @platform tvos 27.1+
117
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/splitarrangementfixedlayoutsize(horizontal:vertical:)).
118
+ */
119
+ export const splitArrangementFixedLayoutSize = (options?: SplitArrangementFixedLayoutSizeParams) =>
120
+ createModifier('splitArrangementFixedLayoutSize', options);
121
+
122
+ /**
123
+ * Sets the horizontal edge that a view in an overlay arrangement occupies when the arrangement
124
+ * transitions to a horizontal layout.
125
+ * @platform ios 27.1+
126
+ * @platform tvos 27.1+
127
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/overlayarrangementedge(_:)).
128
+ */
129
+ export function overlayArrangementEdge(
130
+ edge: 'leading' | 'trailing'
131
+ ): ReturnType<typeof createModifier>;
132
+ /**
133
+ * Sets the vertical edge that a view in an overlay arrangement occupies when the arrangement
134
+ * transitions to a vertical layout.
135
+ * @platform ios 27.1+
136
+ * @platform tvos 27.1+
137
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/overlayarrangementedge(_:)-4tjwn).
138
+ */
139
+ export function overlayArrangementEdge(edge: 'top' | 'bottom'): ReturnType<typeof createModifier>;
140
+ export function overlayArrangementEdge(edge: 'top' | 'bottom' | 'leading' | 'trailing') {
141
+ return createModifier('overlayArrangementEdge', { edge });
142
+ }
@@ -6,8 +6,8 @@ export type ContainerBackgroundPlacement = 'widget' | 'navigation' | 'navigation
6
6
  /**
7
7
  * Sets the container background of the enclosing container.
8
8
  *
9
- * > **Note:** `navigation` and `navigationSplitView` require iOS 18. On iOS 17 they fall back to
10
- * > the `widget` placement.
9
+ * > **Note:** `navigation` and `navigationSplitView` require iOS 18. The `widget` placement works
10
+ * > only in `expo-widgets` widgets, where the other placements fall back to it on iOS 17.
11
11
  *
12
12
  * @param style - Any [`ShapeStyle`](#shapestyle): a color, a hierarchical style, a material, or a gradient.
13
13
  * @param container - The type of container to apply the background to.
@@ -786,6 +786,16 @@ export const scrollDismissesKeyboard = (
786
786
  export const scrollDisabled = (disabled: boolean = true) =>
787
787
  createModifier('scrollDisabled', { disabled });
788
788
 
789
+ /**
790
+ * Sets the preferred color scheme for the nearest enclosing presentation, such as a `BottomSheet`,
791
+ * including its background. The value overrides the device's light or dark appearance for that
792
+ * presentation.
793
+ * @param colorScheme - The preferred color scheme, or `null` to indicate no preference.
794
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/preferredcolorscheme(_:)).
795
+ */
796
+ export const preferredColorScheme = (colorScheme: 'light' | 'dark' | null) =>
797
+ createModifier('preferredColorScheme', { colorScheme });
798
+
789
799
  /**
790
800
  * Disables or enables clipping of a scrollable view's content to its bounds.
791
801
  * Content drawn outside those bounds, such as a shadow or a view scaled up past the edge, is
@@ -1712,6 +1722,41 @@ export const resizable = (
1712
1722
  */
1713
1723
  export const navigationTitle = (title: string) => createModifier('navigationTitle', { title });
1714
1724
 
1725
+ /**
1726
+ * Title display modes for the `navigationBarTitleDisplayMode` modifier.
1727
+ * @platform ios
1728
+ */
1729
+ export type NavigationBarTitleDisplayMode = 'automatic' | 'inline' | 'large';
1730
+
1731
+ /**
1732
+ * Configures the title display mode for a navigation bar.
1733
+ * @param displayMode - The style to use for displaying the navigation bar title.
1734
+ * @platform ios
1735
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/navigationbartitledisplaymode(_:)).
1736
+ */
1737
+ export const navigationBarTitleDisplayMode = (displayMode: NavigationBarTitleDisplayMode) =>
1738
+ createModifier('navigationBarTitleDisplayMode', { displayMode });
1739
+
1740
+ /**
1741
+ * Title display modes for the `toolbarTitleDisplayMode` modifier. On tvOS, `large` and
1742
+ * `inlineLarge` have no effect. On macOS, `large` has no effect.
1743
+ * @platform ios 17.0+
1744
+ * @platform tvos 17.0+
1745
+ * @platform macos 14.0+
1746
+ */
1747
+ export type ToolbarTitleDisplayMode = 'automatic' | 'inline' | 'inlineLarge' | 'large';
1748
+
1749
+ /**
1750
+ * Configures the title display mode for a toolbar.
1751
+ * @param mode - The style to use for displaying the toolbar title.
1752
+ * @platform ios 17.0+
1753
+ * @platform tvos 17.0+
1754
+ * @platform macos 14.0+
1755
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/toolbartitledisplaymode(_:)).
1756
+ */
1757
+ export const toolbarTitleDisplayMode = (mode: ToolbarTitleDisplayMode) =>
1758
+ createModifier('toolbarTitleDisplayMode', { mode });
1759
+
1715
1760
  // =============================================================================
1716
1761
  // Type Definitions
1717
1762
  // =============================================================================
@@ -1799,6 +1844,7 @@ export type BuiltInModifier =
1799
1844
  | ReturnType<typeof containerRelativeFrame>
1800
1845
  | ReturnType<typeof scrollContentBackground>
1801
1846
  | ReturnType<typeof scrollDisabled>
1847
+ | ReturnType<typeof preferredColorScheme>
1802
1848
  | ReturnType<typeof scrollClipDisabled>
1803
1849
  | ReturnType<typeof scrollIndicators>
1804
1850
  | ReturnType<typeof scrollEdgeEffectStyle>
@@ -1857,7 +1903,9 @@ export type BuiltInModifier =
1857
1903
  | ReturnType<typeof widgetURL>
1858
1904
  | ReturnType<typeof activityBackgroundTint>
1859
1905
  | ReturnType<typeof containerBackground>
1860
- | ReturnType<typeof navigationTitle>;
1906
+ | ReturnType<typeof navigationTitle>
1907
+ | ReturnType<typeof navigationBarTitleDisplayMode>
1908
+ | ReturnType<typeof toolbarTitleDisplayMode>;
1861
1909
 
1862
1910
  /**
1863
1911
  * Main ViewModifier type that supports both built-in and 3rd party modifiers.
@@ -1901,6 +1949,7 @@ export * from './pickerStyle';
1901
1949
  export * from './menuOrder';
1902
1950
  export * from './tabViewModifiers';
1903
1951
  export * from './navigationModifiers';
1952
+ export * from './arrangementModifiers';
1904
1953
  export * from './datePickerStyle';
1905
1954
  export * from './progressViewStyle';
1906
1955
  export * from './gaugeStyle';
@@ -1915,5 +1964,6 @@ export type {
1915
1964
  TimingAnimationParams,
1916
1965
  SpringAnimationParams,
1917
1966
  InterpolatingSpringAnimationParams,
1967
+ SpringPresetAnimationParams,
1918
1968
  ChainableAnimationType,
1919
1969
  } from './animation/types';
@@ -57,6 +57,16 @@ export const presentationDetents = (
57
57
  export const presentationDragIndicator = (visibility: 'automatic' | 'visible' | 'hidden') =>
58
58
  createModifier('presentationDragIndicator', { visibility });
59
59
 
60
+ /**
61
+ * Sets the corner radius of a sheet presentation.
62
+ * @param cornerRadius - The corner radius in points, or `null` to use the system default.
63
+ * @platform ios 16.4+
64
+ * @platform tvos 16.4+
65
+ * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/presentationcornerradius(_:)).
66
+ */
67
+ export const presentationCornerRadius = (cornerRadius: number | null) =>
68
+ createModifier('presentationCornerRadius', { cornerRadius });
69
+
60
70
  /**
61
71
  * Presentation background interaction type.
62
72
  */
@@ -1,3 +1,3 @@
1
1
  export { useNativeState } from '@expo/ui/jetpack-compose';
2
2
 
3
- export type ObservableState<T> = { value: T };
3
+ export type { ObservableState } from './types';
@@ -1,3 +1,3 @@
1
1
  export { useNativeState } from '@expo/ui/swift-ui';
2
2
 
3
- export type ObservableState<T> = { value: T };
3
+ export type { ObservableState } from './types';
@@ -1,6 +1,8 @@
1
1
  import { useRef, useState } from 'react';
2
2
 
3
- export type ObservableState<T> = { value: T };
3
+ import type { ObservableState } from './types';
4
+
5
+ export type { ObservableState };
4
6
 
5
7
  /**
6
8
  * Web polyfill for the native `useNativeState` hook.
@@ -13,14 +15,20 @@ export function useNativeState<T>(initialValue: T): ObservableState<T> {
13
15
 
14
16
  const stateRef = useRef<ObservableState<T> | null>(null);
15
17
  if (stateRef.current === null) {
18
+ const get = () => valRef.current;
19
+ const set = (v: T) => {
20
+ valRef.current = v;
21
+ setVal(v);
22
+ };
16
23
  stateRef.current = {
17
24
  get value() {
18
- return valRef.current;
25
+ return get();
19
26
  },
20
27
  set value(v: T) {
21
- valRef.current = v;
22
- setVal(v);
28
+ set(v);
23
29
  },
30
+ get,
31
+ set,
24
32
  };
25
33
  }
26
34
  return stateRef.current;
@@ -1,5 +1,11 @@
1
1
  import { Row, Switch as ComposeSwitch, Text } from '@expo/ui/jetpack-compose';
2
- import { testID as testIDModifier, weight } from '@expo/ui/jetpack-compose/modifiers';
2
+ import {
3
+ fillMaxWidth,
4
+ IntrinsicSize,
5
+ testID as testIDModifier,
6
+ weight,
7
+ width,
8
+ } from '@expo/ui/jetpack-compose/modifiers';
3
9
 
4
10
  import type { SwitchProps } from './types';
5
11
 
@@ -16,7 +22,10 @@ export function Switch({ value, onValueChange, label, disabled, testID, modifier
16
22
  if (label == null) return toggle;
17
23
 
18
24
  return (
19
- <Row verticalAlignment="center" horizontalArrangement={{ spacedBy: 8 }}>
25
+ <Row
26
+ verticalAlignment="center"
27
+ horizontalArrangement={{ spacedBy: 8 }}
28
+ modifiers={[fillMaxWidth(), width(IntrinsicSize.Max)]}>
20
29
  <Text modifiers={[weight(1)]}>{label}</Text>
21
30
  {toggle}
22
31
  </Row>
@@ -2,6 +2,7 @@ import {
2
2
  background,
3
3
  border,
4
4
  clipShape,
5
+ contentShape,
5
6
  disabled as disabledMod,
6
7
  font,
7
8
  foregroundStyle,
@@ -15,6 +16,7 @@ import {
15
16
  onTapGesture,
16
17
  opacity,
17
18
  padding,
19
+ shapes,
18
20
  type ModifierConfig,
19
21
  } from '@expo/ui/swift-ui/modifiers';
20
22
 
@@ -154,8 +156,9 @@ export function transformToModifiers(
154
156
  // type. The event, lifecycle, and behavior modifiers below are never dropped.
155
157
  mods = omitUserOverridden(mods, extraModifiers);
156
158
 
157
- // Events
158
- if (props.onPress) mods.push(onTapGesture(props.onPress));
159
+ // Events. SwiftUI only hit-tests drawn content, so the `contentShape` lets
160
+ // taps on empty space (for example a `Spacer` in a `Row`) reach `onPress`.
161
+ if (props.onPress) mods.push(contentShape(shapes.rectangle()), onTapGesture(props.onPress));
159
162
 
160
163
  // Lifecycle
161
164
  if (props.onAppear) mods.push(onAppear(props.onAppear));
@@ -111,3 +111,30 @@ export interface UniversalBaseProps {
111
111
  * @docsInline
112
112
  */
113
113
  export type UniversalAlignment = 'start' | 'center' | 'end';
114
+
115
+ /**
116
+ * Observable state created with `useNativeState`.
117
+ *
118
+ * On Android and iOS, the value is shared with native views. A write from the JavaScript thread
119
+ * is applied on the UI thread asynchronously, so a read right after it may still return the
120
+ * previous value. Writes don't re-render the component that created the state.
121
+ *
122
+ * On web, the value is backed by React state. A write is readable immediately and re-renders the
123
+ * component that created the state.
124
+ */
125
+ export type ObservableState<T> = {
126
+ /**
127
+ * The current value.
128
+ */
129
+ value: T;
130
+
131
+ /**
132
+ * Reads the current value. A React Compiler-compliant alternative to reading `.value`.
133
+ */
134
+ get(): T;
135
+
136
+ /**
137
+ * Writes a new value. A React Compiler-compliant alternative to assigning `.value`.
138
+ */
139
+ set(value: T): void;
140
+ };
@@ -1,27 +0,0 @@
1
- import SwiftUI
2
- import ExpoModulesCore
3
- #if !os(tvOS)
4
- import WidgetKit
5
- #endif
6
-
7
- public final class AccessoryWidgetBackgroundProps: UIBaseViewProps {}
8
-
9
- public struct AccessoryWidgetBackgroundView: ExpoSwiftUI.View {
10
- @ObservedObject public var props: AccessoryWidgetBackgroundProps
11
-
12
- public init(props: AccessoryWidgetBackgroundProps) {
13
- self.props = props
14
- }
15
-
16
- public var body: some View {
17
- #if !os(tvOS)
18
- if #available(iOS 16.0, *) {
19
- AccessoryWidgetBackground()
20
- } else {
21
- Color.clear
22
- }
23
- #else
24
- EmptyView()
25
- #endif
26
- }
27
- }