@momo-kits/native-kits 0.167.1-duo.2-debug → 0.167.1-duo.20-debug
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/CLAUDE.md +36 -8
- package/README.md +2 -2
- package/compose/build.gradle.kts +15 -1
- package/compose/build.gradle.kts.backup +14 -0
- package/compose/compose.podspec +1 -1
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +2 -0
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/ReservedRegions.android.kt +6 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +168 -52
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +20 -21
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +2 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +4 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +24 -14
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +9 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +11 -12
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +4 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +2 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +10 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +6 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +53 -26
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +12 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +7 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +13 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +13 -5
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +3 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +14 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +19 -21
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +2 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +5 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +3 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +7 -15
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/HostFont.kt +4 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +10 -4
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +3 -17
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/ScreenLayout.kt +173 -21
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +43 -4
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +8 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +10 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +153 -48
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +114 -71
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +8 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoBarCompression.kt +98 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoTabBar.kt +312 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +84 -18
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +33 -13
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderJourney.kt +2 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +51 -19
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +4 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SideBar.kt +46 -23
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +2 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +3 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ReservedRegions.kt +13 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/const/HostFont.ios.kt +38 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +4 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/ReservedRegions.ios.kt +94 -0
- package/gradle.properties +1 -1
- package/ios/Application/ApplicationEnvironment.swift +17 -0
- package/ios/Application/MaxApi.swift +12 -3
- package/ios/Avatar/Avatar.swift +4 -3
- package/ios/Badge/Badge.swift +6 -4
- package/ios/Badge/BadgeDot.swift +1 -1
- package/ios/Badge/BadgeRibbon.swift +0 -1
- package/ios/Button/Button.swift +15 -12
- package/ios/CalculatorKeyboard/CalculatorKeyboard.swift +64 -18
- package/ios/Carousel/Carousel.swift +29 -12
- package/ios/Checkbox/Checkbox.swift +7 -3
- package/ios/Chip/Chip.swift +5 -4
- package/ios/Collapse/Collapse.swift +70 -19
- package/ios/Colors+Radius+Spacing/Colors.swift +10 -1
- package/ios/Colors+Radius+Spacing/Radius.swift +6 -0
- package/ios/DateTimePicker/DateTimePicker.swift +54 -20
- package/ios/DateTimePicker/WheelPicker.swift +103 -105
- package/ios/Divider/Divider.swift +37 -4
- package/ios/Extensions/Color++.swift +38 -9
- package/ios/Extensions/OptionalEnvironmentObject.swift +12 -0
- package/ios/Extensions/SkeletonUICompat.swift +11 -0
- package/ios/Icon/Icon.swift +21 -23
- package/ios/Icon/Icons.swift +1329 -0
- package/ios/IconButton/IconButton.swift +15 -7
- package/ios/Image/Image.swift +7 -23
- package/ios/Information/Information.swift +27 -9
- package/ios/Input/ErrorView.swift +2 -2
- package/ios/Input/Input.swift +160 -147
- package/ios/Input/InputPhoneNumber.swift +12 -9
- package/ios/Input/InputSearch.swift +102 -75
- package/ios/Input/InputTextArea.swift +128 -145
- package/ios/InputDropDown/InputDropDown.swift +10 -7
- package/ios/InputMoney/InputMoney.swift +33 -11
- package/ios/InputOTP/InputOTP.swift +22 -12
- package/ios/Layout/Card.swift +50 -0
- package/ios/Layout/GridContext.swift +187 -3
- package/ios/Layout/Item.swift +5 -4
- package/ios/Layout/ScreenLayout.swift +380 -0
- package/ios/Layout/Section.swift +4 -100
- package/ios/Loader/Loader.swift +5 -9
- package/ios/Lottie/LottieView.swift +14 -2
- package/ios/{Application/Navigation/Overplay → Navigation}/BottomSheet.swift +128 -9
- package/ios/Navigation/BottomTab/BottomTab.swift +185 -0
- package/ios/{Application/Navigation → Navigation}/BottomTab/BottomTabBar.swift +15 -7
- package/ios/Navigation/BottomTab/DuoBarCompression.swift +105 -0
- package/ios/Navigation/BottomTab/DuoTabBar.swift +304 -0
- package/ios/{Application → Navigation/Component}/FloatingButton.swift +14 -3
- package/ios/Navigation/Component/Header.swift +531 -0
- package/ios/Navigation/Component/HeaderBackground.swift +133 -0
- package/ios/Navigation/Component/HeaderJourney.swift +73 -0
- package/ios/Navigation/Component/HeaderLocation.swift +48 -0
- package/ios/Navigation/Component/HeaderRight.swift +377 -0
- package/ios/Navigation/Component/HeaderTitle.swift +36 -0
- package/ios/{Application/Navigation → Navigation/Component}/HeaderUser.swift +21 -24
- package/ios/Navigation/Component/SideBar.swift +183 -0
- package/ios/{Application/Navigation/Overplay → Navigation/Component}/SnackBar.swift +5 -6
- package/ios/Navigation/HostBackGestureBridge.swift +78 -0
- package/ios/{Application/Navigation/Overplay → Navigation}/ModalScreen.swift +5 -2
- package/ios/Navigation/Navigation.swift +204 -0
- package/ios/Navigation/NavigationContainer.swift +194 -0
- package/ios/{Application/Navigation → Navigation}/Navigator.swift +177 -91
- package/ios/Navigation/StackScreen.swift +820 -0
- package/ios/Navigation/StackTransition.swift +400 -0
- package/ios/Navigation/SwipeBackHaptic.swift +33 -0
- package/ios/{Application/Navigation → Navigation}/Tracking/ScreenTracker.swift +12 -5
- package/ios/OTPKeyboard/OTPKeyboard.swift +8 -11
- package/ios/Pagination/PaginationScroll.swift +2 -2
- package/ios/Popup/PopupDisplay.swift +72 -136
- package/ios/Popup/PopupInput.swift +10 -13
- package/ios/Popup/PopupLayout.swift +140 -0
- package/ios/Popup/PopupNotify.swift +56 -73
- package/ios/Popup/PopupPromotion.swift +31 -47
- package/ios/PopupView/FullscreenPopup.swift +13 -19
- package/ios/PopupView/PopupView.swift +1 -1
- package/ios/PopupView/Utils++.swift +0 -8
- package/ios/ProgressInfo/ProgressInfo.swift +4 -2
- package/ios/Radio/Radio.swift +2 -1
- package/ios/Rating/Rating.swift +9 -1
- package/ios/Resources/dot_loading.json +558 -0
- package/ios/Resources/lottie_circle_loader.json +1 -0
- package/ios/ScrollIndicator/ScrollIndicator.swift +11 -10
- package/ios/Skeleton/Skeleton.swift +22 -27
- package/ios/Slider/Slider.swift +16 -18
- package/ios/Stepper/Stepper.swift +6 -1
- package/ios/Steps/Steps.swift +8 -6
- package/ios/SuggestAction/SuggestAction.swift +5 -0
- package/ios/Swipeable/SwipeCell.swift +10 -6
- package/ios/Switch/Switch.swift +22 -20
- package/ios/TabView/TabView.swift +102 -21
- package/ios/Tag/Tag.swift +15 -4
- package/ios/Template/Logo/Logo.swift +2 -1
- package/ios/Template/TrustBanner/TrustBanner.swift +106 -54
- package/ios/Title/Title.swift +6 -17
- package/ios/Tooltip/Tooltip.swift +29 -14
- package/ios/Typography/Text.swift +61 -19
- package/ios/Uploader/Uploader.swift +3 -1
- package/ios/native-kits.podspec +2 -1
- package/ios-demo/MoMoUIKitsDemo.podspec +1 -1
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +1 -1
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DuoTabDemo.swift +80 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +1 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IPhoneDuoDemo.swift +173 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +77 -1
- package/package.json +1 -1
- package/scripts/gen-ios-icons.mjs +36 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +0 -52
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +0 -183
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +0 -207
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +0 -39
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +0 -86
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +0 -76
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +0 -76
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +0 -293
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +0 -33
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +0 -110
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +0 -378
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +0 -69
- package/ios/Application/Components.swift +0 -270
- package/ios/Application/ComposeApi.swift +0 -22
- package/ios/Application/HeaderRight.swift +0 -306
- package/ios/Application/Navigation/BottomTab/BottomTab.swift +0 -104
- package/ios/Application/Navigation/HeaderBackProps.swift +0 -66
- package/ios/Application/Navigation/HeaderTitle.swift +0 -57
- package/ios/Application/Navigation/NavigationContainer.swift +0 -213
- package/ios/Application/Navigation/NavigationOptions.swift +0 -109
- package/ios/Application/Navigation/NavigatorManager.swift +0 -22
- package/ios/Application/Navigation/component/Header.swift +0 -178
- package/ios/Application/Navigation/component/HeaderBackground.swift +0 -83
- package/ios/Application/Navigation/component/HeaderColor.swift +0 -65
- package/ios/Application/Navigation/component/HeaderRightWidthKey.swift +0 -11
- package/ios/Application/Navigation/component/NavigationFooter.swift +0 -90
- package/ios/Application/Navigation/component/NavigationHeaderRight.swift +0 -196
- package/ios/Application/Screen.swift +0 -250
- package/ios/Application/StackScreen.swift +0 -492
- /package/ios/{Application/Navigation → Navigation}/BottomTab/CurvedContainer.swift +0 -0
|
@@ -17,31 +17,30 @@ import vn.momo.kits.application.IsShowBaseLineDebug
|
|
|
17
17
|
import vn.momo.kits.const.*
|
|
18
18
|
import vn.momo.kits.modifier.conditional
|
|
19
19
|
|
|
20
|
+
private val badgePrimaryColors = listOf(
|
|
21
|
+
Color(0xFFF0F0F0),
|
|
22
|
+
Color(0xFFEB2F96),
|
|
23
|
+
Color(0xFF962AF0),
|
|
24
|
+
Color(0xFF4E4BFF),
|
|
25
|
+
Color(0xFF007AFF),
|
|
26
|
+
Color(0xFF13C2C2),
|
|
27
|
+
Color(0xFF34C759),
|
|
28
|
+
Color(0xFFA0D911),
|
|
29
|
+
Color(0xFFFFCC00),
|
|
30
|
+
Color(0xFFFA8C16),
|
|
31
|
+
Color(0xFFFA541C),
|
|
32
|
+
Color(0xFFF5222D)
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
private val badgeNumberRegex = "^\\d+$".toRegex()
|
|
20
36
|
|
|
21
37
|
@Composable
|
|
22
38
|
fun Badge(label: String = "Label", backgroundColor: Color? = null, modifier: Modifier = Modifier) {
|
|
23
|
-
|
|
24
|
-
Color(0xFFF0F0F0),
|
|
25
|
-
Color(0xFFEB2F96),
|
|
26
|
-
Color(0xFF962AF0),
|
|
27
|
-
Color(0xFF4E4BFF),
|
|
28
|
-
Color(0xFF007AFF),
|
|
29
|
-
Color(0xFF13C2C2),
|
|
30
|
-
Color(0xFF34C759),
|
|
31
|
-
Color(0xFFA0D911),
|
|
32
|
-
Color(0xFFFFCC00),
|
|
33
|
-
Color(0xFFFA8C16),
|
|
34
|
-
Color(0xFFFA541C),
|
|
35
|
-
Color(0xFFF5222D)
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
fun isNumber(label: String): Boolean {
|
|
39
|
-
val numberRegex = "^\\d+$".toRegex()
|
|
40
|
-
return numberRegex.matches(label)
|
|
41
|
-
}
|
|
39
|
+
fun isNumber(label: String): Boolean = badgeNumberRegex.matches(label)
|
|
42
40
|
|
|
43
41
|
fun formatTitle(label: String): String {
|
|
44
|
-
|
|
42
|
+
// Digits too long for Int are well over 99; toInt() would throw.
|
|
43
|
+
if (isNumber(label) && (label.toIntOrNull() ?: Int.MAX_VALUE) > 99) {
|
|
45
44
|
return "99+"
|
|
46
45
|
}
|
|
47
46
|
return label
|
|
@@ -54,7 +53,7 @@ fun Badge(label: String = "Label", backgroundColor: Color? = null, modifier: Mod
|
|
|
54
53
|
AppTheme.current.colors.warning.primary
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
if (backgroundColor != null &&
|
|
56
|
+
if (backgroundColor != null && badgePrimaryColors.contains(backgroundColor)) {
|
|
58
57
|
badgeColor = backgroundColor
|
|
59
58
|
}
|
|
60
59
|
val scaleSize = scaleSize(16f)
|
|
@@ -146,7 +146,8 @@ fun RenderIcon(
|
|
|
146
146
|
) {
|
|
147
147
|
val iconSize = remember(size) { getIconSize(size) }
|
|
148
148
|
val margin = remember(size) { getIconSpace(size) }
|
|
149
|
-
|
|
149
|
+
// null = untinted; Color.Unspecified would tint with a transparent color and hide the icon.
|
|
150
|
+
val color = if (useTintColor) textColor else null
|
|
150
151
|
|
|
151
152
|
val modifier = Modifier.padding(
|
|
152
153
|
start = if (isIconLeft) 0.dp else margin,
|
|
@@ -43,6 +43,8 @@ fun Carousel(
|
|
|
43
43
|
val pagerState = rememberPagerState(initialPage = startPage) { virtualPageCount }
|
|
44
44
|
|
|
45
45
|
val realIndex: (Int) -> Int = { page -> page % itemCount }
|
|
46
|
+
val currentOnSnapToItem by rememberUpdatedState(onSnapToItem)
|
|
47
|
+
val currentOnScrollIndexChanged by rememberUpdatedState(onScrollIndexChanged)
|
|
46
48
|
|
|
47
49
|
var isUserScrolling by remember { mutableStateOf(false) }
|
|
48
50
|
|
|
@@ -70,8 +72,8 @@ fun Carousel(
|
|
|
70
72
|
LaunchedEffect(pagerState) {
|
|
71
73
|
snapshotFlow { pagerState.currentPage }.collect { page ->
|
|
72
74
|
val real = realIndex(page)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
currentOnSnapToItem(real)
|
|
76
|
+
currentOnScrollIndexChanged(real)
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
|
|
@@ -77,7 +77,7 @@ fun Chip(
|
|
|
77
77
|
horizontalArrangement = Arrangement.spacedBy(iconSpacing.dp)
|
|
78
78
|
) {
|
|
79
79
|
if (iconLeft != null) {
|
|
80
|
-
Icon(source = iconLeft, size =
|
|
80
|
+
Icon(source = iconLeft, size = iconSize.dp, color = leftTint)
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
if (!label.isNullOrEmpty()) {
|
|
@@ -19,6 +19,7 @@ import coil3.request.ImageRequest
|
|
|
19
19
|
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
20
20
|
import vn.momo.kits.const.AppTheme
|
|
21
21
|
import vn.momo.kits.const.Colors
|
|
22
|
+
import vn.momo.kits.gifimage.GifImage
|
|
22
23
|
import vn.momo.kits.modifier.conditional
|
|
23
24
|
import vn.momo.kits.utils.Icons
|
|
24
25
|
import vn.momo.kits.utils.noThemeIcons
|
|
@@ -41,7 +42,7 @@ fun Icon(
|
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
val iconColor = remember(color) {
|
|
45
|
+
val iconColor = remember(source, color) {
|
|
45
46
|
if (noThemeIcons.contains(source)) null else color
|
|
46
47
|
}
|
|
47
48
|
|
|
@@ -59,18 +60,27 @@ fun Icon(
|
|
|
59
60
|
}
|
|
60
61
|
.semantics { contentDescription = contentDesc }
|
|
61
62
|
) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
63
|
+
if (isGifUrl(iconUrl)) {
|
|
64
|
+
GifImage(
|
|
65
|
+
modifier = Modifier.matchParentSize(),
|
|
66
|
+
url = iconUrl,
|
|
67
|
+
contentDescription = null,
|
|
68
|
+
contentScale = ContentScale.Fit,
|
|
69
|
+
)
|
|
70
|
+
} else {
|
|
71
|
+
AsyncImage(
|
|
72
|
+
modifier = Modifier.matchParentSize(),
|
|
73
|
+
model = ImageRequest.Builder(context)
|
|
74
|
+
.data(iconUrl)
|
|
75
|
+
.size(
|
|
76
|
+
coil3.size.Dimension.Undefined,
|
|
77
|
+
coil3.size.Dimension.Undefined
|
|
78
|
+
)
|
|
79
|
+
.build(),
|
|
80
|
+
contentDescription = null,
|
|
81
|
+
contentScale = ContentScale.Fit,
|
|
82
|
+
colorFilter = colorFilter,
|
|
83
|
+
)
|
|
84
|
+
}
|
|
75
85
|
}
|
|
76
86
|
}
|
|
@@ -77,7 +77,7 @@ private fun getHostFromUrl(url: String): String? {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
internal fun isGifUrl(url: String): Boolean {
|
|
81
81
|
val path = url.substringBefore('#').substringBefore('?')
|
|
82
82
|
return path.endsWith(".gif", ignoreCase = true)
|
|
83
83
|
}
|
|
@@ -90,7 +90,7 @@ fun Information(
|
|
|
90
90
|
width = 0.5.dp,
|
|
91
91
|
shape = RoundedCornerShape(Radius.S),
|
|
92
92
|
color = borderColor
|
|
93
|
-
).background(color = backgroundColor)
|
|
93
|
+
).background(color = backgroundColor, shape = RoundedCornerShape(Radius.S))
|
|
94
94
|
.conditional(IsShowBaseLineDebug) {
|
|
95
95
|
border(1.dp, Colors.blue_03)
|
|
96
96
|
}
|
|
@@ -16,6 +16,7 @@ import androidx.compose.ui.Alignment
|
|
|
16
16
|
import androidx.compose.ui.Modifier
|
|
17
17
|
import androidx.compose.ui.focus.onFocusChanged
|
|
18
18
|
import androidx.compose.ui.graphics.Color
|
|
19
|
+
import androidx.compose.ui.graphics.SolidColor
|
|
19
20
|
import androidx.compose.ui.text.AnnotatedString
|
|
20
21
|
import androidx.compose.ui.text.SpanStyle
|
|
21
22
|
import androidx.compose.ui.text.TextStyle
|
|
@@ -214,7 +215,7 @@ fun Input(
|
|
|
214
215
|
|
|
215
216
|
// Memoized color calculations
|
|
216
217
|
val theme = AppTheme.current
|
|
217
|
-
val colors = remember(disabled, theme) {
|
|
218
|
+
val colors = remember(disabled, theme, iconColor) {
|
|
218
219
|
if (disabled) {
|
|
219
220
|
val disabledColor = theme.colors.text.disable
|
|
220
221
|
Triple(disabledColor, disabledColor, disabledColor)
|
|
@@ -241,8 +242,9 @@ fun Input(
|
|
|
241
242
|
val lineHeight = 24.sp
|
|
242
243
|
val scaleFontSize = scaleSize(fontSize)
|
|
243
244
|
val scaleLineHeight = scaleSize(lineHeight)
|
|
245
|
+
val scaledHeight = scaleSize(size.values.height)
|
|
244
246
|
|
|
245
|
-
val textStyle = remember(textColor, fontWeight) {
|
|
247
|
+
val textStyle = remember(textColor, fontWeight, scaleFontSize, scaleLineHeight) {
|
|
246
248
|
TextStyle(
|
|
247
249
|
color = textColor,
|
|
248
250
|
fontSize = scaleFontSize,
|
|
@@ -268,7 +270,7 @@ fun Input(
|
|
|
268
270
|
|
|
269
271
|
val passwordFontFamily = getFontFamily(AppTheme.current.font, FontWeight.Normal)
|
|
270
272
|
val passwordFontSize = scaleSize(24.sp)
|
|
271
|
-
val visualTransformation = remember(secureTextEntry, inputState.passHidden, passwordFontFamily) {
|
|
273
|
+
val visualTransformation = remember(secureTextEntry, inputState.passHidden, passwordFontFamily, passwordFontSize) {
|
|
272
274
|
if (secureTextEntry && !inputState.passHidden)
|
|
273
275
|
PasswordVisualTransformation(fontFamily = passwordFontFamily, fontSize = passwordFontSize)
|
|
274
276
|
else
|
|
@@ -287,8 +289,9 @@ fun Input(
|
|
|
287
289
|
textStyle = textStyle,
|
|
288
290
|
visualTransformation = visualTransformation,
|
|
289
291
|
keyboardOptions = keyboardOptionsConfig,
|
|
292
|
+
cursorBrush = SolidColor(theme.colors.primary),
|
|
290
293
|
modifier = inputModifier
|
|
291
|
-
.height(
|
|
294
|
+
.height(scaledHeight)
|
|
292
295
|
.onFocusChanged { focusState ->
|
|
293
296
|
val wasFocused = inputState.isFocused
|
|
294
297
|
inputState = inputState.copy(
|
|
@@ -313,7 +316,7 @@ fun Input(
|
|
|
313
316
|
floatingIcon = floatingIcon,
|
|
314
317
|
titleColor = floatingTitleColor,
|
|
315
318
|
iconColor = floatingIconTintColor,
|
|
316
|
-
offsetY = -
|
|
319
|
+
offsetY = -scaledHeight / 2,
|
|
317
320
|
required = required,
|
|
318
321
|
)
|
|
319
322
|
|
|
@@ -359,7 +362,7 @@ fun Input(
|
|
|
359
362
|
}
|
|
360
363
|
|
|
361
364
|
// Clear button
|
|
362
|
-
if (inputState.isFocused && text.value.isNotEmpty()) {
|
|
365
|
+
if (!readOnly && inputState.isFocused && text.value.isNotEmpty()) {
|
|
363
366
|
Row(Modifier.padding(horizontal = Spacing.XS)) {
|
|
364
367
|
Icon(
|
|
365
368
|
source = "24_navigation_close_circle_full",
|
|
@@ -27,6 +27,7 @@ import androidx.compose.ui.Alignment
|
|
|
27
27
|
import androidx.compose.ui.Modifier
|
|
28
28
|
import androidx.compose.ui.focus.onFocusChanged
|
|
29
29
|
import androidx.compose.ui.graphics.Color
|
|
30
|
+
import androidx.compose.ui.graphics.SolidColor
|
|
30
31
|
import androidx.compose.ui.semantics.contentDescription
|
|
31
32
|
import androidx.compose.ui.semantics.semantics
|
|
32
33
|
import androidx.compose.ui.semantics.testTag
|
|
@@ -43,7 +44,9 @@ import vn.momo.kits.application.IsShowBaseLineDebug
|
|
|
43
44
|
import vn.momo.kits.const.Colors
|
|
44
45
|
import vn.momo.kits.const.Typography
|
|
45
46
|
import vn.momo.kits.const.getFontFamily
|
|
47
|
+
import vn.momo.kits.const.scaleSize
|
|
46
48
|
import vn.momo.kits.modifier.conditional
|
|
49
|
+
import vn.momo.kits.modifier.setAutomationId
|
|
47
50
|
|
|
48
51
|
private const val MONEY_CURRENCY = "đ"
|
|
49
52
|
|
|
@@ -134,7 +137,6 @@ fun InputMoney(
|
|
|
134
137
|
val current = if (digitsOf(field.text) == digits) field else moneyDisplay(digits).let {
|
|
135
138
|
TextFieldValue(it, TextRange(caretFromDigitIndex(it, digits.length)))
|
|
136
139
|
}
|
|
137
|
-
var isBlurred = false
|
|
138
140
|
val (textColor, placeholderColor, iconTintColor, floatingTitleColor, floatingIconTintColor) =
|
|
139
141
|
getInputColors(disabled, iconColor, floatingValueColor, floatingIconColor)
|
|
140
142
|
|
|
@@ -153,19 +155,16 @@ fun InputMoney(
|
|
|
153
155
|
value = current,
|
|
154
156
|
textStyle = TextStyle(
|
|
155
157
|
color = textColor,
|
|
156
|
-
fontSize = 20.sp,
|
|
157
|
-
lineHeight = 24.sp,
|
|
158
|
+
fontSize = scaleSize(20.sp),
|
|
159
|
+
lineHeight = scaleSize(24.sp),
|
|
158
160
|
fontWeight = fontWeight.value,
|
|
159
161
|
fontFamily = getFontFamily(AppTheme.current.font, fontWeight.value)
|
|
160
162
|
),
|
|
161
163
|
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = keyboardType),
|
|
164
|
+
cursorBrush = SolidColor(AppTheme.current.colors.primary),
|
|
162
165
|
modifier = Modifier.height(size.values.height).onFocusChanged {
|
|
166
|
+
if (it.isFocused) onFocus() else if (isFocused) onBlur()
|
|
163
167
|
isFocused = it.isFocused
|
|
164
|
-
if (it.isFocused) {
|
|
165
|
-
onFocus()
|
|
166
|
-
}
|
|
167
|
-
if (!it.isFocused && isBlurred) onBlur()
|
|
168
|
-
if (it.isFocused && !isBlurred) isBlurred = true
|
|
169
168
|
},
|
|
170
169
|
onValueChange = { value ->
|
|
171
170
|
if (value.text == current.text) {
|
|
@@ -223,7 +222,7 @@ fun InputMoney(
|
|
|
223
222
|
color = leadingIconColor
|
|
224
223
|
)
|
|
225
224
|
}
|
|
226
|
-
Box(Modifier.weight(9f)
|
|
225
|
+
Box(Modifier.weight(9f), contentAlignment = Alignment.CenterStart) {
|
|
227
226
|
if (text.value.isEmpty()) {
|
|
228
227
|
Text(
|
|
229
228
|
text = placeholder,
|
|
@@ -234,9 +233,9 @@ fun InputMoney(
|
|
|
234
233
|
),
|
|
235
234
|
color = placeholderColor
|
|
236
235
|
)
|
|
237
|
-
} else {
|
|
238
|
-
innerTextField()
|
|
239
236
|
}
|
|
237
|
+
// Composed even when empty so the caret shows over the placeholder.
|
|
238
|
+
innerTextField()
|
|
240
239
|
}
|
|
241
240
|
if (isFocused && text.value.isNotEmpty()) {
|
|
242
241
|
Row {
|
|
@@ -252,7 +251,7 @@ fun InputMoney(
|
|
|
252
251
|
},
|
|
253
252
|
interactionSource = remember { MutableInteractionSource() },
|
|
254
253
|
indication = null
|
|
255
|
-
)
|
|
254
|
+
).setAutomationId("ic_clear")
|
|
256
255
|
)
|
|
257
256
|
}
|
|
258
257
|
}
|
|
@@ -101,7 +101,6 @@ fun InputOTP(
|
|
|
101
101
|
) {
|
|
102
102
|
val maxLength = length ?: 10
|
|
103
103
|
var isFocused by remember { mutableStateOf(false) }
|
|
104
|
-
var isBlurred = false
|
|
105
104
|
|
|
106
105
|
val handleChangeText: (String) -> Unit = { text ->
|
|
107
106
|
if (text.length <= maxLength &&
|
|
@@ -127,13 +126,9 @@ fun InputOTP(
|
|
|
127
126
|
onValueChange = handleChangeText,
|
|
128
127
|
singleLine = true,
|
|
129
128
|
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = if (dataType == "number") KeyboardType.Number else KeyboardType.Ascii),
|
|
130
|
-
modifier =
|
|
129
|
+
modifier = Modifier.height(56.dp).onFocusChanged {
|
|
130
|
+
if (it.isFocused) onFocus() else if (isFocused) onBlur()
|
|
131
131
|
isFocused = it.isFocused
|
|
132
|
-
if (it.isFocused) {
|
|
133
|
-
onFocus()
|
|
134
|
-
}
|
|
135
|
-
if (!it.isFocused && isBlurred) onBlur()
|
|
136
|
-
if (it.isFocused && !isBlurred) isBlurred = true
|
|
137
132
|
},
|
|
138
133
|
decorationBox = { innerTextField ->
|
|
139
134
|
Box {
|
|
@@ -207,11 +202,11 @@ fun InputOTP(
|
|
|
207
202
|
style = Typography.headerDefaultBold,
|
|
208
203
|
text = value[i].toString()
|
|
209
204
|
)
|
|
210
|
-
if (i != value.length - 1 || (isFocused && value.length !=
|
|
205
|
+
if (i != value.length - 1 || (isFocused && value.length != maxLength)) {
|
|
211
206
|
Spacer(Modifier.width(Spacing.L))
|
|
212
207
|
}
|
|
213
208
|
}
|
|
214
|
-
if (isFocused && value.length !=
|
|
209
|
+
if (isFocused && value.length != maxLength) OTPCaret()
|
|
215
210
|
}
|
|
216
211
|
}
|
|
217
212
|
}
|
|
@@ -89,7 +89,7 @@ fun InputPhoneNumber(
|
|
|
89
89
|
|
|
90
90
|
// Memoized color calculations
|
|
91
91
|
val theme = AppTheme.current
|
|
92
|
-
val colors = remember(
|
|
92
|
+
val colors = remember(theme, iconColor) {
|
|
93
93
|
Triple(
|
|
94
94
|
theme.colors.text.default, // textColor
|
|
95
95
|
theme.colors.text.hint, // placeholderColor
|
|
@@ -173,7 +173,7 @@ fun InputPhoneNumber(
|
|
|
173
173
|
Box(
|
|
174
174
|
modifier = Modifier.width(1.dp)
|
|
175
175
|
.height(size.values.dividerHeight)
|
|
176
|
-
.background(
|
|
176
|
+
.background(theme.colors.border.default)
|
|
177
177
|
)
|
|
178
178
|
}
|
|
179
179
|
|
|
@@ -29,6 +29,7 @@ import androidx.compose.ui.Alignment
|
|
|
29
29
|
import androidx.compose.ui.Modifier
|
|
30
30
|
import androidx.compose.ui.focus.onFocusChanged
|
|
31
31
|
import androidx.compose.ui.graphics.Color
|
|
32
|
+
import androidx.compose.ui.graphics.SolidColor
|
|
32
33
|
import androidx.compose.ui.graphics.takeOrElse
|
|
33
34
|
import androidx.compose.ui.text.TextStyle
|
|
34
35
|
import androidx.compose.ui.text.input.KeyboardType
|
|
@@ -99,7 +100,8 @@ data class InputSearchProps(
|
|
|
99
100
|
val loading: Boolean = false,
|
|
100
101
|
val fontWeight: InputFontWeight = InputFontWeight.REGULAR,
|
|
101
102
|
val keyboardType: KeyboardType = KeyboardType.Text,
|
|
102
|
-
|
|
103
|
+
// Unspecified resolves to the theme surface (white in the light theme).
|
|
104
|
+
val backgroundColor: Color = Color.Unspecified,
|
|
103
105
|
val clearCondition: (() -> Boolean)? = null,
|
|
104
106
|
val keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
|
|
105
107
|
val keyboardActions: KeyboardActions = KeyboardActions.Default,
|
|
@@ -118,7 +120,6 @@ fun InputSearch(
|
|
|
118
120
|
),
|
|
119
121
|
) {
|
|
120
122
|
var isFocused by remember { mutableStateOf(false) }
|
|
121
|
-
var isBlurred = false
|
|
122
123
|
val disabledColor = AppTheme.current.colors.text.disable
|
|
123
124
|
var textColor = AppTheme.current.colors.text.default
|
|
124
125
|
var placeholderColor = AppTheme.current.colors.text.hint
|
|
@@ -134,7 +135,7 @@ fun InputSearch(
|
|
|
134
135
|
|
|
135
136
|
val fontFamily = getFontFamily(AppTheme.current.font, inputSearchProps.fontWeight.value)
|
|
136
137
|
|
|
137
|
-
val textStyle = remember(textColor, inputSearchProps.fontWeight.value, fontFamily) {
|
|
138
|
+
val textStyle = remember(textColor, inputSearchProps.fontWeight.value, fontFamily, scaleFontSize) {
|
|
138
139
|
TextStyle(
|
|
139
140
|
color = textColor,
|
|
140
141
|
fontSize = scaleFontSize,
|
|
@@ -167,13 +168,13 @@ fun InputSearch(
|
|
|
167
168
|
textStyle = textStyle,
|
|
168
169
|
keyboardOptions = inputSearchProps.keyboardOptions.copy(keyboardType = inputSearchProps.keyboardType),
|
|
169
170
|
keyboardActions = inputSearchProps.keyboardActions,
|
|
171
|
+
cursorBrush = SolidColor(AppTheme.current.colors.primary),
|
|
172
|
+
// Transitions only: onFocusChanged also runs once on attach with isFocused = false.
|
|
170
173
|
modifier = inputSearchProps.modifier.weight(1f).fillMaxHeight().onFocusChanged {
|
|
174
|
+
val wasFocused = isFocused
|
|
171
175
|
isFocused = it.isFocused
|
|
172
|
-
if (it.isFocused)
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
if (!it.isFocused && isBlurred) inputSearchProps.onBlur()
|
|
176
|
-
if (it.isFocused && !isBlurred) isBlurred = true
|
|
176
|
+
if (it.isFocused && !wasFocused) inputSearchProps.onFocus()
|
|
177
|
+
if (!it.isFocused && wasFocused) inputSearchProps.onBlur()
|
|
177
178
|
},
|
|
178
179
|
onValueChange = inputSearchProps.onChangeText,
|
|
179
180
|
decorationBox = { innerTextField ->
|
|
@@ -186,7 +187,7 @@ fun InputSearch(
|
|
|
186
187
|
)
|
|
187
188
|
).fillMaxHeight()
|
|
188
189
|
.background(
|
|
189
|
-
inputSearchProps.backgroundColor,
|
|
190
|
+
inputSearchProps.backgroundColor.takeOrElse { AppTheme.current.colors.background.surface },
|
|
190
191
|
RoundedCornerShape(Radius.XL)
|
|
191
192
|
),
|
|
192
193
|
horizontalArrangement = Arrangement.Start,
|
|
@@ -13,6 +13,7 @@ import androidx.compose.ui.Alignment
|
|
|
13
13
|
import androidx.compose.ui.Modifier
|
|
14
14
|
import androidx.compose.ui.focus.onFocusChanged
|
|
15
15
|
import androidx.compose.ui.graphics.Color
|
|
16
|
+
import androidx.compose.ui.graphics.SolidColor
|
|
16
17
|
import androidx.compose.ui.text.TextStyle
|
|
17
18
|
import androidx.compose.ui.text.input.KeyboardType
|
|
18
19
|
import androidx.compose.ui.unit.Dp
|
|
@@ -56,7 +57,6 @@ fun InputTextArea(
|
|
|
56
57
|
keyboardType: KeyboardType = KeyboardType.Text,
|
|
57
58
|
) {
|
|
58
59
|
var isFocused by remember { mutableStateOf(false) }
|
|
59
|
-
var isBlurred = false
|
|
60
60
|
val (textColor, placeholderColor, iconTintColor, floatingTitleColor, floatingIconTintColor) =
|
|
61
61
|
getInputColors(disabled, iconColor, floatingValueColor, floatingIconColor)
|
|
62
62
|
|
|
@@ -81,13 +81,13 @@ fun InputTextArea(
|
|
|
81
81
|
fontFamily = getFontFamily(AppTheme.current.font, fontWeight.value)
|
|
82
82
|
),
|
|
83
83
|
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = keyboardType),
|
|
84
|
+
cursorBrush = SolidColor(AppTheme.current.colors.primary),
|
|
85
|
+
// Transitions only: onFocusChanged also runs once on attach with isFocused = false.
|
|
84
86
|
modifier = Modifier.height(scaleHeight).onFocusChanged {
|
|
87
|
+
val wasFocused = isFocused
|
|
85
88
|
isFocused = it.isFocused
|
|
86
|
-
if (it.isFocused)
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
if (!it.isFocused && isBlurred) onBlur()
|
|
90
|
-
if (it.isFocused && !isBlurred) isBlurred = true
|
|
89
|
+
if (it.isFocused && !wasFocused) onFocus()
|
|
90
|
+
if (!it.isFocused && wasFocused) onBlur()
|
|
91
91
|
},
|
|
92
92
|
onValueChange = {
|
|
93
93
|
if (it.length <= maxLength) {
|
|
@@ -4,6 +4,8 @@ import androidx.compose.foundation.background
|
|
|
4
4
|
import androidx.compose.foundation.border
|
|
5
5
|
import androidx.compose.foundation.clickable
|
|
6
6
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
|
7
|
+
import androidx.compose.foundation.rememberScrollState
|
|
8
|
+
import androidx.compose.foundation.verticalScroll
|
|
7
9
|
import androidx.compose.foundation.layout.*
|
|
8
10
|
import androidx.compose.foundation.lazy.LazyColumn
|
|
9
11
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
@@ -20,7 +22,7 @@ import vn.momo.kits.application.LocalLocalize
|
|
|
20
22
|
import vn.momo.kits.const.*
|
|
21
23
|
import vn.momo.kits.modifier.conditional
|
|
22
24
|
import vn.momo.kits.modifier.setAutomationId
|
|
23
|
-
import vn.momo.kits.
|
|
25
|
+
import vn.momo.kits.layout.getScreenLayout
|
|
24
26
|
import kotlin.math.min
|
|
25
27
|
|
|
26
28
|
data class PopupAction(
|
|
@@ -34,9 +36,21 @@ enum class PopupActionDirection {
|
|
|
34
36
|
AUTO
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
//
|
|
39
|
+
// Width of a system alert on the iPhone Duo inner display, in both orientations (RN Popup/utils.ts).
|
|
40
|
+
private val DUO_POPUP_MAX_WIDTH = 440.dp
|
|
41
|
+
|
|
42
|
+
// Card width cap plus the popup's own side padding; unbounded off iPhone Duo.
|
|
43
|
+
@Composable
|
|
44
|
+
internal fun popupMaxWidth(horizontalPadding: Dp): Dp =
|
|
45
|
+
if (getScreenLayout().isIPhoneDuoDevice) DUO_POPUP_MAX_WIDTH + horizontalPadding * 2 else Dp.Unspecified
|
|
46
|
+
|
|
47
|
+
// Room left for a popup on iPhone Duo, where landscape is too short for it; null elsewhere.
|
|
38
48
|
@Composable
|
|
39
|
-
internal fun
|
|
49
|
+
internal fun popupMaxHeight(): Dp? {
|
|
50
|
+
val layout = getScreenLayout()
|
|
51
|
+
if (!layout.isIPhoneDuoDevice) return null
|
|
52
|
+
return layout.height - layout.duoTopInset - layout.insetBottom - Spacing.XL * 2
|
|
53
|
+
}
|
|
40
54
|
|
|
41
55
|
private fun heightForLines(
|
|
42
56
|
layout: TextLayoutResult,
|
|
@@ -129,12 +143,15 @@ fun PopupNotify(
|
|
|
129
143
|
callback?.invoke()
|
|
130
144
|
}
|
|
131
145
|
|
|
146
|
+
val maxHeight = popupMaxHeight()
|
|
147
|
+
val bodyScrollState = rememberScrollState()
|
|
148
|
+
|
|
132
149
|
Box(
|
|
133
150
|
Modifier.setAutomationId("popup_notify"), contentAlignment = Alignment.TopEnd
|
|
134
151
|
) {
|
|
135
152
|
Column(
|
|
136
153
|
modifier = Modifier
|
|
137
|
-
.widthIn(max = popupMaxWidth())
|
|
154
|
+
.widthIn(max = popupMaxWidth(horizontalPadding = 12.dp))
|
|
138
155
|
.fillMaxWidth()
|
|
139
156
|
.padding(horizontal = 12.dp)
|
|
140
157
|
.clip(RoundedCornerShape(Radius.L))
|
|
@@ -145,31 +162,41 @@ fun PopupNotify(
|
|
|
145
162
|
.conditional(IsShowBaseLineDebug) {
|
|
146
163
|
border(1.dp, Colors.blue_03)
|
|
147
164
|
}
|
|
165
|
+
.conditional(maxHeight != null) {
|
|
166
|
+
heightIn(max = maxHeight ?: Dp.Unspecified)
|
|
167
|
+
}
|
|
148
168
|
) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
169
|
+
// scrolls when iPhone Duo landscape is too short; actions stay visible
|
|
170
|
+
Column(
|
|
171
|
+
Modifier.conditional(maxHeight != null) {
|
|
172
|
+
weight(1f, fill = false).verticalScroll(bodyScrollState)
|
|
173
|
+
}
|
|
174
|
+
) {
|
|
175
|
+
if(props.image.isNotEmpty()) {
|
|
176
|
+
Image(
|
|
177
|
+
source = props.image,
|
|
178
|
+
modifier = Modifier.fillMaxWidth().aspectRatio(1.777f),
|
|
179
|
+
options = Options(alignment = Alignment.Center)
|
|
180
|
+
)
|
|
181
|
+
}
|
|
156
182
|
|
|
157
|
-
|
|
158
|
-
Text(
|
|
159
|
-
style = Typography.headerDefaultBold,
|
|
160
|
-
maxLines = 2,
|
|
161
|
-
text = props.title,
|
|
162
|
-
modifier = Modifier.setAutomationId("title_popup_permission")
|
|
163
|
-
)
|
|
164
|
-
content(Modifier.padding(top = Spacing.S))
|
|
165
|
-
if (props.error.isNotEmpty()) {
|
|
183
|
+
Column(modifier = Modifier.padding(Spacing.XL)) {
|
|
166
184
|
Text(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
modifier = Modifier.padding(top = Spacing.S)
|
|
185
|
+
style = Typography.headerDefaultBold,
|
|
186
|
+
maxLines = 2,
|
|
187
|
+
text = props.title,
|
|
188
|
+
modifier = Modifier.setAutomationId("title_popup_permission")
|
|
172
189
|
)
|
|
190
|
+
content(Modifier.padding(top = Spacing.S))
|
|
191
|
+
if (props.error.isNotEmpty()) {
|
|
192
|
+
Text(
|
|
193
|
+
text = LocalLocalize.current.translate("errorCode") + props.error,
|
|
194
|
+
style = Typography.descriptionXsRegular,
|
|
195
|
+
color = AppTheme.current.colors.text.hint,
|
|
196
|
+
maxLines = 1,
|
|
197
|
+
modifier = Modifier.padding(top = Spacing.S)
|
|
198
|
+
)
|
|
199
|
+
}
|
|
173
200
|
}
|
|
174
201
|
}
|
|
175
202
|
|
|
@@ -227,7 +254,7 @@ internal fun BuildAction(
|
|
|
227
254
|
val closeAction = remember { mutableStateOf("button_action") }
|
|
228
255
|
when (buttonDirection) {
|
|
229
256
|
PopupActionDirection.AUTO -> {
|
|
230
|
-
if (secondary != null && (secondary.title.length > 12 || primary?.title?.length
|
|
257
|
+
if (secondary != null && (secondary.title.length > 12 || (primary?.title?.length ?: 0) > 12)) {
|
|
231
258
|
RenderColumn(
|
|
232
259
|
secondary = secondary,
|
|
233
260
|
onAction = onAction,
|
|
@@ -22,14 +22,24 @@ import vn.momo.kits.modifier.conditional
|
|
|
22
22
|
import vn.momo.kits.modifier.setAutomationId
|
|
23
23
|
import vn.momo.kits.utils.ifNotNull
|
|
24
24
|
|
|
25
|
+
private const val ASPECT_RATIO = 0.72f
|
|
26
|
+
private val CLOSE_ROW_HEIGHT = Spacing.S + 40.dp
|
|
27
|
+
|
|
25
28
|
@Composable
|
|
26
29
|
fun PopupPromotion(
|
|
27
30
|
source: String = "",
|
|
28
31
|
onPress: (() -> Unit) = {},
|
|
29
32
|
onClose: (() -> Unit) = {},
|
|
30
33
|
) {
|
|
34
|
+
val maxHeight = popupMaxHeight()
|
|
35
|
+
var maxWidth = popupMaxWidth(horizontalPadding = Spacing.M)
|
|
36
|
+
if (maxHeight != null) {
|
|
37
|
+
// fit the portrait image by height when iPhone Duo leaves too little room
|
|
38
|
+
maxWidth = minOf(maxWidth, (maxHeight - CLOSE_ROW_HEIGHT) * ASPECT_RATIO + Spacing.M * 2)
|
|
39
|
+
}
|
|
40
|
+
|
|
31
41
|
Column(Modifier
|
|
32
|
-
.widthIn(max =
|
|
42
|
+
.widthIn(max = maxWidth)
|
|
33
43
|
.padding(horizontal = Spacing.M)
|
|
34
44
|
.conditional(IsShowBaseLineDebug) {
|
|
35
45
|
border(1.dp, Colors.blue_03)
|
|
@@ -39,7 +49,7 @@ fun PopupPromotion(
|
|
|
39
49
|
Image(
|
|
40
50
|
source = source,
|
|
41
51
|
modifier = Modifier.fillMaxWidth()
|
|
42
|
-
.aspectRatio(
|
|
52
|
+
.aspectRatio(ASPECT_RATIO)
|
|
43
53
|
.clickable(
|
|
44
54
|
interactionSource = remember { MutableInteractionSource() },
|
|
45
55
|
indication = null,
|