@expo/ui 55.0.1 → 55.0.2

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 (144) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/CONTRIBUTING.md +30 -0
  3. package/android/build.gradle +2 -2
  4. package/android/src/main/java/expo/modules/ui/DatePickerView.kt +90 -7
  5. package/android/src/main/java/expo/modules/ui/HorizontalFloatingToolbarView.kt +21 -8
  6. package/android/src/main/java/expo/modules/ui/ModifierRegistry.kt +105 -39
  7. package/android/src/main/java/expo/modules/ui/RNHostView.kt +204 -50
  8. package/android/src/main/java/expo/modules/ui/SwitchView.kt +70 -4
  9. package/android/src/main/java/expo/modules/ui/button/IconButton.kt +7 -1
  10. package/android/src/main/java/expo/modules/ui/convertibles/AnimatableFloat.kt +26 -0
  11. package/android/src/main/java/expo/modules/ui/convertibles/AnimationSpecParams.kt +93 -0
  12. package/android/src/main/java/expo/modules/ui/convertibles/GraphicsLayerParams.kt +24 -0
  13. package/build/jetpack-compose/DatePicker/index.d.ts +99 -0
  14. package/build/jetpack-compose/DatePicker/index.d.ts.map +1 -1
  15. package/build/jetpack-compose/Spacer/index.d.ts +2 -2
  16. package/build/jetpack-compose/Switch/index.d.ts +18 -0
  17. package/build/jetpack-compose/Switch/index.d.ts.map +1 -1
  18. package/build/jetpack-compose/modifiers/animation.d.ts +44 -0
  19. package/build/jetpack-compose/modifiers/animation.d.ts.map +1 -0
  20. package/build/jetpack-compose/modifiers/index.d.ts +50 -3
  21. package/build/jetpack-compose/modifiers/index.d.ts.map +1 -1
  22. package/build/swift-ui/AccessoryWidgetBackground/index.d.ts +4 -0
  23. package/build/swift-ui/AccessoryWidgetBackground/index.d.ts.map +1 -0
  24. package/build/swift-ui/ConfirmationDialog/index.d.ts.map +1 -1
  25. package/build/swift-ui/ContextMenu/index.d.ts.map +1 -1
  26. package/build/swift-ui/ControlGroup/index.d.ts +29 -0
  27. package/build/swift-ui/ControlGroup/index.d.ts.map +1 -0
  28. package/build/swift-ui/Gauge/index.d.ts.map +1 -1
  29. package/build/swift-ui/Image/index.d.ts +7 -1
  30. package/build/swift-ui/Image/index.d.ts.map +1 -1
  31. package/build/swift-ui/Label/index.d.ts.map +1 -1
  32. package/build/swift-ui/LabeledContent/index.d.ts.map +1 -1
  33. package/build/swift-ui/Menu/index.d.ts.map +1 -1
  34. package/build/swift-ui/Picker/index.d.ts.map +1 -1
  35. package/build/swift-ui/Popover/index.d.ts.map +1 -1
  36. package/build/swift-ui/Section/index.d.ts.map +1 -1
  37. package/build/swift-ui/Slider/index.d.ts.map +1 -1
  38. package/build/swift-ui/SlotView.d.ts +5 -0
  39. package/build/swift-ui/SlotView.d.ts.map +1 -0
  40. package/build/swift-ui/index.d.ts +2 -0
  41. package/build/swift-ui/index.d.ts.map +1 -1
  42. package/build/swift-ui/modifiers/index.d.ts +33 -1
  43. package/build/swift-ui/modifiers/index.d.ts.map +1 -1
  44. package/expo-module.config.json +1 -1
  45. package/ios/AccessoryWidgetBackgroundView.swift +27 -0
  46. package/ios/ConfirmationDialog/ConfirmationDialog.swift +3 -9
  47. package/ios/ConfirmationDialog/ConfirmationDialogProps.swift +0 -5
  48. package/ios/ContextMenu/ContextMenu.swift +27 -22
  49. package/ios/ContextMenu/ContextMenuRecords.swift +0 -6
  50. package/ios/ControlGroupView.swift +33 -0
  51. package/ios/ExpoUIModule.swift +10 -32
  52. package/ios/GaugeView.swift +4 -26
  53. package/ios/HostView.swift +1 -2
  54. package/ios/ImageView.swift +22 -11
  55. package/ios/Label.swift +2 -17
  56. package/ios/LabeledContentView.swift +3 -27
  57. package/ios/Menu/MenuRecords.swift +0 -2
  58. package/ios/Menu/MenuView.swift +2 -5
  59. package/ios/Modifiers/ResizableModifier.swift +24 -0
  60. package/ios/Modifiers/Rotation3DEffectModifier.swift +20 -0
  61. package/ios/Modifiers/View+ModifierArray.swift +29 -0
  62. package/ios/Modifiers/ViewModifierRegistry.swift +29 -3
  63. package/ios/Modifiers/WidgetModifiers.swift +46 -0
  64. package/ios/Picker/PickerView.swift +2 -6
  65. package/ios/Popover/PopoverProps.swift +0 -4
  66. package/ios/Popover/PopoverView.swift +2 -6
  67. package/ios/RNHostView.swift +91 -10
  68. package/ios/SectionView.swift +6 -12
  69. package/ios/SecureFieldView.swift +0 -1
  70. package/ios/ShareLink/ShareLinkView.swift +1 -1
  71. package/ios/SliderView.swift +10 -27
  72. package/ios/SlotView.swift +38 -0
  73. package/ios/TextFieldView.swift +0 -1
  74. package/ios/UIBaseView.swift +34 -3
  75. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.1/expo.modules.ui-55.0.1-sources.jar → 55.0.2/expo.modules.ui-55.0.2-sources.jar} +0 -0
  76. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2-sources.jar.md5 +1 -0
  77. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2-sources.jar.sha1 +1 -0
  78. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2-sources.jar.sha256 +1 -0
  79. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2-sources.jar.sha512 +1 -0
  80. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.aar +0 -0
  81. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.aar.md5 +1 -0
  82. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.aar.sha1 +1 -0
  83. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.aar.sha256 +1 -0
  84. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.aar.sha512 +1 -0
  85. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.1/expo.modules.ui-55.0.1.module → 55.0.2/expo.modules.ui-55.0.2.module} +22 -22
  86. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.module.md5 +1 -0
  87. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.module.sha1 +1 -0
  88. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.module.sha256 +1 -0
  89. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.module.sha512 +1 -0
  90. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.1/expo.modules.ui-55.0.1.pom → 55.0.2/expo.modules.ui-55.0.2.pom} +1 -1
  91. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.pom.md5 +1 -0
  92. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.pom.sha1 +1 -0
  93. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.pom.sha256 +1 -0
  94. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.pom.sha512 +1 -0
  95. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
  96. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
  97. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
  98. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
  99. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
  100. package/package.json +2 -2
  101. package/src/jetpack-compose/DatePicker/index.tsx +106 -2
  102. package/src/jetpack-compose/Spacer/index.tsx +2 -2
  103. package/src/jetpack-compose/Switch/index.tsx +18 -0
  104. package/src/jetpack-compose/modifiers/animation.ts +37 -0
  105. package/src/jetpack-compose/modifiers/index.ts +60 -4
  106. package/src/swift-ui/AccessoryWidgetBackground/index.tsx +12 -0
  107. package/src/swift-ui/ConfirmationDialog/index.tsx +4 -12
  108. package/src/swift-ui/ContextMenu/index.tsx +6 -20
  109. package/src/swift-ui/ControlGroup/index.tsx +59 -0
  110. package/src/swift-ui/Gauge/index.tsx +5 -20
  111. package/src/swift-ui/Image/index.tsx +7 -1
  112. package/src/swift-ui/Label/index.tsx +2 -5
  113. package/src/swift-ui/LabeledContent/index.tsx +3 -12
  114. package/src/swift-ui/Menu/index.tsx +2 -6
  115. package/src/swift-ui/Picker/index.tsx +4 -11
  116. package/src/swift-ui/Popover/index.tsx +3 -12
  117. package/src/swift-ui/Section/index.tsx +4 -9
  118. package/src/swift-ui/Slider/index.tsx +4 -12
  119. package/src/swift-ui/SlotView.tsx +8 -0
  120. package/src/swift-ui/index.tsx +2 -0
  121. package/src/swift-ui/modifiers/index.ts +47 -1
  122. package/ios/ConfirmationDialog/ConfirmationDialogComponents.swift +0 -26
  123. package/ios/ContextMenu/ContextMenuComponents.swift +0 -37
  124. package/ios/Menu/MenuComponents.swift +0 -12
  125. package/ios/Picker/PickerComponents.swift +0 -24
  126. package/ios/Popover/PopoverComponents.swift +0 -18
  127. package/ios/SectionComponents.swift +0 -34
  128. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1-sources.jar.md5 +0 -1
  129. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1-sources.jar.sha1 +0 -1
  130. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1-sources.jar.sha256 +0 -1
  131. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1-sources.jar.sha512 +0 -1
  132. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1.aar +0 -0
  133. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1.aar.md5 +0 -1
  134. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1.aar.sha1 +0 -1
  135. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1.aar.sha256 +0 -1
  136. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1.aar.sha512 +0 -1
  137. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1.module.md5 +0 -1
  138. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1.module.sha1 +0 -1
  139. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1.module.sha256 +0 -1
  140. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1.module.sha512 +0 -1
  141. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1.pom.md5 +0 -1
  142. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1.pom.sha1 +0 -1
  143. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1.pom.sha256 +0 -1
  144. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.1/expo.modules.ui-55.0.1.pom.sha512 +0 -1
@@ -0,0 +1 @@
1
+ af7c2dbb1d6562a281f052003f7040abe11d3675d03857f5c7d3519b28a1a8be54a73ccc7f2fab909b7edbfd864d888936d71a737737fac71ff13783d969229d
@@ -3,11 +3,11 @@
3
3
  <groupId>expo.modules.ui</groupId>
4
4
  <artifactId>expo.modules.ui</artifactId>
5
5
  <versioning>
6
- <latest>55.0.1</latest>
7
- <release>55.0.1</release>
6
+ <latest>55.0.2</latest>
7
+ <release>55.0.2</release>
8
8
  <versions>
9
- <version>55.0.1</version>
9
+ <version>55.0.2</version>
10
10
  </versions>
11
- <lastUpdated>20260225202620</lastUpdated>
11
+ <lastUpdated>20260311141702</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- f6c9c7a26f591d85be1f92bd770048b0
1
+ 3297c0326287d50f819c398744e70f0b
@@ -1 +1 @@
1
- 606ee81d636b618e409a977c41c18f0c102cf7ed
1
+ 52a054a9646396b7224594f0d12720d91de3d216
@@ -1 +1 @@
1
- 27c261098239e26d801540abddfcc9df7dc49b3ae8f839fadf7157e7062366de
1
+ 0ae7bf34378bccc60cb770b147533c2b4f1d10ede0a368c6ce75ab9763c6f66e
@@ -1 +1 @@
1
- a15e7a136c573d55ad8bfb73aecd9d47acf97323477120337ca51876f53194f40bbaeaf55cfca25ed68760ed6e241758806b61f0435247c0fa3393157f466ce3
1
+ b3f9f47205d7673ff988ddfc4632e556083ab8f5452376963677b9cc91314ff7363f811f1dfa575e8ead3c870ad237f0e930ee8804bdda308b00487e82bcd112
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/ui",
3
- "version": "55.0.1",
3
+ "version": "55.0.2",
4
4
  "description": "A collection of UI components",
5
5
  "sideEffects": [
6
6
  "*.fx.js"
@@ -60,5 +60,5 @@
60
60
  "react": "*",
61
61
  "react-native": "*"
62
62
  },
63
- "gitHead": "39a7a009e215eb71a112f4a20dba2d471ab21108"
63
+ "gitHead": "bcdd2c239f8a92cdf5140e35cde768352630acd6"
64
64
  }
@@ -8,6 +8,96 @@ export type AndroidVariant = 'picker' | 'input';
8
8
 
9
9
  export type DisplayedComponents = 'date' | 'hourAndMinute' | 'dateAndTime';
10
10
 
11
+ /**
12
+ * Color overrides for the Material 3 DatePicker component.
13
+ * All properties are optional — unset values use Material 3 theme defaults.
14
+ */
15
+ export type DatePickerElementColors = {
16
+ /** The background color of the date picker. */
17
+ containerColor?: ColorValue;
18
+ /** The color used for the date picker's title. */
19
+ titleContentColor?: ColorValue;
20
+ /** The color used for the date picker's headline. */
21
+ headlineContentColor?: ColorValue;
22
+ /** The color used for the weekday letters (Mon, Tue, etc.). */
23
+ weekdayContentColor?: ColorValue;
24
+ /** The color used for the month and year subhead labels. */
25
+ subheadContentColor?: ColorValue;
26
+ /** The color used for navigation arrows and year selection menu button. */
27
+ navigationContentColor?: ColorValue;
28
+ /** The color used for year item content. */
29
+ yearContentColor?: ColorValue;
30
+ /** The color used for disabled year item content. */
31
+ disabledYearContentColor?: ColorValue;
32
+ /** The color used for the current year content. */
33
+ currentYearContentColor?: ColorValue;
34
+ /** The color used for the selected year content. */
35
+ selectedYearContentColor?: ColorValue;
36
+ /** The color used for a disabled selected year content. */
37
+ disabledSelectedYearContentColor?: ColorValue;
38
+ /** The color used for the selected year container/background. */
39
+ selectedYearContainerColor?: ColorValue;
40
+ /** The color used for a disabled selected year container. */
41
+ disabledSelectedYearContainerColor?: ColorValue;
42
+ /** The color used for day content (number text). */
43
+ dayContentColor?: ColorValue;
44
+ /** The color used for disabled day content. */
45
+ disabledDayContentColor?: ColorValue;
46
+ /** The color used for selected day content. */
47
+ selectedDayContentColor?: ColorValue;
48
+ /** The color used for a disabled selected day content. */
49
+ disabledSelectedDayContentColor?: ColorValue;
50
+ /** The color used for the selected day container/background circle. */
51
+ selectedDayContainerColor?: ColorValue;
52
+ /** The color used for a disabled selected day container. */
53
+ disabledSelectedDayContainerColor?: ColorValue;
54
+ /** The color used for today's date text. */
55
+ todayContentColor?: ColorValue;
56
+ /** The color used for today's date border. */
57
+ todayDateBorderColor?: ColorValue;
58
+ /** The content color for days within a date range selection. */
59
+ dayInSelectionRangeContentColor?: ColorValue;
60
+ /** The container color for days within a date range selection. */
61
+ dayInSelectionRangeContainerColor?: ColorValue;
62
+ /** The color used for divider lines. */
63
+ dividerColor?: ColorValue;
64
+ };
65
+
66
+ /**
67
+ * Color overrides for the Material 3 TimePicker component.
68
+ * All properties are optional — unset values use Material 3 theme defaults.
69
+ */
70
+ export type TimePickerElementColors = {
71
+ /** The container/background color of the time picker. */
72
+ containerColor?: ColorValue;
73
+ /** The background color of the clock dial. */
74
+ clockDialColor?: ColorValue;
75
+ /** The color of clock dial numbers when selected or overlapping the selector. */
76
+ clockDialSelectedContentColor?: ColorValue;
77
+ /** The color of clock dial numbers when unselected. */
78
+ clockDialUnselectedContentColor?: ColorValue;
79
+ /** The color of the clock dial selector (hand). */
80
+ selectorColor?: ColorValue;
81
+ /** The border color of the AM/PM period selector. */
82
+ periodSelectorBorderColor?: ColorValue;
83
+ /** The background color of the selected AM/PM period. */
84
+ periodSelectorSelectedContainerColor?: ColorValue;
85
+ /** The background color of the unselected AM/PM period. */
86
+ periodSelectorUnselectedContainerColor?: ColorValue;
87
+ /** The text color of the selected AM/PM period. */
88
+ periodSelectorSelectedContentColor?: ColorValue;
89
+ /** The text color of the unselected AM/PM period. */
90
+ periodSelectorUnselectedContentColor?: ColorValue;
91
+ /** The background color of the selected hour/minute segment. */
92
+ timeSelectorSelectedContainerColor?: ColorValue;
93
+ /** The background color of the unselected hour/minute segment. */
94
+ timeSelectorUnselectedContainerColor?: ColorValue;
95
+ /** The text color of the selected hour/minute segment. */
96
+ timeSelectorSelectedContentColor?: ColorValue;
97
+ /** The text color of the unselected hour/minute segment. */
98
+ timeSelectorUnselectedContentColor?: ColorValue;
99
+ };
100
+
11
101
  export type DateTimePickerProps = {
12
102
  /**
13
103
  * The initial date to display on the picker.
@@ -37,8 +127,19 @@ export type DateTimePickerProps = {
37
127
  displayedComponents?: DisplayedComponents;
38
128
  /**
39
129
  * The tint color to use on the picker elements.
130
+ * When `elementColors` is not provided, this color is applied to a subset of
131
+ * picker elements (selected day, title, headline, today border for date picker;
132
+ * selector, selected time segment, clock dial for time picker).
40
133
  */
41
134
  color?: ColorValue;
135
+ /**
136
+ * Fine-grained color overrides for individual picker elements.
137
+ * When provided, these take precedence over the `color` prop.
138
+ * Date picker color keys are used when `displayedComponents` is 'date' or 'dateAndTime'.
139
+ * Time picker color keys are used when `displayedComponents` is 'hourAndMinute'.
140
+ * Unset values fall back to Material 3 theme defaults.
141
+ */
142
+ elementColors?: DatePickerElementColors & TimePickerElementColors;
42
143
  /**
43
144
  * Determines what format the clock should be displayed in on Android.
44
145
  * @default true
@@ -52,14 +153,15 @@ export type DateTimePickerProps = {
52
153
 
53
154
  type NativeDatePickerProps = Omit<
54
155
  DateTimePickerProps,
55
- 'variant' | 'onDateSelected' | 'initialDate'
156
+ 'variant' | 'onDateSelected' | 'initialDate' | 'elementColors'
56
157
  > & {
57
158
  variant?: AndroidVariant;
58
159
  initialDate?: number | null;
160
+ elementColors?: DatePickerElementColors & TimePickerElementColors;
59
161
  } & ViewEvent<'onDateSelected', { date: Date }>;
60
162
 
61
163
  function transformDateTimePickerProps(props: DateTimePickerProps): NativeDatePickerProps {
62
- const { modifiers, variant, initialDate, ...rest } = props;
164
+ const { modifiers, variant, initialDate, elementColors, color, ...rest } = props;
63
165
 
64
166
  // Convert ISO string to timestamp for Android
65
167
  const initialDateTimestamp = initialDate ? new Date(initialDate).getTime() : null;
@@ -68,11 +170,13 @@ function transformDateTimePickerProps(props: DateTimePickerProps): NativeDatePic
68
170
  modifiers,
69
171
  ...(modifiers ? createViewModifierEventListener(modifiers) : undefined),
70
172
  ...rest,
173
+ color,
71
174
  initialDate: initialDateTimestamp,
72
175
  onDateSelected: ({ nativeEvent: { date } }) => {
73
176
  props?.onDateSelected?.(new Date(date));
74
177
  },
75
178
  variant,
179
+ ...(elementColors != null ? { elementColors } : {}),
76
180
  };
77
181
  }
78
182
 
@@ -5,7 +5,7 @@ import { createViewModifierEventListener } from '../modifiers/utils';
5
5
 
6
6
  export type SpacerProps = {
7
7
  /**
8
- * Modifiers for the component. Use weight() modifier to make the spacer flexible.
8
+ * Modifiers for the component. Use `weight()` modifier to make the spacer flexible.
9
9
  */
10
10
  modifiers?: ExpoModifier[];
11
11
  };
@@ -27,7 +27,7 @@ function transformProps(props: SpacerProps): NativeSpacerProps {
27
27
 
28
28
  /**
29
29
  * A spacer component that fills available space.
30
- * Use with the weight() modifier to create flexible spacing in Row or Column layouts.
30
+ * Use with the `weight()` modifier to create flexible spacing in `Row` or `Column` layouts.
31
31
  *
32
32
  * @example
33
33
  * ```tsx
@@ -12,8 +12,20 @@ import { createViewModifierEventListener } from '../modifiers/utils';
12
12
  type SwitchElementColors = {
13
13
  checkedThumbColor?: ColorValue;
14
14
  checkedTrackColor?: ColorValue;
15
+ checkedBorderColor?: ColorValue;
16
+ checkedIconColor?: ColorValue;
15
17
  uncheckedThumbColor?: ColorValue;
16
18
  uncheckedTrackColor?: ColorValue;
19
+ uncheckedBorderColor?: ColorValue;
20
+ uncheckedIconColor?: ColorValue;
21
+ disabledCheckedThumbColor?: ColorValue;
22
+ disabledCheckedTrackColor?: ColorValue;
23
+ disabledCheckedBorderColor?: ColorValue;
24
+ disabledCheckedIconColor?: ColorValue;
25
+ disabledUncheckedThumbColor?: ColorValue;
26
+ disabledUncheckedTrackColor?: ColorValue;
27
+ disabledUncheckedBorderColor?: ColorValue;
28
+ disabledUncheckedIconColor?: ColorValue;
17
29
  };
18
30
 
19
31
  // @docsMissing
@@ -46,6 +58,12 @@ export type SwitchProps = {
46
58
  * @default 'switch'
47
59
  */
48
60
  variant?: 'checkbox' | 'switch' | 'button';
61
+ /**
62
+ * Whether the switch is enabled.
63
+ * @default true
64
+ * @platform android
65
+ */
66
+ enabled?: boolean;
49
67
  /**
50
68
  * Callback function that is called when the checked state changes.
51
69
  */
@@ -0,0 +1,37 @@
1
+ // AnimationSpec factories — return typed JSON matching Compose's AnimationSpec subtypes
2
+
3
+ export const spring = (params?: {
4
+ dampingRatio?: number;
5
+ stiffness?: number;
6
+ visibilityThreshold?: number;
7
+ }) => ({ $type: 'spring' as const, ...params });
8
+
9
+ export const tween = (params?: {
10
+ durationMillis?: number;
11
+ delayMillis?: number;
12
+ easing?: 'linear' | 'fastOutSlowIn' | 'fastOutLinearIn' | 'linearOutSlowIn' | 'ease';
13
+ }) => ({ $type: 'tween' as const, ...params });
14
+
15
+ export const snap = (params?: { delayMillis?: number }) => ({
16
+ $type: 'snap' as const,
17
+ ...params,
18
+ });
19
+
20
+ export const keyframes = (params: {
21
+ durationMillis: number;
22
+ delayMillis?: number;
23
+ keyframes: Record<number, number>;
24
+ }) => ({ $type: 'keyframes' as const, ...params });
25
+
26
+ export type AnimationSpec = ReturnType<
27
+ typeof spring | typeof tween | typeof snap | typeof keyframes
28
+ >;
29
+
30
+ // animated() wrapper — wraps a target value with an animation spec
31
+ export const animated = (targetValue: number, spec: AnimationSpec = spring()) => ({
32
+ $animated: true as const,
33
+ targetValue,
34
+ animationSpec: spec,
35
+ });
36
+
37
+ export type AnimatedValue = ReturnType<typeof animated>;
@@ -1,7 +1,17 @@
1
1
  import { type ColorValue } from 'react-native';
2
2
 
3
+ import { type AnimatedValue } from './animation';
3
4
  import { createModifier, createModifierWithEventListener } from './createModifier';
4
5
  export { type ExpoModifier } from '../../types';
6
+ export {
7
+ animated,
8
+ spring,
9
+ tween,
10
+ snap,
11
+ keyframes,
12
+ type AnimationSpec,
13
+ type AnimatedValue,
14
+ } from './animation';
5
15
 
6
16
  export type Alignment =
7
17
  // 2D Alignments
@@ -151,6 +161,48 @@ export const blur = (radius: number) => createModifier('blur', { radius });
151
161
  */
152
162
  export const rotate = (degrees: number) => createModifier('rotate', { degrees });
153
163
 
164
+ /**
165
+ * Applies a graphics layer transformation with animation support.
166
+ * @param params - Transform and visual effect parameters.
167
+ * @see [Compose graphicsLayer documentation](https://developer.android.com/develop/ui/compose/graphics/draw/modifiers).
168
+ */
169
+ export const graphicsLayer = (params: {
170
+ /** Rotation around the X axis in degrees. */
171
+ rotationX?: number | AnimatedValue;
172
+ /** Rotation around the Y axis in degrees. */
173
+ rotationY?: number | AnimatedValue;
174
+ /** Rotation around the Z axis in degrees. */
175
+ rotationZ?: number | AnimatedValue;
176
+ /** Horizontal scale factor (1.0 = no change). */
177
+ scaleX?: number | AnimatedValue;
178
+ /** Vertical scale factor (1.0 = no change). */
179
+ scaleY?: number | AnimatedValue;
180
+ /** Opacity (0.0 = transparent, 1.0 = opaque). */
181
+ alpha?: number | AnimatedValue;
182
+ /** Horizontal translation in dp. */
183
+ translationX?: number | AnimatedValue;
184
+ /** Vertical translation in dp. */
185
+ translationY?: number | AnimatedValue;
186
+ /** Distance from the camera in dp. Affects 3D rotation perspective. */
187
+ cameraDistance?: number;
188
+ /** Shadow elevation in dp. */
189
+ shadowElevation?: number | AnimatedValue;
190
+ /** Horizontal pivot point for transforms (0.0 = left, 0.5 = center, 1.0 = right). */
191
+ transformOriginX?: number;
192
+ /** Vertical pivot point for transforms (0.0 = top, 0.5 = center, 1.0 = bottom). */
193
+ transformOriginY?: number;
194
+ /** Whether to clip content to the shape. */
195
+ clip?: boolean;
196
+ /** Shape for clipping and shadow. Uses the same shapes as the `clip` modifier. */
197
+ shape?: BuiltinShape;
198
+ /** Color of the ambient shadow. */
199
+ ambientShadowColor?: ColorValue;
200
+ /** Color of the spot shadow. */
201
+ spotShadowColor?: ColorValue;
202
+ /** Compositing strategy: 'auto', 'offscreen', or 'modulate'. */
203
+ compositingStrategy?: 'auto' | 'offscreen' | 'modulate';
204
+ }) => createModifier('graphicsLayer', params);
205
+
154
206
  /**
155
207
  * Sets the z-index for layering.
156
208
  * @param index - Z-index value.
@@ -163,8 +215,8 @@ export const zIndex = (index: number) => createModifier('zIndex', { index });
163
215
 
164
216
  /**
165
217
  * Animates size changes with spring animation.
166
- * @param dampingRatio - Spring damping ratio. Default is DampingRatioNoBouncy.
167
- * @param stiffness - Spring stiffness. Default is StiffnessMedium.
218
+ * @param dampingRatio - Spring damping ratio. Default is `DampingRatioNoBouncy`.
219
+ * @param stiffness - Spring stiffness. Default is `StiffnessMedium`.
168
220
  */
169
221
  export const animateContentSize = (dampingRatio?: number, stiffness?: number) =>
170
222
  createModifier('animateContentSize', { dampingRatio, stiffness });
@@ -198,9 +250,13 @@ export const matchParentSize = () => createModifier('matchParentSize');
198
250
  /**
199
251
  * Makes the view clickable.
200
252
  * @param handler - Function to call when clicked.
253
+ * @param options - Optional configuration.
254
+ * @param options.indication - Whether to show a ripple indication. Defaults to `true`.
201
255
  */
202
- export const clickable = (handler: () => void) =>
203
- createModifierWithEventListener('clickable', handler);
256
+ export const clickable = (handler: () => void, options?: { indication?: boolean }) =>
257
+ createModifierWithEventListener('clickable', handler, {
258
+ indication: options?.indication ?? true,
259
+ });
204
260
 
205
261
  /**
206
262
  * Makes the view selectable, like a radio button row.
@@ -0,0 +1,12 @@
1
+ import { requireNativeView } from 'expo';
2
+
3
+ import { type CommonViewModifierProps } from '../types';
4
+
5
+ export type AccessoryWidgetBackgroundProps = CommonViewModifierProps;
6
+
7
+ const AccessoryWidgetBackgroundNativeView: React.ComponentType<AccessoryWidgetBackgroundProps> =
8
+ requireNativeView('ExpoUI', 'AccessoryWidgetBackgroundView');
9
+
10
+ export function AccessoryWidgetBackground(props: AccessoryWidgetBackgroundProps) {
11
+ return <AccessoryWidgetBackgroundNativeView {...props} />;
12
+ }
@@ -1,6 +1,7 @@
1
1
  import { requireNativeView } from 'expo';
2
2
  import { NativeSyntheticEvent } from 'react-native';
3
3
 
4
+ import { Slot } from '../SlotView';
4
5
  import { createViewModifierEventListener } from '../modifiers/utils';
5
6
  import { type CommonViewModifierProps } from '../types';
6
7
 
@@ -39,34 +40,25 @@ type NativeConfirmationDialogProps = Omit<ConfirmationDialogProps, 'onIsPresente
39
40
  const ConfirmationDialogNativeView: React.ComponentType<NativeConfirmationDialogProps> =
40
41
  requireNativeView('ExpoUI', 'ConfirmationDialogView');
41
42
 
42
- const ConfirmationDialogNativeTrigger: React.ComponentType<{ children: React.ReactNode }> =
43
- requireNativeView('ExpoUI', 'ConfirmationDialogTrigger');
44
-
45
- const ConfirmationDialogNativeActions: React.ComponentType<{ children: React.ReactNode }> =
46
- requireNativeView('ExpoUI', 'ConfirmationDialogActions');
47
-
48
- const ConfirmationDialogNativeMessage: React.ComponentType<{ children: React.ReactNode }> =
49
- requireNativeView('ExpoUI', 'ConfirmationDialogMessage');
50
-
51
43
  /**
52
44
  * The component visible all the time that triggers the confirmation dialog presentation.
53
45
  */
54
46
  function Trigger(props: { children: React.ReactNode }) {
55
- return <ConfirmationDialogNativeTrigger {...props} />;
47
+ return <Slot name="trigger">{props.children}</Slot>;
56
48
  }
57
49
 
58
50
  /**
59
51
  * The action buttons displayed in the confirmation dialog. Use `Button` components from `@expo/ui/swift-ui` as children.
60
52
  */
61
53
  function Actions(props: { children: React.ReactNode }) {
62
- return <ConfirmationDialogNativeActions {...props} />;
54
+ return <Slot name="actions">{props.children}</Slot>;
63
55
  }
64
56
 
65
57
  /**
66
58
  * An optional message displayed below the title in the confirmation dialog.
67
59
  */
68
60
  function Message(props: { children: React.ReactNode }) {
69
- return <ConfirmationDialogNativeMessage {...props} />;
61
+ return <Slot name="message">{props.children}</Slot>;
70
62
  }
71
63
 
72
64
  /**
@@ -2,47 +2,33 @@ import { requireNativeView } from 'expo';
2
2
  import { ComponentType } from 'react';
3
3
 
4
4
  import { type ContextMenuProps } from './types';
5
+ import { Slot } from '../SlotView';
5
6
 
6
7
  export { type ContextMenuProps } from './types';
7
8
 
8
- const MenuNativeView: ComponentType<NativeMenuProps> = requireNativeView('ExpoUI', 'ContextMenu');
9
-
10
- const MenuNativeTriggerView: ComponentType<object> = requireNativeView(
11
- 'ExpoUI',
12
- 'ContextMenuActivationElement'
13
- );
14
-
15
- const MenuNativePreviewView: ComponentType<object> = requireNativeView(
16
- 'ExpoUI',
17
- 'ContextMenuPreview'
18
- );
19
-
20
- const MenuNativeItemsView: ComponentType<object> = requireNativeView(
21
- 'ExpoUI',
22
- 'ContextMenuContent'
23
- );
24
-
25
9
  type NativeMenuProps = ContextMenuProps;
26
10
 
11
+ const MenuNativeView: ComponentType<NativeMenuProps> = requireNativeView('ExpoUI', 'ContextMenu');
12
+
27
13
  /**
28
14
  * Items visible inside the context menu. It could be `Section`, `Divider`, `Button`, `Toggle`, `Picker` or even `ContextMenu` itself for nested menus. Remember to use components from the `@expo/ui/swift-ui` library.
29
15
  */
30
16
  export function Items(props: { children: React.ReactNode }) {
31
- return <MenuNativeItemsView {...props} />;
17
+ return <Slot name="items">{props.children}</Slot>;
32
18
  }
33
19
 
34
20
  /**
35
21
  * The component visible all the time that triggers the context menu when long-pressed.
36
22
  */
37
23
  export function Trigger(props: { children: React.ReactNode }) {
38
- return <MenuNativeTriggerView {...props} />;
24
+ return <Slot name="trigger">{props.children}</Slot>;
39
25
  }
40
26
 
41
27
  /**
42
28
  * The component visible above the menu when it is opened.
43
29
  */
44
30
  export function Preview(props: { children: React.ReactNode }) {
45
- return <MenuNativePreviewView {...props} />;
31
+ return <Slot name="preview">{props.children}</Slot>;
46
32
  }
47
33
 
48
34
  /**
@@ -0,0 +1,59 @@
1
+ import { requireNativeView } from 'expo';
2
+ import { type ReactNode, type ComponentType } from 'react';
3
+ import { type SFSymbol } from 'sf-symbols-typescript';
4
+
5
+ import { Slot } from '../SlotView';
6
+ import { createViewModifierEventListener } from '../modifiers/utils';
7
+ import { type CommonViewModifierProps } from '../types';
8
+
9
+ export interface ControlGroupProps extends CommonViewModifierProps {
10
+ /**
11
+ * The label for the control group. Can be a string for simple text labels,
12
+ * or a `Label` component for custom label content. When omitted, the control group
13
+ * has no label.
14
+ * @platform iOS 16.0+
15
+ * @platform tvOS 17.0+
16
+ */
17
+ label?: string | ReactNode;
18
+ /**
19
+ * An SF Symbol name to display alongside the label.
20
+ * Only used when `label` is a string.
21
+ * @platform iOS 16.0+
22
+ * @platform tvOS 17.0+
23
+ */
24
+ systemImage?: SFSymbol;
25
+ /**
26
+ * The control group's content.
27
+ * Can contain `Button`, `Toggle`, `Picker`, or other interactive controls.
28
+ * @platform iOS
29
+ * @platform tvOS 17.0+
30
+ */
31
+ children: ReactNode;
32
+ }
33
+
34
+ type NativeControlGroupProps = Omit<ControlGroupProps, 'label'> & {
35
+ label?: string;
36
+ };
37
+
38
+ const ControlGroupNativeView: ComponentType<NativeControlGroupProps> = requireNativeView(
39
+ 'ExpoUI',
40
+ 'ControlGroupView'
41
+ );
42
+
43
+ export function ControlGroup(props: ControlGroupProps) {
44
+ const { label, children, systemImage, modifiers, ...rest } = props;
45
+
46
+ const isStringLabel = typeof label === 'string';
47
+
48
+ return (
49
+ <ControlGroupNativeView
50
+ label={isStringLabel ? label : undefined}
51
+ systemImage={systemImage}
52
+ modifiers={modifiers}
53
+ {...(modifiers ? createViewModifierEventListener(modifiers) : undefined)}
54
+ {...rest}>
55
+ {!isStringLabel && label != null ? <Slot name="label">{label}</Slot> : null}
56
+ {children}
57
+ </ControlGroupNativeView>
58
+ );
59
+ }
@@ -1,13 +1,9 @@
1
1
  import { requireNativeView } from 'expo';
2
2
 
3
+ import { Slot } from '../SlotView';
3
4
  import { createViewModifierEventListener } from '../modifiers/utils';
4
5
  import { type CommonViewModifierProps } from '../types';
5
6
 
6
- /**
7
- * The type of gauge label.
8
- */
9
- type GaugeLabelKind = 'label' | 'currentValue' | 'minimumValue' | 'maximumValue';
10
-
11
7
  export type GaugeProps = {
12
8
  /**
13
9
  * The current value of the gauge.
@@ -53,11 +49,6 @@ const GaugeNativeView: React.ComponentType<NativeGaugeProps> = requireNativeView
53
49
  'GaugeView'
54
50
  );
55
51
 
56
- const GaugeLabelNativeView: React.ComponentType<{
57
- kind: GaugeLabelKind;
58
- children?: React.ReactNode;
59
- }> = requireNativeView('ExpoUI', 'GaugeLabelView');
60
-
61
52
  /**
62
53
  * Renders a SwiftUI `Gauge` component.
63
54
  */
@@ -76,16 +67,10 @@ export function Gauge(props: GaugeProps) {
76
67
  modifiers={modifiers}
77
68
  {...(modifiers ? createViewModifierEventListener(modifiers) : undefined)}
78
69
  {...restProps}>
79
- {children && <GaugeLabelNativeView kind="label">{children}</GaugeLabelNativeView>}
80
- {currentValueLabel && (
81
- <GaugeLabelNativeView kind="currentValue">{currentValueLabel}</GaugeLabelNativeView>
82
- )}
83
- {minimumValueLabel && (
84
- <GaugeLabelNativeView kind="minimumValue">{minimumValueLabel}</GaugeLabelNativeView>
85
- )}
86
- {maximumValueLabel && (
87
- <GaugeLabelNativeView kind="maximumValue">{maximumValueLabel}</GaugeLabelNativeView>
88
- )}
70
+ {children && <Slot name="label">{children}</Slot>}
71
+ {currentValueLabel && <Slot name="currentValue">{currentValueLabel}</Slot>}
72
+ {minimumValueLabel && <Slot name="minimumValue">{minimumValueLabel}</Slot>}
73
+ {maximumValueLabel && <Slot name="maximumValue">{maximumValueLabel}</Slot>}
89
74
  </GaugeNativeView>
90
75
  );
91
76
  }
@@ -11,7 +11,13 @@ export interface ImageProps extends CommonViewModifierProps {
11
11
  * The name of the system image (SF Symbol).
12
12
  * For example: 'photo', 'heart.fill', 'star.circle'
13
13
  */
14
- systemName: SFSymbol;
14
+ systemName?: SFSymbol;
15
+ /**
16
+ * The URI of the local image file to display.
17
+ * For example: 'file:///path/to/image.jpg'
18
+ * Performs a synchronous read operation that blocks the main thread.
19
+ */
20
+ uiImage?: string;
15
21
  /**
16
22
  * The size of the system image.
17
23
  */
@@ -2,6 +2,7 @@ import { requireNativeView } from 'expo';
2
2
  import type { ColorValue } from 'react-native';
3
3
  import { type SFSymbol } from 'sf-symbols-typescript';
4
4
 
5
+ import { Slot } from '../SlotView';
5
6
  import { createViewModifierEventListener } from '../modifiers/utils';
6
7
  import { type CommonViewModifierProps } from '../types';
7
8
 
@@ -31,10 +32,6 @@ export type LabelProps = {
31
32
 
32
33
  const LabelNativeView: React.ComponentType<LabelProps & { children?: React.ReactNode }> =
33
34
  requireNativeView('ExpoUI', 'LabelView');
34
- const LabelIconNativeView: React.ComponentType<{ children?: React.ReactNode }> = requireNativeView(
35
- 'ExpoUI',
36
- 'LabelIcon'
37
- );
38
35
 
39
36
  /**
40
37
  * Renders a native label view, which could be used in a list or section.
@@ -49,7 +46,7 @@ export function Label(props: LabelProps) {
49
46
  modifiers={modifiers}
50
47
  {...(modifiers ? createViewModifierEventListener(modifiers) : undefined)}
51
48
  {...restProps}>
52
- {icon && <LabelIconNativeView>{icon}</LabelIconNativeView>}
49
+ {icon && <Slot name="icon">{icon}</Slot>}
53
50
  </LabelNativeView>
54
51
  );
55
52
  }