@expo/ui 55.0.3 → 55.0.5

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 (97) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/ui/BottomSheetView.kt +91 -13
  4. package/android/src/main/java/expo/modules/ui/CarouselView.kt +93 -67
  5. package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +15 -6
  6. package/android/src/main/java/expo/modules/ui/TextInputView.kt +39 -15
  7. package/build/datetime-picker/DateTimePicker.android.d.ts +3 -0
  8. package/build/datetime-picker/DateTimePicker.android.d.ts.map +1 -0
  9. package/build/datetime-picker/DateTimePicker.d.ts +3 -0
  10. package/build/datetime-picker/DateTimePicker.d.ts.map +1 -0
  11. package/build/datetime-picker/DateTimePicker.web.d.ts +3 -0
  12. package/build/datetime-picker/DateTimePicker.web.d.ts.map +1 -0
  13. package/build/datetime-picker/index.d.ts +5 -0
  14. package/build/datetime-picker/index.d.ts.map +1 -0
  15. package/build/datetime-picker/types.d.ts +128 -0
  16. package/build/datetime-picker/types.d.ts.map +1 -0
  17. package/build/jetpack-compose/Carousel/index.d.ts +86 -23
  18. package/build/jetpack-compose/Carousel/index.d.ts.map +1 -1
  19. package/build/jetpack-compose/ModalBottomSheet/index.d.ts +65 -13
  20. package/build/jetpack-compose/ModalBottomSheet/index.d.ts.map +1 -1
  21. package/build/jetpack-compose/Progress/index.d.ts +6 -7
  22. package/build/jetpack-compose/Progress/index.d.ts.map +1 -1
  23. package/build/jetpack-compose/TextInput/index.d.ts +9 -0
  24. package/build/jetpack-compose/TextInput/index.d.ts.map +1 -1
  25. package/build/swift-ui/Link/index.d.ts +36 -0
  26. package/build/swift-ui/Link/index.d.ts.map +1 -0
  27. package/build/swift-ui/index.d.ts +1 -0
  28. package/build/swift-ui/index.d.ts.map +1 -1
  29. package/build/swift-ui/modifiers/environment.d.ts +16 -1
  30. package/build/swift-ui/modifiers/environment.d.ts.map +1 -1
  31. package/build/swift-ui/modifiers/index.d.ts +3 -7
  32. package/build/swift-ui/modifiers/index.d.ts.map +1 -1
  33. package/build/swift-ui/modifiers/widgets.d.ts +14 -0
  34. package/build/swift-ui/modifiers/widgets.d.ts.map +1 -0
  35. package/expo-module.config.json +1 -1
  36. package/ios/ExpoUIModule.swift +1 -0
  37. package/ios/LinkView.swift +29 -0
  38. package/ios/Modifiers/EnvironmentModifier.swift +14 -0
  39. package/ios/Modifiers/ViewModifierRegistry.swift +4 -0
  40. package/ios/Modifiers/WidgetModifiers.swift +12 -0
  41. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.3/expo.modules.ui-55.0.3-sources.jar → 55.0.5/expo.modules.ui-55.0.5-sources.jar} +0 -0
  42. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5-sources.jar.md5 +1 -0
  43. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5-sources.jar.sha1 +1 -0
  44. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5-sources.jar.sha256 +1 -0
  45. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5-sources.jar.sha512 +1 -0
  46. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.aar +0 -0
  47. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.aar.md5 +1 -0
  48. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.aar.sha1 +1 -0
  49. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.aar.sha256 +1 -0
  50. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.aar.sha512 +1 -0
  51. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.3/expo.modules.ui-55.0.3.module → 55.0.5/expo.modules.ui-55.0.5.module} +22 -22
  52. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.module.md5 +1 -0
  53. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.module.sha1 +1 -0
  54. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.module.sha256 +1 -0
  55. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.module.sha512 +1 -0
  56. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.3/expo.modules.ui-55.0.3.pom → 55.0.5/expo.modules.ui-55.0.5.pom} +1 -1
  57. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.pom.md5 +1 -0
  58. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.pom.sha1 +1 -0
  59. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.pom.sha256 +1 -0
  60. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.pom.sha512 +1 -0
  61. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
  62. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
  63. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
  64. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
  65. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
  66. package/package.json +6 -2
  67. package/src/datetime-picker/DateTimePicker.android.tsx +126 -0
  68. package/src/datetime-picker/DateTimePicker.tsx +94 -0
  69. package/src/datetime-picker/DateTimePicker.web.tsx +5 -0
  70. package/src/datetime-picker/index.tsx +11 -0
  71. package/src/datetime-picker/types.tsx +147 -0
  72. package/src/jetpack-compose/Carousel/index.tsx +118 -30
  73. package/src/jetpack-compose/ModalBottomSheet/index.tsx +85 -15
  74. package/src/jetpack-compose/Progress/index.tsx +7 -7
  75. package/src/jetpack-compose/TextInput/index.tsx +10 -0
  76. package/src/swift-ui/Link/index.tsx +52 -0
  77. package/src/swift-ui/index.tsx +1 -0
  78. package/src/swift-ui/modifiers/environment.ts +17 -4
  79. package/src/swift-ui/modifiers/index.ts +4 -10
  80. package/src/swift-ui/modifiers/widgets.ts +18 -0
  81. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3-sources.jar.md5 +0 -1
  82. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3-sources.jar.sha1 +0 -1
  83. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3-sources.jar.sha256 +0 -1
  84. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3-sources.jar.sha512 +0 -1
  85. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.aar +0 -0
  86. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.aar.md5 +0 -1
  87. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.aar.sha1 +0 -1
  88. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.aar.sha256 +0 -1
  89. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.aar.sha512 +0 -1
  90. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.module.md5 +0 -1
  91. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.module.sha1 +0 -1
  92. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.module.sha256 +0 -1
  93. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.module.sha512 +0 -1
  94. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.pom.md5 +0 -1
  95. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.pom.sha1 +0 -1
  96. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.pom.sha256 +0 -1
  97. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.pom.sha512 +0 -1
@@ -0,0 +1,147 @@
1
+ import type { ViewProps } from 'react-native';
2
+
3
+ // -- Public types matching @react-native-community/datetimepicker ----------
4
+
5
+ /**
6
+ * @deprecated used with the deprecated `onChange` prop
7
+ * */
8
+ export type DateTimePickerEvent = {
9
+ /**
10
+ * `'set'` when the user selects a date. `'dismissed'` when the user cancels
11
+ * an Android dialog picker. iOS never fires `'dismissed'`.
12
+ */
13
+ type: 'set' | 'dismissed';
14
+ nativeEvent: {
15
+ timestamp: number;
16
+ utcOffset: number;
17
+ };
18
+ };
19
+
20
+ export type DateTimePickerChangeEvent = {
21
+ nativeEvent: {
22
+ timestamp: number;
23
+ utcOffset: number;
24
+ };
25
+ };
26
+
27
+ export type DateTimePickerProps = {
28
+ /**
29
+ * The current date value (controlled).
30
+ */
31
+ value: Date;
32
+ /**
33
+ * @deprecated Use `onValueChange` and `onDismiss` instead.
34
+ *
35
+ * Called when the user changes the date/time or dismisses the picker.
36
+ * The event type is encoded in `event.type`.
37
+ * If the new specific listeners are provided, they take precedence.
38
+ */
39
+ onChange?: (event: DateTimePickerEvent, date?: Date) => void;
40
+ /**
41
+ * Called when the user selects a date or time.
42
+ */
43
+ onValueChange?: (event: DateTimePickerChangeEvent, date: Date) => void;
44
+ /**
45
+ * Called when the picker is dismissed without selecting a value.
46
+ * @platform android
47
+ */
48
+ onDismiss?: () => void;
49
+ /**
50
+ * The picker mode.
51
+ * @default 'date'
52
+ */
53
+ mode?: 'date' | 'time' | 'datetime';
54
+ /**
55
+ * The earliest selectable date.
56
+ */
57
+ minimumDate?: Date;
58
+ /**
59
+ * The latest selectable date.
60
+ */
61
+ maximumDate?: Date;
62
+ /**
63
+ * A test ID forwarded to the native view.
64
+ * Note: on Android dialog presentation, the test ID is not forwarded.
65
+ */
66
+ testID?: string;
67
+ /**
68
+ * Display style. Android supports `'default' | 'spinner'` — `'spinner'` shows a text input
69
+ * rather than a scroll wheel (Material 3 does not have a wheel-style picker).
70
+ * iOS supports `'default' | 'spinner' | 'compact' | 'inline'`.
71
+ * @default 'default'
72
+ */
73
+ display?: 'default' | 'spinner' | 'compact' | 'inline' | 'calendar' | 'clock';
74
+ /**
75
+ * Use 24-hour format.
76
+ * @platform android
77
+ */
78
+ is24Hour?: boolean;
79
+ /**
80
+ * Accent/tint color applied to the picker.
81
+ * Maps to `color` on Android and `tint` on iOS.
82
+ */
83
+ accentColor?: string;
84
+ /**
85
+ * Whether the picker is disabled.
86
+ * @platform ios
87
+ */
88
+ disabled?: boolean;
89
+ /**
90
+ * Locale identifier (e.g. 'en_US', 'fr_FR') for the picker display.
91
+ * @platform ios
92
+ */
93
+ locale?: string;
94
+ /**
95
+ * Force a specific color scheme on the picker.
96
+ * @platform ios
97
+ */
98
+ themeVariant?: 'dark' | 'light';
99
+ /**
100
+ * IANA time zone name (e.g. 'America/New_York') for the picker display.
101
+ * @platform ios
102
+ */
103
+ timeZoneName?: string;
104
+ /**
105
+ * How the picker is presented.
106
+ * - `'inline'` renders the picker directly in the view hierarchy.
107
+ * - `'dialog'` shows a modal dialog that opens on mount. Fires `onValueChange` on confirmation, `onDismiss` on cancel. The caller should
108
+ * unmount the component in response.
109
+ *
110
+ * On iOS this prop is accepted but ignored (always inline).
111
+ * On Android the default is `'dialog'`.
112
+ * @default 'dialog'
113
+ * @platform android
114
+ */
115
+ presentation?: 'inline' | 'dialog';
116
+ /**
117
+ * Set the positive (confirm) button label.
118
+ * @platform android
119
+ */
120
+ positiveButton?: { label?: string };
121
+ /**
122
+ * Set the negative (cancel) button label.
123
+ * @platform android
124
+ */
125
+ negativeButton?: { label?: string };
126
+ } & Pick<ViewProps, 'style'>;
127
+
128
+ // -- Helpers ---------------------------------------------------------------
129
+
130
+ export function buildEvent(date: Date): DateTimePickerEvent {
131
+ return {
132
+ type: 'set',
133
+ nativeEvent: {
134
+ timestamp: date.getTime(),
135
+ utcOffset: -date.getTimezoneOffset(),
136
+ },
137
+ };
138
+ }
139
+
140
+ export function buildChangeEvent(date: Date): DateTimePickerChangeEvent {
141
+ return {
142
+ nativeEvent: {
143
+ timestamp: date.getTime(),
144
+ utcOffset: -date.getTimezoneOffset(),
145
+ },
146
+ };
147
+ }
@@ -1,8 +1,11 @@
1
1
  import { requireNativeView } from 'expo';
2
2
 
3
- import { ExpoModifier } from '../../types';
3
+ import { type ModifierConfig } from '../../types';
4
4
  import { createViewModifierEventListener } from '../modifiers/utils';
5
5
 
6
+ /**
7
+ * Per-side padding values in dp for carousel content.
8
+ */
6
9
  export type PaddingValuesRecord = {
7
10
  start?: number;
8
11
  top?: number;
@@ -10,50 +13,135 @@ export type PaddingValuesRecord = {
10
13
  bottom?: number;
11
14
  };
12
15
 
13
- export type CarouselVariant = 'multiBrowse' | 'unconstrained';
16
+ /**
17
+ * Fling behavior type for controlling carousel snapping.
18
+ */
14
19
  export type FlingBehaviorType = 'singleAdvance' | 'noSnap';
15
20
 
16
- export type CarouselProps = {
21
+ /**
22
+ * Shared props across all carousel components.
23
+ */
24
+ export type CarouselCommonConfig = {
17
25
  /**
18
- * Modifiers for the component.
26
+ * Spacing between items in dp.
27
+ * @default 0
19
28
  */
20
- modifiers?: ExpoModifier[];
21
- /** Carousel variant */
22
- variant?: CarouselVariant;
23
- /** Spacing between items (dp) */
24
29
  itemSpacing?: number;
25
- /** Padding for carousel content (dp or object) */
30
+ /**
31
+ * Padding for carousel content (dp or object).
32
+ */
26
33
  contentPadding?: number | PaddingValuesRecord;
27
- /** Minimum small item width (dp) */
28
- minSmallItemWidth?: number;
29
- /** Maximum small item width (dp) */
30
- maxSmallItemWidth?: number;
31
- /** Fling behavior type */
34
+ /**
35
+ * Controls snapping behavior when the user flings the carousel.
36
+ * `'singleAdvance'` snaps to the next item, `'noSnap'` allows free scrolling.
37
+ */
32
38
  flingBehavior?: FlingBehaviorType;
33
- /** Preferred item width (dp) for multiBrowse variant */
34
- preferredItemWidth?: number;
35
- /** Item width (dp) for unconstrained variant */
36
- itemWidth?: number;
37
- /** Children to render */
39
+ /**
40
+ * Whether the user can scroll the carousel.
41
+ * @default true
42
+ */
43
+ userScrollEnabled?: boolean;
44
+ /**
45
+ * Modifiers for the component.
46
+ */
47
+ modifiers?: ModifierConfig[];
48
+ /**
49
+ * Children to render as carousel items.
50
+ */
38
51
  children: React.ReactNode;
39
52
  };
40
53
 
41
- type NativeCarouselProps = CarouselProps;
42
-
43
- const CarouselNativeView: React.ComponentType<NativeCarouselProps> = requireNativeView(
44
- 'ExpoUI',
45
- 'CarouselView'
46
- );
47
-
48
- export function transformCarouselProps(props: CarouselProps): NativeCarouselProps {
54
+ function transformProps<T extends { modifiers?: ModifierConfig[] }>(props: T): T {
49
55
  const { modifiers, ...restProps } = props;
50
56
  return {
51
57
  modifiers,
52
58
  ...(modifiers ? createViewModifierEventListener(modifiers) : undefined),
53
59
  ...restProps,
54
- };
60
+ } as T;
55
61
  }
56
62
 
57
- export function Carousel(props: CarouselProps) {
58
- return <CarouselNativeView {...transformCarouselProps(props)} />;
63
+ function createCarouselComponent<P extends { modifiers?: ModifierConfig[] }>(
64
+ viewName: string
65
+ ): React.ComponentType<P> {
66
+ const NativeView: React.ComponentType<P> = requireNativeView('ExpoUI', viewName);
67
+ return function CarouselComponent(props: P) {
68
+ return <NativeView {...transformProps(props)} />;
69
+ };
59
70
  }
71
+
72
+ // region HorizontalCenteredHeroCarousel
73
+
74
+ export type HorizontalCenteredHeroCarouselProps = CarouselCommonConfig & {
75
+ /**
76
+ * Maximum width of the hero item in dp.
77
+ * When unspecified, the hero item will be as wide as possible.
78
+ */
79
+ maxItemWidth?: number;
80
+ /**
81
+ * Minimum width of small peek items in dp.
82
+ * @default CarouselDefaults.MinSmallItemSize
83
+ */
84
+ minSmallItemWidth?: number;
85
+ /**
86
+ * Maximum width of small peek items in dp.
87
+ * @default CarouselDefaults.MaxSmallItemSize
88
+ */
89
+ maxSmallItemWidth?: number;
90
+ };
91
+
92
+ /**
93
+ * A hero carousel that centers one large item between two small peek items,
94
+ * matching Compose's `HorizontalCenteredHeroCarousel`.
95
+ */
96
+ export const HorizontalCenteredHeroCarousel =
97
+ createCarouselComponent<HorizontalCenteredHeroCarouselProps>(
98
+ 'HorizontalCenteredHeroCarouselView'
99
+ );
100
+
101
+ // endregion
102
+
103
+ // region HorizontalMultiBrowseCarousel
104
+
105
+ export type HorizontalMultiBrowseCarouselProps = CarouselCommonConfig & {
106
+ /**
107
+ * The preferred width of the large item in dp.
108
+ */
109
+ preferredItemWidth: number;
110
+ /**
111
+ * Minimum width of small peek items in dp.
112
+ * @default CarouselDefaults.MinSmallItemSize
113
+ */
114
+ minSmallItemWidth?: number;
115
+ /**
116
+ * Maximum width of small peek items in dp.
117
+ * @default CarouselDefaults.MaxSmallItemSize
118
+ */
119
+ maxSmallItemWidth?: number;
120
+ };
121
+
122
+ /**
123
+ * A carousel that shows a large item alongside smaller peek items,
124
+ * matching Compose's `HorizontalMultiBrowseCarousel`.
125
+ */
126
+ export const HorizontalMultiBrowseCarousel =
127
+ createCarouselComponent<HorizontalMultiBrowseCarouselProps>('HorizontalMultiBrowseCarouselView');
128
+
129
+ // endregion
130
+
131
+ // region HorizontalUncontainedCarousel
132
+
133
+ export type HorizontalUncontainedCarouselProps = CarouselCommonConfig & {
134
+ /**
135
+ * The width of each item in dp.
136
+ */
137
+ itemWidth: number;
138
+ };
139
+
140
+ /**
141
+ * A carousel where each item has a fixed width with free-form scrolling,
142
+ * matching Compose's `HorizontalUncontainedCarousel`.
143
+ */
144
+ export const HorizontalUncontainedCarousel =
145
+ createCarouselComponent<HorizontalUncontainedCarouselProps>('HorizontalUncontainedCarouselView');
146
+
147
+ // endregion
@@ -1,16 +1,54 @@
1
1
  import { requireNativeView } from 'expo';
2
- import React from 'react';
2
+ import React, { Ref } from 'react';
3
+ import { type ColorValue } from 'react-native';
3
4
 
4
- import { type ExpoModifier, type ViewEvent } from '../../types';
5
+ import { type ModifierConfig } from '../../types';
5
6
  import { createViewModifierEventListener } from '../modifiers/utils';
6
7
 
8
+ type SlotNativeViewProps = {
9
+ slotName: string;
10
+ children: React.ReactNode;
11
+ };
12
+
13
+ const SlotNativeView: React.ComponentType<SlotNativeViewProps> = requireNativeView(
14
+ 'ExpoUI',
15
+ 'SlotView'
16
+ );
17
+
18
+ export type ModalBottomSheetRef = {
19
+ /**
20
+ * Programmatically hides the bottom sheet with an animation.
21
+ * The returned promise resolves after the dismiss animation completes.
22
+ */
23
+ hide: () => Promise<void>;
24
+ };
25
+
26
+ export type ModalBottomSheetProperties = {
27
+ /**
28
+ * Whether the bottom sheet can be dismissed by pressing the back button.
29
+ * @default true
30
+ */
31
+ shouldDismissOnBackPress?: boolean;
32
+ /**
33
+ * Whether the bottom sheet can be dismissed by clicking outside (on the scrim).
34
+ * @default true
35
+ */
36
+ shouldDismissOnClickOutside?: boolean;
37
+ };
38
+
7
39
  export type ModalBottomSheetProps = {
8
40
  /**
9
41
  * The children of the `ModalBottomSheet` component.
42
+ * Can include a `ModalBottomSheet.DragHandle` slot for a custom drag handle.
10
43
  */
11
44
  children: React.ReactNode;
12
45
  /**
13
- * Callback function that is called when the bottom sheet is dismissed.
46
+ * Can be used to imperatively hide the bottom sheet with an animation.
47
+ */
48
+ ref?: Ref<ModalBottomSheetRef>;
49
+ /**
50
+ * Callback function that is called when the user dismisses the bottom sheet
51
+ * (via swipe, back press, or tapping outside the scrim).
14
52
  */
15
53
  onDismissRequest: () => void;
16
54
  /**
@@ -18,14 +56,42 @@ export type ModalBottomSheetProps = {
18
56
  * @default false
19
57
  */
20
58
  skipPartiallyExpanded?: boolean;
59
+ /**
60
+ * The background color of the bottom sheet.
61
+ */
62
+ containerColor?: ColorValue;
63
+ /**
64
+ * The preferred color of the content inside the bottom sheet.
65
+ */
66
+ contentColor?: ColorValue;
67
+ /**
68
+ * The color of the scrim overlay behind the bottom sheet.
69
+ */
70
+ scrimColor?: ColorValue;
71
+ /**
72
+ * Whether to show the default drag handle at the top of the bottom sheet.
73
+ * Ignored if a custom `ModalBottomSheet.DragHandle` slot is provided.
74
+ * @default true
75
+ */
76
+ showDragHandle?: boolean;
77
+ /**
78
+ * Whether gestures (swipe to dismiss) are enabled on the bottom sheet.
79
+ * @default true
80
+ */
81
+ sheetGesturesEnabled?: boolean;
82
+ /**
83
+ * Properties for the modal window behavior.
84
+ */
85
+ properties?: ModalBottomSheetProperties;
21
86
  /**
22
87
  * Modifiers for the component.
23
88
  */
24
- modifiers?: ExpoModifier[];
89
+ modifiers?: ModifierConfig[];
25
90
  };
26
91
 
27
- type NativeModalBottomSheetProps = Omit<ModalBottomSheetProps, 'onDismissRequest'> &
28
- ViewEvent<'onDismissRequest', void>;
92
+ type NativeModalBottomSheetProps = Omit<ModalBottomSheetProps, 'onDismissRequest'> & {
93
+ onDismissRequest: () => void;
94
+ };
29
95
 
30
96
  const ModalBottomSheetNativeView: React.ComponentType<NativeModalBottomSheetProps> =
31
97
  requireNativeView('ExpoUI', 'ModalBottomSheetView');
@@ -44,18 +110,22 @@ function transformProps(props: ModalBottomSheetProps): NativeModalBottomSheetPro
44
110
  }
45
111
 
46
112
  /**
47
- * A Material Design modal bottom sheet.
113
+ * A custom drag handle slot for `ModalBottomSheet`.
114
+ * Wrap any content to use as the sheet's drag handle.
115
+ *
116
+ * @platform android
48
117
  */
49
- export function ModalBottomSheet(props: ModalBottomSheetProps) {
50
- return <ModalBottomSheetNativeView {...transformProps(props)} />;
118
+ function DragHandle(props: { children: React.ReactNode }) {
119
+ return <SlotNativeView slotName="dragHandle">{props.children}</SlotNativeView>;
51
120
  }
52
121
 
53
122
  /**
54
- * @deprecated Use `ModalBottomSheet` instead.
123
+ * A Material Design modal bottom sheet.
55
124
  */
56
- export const BottomSheet = ModalBottomSheet;
125
+ function ModalBottomSheetComponent(props: ModalBottomSheetProps) {
126
+ return <ModalBottomSheetNativeView {...transformProps(props)} />;
127
+ }
57
128
 
58
- /**
59
- * @deprecated Use `ModalBottomSheetProps` instead.
60
- */
61
- export type BottomSheetProps = ModalBottomSheetProps;
129
+ ModalBottomSheetComponent.DragHandle = DragHandle;
130
+
131
+ export const ModalBottomSheet = ModalBottomSheetComponent;
@@ -12,7 +12,7 @@ export type StrokeCap = 'round' | 'butt' | 'square';
12
12
  /**
13
13
  * Common props shared by all progress indicator variants.
14
14
  */
15
- type BaseProgressProps = {
15
+ export type ProgressCommonConfig = {
16
16
  /**
17
17
  * The current progress value between `0` and `1`. Omit for indeterminate.
18
18
  */
@@ -31,7 +31,7 @@ type BaseProgressProps = {
31
31
  modifiers?: ModifierConfig[];
32
32
  };
33
33
 
34
- function transformProps<T extends BaseProgressProps>(props: T): T {
34
+ function transformProps<T extends ProgressCommonConfig>(props: T): T {
35
35
  const { modifiers, ...restProps } = props;
36
36
  return {
37
37
  modifiers,
@@ -40,7 +40,7 @@ function transformProps<T extends BaseProgressProps>(props: T): T {
40
40
  } as T;
41
41
  }
42
42
 
43
- function createProgressComponent<P extends BaseProgressProps>(
43
+ function createProgressComponent<P extends ProgressCommonConfig>(
44
44
  viewName: string
45
45
  ): React.ComponentType<P> {
46
46
  const NativeView: React.ComponentType<P> = requireNativeView('ExpoUI', viewName);
@@ -70,7 +70,7 @@ export type DrawStopIndicatorConfig = {
70
70
  stopSize?: number;
71
71
  };
72
72
 
73
- export type LinearProgressIndicatorProps = BaseProgressProps & {
73
+ export type LinearProgressIndicatorProps = ProgressCommonConfig & {
74
74
  /**
75
75
  * Stroke cap style for the indicator ends.
76
76
  * @default 'round'
@@ -99,7 +99,7 @@ export const LinearProgressIndicator = createProgressComponent<LinearProgressInd
99
99
 
100
100
  // region CircularProgressIndicator
101
101
 
102
- export type CircularProgressIndicatorProps = BaseProgressProps & {
102
+ export type CircularProgressIndicatorProps = ProgressCommonConfig & {
103
103
  /**
104
104
  * Width of the circular stroke in dp.
105
105
  */
@@ -128,7 +128,7 @@ export const CircularProgressIndicator = createProgressComponent<CircularProgres
128
128
 
129
129
  // region LinearWavyProgressIndicator
130
130
 
131
- export type LinearWavyProgressIndicatorProps = BaseProgressProps & {
131
+ export type LinearWavyProgressIndicatorProps = ProgressCommonConfig & {
132
132
  /**
133
133
  * Size of the stop indicator in dp at the end of the determinate progress track.
134
134
  */
@@ -147,7 +147,7 @@ export const LinearWavyProgressIndicator =
147
147
 
148
148
  // region CircularWavyProgressIndicator
149
149
 
150
- export type CircularWavyProgressIndicatorProps = BaseProgressProps;
150
+ export type CircularWavyProgressIndicatorProps = ProgressCommonConfig;
151
151
 
152
152
  /**
153
153
  * A circular progress indicator with wavy animation style.
@@ -13,6 +13,8 @@ export type TextInputRef = {
13
13
  setText: (newText: string) => Promise<void>;
14
14
  };
15
15
 
16
+ export type TextInputVariant = 'filled' | 'outlined';
17
+
16
18
  export type TextInputProps = {
17
19
  /**
18
20
  * Can be used for imperatively setting text on the TextInput component.
@@ -22,6 +24,14 @@ export type TextInputProps = {
22
24
  * Initial value that the TextInput displays when being mounted. As the TextInput is an uncontrolled component, change the key prop if you need to change the text value.
23
25
  */
24
26
  defaultValue?: string;
27
+ /**
28
+ * The visual style of the text input field.
29
+ * - `filled` - A text field with a filled background (default).
30
+ * - `outlined` - A text field with a transparent background and a border outline.
31
+ * @default filled
32
+ * @platform android
33
+ */
34
+ variant?: TextInputVariant;
25
35
  /**
26
36
  * A callback triggered when user types in text into the TextInput.
27
37
  */
@@ -0,0 +1,52 @@
1
+ import { requireNativeView } from 'expo';
2
+
3
+ import { createViewModifierEventListener } from '../modifiers/utils';
4
+ import { type CommonViewModifierProps } from '../types';
5
+
6
+ export type LinkProps = {
7
+ /**
8
+ * The text label for the Link. Use this for simple text links.
9
+ */
10
+ label?: string;
11
+ /**
12
+ * The URL for the link.
13
+ */
14
+ destination: string;
15
+ /**
16
+ * Custom content for the link label. Use this for custom label views.
17
+ * Only nested elements are supported, not plain strings.
18
+ */
19
+ children?: React.ReactElement | React.ReactElement[];
20
+ } & CommonViewModifierProps;
21
+
22
+ const LinkNativeView: React.ComponentType<LinkProps> = requireNativeView('ExpoUI', 'LinkView');
23
+
24
+ /**
25
+ * Displays a native link component.
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * import { Link } from '@expo/ui/swift-ui';
30
+ * import { foregroundStyle, font } from '@expo/ui/swift-ui/modifiers';
31
+ *
32
+ * <Link
33
+ * label="Open"
34
+ * destination="https://expo.dev"
35
+ * modifiers={[
36
+ * foregroundStyle('red'),
37
+ * font({ size: 24, weight: 'bold' })
38
+ * ]}
39
+ * />
40
+ * ```
41
+ */
42
+ export function Link(props: LinkProps) {
43
+ const { children, modifiers, ...restProps } = props;
44
+
45
+ const baseProps = {
46
+ ...restProps,
47
+ modifiers,
48
+ ...(modifiers ? createViewModifierEventListener(modifiers) : undefined),
49
+ };
50
+
51
+ return <LinkNativeView {...baseProps}>{children}</LinkNativeView>;
52
+ }
@@ -40,4 +40,5 @@ export * from './Shapes';
40
40
  export * from './Popover';
41
41
  export * from './Grid';
42
42
  export * from './RNHostView';
43
+ export * from './Link';
43
44
  export { type CommonViewModifierProps } from './types';
@@ -1,10 +1,23 @@
1
1
  import { createModifier } from './createModifier';
2
2
 
3
+ export type EnvironmentConfig =
4
+ | { key: 'editMode'; value: 'active' | 'inactive' | 'transient' }
5
+ | { key: 'colorScheme'; value: 'light' | 'dark' }
6
+ | { key: 'locale'; value: string }
7
+ | { key: 'timeZone'; value: string };
8
+
3
9
  /**
4
10
  * Sets a SwiftUI environment value.
5
11
  * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/environment(_:_:)).
6
12
  */
7
- export const environment = (
8
- key: 'editMode' | 'colorScheme',
9
- value: 'active' | 'inactive' | 'transient' | 'light' | 'dark'
10
- ) => createModifier('environment', { key, value });
13
+ export function environment(config: EnvironmentConfig): ReturnType<typeof createModifier>;
14
+ export function environment(
15
+ key: EnvironmentConfig['key'],
16
+ value: string
17
+ ): ReturnType<typeof createModifier>;
18
+ export function environment(configOrKey: EnvironmentConfig | string, value?: string) {
19
+ if (typeof configOrKey === 'string') {
20
+ return createModifier('environment', { key: configOrKey, value });
21
+ }
22
+ return createModifier('environment', configOrKey);
23
+ }
@@ -15,6 +15,7 @@ import { environment } from './environment';
15
15
  import { gaugeStyle } from './gaugeStyle';
16
16
  import { progressViewStyle } from './progressViewStyle';
17
17
  import type { Color } from './types';
18
+ import { widgetAccentedRenderingMode, widgetURL } from './widgets';
18
19
 
19
20
  const ExpoUI = requireNativeModule('ExpoUI');
20
21
 
@@ -1056,15 +1057,6 @@ export const resizable = (
1056
1057
  resizingMode?: 'stretch' | 'tile'
1057
1058
  ) => createModifier('resizable', { ...capInsets, resizingMode });
1058
1059
 
1059
- /**
1060
- * Specifies the how to render an Image when using the WidgetKit/WidgetRenderingMode/accented mode.
1061
- * @param renderingMode - A constant describing how the Image should be rendered.
1062
- * @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/image/widgetaccentedrenderingmode(_:)).
1063
- */
1064
- export const widgetAccentedRenderingMode = (
1065
- renderingMode: 'fullColor' | 'accented' | 'desaturated' | 'accentedDesaturated'
1066
- ) => createModifier('widgetAccentedRenderingMode', { renderingMode });
1067
-
1068
1060
  // =============================================================================
1069
1061
  // Type Definitions
1070
1062
  // =============================================================================
@@ -1169,7 +1161,8 @@ export type BuiltInModifier =
1169
1161
  | ReturnType<typeof listStyle>
1170
1162
  | ReturnType<typeof contentTransition>
1171
1163
  | ReturnType<typeof resizable>
1172
- | ReturnType<typeof widgetAccentedRenderingMode>;
1164
+ | ReturnType<typeof widgetAccentedRenderingMode>
1165
+ | ReturnType<typeof widgetURL>;
1173
1166
 
1174
1167
  /**
1175
1168
  * Main ViewModifier type that supports both built-in and 3rd party modifiers.
@@ -1214,6 +1207,7 @@ export * from './progressViewStyle';
1214
1207
  export * from './gaugeStyle';
1215
1208
  export * from './presentationModifiers';
1216
1209
  export * from './environment';
1210
+ export * from './widgets';
1217
1211
  export type {
1218
1212
  TimingAnimationParams,
1219
1213
  SpringAnimationParams,