@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.
- package/CHANGELOG.md +17 -0
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/ui/BottomSheetView.kt +91 -13
- package/android/src/main/java/expo/modules/ui/CarouselView.kt +93 -67
- package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +15 -6
- package/android/src/main/java/expo/modules/ui/TextInputView.kt +39 -15
- package/build/datetime-picker/DateTimePicker.android.d.ts +3 -0
- package/build/datetime-picker/DateTimePicker.android.d.ts.map +1 -0
- package/build/datetime-picker/DateTimePicker.d.ts +3 -0
- package/build/datetime-picker/DateTimePicker.d.ts.map +1 -0
- package/build/datetime-picker/DateTimePicker.web.d.ts +3 -0
- package/build/datetime-picker/DateTimePicker.web.d.ts.map +1 -0
- package/build/datetime-picker/index.d.ts +5 -0
- package/build/datetime-picker/index.d.ts.map +1 -0
- package/build/datetime-picker/types.d.ts +128 -0
- package/build/datetime-picker/types.d.ts.map +1 -0
- package/build/jetpack-compose/Carousel/index.d.ts +86 -23
- package/build/jetpack-compose/Carousel/index.d.ts.map +1 -1
- package/build/jetpack-compose/ModalBottomSheet/index.d.ts +65 -13
- package/build/jetpack-compose/ModalBottomSheet/index.d.ts.map +1 -1
- package/build/jetpack-compose/Progress/index.d.ts +6 -7
- package/build/jetpack-compose/Progress/index.d.ts.map +1 -1
- package/build/jetpack-compose/TextInput/index.d.ts +9 -0
- package/build/jetpack-compose/TextInput/index.d.ts.map +1 -1
- package/build/swift-ui/Link/index.d.ts +36 -0
- package/build/swift-ui/Link/index.d.ts.map +1 -0
- package/build/swift-ui/index.d.ts +1 -0
- package/build/swift-ui/index.d.ts.map +1 -1
- package/build/swift-ui/modifiers/environment.d.ts +16 -1
- package/build/swift-ui/modifiers/environment.d.ts.map +1 -1
- package/build/swift-ui/modifiers/index.d.ts +3 -7
- package/build/swift-ui/modifiers/index.d.ts.map +1 -1
- package/build/swift-ui/modifiers/widgets.d.ts +14 -0
- package/build/swift-ui/modifiers/widgets.d.ts.map +1 -0
- package/expo-module.config.json +1 -1
- package/ios/ExpoUIModule.swift +1 -0
- package/ios/LinkView.swift +29 -0
- package/ios/Modifiers/EnvironmentModifier.swift +14 -0
- package/ios/Modifiers/ViewModifierRegistry.swift +4 -0
- package/ios/Modifiers/WidgetModifiers.swift +12 -0
- 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
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5-sources.jar.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5-sources.jar.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5-sources.jar.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5-sources.jar.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.aar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.aar.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.aar.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.aar.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.aar.sha512 +1 -0
- 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
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.module.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.module.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.module.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.module.sha512 +1 -0
- 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
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.pom.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.pom.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.pom.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.pom.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
- package/package.json +6 -2
- package/src/datetime-picker/DateTimePicker.android.tsx +126 -0
- package/src/datetime-picker/DateTimePicker.tsx +94 -0
- package/src/datetime-picker/DateTimePicker.web.tsx +5 -0
- package/src/datetime-picker/index.tsx +11 -0
- package/src/datetime-picker/types.tsx +147 -0
- package/src/jetpack-compose/Carousel/index.tsx +118 -30
- package/src/jetpack-compose/ModalBottomSheet/index.tsx +85 -15
- package/src/jetpack-compose/Progress/index.tsx +7 -7
- package/src/jetpack-compose/TextInput/index.tsx +10 -0
- package/src/swift-ui/Link/index.tsx +52 -0
- package/src/swift-ui/index.tsx +1 -0
- package/src/swift-ui/modifiers/environment.ts +17 -4
- package/src/swift-ui/modifiers/index.ts +4 -10
- package/src/swift-ui/modifiers/widgets.ts +18 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3-sources.jar.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3-sources.jar.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3-sources.jar.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3-sources.jar.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.aar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.aar.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.aar.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.aar.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.aar.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.module.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.module.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.module.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.module.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.pom.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.pom.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.pom.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.3/expo.modules.ui-55.0.3.pom.sha512 +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,19 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 55.0.5 — 2026-03-19
|
|
14
|
+
|
|
15
|
+
### 🛠 Breaking changes
|
|
16
|
+
|
|
17
|
+
- [android] Split `Carousel` into `HorizontalCenteredHeroCarousel`, `HorizontalMultiBrowseCarousel`, and `HorizontalUncontainedCarousel` matching native Compose components. Added `HorizontalCenteredHeroCarousel`. ([#44034](https://github.com/expo/expo/pull/44034) by [@nishan](https://github.com/intergalacticspacehighway))
|
|
18
|
+
|
|
19
|
+
## 55.0.4 — 2026-03-18
|
|
20
|
+
|
|
21
|
+
### 🎉 New features
|
|
22
|
+
|
|
23
|
+
- [iOS] Add `Link` view. ([#43983](https://github.com/expo/expo/pull/43983) by [@jakex7](https://github.com/jakex7))
|
|
24
|
+
- [iOS] Add `widgetURL` modifier. ([#43984](https://github.com/expo/expo/pull/43984) by [@jakex7](https://github.com/jakex7))
|
|
25
|
+
|
|
13
26
|
## 55.0.3 — 2026-03-17
|
|
14
27
|
|
|
15
28
|
### 🛠 Breaking changes
|
|
@@ -30,6 +43,10 @@
|
|
|
30
43
|
|
|
31
44
|
### 🎉 New features
|
|
32
45
|
|
|
46
|
+
- [android] Added `outlined` variant to `TextInput` component. ([#43719](https://github.com/expo/expo/pull/43719) by [@benjaminkomen](https://github.com/benjaminkomen))
|
|
47
|
+
- Added `@expo/ui/datetimepicker` — a cross-platform `DateTimePicker` drop-in replacement for `@react-native-community/datetimepicker`. ([#44014](https://github.com/expo/expo/pull/44014) by [@vonovak](https://github.com/vonovak))
|
|
48
|
+
- [iOS] Added `locale` and `timeZone` support to `modifiers`. ([#44013](https://github.com/expo/expo/pull/44013) by [@vonovak](https://github.com/vonovak))
|
|
49
|
+
- [android] Added `ref.hide()` for animated dismiss and more configurable props (`containerColor`, `contentColor`, `scrimColor`, `showDragHandle`, `sheetGesturesEnabled`, `properties`, `DragHandle` slot) to `BottomSheet`. ([#43972](https://github.com/expo/expo/pull/43972) by [@nishan](https://github.com/intergalacticspacehighway))
|
|
33
50
|
- [iOS] Added `date`, `dateStyle`, `timerInterval`, `countsDown`, and `pauseTime` props to `Text` component for displaying auto-updating dates, timers, and countdowns using SwiftUI's `Text.DateStyle`. ([#43552](https://github.com/expo/expo/pull/43552) by [@LouisRaverdy](https://github.com/LouisRaverdy))
|
|
34
51
|
- [android] Added `Checkbox` and `TriStateCheckbox` components. ([#43887](https://github.com/expo/expo/pull/43887) by [@nishan](https://github.com/intergalacticspacehighway))
|
|
35
52
|
- [Android] Added `DatePickerDialog` and `TimePickerDialog` components, and `selectableDates` prop to `DateTimePicker`. ([#43895](https://github.com/expo/expo/pull/43895) by [@vonovak](https://github.com/vonovak))
|
package/android/build.gradle
CHANGED
|
@@ -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.
|
|
15
|
+
version = '55.0.5'
|
|
16
16
|
|
|
17
17
|
android {
|
|
18
18
|
namespace "expo.modules.ui"
|
|
19
19
|
defaultConfig {
|
|
20
20
|
versionCode 1
|
|
21
|
-
versionName "55.0.
|
|
21
|
+
versionName "55.0.5"
|
|
22
22
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
23
23
|
}
|
|
24
24
|
buildFeatures {
|
|
@@ -2,28 +2,106 @@
|
|
|
2
2
|
|
|
3
3
|
package expo.modules.ui
|
|
4
4
|
|
|
5
|
+
import android.annotation.SuppressLint
|
|
6
|
+
import android.content.Context
|
|
7
|
+
import android.graphics.Color
|
|
8
|
+
import androidx.compose.material3.BottomSheetDefaults
|
|
5
9
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
6
10
|
import androidx.compose.material3.ModalBottomSheet
|
|
11
|
+
import androidx.compose.material3.ModalBottomSheetProperties
|
|
12
|
+
import androidx.compose.material3.SheetState
|
|
13
|
+
import androidx.compose.material3.contentColorFor
|
|
7
14
|
import androidx.compose.material3.rememberModalBottomSheetState
|
|
8
15
|
import androidx.compose.runtime.Composable
|
|
16
|
+
import androidx.compose.runtime.MutableState
|
|
17
|
+
import androidx.compose.runtime.mutableStateOf
|
|
18
|
+
import androidx.compose.runtime.rememberCoroutineScope
|
|
19
|
+
import kotlin.coroutines.cancellation.CancellationException
|
|
20
|
+
import kotlinx.coroutines.CoroutineScope
|
|
21
|
+
import kotlinx.coroutines.withContext
|
|
22
|
+
import expo.modules.kotlin.AppContext
|
|
23
|
+
import expo.modules.kotlin.records.Field
|
|
24
|
+
import expo.modules.kotlin.records.Record
|
|
25
|
+
import expo.modules.kotlin.viewevent.EventDispatcher
|
|
9
26
|
import expo.modules.kotlin.views.ComposableScope
|
|
10
27
|
import expo.modules.kotlin.views.ComposeProps
|
|
11
|
-
import expo.modules.kotlin.views.
|
|
28
|
+
import expo.modules.kotlin.views.ExpoComposeView
|
|
12
29
|
|
|
13
|
-
data class
|
|
14
|
-
val
|
|
15
|
-
val
|
|
30
|
+
data class ModalBottomSheetPropertiesRecord(
|
|
31
|
+
@Field val shouldDismissOnBackPress: Boolean = true,
|
|
32
|
+
@Field val shouldDismissOnClickOutside: Boolean = true
|
|
33
|
+
) : Record
|
|
34
|
+
|
|
35
|
+
data class ModalBottomSheetViewProps(
|
|
36
|
+
val skipPartiallyExpanded: MutableState<Boolean> = mutableStateOf(false),
|
|
37
|
+
val containerColor: MutableState<Color?> = mutableStateOf(null),
|
|
38
|
+
val contentColor: MutableState<Color?> = mutableStateOf(null),
|
|
39
|
+
val scrimColor: MutableState<Color?> = mutableStateOf(null),
|
|
40
|
+
val showDragHandle: MutableState<Boolean> = mutableStateOf(true),
|
|
41
|
+
val sheetGesturesEnabled: MutableState<Boolean> = mutableStateOf(true),
|
|
42
|
+
val properties: MutableState<ModalBottomSheetPropertiesRecord> = mutableStateOf(ModalBottomSheetPropertiesRecord()),
|
|
43
|
+
val modifiers: MutableState<ModifierList> = mutableStateOf(emptyList())
|
|
16
44
|
) : ComposeProps
|
|
17
45
|
|
|
18
|
-
@
|
|
19
|
-
|
|
20
|
-
|
|
46
|
+
@SuppressLint("ViewConstructor")
|
|
47
|
+
class ModalBottomSheetView(context: Context, appContext: AppContext) :
|
|
48
|
+
ExpoComposeView<ModalBottomSheetViewProps>(context, appContext) {
|
|
49
|
+
override val props = ModalBottomSheetViewProps()
|
|
50
|
+
internal val onDismissRequest by EventDispatcher<Unit>()
|
|
51
|
+
|
|
52
|
+
internal var sheetState: SheetState? = null
|
|
53
|
+
private var composeScope: CoroutineScope? = null
|
|
54
|
+
|
|
55
|
+
suspend fun hide() {
|
|
56
|
+
val scope = composeScope ?: return
|
|
57
|
+
val state = sheetState ?: return
|
|
58
|
+
try {
|
|
59
|
+
withContext(scope.coroutineContext) {
|
|
60
|
+
state.hide()
|
|
61
|
+
}
|
|
62
|
+
} catch (_: CancellationException) {
|
|
63
|
+
// Swipe-dismiss may cancel the coroutine scope while hide() is in-flight.
|
|
64
|
+
// Swallowing the exception avoids an unhandled promise rejection on the JS side.
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@Composable
|
|
69
|
+
override fun ComposableScope.Content() {
|
|
70
|
+
val sheetState = rememberModalBottomSheetState(props.skipPartiallyExpanded.value)
|
|
71
|
+
val scope = rememberCoroutineScope()
|
|
72
|
+
this@ModalBottomSheetView.sheetState = sheetState
|
|
73
|
+
this@ModalBottomSheetView.composeScope = scope
|
|
74
|
+
|
|
75
|
+
val resolvedContainerColor = props.containerColor.value.composeOrNull ?: BottomSheetDefaults.ContainerColor
|
|
76
|
+
val resolvedContentColor = props.contentColor.value.composeOrNull ?: contentColorFor(resolvedContainerColor)
|
|
77
|
+
val resolvedScrimColor = props.scrimColor.value.composeOrNull ?: BottomSheetDefaults.ScrimColor
|
|
78
|
+
val dragHandleSlotView = findChildSlotView(this@ModalBottomSheetView, "dragHandle")
|
|
21
79
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
80
|
+
ModalBottomSheet(
|
|
81
|
+
sheetState = sheetState,
|
|
82
|
+
onDismissRequest = {
|
|
83
|
+
onDismissRequest(Unit)
|
|
84
|
+
},
|
|
85
|
+
containerColor = resolvedContainerColor,
|
|
86
|
+
contentColor = resolvedContentColor,
|
|
87
|
+
scrimColor = resolvedScrimColor,
|
|
88
|
+
sheetGesturesEnabled = props.sheetGesturesEnabled.value,
|
|
89
|
+
dragHandle = when {
|
|
90
|
+
dragHandleSlotView != null -> {
|
|
91
|
+
{ with(ComposableScope()) { with(dragHandleSlotView) { Content() } } }
|
|
92
|
+
}
|
|
93
|
+
props.showDragHandle.value -> {
|
|
94
|
+
{ BottomSheetDefaults.DragHandle() }
|
|
95
|
+
}
|
|
96
|
+
else -> null
|
|
97
|
+
},
|
|
98
|
+
properties = ModalBottomSheetProperties(
|
|
99
|
+
shouldDismissOnBackPress = props.properties.value.shouldDismissOnBackPress,
|
|
100
|
+
shouldDismissOnClickOutside = props.properties.value.shouldDismissOnClickOutside
|
|
101
|
+
),
|
|
102
|
+
modifier = ModifierRegistry.applyModifiers(props.modifiers.value, appContext, this@Content, globalEventDispatcher)
|
|
103
|
+
) {
|
|
104
|
+
Children(ComposableScope(), filter = { !isSlotView(it) })
|
|
105
|
+
}
|
|
28
106
|
}
|
|
29
107
|
}
|
|
@@ -4,10 +4,12 @@ import androidx.compose.foundation.gestures.TargetedFlingBehavior
|
|
|
4
4
|
import androidx.compose.foundation.layout.PaddingValues
|
|
5
5
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
6
6
|
import androidx.compose.material3.carousel.CarouselDefaults
|
|
7
|
+
import androidx.compose.material3.carousel.HorizontalCenteredHeroCarousel
|
|
7
8
|
import androidx.compose.material3.carousel.HorizontalMultiBrowseCarousel
|
|
8
9
|
import androidx.compose.material3.carousel.HorizontalUncontainedCarousel
|
|
9
10
|
import androidx.compose.material3.carousel.rememberCarouselState
|
|
10
11
|
import androidx.compose.runtime.Composable
|
|
12
|
+
import androidx.compose.ui.unit.Dp
|
|
11
13
|
import androidx.compose.ui.unit.dp
|
|
12
14
|
import androidx.core.view.size
|
|
13
15
|
import expo.modules.kotlin.records.Field
|
|
@@ -18,28 +20,16 @@ import expo.modules.kotlin.views.ComposableScope
|
|
|
18
20
|
import expo.modules.kotlin.views.ComposeProps
|
|
19
21
|
import expo.modules.kotlin.views.FunctionalComposableScope
|
|
20
22
|
|
|
21
|
-
enum class CarouselVariant(val value: String) : Enumerable {
|
|
22
|
-
MULTI_BROWSE("multiBrowse"),
|
|
23
|
-
UNCONSTRAINED("unconstrained")
|
|
24
|
-
}
|
|
25
|
-
|
|
26
23
|
enum class FlingBehaviorType(val value: String) : Enumerable {
|
|
27
24
|
SINGLE_ADVANCE("singleAdvance"),
|
|
28
25
|
NO_SNAP("noSnap")
|
|
29
26
|
}
|
|
30
27
|
|
|
31
28
|
class PaddingValuesRecord : Record {
|
|
32
|
-
@Field
|
|
33
|
-
val
|
|
34
|
-
|
|
35
|
-
@Field
|
|
36
|
-
val top: Float? = null
|
|
37
|
-
|
|
38
|
-
@Field
|
|
39
|
-
val end: Float? = null
|
|
40
|
-
|
|
41
|
-
@Field
|
|
42
|
-
val bottom: Float? = null
|
|
29
|
+
@Field val start: Float? = null
|
|
30
|
+
@Field val top: Float? = null
|
|
31
|
+
@Field val end: Float? = null
|
|
32
|
+
@Field val bottom: Float? = null
|
|
43
33
|
|
|
44
34
|
fun toPaddingValues(): PaddingValues {
|
|
45
35
|
return PaddingValues(
|
|
@@ -63,77 +53,113 @@ fun paddingValuesFromEither(either: Either<Float, PaddingValuesRecord>?): Paddin
|
|
|
63
53
|
}
|
|
64
54
|
}
|
|
65
55
|
|
|
66
|
-
data class
|
|
67
|
-
val
|
|
56
|
+
data class HorizontalCenteredHeroCarouselProps(
|
|
57
|
+
val maxItemWidth: Float? = null,
|
|
68
58
|
val itemSpacing: Float? = null,
|
|
69
59
|
val contentPadding: Either<Float, PaddingValuesRecord>? = null,
|
|
70
60
|
val minSmallItemWidth: Float? = null,
|
|
71
61
|
val maxSmallItemWidth: Float? = null,
|
|
72
62
|
val flingBehavior: FlingBehaviorType? = null,
|
|
73
|
-
val
|
|
74
|
-
val itemWidth: Float? = null,
|
|
63
|
+
val userScrollEnabled: Boolean? = null,
|
|
75
64
|
val modifiers: ModifierList = emptyList()
|
|
76
65
|
) : ComposeProps
|
|
77
66
|
|
|
78
|
-
const val DEFAULT_MIN_SMALL_ITEM_WIDTH = 40f
|
|
79
|
-
const val DEFAULT_MAX_SMALL_ITEM_WIDTH = 56f
|
|
80
|
-
const val DEFAULT_PREFERRED_ITEM_WIDTH = 200f
|
|
81
|
-
const val DEFAULT_ITEM_WIDTH = 200f
|
|
82
|
-
|
|
83
67
|
@OptIn(ExperimentalMaterial3Api::class)
|
|
84
68
|
@Composable
|
|
85
|
-
fun FunctionalComposableScope.
|
|
86
|
-
val variant = props.variant ?: CarouselVariant.MULTI_BROWSE
|
|
87
|
-
val modifiers = props.modifiers ?: emptyList()
|
|
88
|
-
val itemSpacing = (props.itemSpacing ?: 0f).dp
|
|
89
|
-
val minSmallItemWidth = (props.minSmallItemWidth ?: DEFAULT_MIN_SMALL_ITEM_WIDTH).dp
|
|
90
|
-
|
|
91
|
-
// we need to constrain maxSmallItemWidth to be at least minSmallItemWidth or the app will crash
|
|
92
|
-
val maxSmallItemWidth = minSmallItemWidth.coerceAtLeast((props.maxSmallItemWidth ?: DEFAULT_MAX_SMALL_ITEM_WIDTH).dp)
|
|
93
|
-
val preferredItemWidth = (props.preferredItemWidth ?: DEFAULT_PREFERRED_ITEM_WIDTH).dp
|
|
94
|
-
val itemWidth = (props.itemWidth ?: DEFAULT_ITEM_WIDTH).dp
|
|
95
|
-
val flingBehaviorType = props.flingBehavior ?: FlingBehaviorType.SINGLE_ADVANCE
|
|
69
|
+
fun FunctionalComposableScope.HorizontalCenteredHeroCarouselContent(props: HorizontalCenteredHeroCarouselProps) {
|
|
96
70
|
val contentPadding = paddingValuesFromEither(props.contentPadding)
|
|
97
|
-
|
|
98
71
|
val carouselState = rememberCarouselState(0) { view.size }
|
|
72
|
+
val flingBehavior: TargetedFlingBehavior = when (props.flingBehavior ?: FlingBehaviorType.SINGLE_ADVANCE) {
|
|
73
|
+
FlingBehaviorType.SINGLE_ADVANCE -> CarouselDefaults.singleAdvanceFlingBehavior(state = carouselState)
|
|
74
|
+
FlingBehaviorType.NO_SNAP -> CarouselDefaults.noSnapFlingBehavior()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
val minSmallItemWidth = props.minSmallItemWidth?.dp ?: CarouselDefaults.MinSmallItemSize
|
|
78
|
+
val maxSmallItemWidth = (props.maxSmallItemWidth?.dp ?: CarouselDefaults.MaxSmallItemSize).coerceAtLeast(minSmallItemWidth)
|
|
79
|
+
|
|
80
|
+
HorizontalCenteredHeroCarousel(
|
|
81
|
+
state = carouselState,
|
|
82
|
+
modifier = ModifierRegistry.applyModifiers(props.modifiers, appContext, composableScope, globalEventDispatcher),
|
|
83
|
+
maxItemWidth = props.maxItemWidth?.dp ?: Dp.Unspecified,
|
|
84
|
+
itemSpacing = (props.itemSpacing ?: 0f).dp,
|
|
85
|
+
flingBehavior = flingBehavior,
|
|
86
|
+
userScrollEnabled = props.userScrollEnabled ?: true,
|
|
87
|
+
minSmallItemWidth = minSmallItemWidth,
|
|
88
|
+
maxSmallItemWidth = maxSmallItemWidth,
|
|
89
|
+
contentPadding = contentPadding
|
|
90
|
+
) { itemIndex ->
|
|
91
|
+
Child(ComposableScope(), itemIndex)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
data class HorizontalMultiBrowseCarouselProps(
|
|
96
|
+
val preferredItemWidth: Float = 200f,
|
|
97
|
+
val itemSpacing: Float? = null,
|
|
98
|
+
val contentPadding: Either<Float, PaddingValuesRecord>? = null,
|
|
99
|
+
val minSmallItemWidth: Float? = null,
|
|
100
|
+
val maxSmallItemWidth: Float? = null,
|
|
101
|
+
val flingBehavior: FlingBehaviorType? = null,
|
|
102
|
+
val userScrollEnabled: Boolean? = null,
|
|
103
|
+
val modifiers: ModifierList = emptyList()
|
|
104
|
+
) : ComposeProps
|
|
99
105
|
|
|
100
|
-
|
|
106
|
+
@OptIn(ExperimentalMaterial3Api::class)
|
|
107
|
+
@Composable
|
|
108
|
+
fun FunctionalComposableScope.HorizontalMultiBrowseCarouselContent(props: HorizontalMultiBrowseCarouselProps) {
|
|
109
|
+
val contentPadding = paddingValuesFromEither(props.contentPadding)
|
|
110
|
+
val carouselState = rememberCarouselState(0) { view.size }
|
|
111
|
+
val flingBehavior: TargetedFlingBehavior = when (props.flingBehavior ?: FlingBehaviorType.SINGLE_ADVANCE) {
|
|
101
112
|
FlingBehaviorType.SINGLE_ADVANCE -> CarouselDefaults.singleAdvanceFlingBehavior(state = carouselState)
|
|
102
113
|
FlingBehaviorType.NO_SNAP -> CarouselDefaults.noSnapFlingBehavior()
|
|
103
114
|
}
|
|
104
115
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
116
|
+
val minSmallItemWidth = props.minSmallItemWidth?.dp ?: CarouselDefaults.MinSmallItemSize
|
|
117
|
+
val maxSmallItemWidth = (props.maxSmallItemWidth?.dp ?: CarouselDefaults.MaxSmallItemSize).coerceAtLeast(minSmallItemWidth)
|
|
118
|
+
|
|
119
|
+
HorizontalMultiBrowseCarousel(
|
|
120
|
+
state = carouselState,
|
|
121
|
+
preferredItemWidth = props.preferredItemWidth.dp,
|
|
122
|
+
modifier = ModifierRegistry.applyModifiers(props.modifiers, appContext, composableScope, globalEventDispatcher),
|
|
123
|
+
itemSpacing = (props.itemSpacing ?: 0f).dp,
|
|
124
|
+
flingBehavior = flingBehavior,
|
|
125
|
+
userScrollEnabled = props.userScrollEnabled ?: true,
|
|
126
|
+
minSmallItemWidth = minSmallItemWidth,
|
|
127
|
+
maxSmallItemWidth = maxSmallItemWidth,
|
|
128
|
+
contentPadding = contentPadding
|
|
129
|
+
) { itemIndex ->
|
|
130
|
+
Child(ComposableScope(), itemIndex)
|
|
119
131
|
}
|
|
132
|
+
}
|
|
120
133
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
134
|
+
data class HorizontalUncontainedCarouselProps(
|
|
135
|
+
val itemWidth: Float = 200f,
|
|
136
|
+
val itemSpacing: Float? = null,
|
|
137
|
+
val contentPadding: Either<Float, PaddingValuesRecord>? = null,
|
|
138
|
+
val flingBehavior: FlingBehaviorType? = null,
|
|
139
|
+
val userScrollEnabled: Boolean? = null,
|
|
140
|
+
val modifiers: ModifierList = emptyList()
|
|
141
|
+
) : ComposeProps
|
|
142
|
+
|
|
143
|
+
@OptIn(ExperimentalMaterial3Api::class)
|
|
144
|
+
@Composable
|
|
145
|
+
fun FunctionalComposableScope.HorizontalUncontainedCarouselContent(props: HorizontalUncontainedCarouselProps) {
|
|
146
|
+
val contentPadding = paddingValuesFromEither(props.contentPadding)
|
|
147
|
+
val carouselState = rememberCarouselState(0) { view.size }
|
|
148
|
+
// Uncontained defaults to noSnap, unlike the other two which default to singleAdvance
|
|
149
|
+
val flingBehavior: TargetedFlingBehavior = when (props.flingBehavior ?: FlingBehaviorType.NO_SNAP) {
|
|
150
|
+
FlingBehaviorType.SINGLE_ADVANCE -> CarouselDefaults.singleAdvanceFlingBehavior(state = carouselState)
|
|
151
|
+
FlingBehaviorType.NO_SNAP -> CarouselDefaults.noSnapFlingBehavior()
|
|
133
152
|
}
|
|
134
153
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
154
|
+
HorizontalUncontainedCarousel(
|
|
155
|
+
state = carouselState,
|
|
156
|
+
itemWidth = props.itemWidth.dp,
|
|
157
|
+
modifier = ModifierRegistry.applyModifiers(props.modifiers, appContext, composableScope, globalEventDispatcher),
|
|
158
|
+
itemSpacing = (props.itemSpacing ?: 0f).dp,
|
|
159
|
+
flingBehavior = flingBehavior,
|
|
160
|
+
userScrollEnabled = props.userScrollEnabled ?: true,
|
|
161
|
+
contentPadding = contentPadding
|
|
162
|
+
) { itemIndex ->
|
|
163
|
+
Child(ComposableScope(), itemIndex)
|
|
138
164
|
}
|
|
139
165
|
}
|
|
@@ -6,6 +6,7 @@ import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
|
|
6
6
|
import androidx.compose.material3.SwitchDefaults
|
|
7
7
|
import androidx.compose.material3.ToggleButtonDefaults
|
|
8
8
|
import androidx.compose.runtime.remember
|
|
9
|
+
import expo.modules.kotlin.functions.Coroutine
|
|
9
10
|
import expo.modules.kotlin.modules.Module
|
|
10
11
|
import expo.modules.kotlin.modules.ModuleDefinition
|
|
11
12
|
import expo.modules.kotlin.viewevent.getValue
|
|
@@ -92,11 +93,11 @@ class ExpoUIModule : Module() {
|
|
|
92
93
|
|
|
93
94
|
//region Expo UI views
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
View(ModalBottomSheetView::class) {
|
|
96
97
|
Events("onDismissRequest")
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
AsyncFunction("hide") Coroutine { view: ModalBottomSheetView ->
|
|
99
|
+
view.hide()
|
|
100
|
+
}
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
ExpoUIView("SingleChoiceSegmentedButtonRowView") { props: SingleChoiceSegmentedButtonRowProps ->
|
|
@@ -311,8 +312,16 @@ class ExpoUIModule : Module() {
|
|
|
311
312
|
PullToRefreshBoxContent(props) { onRefresh(Unit) }
|
|
312
313
|
}
|
|
313
314
|
|
|
314
|
-
ExpoUIView("
|
|
315
|
-
|
|
315
|
+
ExpoUIView("HorizontalCenteredHeroCarouselView") { props: HorizontalCenteredHeroCarouselProps ->
|
|
316
|
+
HorizontalCenteredHeroCarouselContent(props)
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
ExpoUIView("HorizontalMultiBrowseCarouselView") { props: HorizontalMultiBrowseCarouselProps ->
|
|
320
|
+
HorizontalMultiBrowseCarouselContent(props)
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
ExpoUIView("HorizontalUncontainedCarouselView") { props: HorizontalUncontainedCarouselProps ->
|
|
324
|
+
HorizontalUncontainedCarouselContent(props)
|
|
316
325
|
}
|
|
317
326
|
|
|
318
327
|
ExpoUIView("AlertDialogView", events = {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
package expo.modules.ui
|
|
2
2
|
|
|
3
|
+
import android.annotation.SuppressLint
|
|
3
4
|
import android.content.Context
|
|
4
5
|
import androidx.compose.foundation.text.KeyboardOptions
|
|
6
|
+
import androidx.compose.material3.OutlinedTextField
|
|
5
7
|
import androidx.compose.material3.Text
|
|
6
8
|
import androidx.compose.material3.TextField
|
|
7
9
|
import androidx.compose.runtime.Composable
|
|
@@ -18,6 +20,7 @@ import expo.modules.kotlin.views.ExpoComposeView
|
|
|
18
20
|
data class TextInputProps(
|
|
19
21
|
val defaultValue: MutableState<String> = mutableStateOf(""),
|
|
20
22
|
val placeholder: MutableState<String> = mutableStateOf(""),
|
|
23
|
+
val variant: MutableState<String> = mutableStateOf("filled"),
|
|
21
24
|
val multiline: MutableState<Boolean> = mutableStateOf(false),
|
|
22
25
|
val numberOfLines: MutableState<Int?> = mutableStateOf(null),
|
|
23
26
|
val keyboardType: MutableState<String> = mutableStateOf("default"),
|
|
@@ -52,6 +55,7 @@ private fun String.autoCapitalize(): KeyboardCapitalization {
|
|
|
52
55
|
}
|
|
53
56
|
}
|
|
54
57
|
|
|
58
|
+
@SuppressLint("ViewConstructor")
|
|
55
59
|
class TextInputView(context: Context, appContext: AppContext) :
|
|
56
60
|
ExpoComposeView<TextInputProps>(context, appContext) {
|
|
57
61
|
override val props = TextInputProps()
|
|
@@ -68,21 +72,41 @@ class TextInputView(context: Context, appContext: AppContext) :
|
|
|
68
72
|
|
|
69
73
|
@Composable
|
|
70
74
|
override fun ComposableScope.Content() {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
capitalization = props.autoCapitalize.value.autoCapitalize()
|
|
84
|
-
),
|
|
85
|
-
modifier = ModifierRegistry.applyModifiers(props.modifiers.value, appContext, this@Content, globalEventDispatcher)
|
|
75
|
+
val value = textState.value ?: props.defaultValue.value
|
|
76
|
+
val onValueChange: (String) -> Unit = {
|
|
77
|
+
textState.value = it
|
|
78
|
+
onValueChanged(mapOf("value" to it))
|
|
79
|
+
}
|
|
80
|
+
val placeholder: @Composable () -> Unit = { Text(props.placeholder.value) }
|
|
81
|
+
val maxLines = if (props.multiline.value) props.numberOfLines.value ?: Int.MAX_VALUE else 1
|
|
82
|
+
val singleLine = !props.multiline.value
|
|
83
|
+
val keyboardOptions = KeyboardOptions.Default.copy(
|
|
84
|
+
keyboardType = props.keyboardType.value.keyboardType(),
|
|
85
|
+
autoCorrectEnabled = props.autocorrection.value,
|
|
86
|
+
capitalization = props.autoCapitalize.value.autoCapitalize()
|
|
86
87
|
)
|
|
88
|
+
val modifier = ModifierRegistry.applyModifiers(props.modifiers.value, appContext, this@Content, globalEventDispatcher)
|
|
89
|
+
|
|
90
|
+
if (props.variant.value == "outlined") {
|
|
91
|
+
OutlinedTextField(
|
|
92
|
+
value = value,
|
|
93
|
+
onValueChange = onValueChange,
|
|
94
|
+
placeholder = placeholder,
|
|
95
|
+
maxLines = maxLines,
|
|
96
|
+
singleLine = singleLine,
|
|
97
|
+
keyboardOptions = keyboardOptions,
|
|
98
|
+
modifier = modifier
|
|
99
|
+
)
|
|
100
|
+
} else {
|
|
101
|
+
TextField(
|
|
102
|
+
value = value,
|
|
103
|
+
onValueChange = onValueChange,
|
|
104
|
+
placeholder = placeholder,
|
|
105
|
+
maxLines = maxLines,
|
|
106
|
+
singleLine = singleLine,
|
|
107
|
+
keyboardOptions = keyboardOptions,
|
|
108
|
+
modifier = modifier
|
|
109
|
+
)
|
|
110
|
+
}
|
|
87
111
|
}
|
|
88
112
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateTimePicker.android.d.ts","sourceRoot":"","sources":["../../src/datetime-picker/DateTimePicker.android.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAmCjF,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,+BA0FxD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateTimePicker.d.ts","sourceRoot":"","sources":["../../src/datetime-picker/DateTimePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAoCjF,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,+BAyDxD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateTimePicker.web.d.ts","sourceRoot":"","sources":["../../src/datetime-picker/DateTimePicker.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,wBAAgB,cAAc,CAAC,MAAM,EAAE,mBAAmB,QAEzD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/datetime-picker/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,GACzB,MAAM,SAAS,CAAC;AAEjB,eAAe,cAAc,CAAC;AAE9B,OAAO,EAAE,cAAc,EAAE,CAAC"}
|