@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
package/CHANGELOG.md CHANGED
@@ -10,6 +10,33 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 55.0.2 — 2026-03-11
14
+
15
+ ### 🎉 New features
16
+
17
+ - [Android] Added `graphicsLayer` modifier and animation helpers for per-value animation in it. Added `indication` option to `clickable` modifier to control ripple effects. ([#43655](https://github.com/expo/expo/pull/43655) by [@vonovak](https://github.com/vonovak))
18
+ - [Android] Added border color customization for `Switch` and `Checkbox` components. ([#43770](https://github.com/expo/expo/pull/43770) by [@liestig](https://github.com/liestig))
19
+ - [iOS] Added `rotation3DEffect` modifier for 3D rotation transforms ([#43640](https://github.com/expo/expo/pull/43640) by [@vonovak](https://github.com/vonovak))
20
+ - [iOS] Added `ControlGroup` component. ([#43581](https://github.com/expo/expo/pull/43581) by [@nishan](https://github.com/intergalacticspacehighway))
21
+ - [android] detect FAB in HorizontalFloatingToolbar ([#43601](https://github.com/expo/expo/pull/43601) by [@Ubax](https://github.com/Ubax))
22
+ - [android] Add `elementColors` prop to the `DateTimePicker` component ([#43787](https://github.com/expo/expo/pull/43787) by [@iankberry](https://github.com/iankberry))
23
+ - [iOS] Added `AccessoryWidgetBackground` component ([#43729](https://github.com/expo/expo/pull/43729) by [@huextrat](https://github.com/huextrat))
24
+ - [iOS] Add support for local image uri ([#43707](https://github.com/expo/expo/pull/43707) by [@jakex7](https://github.com/jakex7))
25
+
26
+ ### 🐛 Bug fixes
27
+
28
+ - [iOS] Fix `Slider` thumb snapping back during drag by guarding `.onReceive` with `isEditing` state. ([#43701](https://github.com/expo/expo/issues/43701) by [@fedeciancaglini](https://github.com/fedeciancaglini)) ([#43797](https://github.com/expo/expo/pull/43797) by [@fedeciancaglini](https://github.com/fedeciancaglini))
29
+ - [Android] Fix touch events for RN views inside Compose BottomSheet. ([#43716](https://github.com/expo/expo/pull/43716) by [@nishan](https://github.com/intergalacticspacehighway))
30
+ - [Android] Fix `RNHostView` child parent related crash. ([#43691](https://github.com/expo/expo/pull/43691) by [@nishan](https://github.com/intergalacticspacehighway))
31
+ - [Android] Added `RNHostView` to improve RN component layout inside Compose views. ([#43495](https://github.com/expo/expo/pull/43495) by [@nishan](https://github.com/intergalacticspacehighway))
32
+ - [Android] Fix `ContextMenu` not expanding when triggered by `IconButton`. ([#43592](https://github.com/expo/expo/pull/43592) by [@nishan](https://github.com/intergalacticspacehighway))
33
+
34
+ ### 💡 Others
35
+
36
+ - [iOS] Add `AsyncFunction` support in `ExpoUIView` definition function. ([#43669](https://github.com/expo/expo/pull/43669) by [@nishan](https://github.com/intergalacticspacehighway))
37
+ - [iOS] Introduce `SlotView` to replace structural child view types with a single generic slot. ([#43607](https://github.com/expo/expo/pull/43607) by [@nishan](https://github.com/intergalacticspacehighway))
38
+ - [iOS] Make RNHostView SwiftUI view ([#43570](https://github.com/expo/expo/pull/43570) by [@nishan](https://github.com/intergalacticspacehighway))
39
+
13
40
  ## 55.0.1 — 2026-02-25
14
41
 
15
42
  ### 🎉 New features
@@ -0,0 +1,30 @@
1
+ # Contributing to `@expo/ui`
2
+
3
+ `@expo/ui` maps native UI frameworks (SwiftUI on iOS, Jetpack Compose on Android) to React Native.
4
+
5
+ ## Before opening a PR
6
+
7
+ - [ ] Rebuilt JS output: `yarn build` (from `packages/expo-ui/`) and committed the `build/` output.
8
+
9
+ ### When adding or updating a component
10
+
11
+ - [ ] Added an example to the relevant screen in `apps/native-component-list/src/screens/UI/`
12
+ - [ ] Regenerated docs (from repo root): `et gdad -p "expo-ui/swift-ui/<component>"` and/or `et gdad -p "expo-ui/jetpack-compose/<component>"`
13
+ - [ ] Added an example in the relevant docs page
14
+
15
+ ### When adding or updating a modifier
16
+
17
+ - [ ] Added an example to the relevant screen in `apps/native-component-list/src/screens/UI/`
18
+ - [ ] Regenerated docs (from repo root): `et gdad -p "expo-ui/swift-ui/modifiers"` and/or `et gdad -p "expo-ui/jetpack-compose/modifiers"`
19
+
20
+ ## Project structure
21
+
22
+ - `packages/expo-ui/ios/` - Swift/SwiftUI source files
23
+ - `packages/expo-ui/android/` - Kotlin/Jetpack Compose source files
24
+ - `packages/expo-ui/src/swift-ui/` - TypeScript components and types for the SwiftUI side
25
+ - `packages/expo-ui/src/jetpack-compose/` - TypeScript components and types for the Compose side
26
+
27
+ ## General guidelines
28
+
29
+ - **Match the native APIs** — prop names, types, and behavior should mirror their SwiftUI / Jetpack Compose counterparts as closely as possible.
30
+ - **Reuse existing types** — before creating a new Record or TypeScript type, check if one already exists.
@@ -12,13 +12,13 @@ apply plugin: 'expo-module-gradle-plugin'
12
12
  apply plugin: 'org.jetbrains.kotlin.plugin.compose'
13
13
 
14
14
  group = 'expo.modules.ui'
15
- version = '55.0.1'
15
+ version = '55.0.2'
16
16
 
17
17
  android {
18
18
  namespace "expo.modules.ui"
19
19
  defaultConfig {
20
20
  versionCode 1
21
- versionName "55.0.1"
21
+ versionName "55.0.2"
22
22
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
23
23
  }
24
24
  buildFeatures {
@@ -47,6 +47,49 @@ enum class Variant(val value: String) : Enumerable {
47
47
  }
48
48
  }
49
49
 
50
+ class DateTimePickerColorOverrides : Record {
51
+ // DatePicker colors
52
+ @Field val containerColor: AndroidColor? = null
53
+ @Field val titleContentColor: AndroidColor? = null
54
+ @Field val headlineContentColor: AndroidColor? = null
55
+ @Field val weekdayContentColor: AndroidColor? = null
56
+ @Field val subheadContentColor: AndroidColor? = null
57
+ @Field val navigationContentColor: AndroidColor? = null
58
+ @Field val yearContentColor: AndroidColor? = null
59
+ @Field val disabledYearContentColor: AndroidColor? = null
60
+ @Field val currentYearContentColor: AndroidColor? = null
61
+ @Field val selectedYearContentColor: AndroidColor? = null
62
+ @Field val disabledSelectedYearContentColor: AndroidColor? = null
63
+ @Field val selectedYearContainerColor: AndroidColor? = null
64
+ @Field val disabledSelectedYearContainerColor: AndroidColor? = null
65
+ @Field val dayContentColor: AndroidColor? = null
66
+ @Field val disabledDayContentColor: AndroidColor? = null
67
+ @Field val selectedDayContentColor: AndroidColor? = null
68
+ @Field val disabledSelectedDayContentColor: AndroidColor? = null
69
+ @Field val selectedDayContainerColor: AndroidColor? = null
70
+ @Field val disabledSelectedDayContainerColor: AndroidColor? = null
71
+ @Field val todayContentColor: AndroidColor? = null
72
+ @Field val todayDateBorderColor: AndroidColor? = null
73
+ @Field val dayInSelectionRangeContentColor: AndroidColor? = null
74
+ @Field val dayInSelectionRangeContainerColor: AndroidColor? = null
75
+ @Field val dividerColor: AndroidColor? = null
76
+
77
+ // TimePicker colors
78
+ @Field val clockDialColor: AndroidColor? = null
79
+ @Field val clockDialSelectedContentColor: AndroidColor? = null
80
+ @Field val clockDialUnselectedContentColor: AndroidColor? = null
81
+ @Field val selectorColor: AndroidColor? = null
82
+ @Field val periodSelectorBorderColor: AndroidColor? = null
83
+ @Field val periodSelectorSelectedContainerColor: AndroidColor? = null
84
+ @Field val periodSelectorUnselectedContainerColor: AndroidColor? = null
85
+ @Field val periodSelectorSelectedContentColor: AndroidColor? = null
86
+ @Field val periodSelectorUnselectedContentColor: AndroidColor? = null
87
+ @Field val timeSelectorSelectedContainerColor: AndroidColor? = null
88
+ @Field val timeSelectorUnselectedContainerColor: AndroidColor? = null
89
+ @Field val timeSelectorSelectedContentColor: AndroidColor? = null
90
+ @Field val timeSelectorUnselectedContentColor: AndroidColor? = null
91
+ }
92
+
50
93
  data class DateTimePickerProps(
51
94
  val title: String = "",
52
95
  val initialDate: Long? = null,
@@ -55,6 +98,7 @@ data class DateTimePickerProps(
55
98
  val showVariantToggle: Boolean = true,
56
99
  val is24Hour: Boolean = true,
57
100
  val color: AndroidColor? = null,
101
+ val elementColors: DateTimePickerColorOverrides = DateTimePickerColorOverrides(),
58
102
  val modifiers: ModifierList = emptyList()
59
103
  ) : ComposeProps
60
104
 
@@ -94,15 +138,39 @@ fun ExpoDatePicker(modifier: Modifier = Modifier, props: DateTimePickerProps, on
94
138
  onDateSelected(DatePickerResult(date = state.selectedDateMillis))
95
139
  }
96
140
 
141
+ val elementColors = props.elementColors
142
+ val colorProp = props.color.composeOrNull
143
+ val defaults = DatePickerDefaults.colors()
144
+
97
145
  DatePicker(
98
146
  modifier = modifier,
99
147
  state = state,
100
148
  showModeToggle = props.showVariantToggle,
101
149
  colors = DatePickerDefaults.colors().copy(
102
- titleContentColor = colorToComposeColor(props.color),
103
- selectedDayContainerColor = colorToComposeColor(props.color),
104
- todayDateBorderColor = colorToComposeColor(props.color),
105
- headlineContentColor = colorToComposeColor(props.color)
150
+ containerColor = elementColors.containerColor.composeOrNull ?: defaults.containerColor,
151
+ titleContentColor = elementColors.titleContentColor.composeOrNull ?: colorProp ?: defaults.titleContentColor,
152
+ headlineContentColor = elementColors.headlineContentColor.composeOrNull ?: colorProp ?: defaults.headlineContentColor,
153
+ weekdayContentColor = elementColors.weekdayContentColor.composeOrNull ?: defaults.weekdayContentColor,
154
+ subheadContentColor = elementColors.subheadContentColor.composeOrNull ?: defaults.subheadContentColor,
155
+ navigationContentColor = elementColors.navigationContentColor.composeOrNull ?: defaults.navigationContentColor,
156
+ yearContentColor = elementColors.yearContentColor.composeOrNull ?: defaults.yearContentColor,
157
+ disabledYearContentColor = elementColors.disabledYearContentColor.composeOrNull ?: defaults.disabledYearContentColor,
158
+ currentYearContentColor = elementColors.currentYearContentColor.composeOrNull ?: defaults.currentYearContentColor,
159
+ selectedYearContentColor = elementColors.selectedYearContentColor.composeOrNull ?: defaults.selectedYearContentColor,
160
+ disabledSelectedYearContentColor = elementColors.disabledSelectedYearContentColor.composeOrNull ?: defaults.disabledSelectedYearContentColor,
161
+ selectedYearContainerColor = elementColors.selectedYearContainerColor.composeOrNull ?: defaults.selectedYearContainerColor,
162
+ disabledSelectedYearContainerColor = elementColors.disabledSelectedYearContainerColor.composeOrNull ?: defaults.disabledSelectedYearContainerColor,
163
+ dayContentColor = elementColors.dayContentColor.composeOrNull ?: defaults.dayContentColor,
164
+ disabledDayContentColor = elementColors.disabledDayContentColor.composeOrNull ?: defaults.disabledDayContentColor,
165
+ selectedDayContentColor = elementColors.selectedDayContentColor.composeOrNull ?: defaults.selectedDayContentColor,
166
+ disabledSelectedDayContentColor = elementColors.disabledSelectedDayContentColor.composeOrNull ?: defaults.disabledSelectedDayContentColor,
167
+ selectedDayContainerColor = elementColors.selectedDayContainerColor.composeOrNull ?: colorProp ?: defaults.selectedDayContainerColor,
168
+ disabledSelectedDayContainerColor = elementColors.disabledSelectedDayContainerColor.composeOrNull ?: defaults.disabledSelectedDayContainerColor,
169
+ todayContentColor = elementColors.todayContentColor.composeOrNull ?: defaults.todayContentColor,
170
+ todayDateBorderColor = elementColors.todayDateBorderColor.composeOrNull ?: colorProp ?: defaults.todayDateBorderColor,
171
+ dayInSelectionRangeContentColor = elementColors.dayInSelectionRangeContentColor.composeOrNull ?: defaults.dayInSelectionRangeContentColor,
172
+ dayInSelectionRangeContainerColor = elementColors.dayInSelectionRangeContainerColor.composeOrNull ?: defaults.dayInSelectionRangeContainerColor,
173
+ dividerColor = elementColors.dividerColor.composeOrNull ?: defaults.dividerColor
106
174
  )
107
175
  )
108
176
  }
@@ -137,14 +205,29 @@ fun ExpoTimePicker(modifier: Modifier = Modifier, props: DateTimePickerProps, on
137
205
  onDateSelected(DatePickerResult(date = cal.time.time))
138
206
  }
139
207
 
208
+ val elementColors = props.elementColors
209
+ val colorProp = props.color.composeOrNull
210
+ val defaults = TimePickerDefaults.colors()
211
+
140
212
  TimePicker(
141
213
  modifier = modifier,
142
214
  state = state,
143
215
  layoutType = TimePickerLayoutType.Vertical,
144
216
  colors = TimePickerDefaults.colors().copy(
145
- selectorColor = colorToComposeColor(props.color),
146
- timeSelectorSelectedContainerColor = colorToComposeColor(props.color),
147
- clockDialColor = colorToComposeColor(props.color).copy(alpha = 0.3f)
217
+ containerColor = elementColors.containerColor.composeOrNull ?: defaults.containerColor,
218
+ clockDialColor = elementColors.clockDialColor.composeOrNull ?: colorProp?.copy(alpha = 0.3f) ?: defaults.clockDialColor,
219
+ clockDialSelectedContentColor = elementColors.clockDialSelectedContentColor.composeOrNull ?: defaults.clockDialSelectedContentColor,
220
+ clockDialUnselectedContentColor = elementColors.clockDialUnselectedContentColor.composeOrNull ?: defaults.clockDialUnselectedContentColor,
221
+ selectorColor = elementColors.selectorColor.composeOrNull ?: colorProp ?: defaults.selectorColor,
222
+ periodSelectorBorderColor = elementColors.periodSelectorBorderColor.composeOrNull ?: defaults.periodSelectorBorderColor,
223
+ periodSelectorSelectedContainerColor = elementColors.periodSelectorSelectedContainerColor.composeOrNull ?: defaults.periodSelectorSelectedContainerColor,
224
+ periodSelectorUnselectedContainerColor = elementColors.periodSelectorUnselectedContainerColor.composeOrNull ?: defaults.periodSelectorUnselectedContainerColor,
225
+ periodSelectorSelectedContentColor = elementColors.periodSelectorSelectedContentColor.composeOrNull ?: defaults.periodSelectorSelectedContentColor,
226
+ periodSelectorUnselectedContentColor = elementColors.periodSelectorUnselectedContentColor.composeOrNull ?: defaults.periodSelectorUnselectedContentColor,
227
+ timeSelectorSelectedContainerColor = elementColors.timeSelectorSelectedContainerColor.composeOrNull ?: colorProp ?: defaults.timeSelectorSelectedContainerColor,
228
+ timeSelectorUnselectedContainerColor = elementColors.timeSelectorUnselectedContainerColor.composeOrNull ?: defaults.timeSelectorUnselectedContainerColor,
229
+ timeSelectorSelectedContentColor = elementColors.timeSelectorSelectedContentColor.composeOrNull ?: defaults.timeSelectorSelectedContentColor,
230
+ timeSelectorUnselectedContentColor = elementColors.timeSelectorUnselectedContentColor.composeOrNull ?: defaults.timeSelectorUnselectedContentColor
148
231
  )
149
232
  )
150
233
  }
@@ -51,13 +51,26 @@ fun FunctionalComposableScope.HorizontalFloatingToolbarContent(props: Horizontal
51
51
  }
52
52
 
53
53
  val scrollBehavior = composableScope.nestedScrollConnection as? FloatingToolbarScrollBehavior
54
- HorizontalFloatingToolbar(
55
- expanded = true,
56
- colors = colors,
57
- scrollBehavior = scrollBehavior,
58
- modifier = ModifierRegistry.applyModifiers(props.modifiers, appContext, composableScope, globalEventDispatcher),
59
- floatingActionButton = floatingActionButton
60
- ) {
61
- Children(ComposableScope(), filter = { !isSlotView(it) })
54
+ val modifier = ModifierRegistry.applyModifiers(props.modifiers, appContext, composableScope, globalEventDispatcher)
55
+
56
+ if (fabSlotView != null) {
57
+ HorizontalFloatingToolbar(
58
+ expanded = true,
59
+ floatingActionButton = floatingActionButton,
60
+ colors = colors,
61
+ scrollBehavior = scrollBehavior,
62
+ modifier = modifier,
63
+ ) {
64
+ Children(ComposableScope(), filter = { !isSlotView(it) })
65
+ }
66
+ } else {
67
+ HorizontalFloatingToolbar(
68
+ expanded = true,
69
+ colors = colors,
70
+ scrollBehavior = scrollBehavior,
71
+ modifier = modifier,
72
+ ) {
73
+ Children(ComposableScope(), filter = { !isSlotView(it) })
74
+ }
62
75
  }
63
76
  }
@@ -27,14 +27,20 @@ import androidx.compose.foundation.shape.RoundedCornerShape
27
27
  import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
28
28
  import androidx.compose.material3.toShape
29
29
  import androidx.compose.runtime.Composable
30
+ import expo.modules.ui.convertibles.resolveAnimatable
30
31
  import androidx.compose.ui.Modifier
31
32
  import androidx.compose.ui.draw.alpha
32
33
  import androidx.compose.ui.draw.blur
33
34
  import androidx.compose.ui.draw.clip
34
35
  import androidx.compose.ui.draw.rotate
35
36
  import androidx.compose.ui.draw.shadow
37
+ import androidx.compose.ui.graphics.CompositingStrategy
36
38
  import androidx.compose.ui.graphics.RectangleShape
39
+ import androidx.compose.ui.graphics.Shape
40
+ import androidx.compose.ui.graphics.TransformOrigin
41
+ import androidx.compose.ui.graphics.graphicsLayer
37
42
  import androidx.compose.ui.unit.dp
43
+ import androidx.compose.ui.platform.LocalDensity
38
44
  import androidx.compose.ui.zIndex
39
45
  import expo.modules.kotlin.AppContext
40
46
  import expo.modules.kotlin.records.Field
@@ -43,6 +49,8 @@ import expo.modules.kotlin.records.recordFromMap
43
49
  import expo.modules.kotlin.types.Enumerable
44
50
  import expo.modules.kotlin.views.ComposableScope
45
51
  import expo.modules.ui.convertibles.AlignmentType
52
+ import expo.modules.ui.convertibles.CompositingStrategyType
53
+ import expo.modules.ui.convertibles.GraphicsLayerParams
46
54
 
47
55
  typealias ModifierType = Map<String, Any?>
48
56
  typealias ModifierList = List<ModifierType>
@@ -172,6 +180,10 @@ internal data class SelectableParams(
172
180
  @Field val selected: Boolean = false
173
181
  ) : Record
174
182
 
183
+ internal data class ClickableParams(
184
+ @Field val indication: Boolean = true
185
+ ) : Record
186
+
175
187
  // endregion
176
188
 
177
189
  /**
@@ -191,6 +203,43 @@ object ModifierRegistry {
191
203
 
192
204
  private val modifierFactories: MutableMap<String, ModifierFactory> = mutableMapOf()
193
205
 
206
+ @Composable
207
+ private fun resolveShape(shape: BuiltinShapeRecord): Shape? {
208
+ return when (shape.type) {
209
+ BuiltinShapeType.RECTANGLE -> RectangleShape
210
+ BuiltinShapeType.CIRCLE -> CircleShape
211
+ BuiltinShapeType.ROUNDED_CORNER -> {
212
+ val hasPerCorner = shape.topStart != null || shape.topEnd != null || shape.bottomStart != null || shape.bottomEnd != null
213
+ if (hasPerCorner) {
214
+ RoundedCornerShape(
215
+ topStart = (shape.topStart ?: 0f).dp,
216
+ topEnd = (shape.topEnd ?: 0f).dp,
217
+ bottomStart = (shape.bottomStart ?: 0f).dp,
218
+ bottomEnd = (shape.bottomEnd ?: 0f).dp
219
+ )
220
+ } else {
221
+ RoundedCornerShape((shape.radius ?: 0f).dp)
222
+ }
223
+ }
224
+ BuiltinShapeType.CUT_CORNER -> {
225
+ val hasPerCorner = shape.topStart != null || shape.topEnd != null || shape.bottomStart != null || shape.bottomEnd != null
226
+ if (hasPerCorner) {
227
+ CutCornerShape(
228
+ topStart = (shape.topStart ?: 0f).dp,
229
+ topEnd = (shape.topEnd ?: 0f).dp,
230
+ bottomStart = (shape.bottomStart ?: 0f).dp,
231
+ bottomEnd = (shape.bottomEnd ?: 0f).dp
232
+ )
233
+ } else {
234
+ CutCornerShape((shape.radius ?: 0f).dp)
235
+ }
236
+ }
237
+ BuiltinShapeType.MATERIAL -> {
238
+ shape.name?.toRoundedPolygon()?.toShape()
239
+ }
240
+ }
241
+ }
242
+
194
243
  init {
195
244
  registerBuiltInModifiers()
196
245
  }
@@ -342,6 +391,48 @@ object ModifierRegistry {
342
391
  Modifier.rotate(params.degrees)
343
392
  }
344
393
 
394
+ register("graphicsLayer") { map, _, _, _ ->
395
+ val rotationX = resolveAnimatable(map, "rotationX", 0f)
396
+ val rotationY = resolveAnimatable(map, "rotationY", 0f)
397
+ val rotationZ = resolveAnimatable(map, "rotationZ", 0f)
398
+ val scaleX = resolveAnimatable(map, "scaleX", 1f)
399
+ val scaleY = resolveAnimatable(map, "scaleY", 1f)
400
+ val alphaVal = resolveAnimatable(map, "alpha", 1f)
401
+ val translationX = resolveAnimatable(map, "translationX", 0f)
402
+ val translationY = resolveAnimatable(map, "translationY", 0f)
403
+ val shadowElevation = resolveAnimatable(map, "shadowElevation", 0f)
404
+
405
+ // Non-animatable params parsed via Record
406
+ val params = recordFromMap<GraphicsLayerParams>(map)
407
+ val composeShape = params.shape?.let { resolveShape(it) } ?: RectangleShape
408
+ val compositingStrategy = when (params.compositingStrategy) {
409
+ CompositingStrategyType.OFFSCREEN -> CompositingStrategy.Offscreen
410
+ CompositingStrategyType.MODULATE -> CompositingStrategy.ModulateAlpha
411
+ else -> CompositingStrategy.Auto
412
+ }
413
+
414
+ val density = LocalDensity.current.density
415
+
416
+ Modifier.graphicsLayer {
417
+ this.rotationX = rotationX
418
+ this.rotationY = rotationY
419
+ this.rotationZ = rotationZ
420
+ this.scaleX = scaleX
421
+ this.scaleY = scaleY
422
+ this.alpha = alphaVal
423
+ this.translationX = translationX * density
424
+ this.translationY = translationY * density
425
+ this.cameraDistance = params.cameraDistance * density
426
+ this.shadowElevation = shadowElevation * density
427
+ this.transformOrigin = TransformOrigin(params.transformOriginX, params.transformOriginY)
428
+ this.clip = params.clip
429
+ this.shape = composeShape
430
+ this.compositingStrategy = compositingStrategy
431
+ params.ambientShadowColor?.let { this.ambientShadowColor = it.compose }
432
+ params.spotShadowColor?.let { this.spotShadowColor = it.compose }
433
+ }
434
+ }
435
+
345
436
  register("zIndex") { map, _, _, _ ->
346
437
  val params = recordFromMap<ZIndexParams>(map)
347
438
  Modifier.zIndex(params.index)
@@ -393,48 +484,23 @@ object ModifierRegistry {
393
484
  register("clip") { map, _, _, _ ->
394
485
  val params = recordFromMap<ClipParams>(map)
395
486
  params.shape?.let { shape ->
396
- val composeShape = when (shape.type) {
397
- BuiltinShapeType.RECTANGLE -> RectangleShape
398
- BuiltinShapeType.CIRCLE -> CircleShape
399
- BuiltinShapeType.ROUNDED_CORNER -> {
400
- val hasPerCorner = shape.topStart != null || shape.topEnd != null || shape.bottomStart != null || shape.bottomEnd != null
401
- if (hasPerCorner) {
402
- RoundedCornerShape(
403
- topStart = (shape.topStart ?: 0f).dp,
404
- topEnd = (shape.topEnd ?: 0f).dp,
405
- bottomStart = (shape.bottomStart ?: 0f).dp,
406
- bottomEnd = (shape.bottomEnd ?: 0f).dp
407
- )
408
- } else {
409
- RoundedCornerShape((shape.radius ?: 0f).dp)
410
- }
411
- }
412
- BuiltinShapeType.CUT_CORNER -> {
413
- val hasPerCorner = shape.topStart != null || shape.topEnd != null || shape.bottomStart != null || shape.bottomEnd != null
414
- if (hasPerCorner) {
415
- CutCornerShape(
416
- topStart = (shape.topStart ?: 0f).dp,
417
- topEnd = (shape.topEnd ?: 0f).dp,
418
- bottomStart = (shape.bottomStart ?: 0f).dp,
419
- bottomEnd = (shape.bottomEnd ?: 0f).dp
420
- )
421
- } else {
422
- CutCornerShape((shape.radius ?: 0f).dp)
423
- }
424
- }
425
- BuiltinShapeType.MATERIAL -> {
426
- shape.name?.toRoundedPolygon()?.toShape()
427
- }
428
- }
429
- composeShape?.let {
430
- Modifier.clip(it)
431
- }
487
+ resolveShape(shape)?.let { Modifier.clip(it) }
432
488
  } ?: Modifier
433
489
  }
434
490
 
435
- register("clickable") { _, _, _, eventDispatcher ->
436
- Modifier.clickable {
437
- eventDispatcher("clickable", emptyMap())
491
+ register("clickable") { map, _, _, eventDispatcher ->
492
+ val params = recordFromMap<ClickableParams>(map)
493
+ if (params.indication) {
494
+ Modifier.clickable {
495
+ eventDispatcher("clickable", emptyMap())
496
+ }
497
+ } else {
498
+ Modifier.clickable(
499
+ interactionSource = null,
500
+ indication = null
501
+ ) {
502
+ eventDispatcher("clickable", emptyMap())
503
+ }
438
504
  }
439
505
  }
440
506