@momo-kits/native-kits 0.162.3-debug → 0.162.3-fontscale.1-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/.codegraph/.gitignore +5 -0
- package/CLAUDE.md +78 -0
- package/compose/build.gradle.kts +12 -8
- package/compose/build.gradle.kts.backup +11 -7
- package/compose/compose.podspec +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +2 -7
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +3 -11
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +6 -24
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +4 -19
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +1 -10
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +2 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +6 -17
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +6 -101
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Localize.kt +269 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +5 -19
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +8 -33
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +1 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +27 -29
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +3 -26
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +27 -26
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +3 -13
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -5
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +3 -11
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +3 -18
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +11 -11
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +3 -11
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +69 -26
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +1 -5
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +84 -59
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +13 -71
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +10 -51
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +6 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +4 -21
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +16 -75
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +5 -26
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +3 -11
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +16 -40
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +3 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +0 -28
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +2 -13
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +4 -10
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +3 -28
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +8 -47
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +4 -25
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +2 -11
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +1 -17
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +1 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +50 -111
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +1 -5
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +1 -5
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +1 -12
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +4 -96
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +5 -7
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +2 -12
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +9 -21
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +2 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +9 -14
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +8 -11
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +3 -18
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +0 -5
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +94 -4
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +0 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +2 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +3 -7
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +5 -15
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +42 -24
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +48 -33
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +58 -57
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +28 -25
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +13 -31
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +6 -24
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +11 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +2 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +9 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +3 -13
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +3 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +1 -40
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +0 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -8
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +2 -17
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +3 -3
- package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +2 -3
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -2
- package/example/ios/Example.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/Example.xcscheme +32 -0
- package/example/ios/Example.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/WorkspaceSettings.xcsettings +16 -0
- package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +6 -0
- package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +5 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +58 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/Pods-Example.xcscheme +58 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SDWebImage.xcscheme +58 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SDWebImageSwiftUI.xcscheme +58 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SkeletonUI.xcscheme +58 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/lottie-ios-LottiePrivacyInfo.xcscheme +58 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/lottie-ios.xcscheme +58 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +60 -0
- package/gradle/libs.versions.toml +2 -0
- package/gradle.properties +1 -1
- package/ios/Application/Components.swift +1 -0
- package/ios/Application/FloatingButton.swift +1 -0
- package/ios/Badge/Badge.swift +1 -0
- package/ios/Badge/BadgeRibbon.swift +2 -0
- package/ios/Button/Button.swift +1 -1
- package/ios/Checkbox/Checkbox.swift +1 -0
- package/ios/Information/Information.swift +151 -0
- package/ios/Input/Input.swift +1 -0
- package/ios/Input/InputPhoneNumber.swift +1 -0
- package/ios/Input/InputSearch.swift +3 -0
- package/ios/Input/InputTextArea.swift +1 -0
- package/ios/OTPKeyboard/KeyboardButton.swift +1 -1
- package/ios/Popup/PopupDisplay.swift +6 -0
- package/ios/Popup/PopupInput.swift +2 -0
- package/ios/Template/TrustBanner/TrustBanner.swift +2 -0
- package/ios/Typography/Text.swift +1 -0
- package/ios/Typography/Typography.swift +14 -5
- package/local.properties +8 -0
- package/package.json +1 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
package vn.momo.kits.components
|
|
2
2
|
|
|
3
|
+
import vn.momo.kits.modifier.InternalApi
|
|
4
|
+
|
|
3
5
|
import androidx.compose.animation.core.animateDpAsState
|
|
4
6
|
import androidx.compose.animation.core.animateFloatAsState
|
|
5
7
|
import androidx.compose.animation.core.tween
|
|
@@ -8,14 +10,7 @@ import androidx.compose.foundation.border
|
|
|
8
10
|
import androidx.compose.foundation.clickable
|
|
9
11
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
|
10
12
|
import androidx.compose.foundation.interaction.collectIsPressedAsState
|
|
11
|
-
import androidx.compose.foundation.layout
|
|
12
|
-
import androidx.compose.foundation.layout.Box
|
|
13
|
-
import androidx.compose.foundation.layout.Row
|
|
14
|
-
import androidx.compose.foundation.layout.fillMaxWidth
|
|
15
|
-
import androidx.compose.foundation.layout.height
|
|
16
|
-
import androidx.compose.foundation.layout.padding
|
|
17
|
-
import androidx.compose.foundation.layout.size
|
|
18
|
-
import androidx.compose.foundation.layout.wrapContentHeight
|
|
13
|
+
import androidx.compose.foundation.layout.*
|
|
19
14
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
20
15
|
import androidx.compose.runtime.Composable
|
|
21
16
|
import androidx.compose.runtime.getValue
|
|
@@ -30,11 +25,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
|
|
30
25
|
import androidx.compose.ui.unit.Dp
|
|
31
26
|
import androidx.compose.ui.unit.dp
|
|
32
27
|
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
33
|
-
import vn.momo.kits.const
|
|
34
|
-
import vn.momo.kits.const.Colors
|
|
35
|
-
import vn.momo.kits.const.Radius
|
|
36
|
-
import vn.momo.kits.const.Spacing
|
|
37
|
-
import vn.momo.kits.const.Typography
|
|
28
|
+
import vn.momo.kits.const.*
|
|
38
29
|
import vn.momo.kits.modifier.conditional
|
|
39
30
|
import vn.momo.kits.platform.LottieAnimation
|
|
40
31
|
|
|
@@ -100,32 +91,39 @@ private val iconSpaceCache = mapOf(
|
|
|
100
91
|
Size.LARGE to Spacing.S
|
|
101
92
|
)
|
|
102
93
|
|
|
103
|
-
fun getStyle(size: Size): TextStyle {
|
|
94
|
+
private fun getStyle(size: Size): TextStyle {
|
|
104
95
|
return styleCache[size] ?: Typography.actionDefaultBold
|
|
105
96
|
}
|
|
106
97
|
|
|
98
|
+
@InternalApi
|
|
107
99
|
fun getIconSize(size: Size): Dp = iconSizeCache[size] ?: 24.dp
|
|
108
|
-
fun getIconSpace(size: Size): Dp = iconSpaceCache[size] ?: Spacing.S
|
|
100
|
+
private fun getIconSpace(size: Size): Dp = iconSpaceCache[size] ?: Spacing.S
|
|
109
101
|
|
|
102
|
+
@InternalApi
|
|
110
103
|
@Composable
|
|
111
104
|
fun getTextColor(loading: Boolean, type: ButtonType): Color {
|
|
112
105
|
val theme = AppTheme.current
|
|
113
106
|
|
|
114
107
|
return remember(type, theme, loading) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
108
|
+
getButtonColor(type, theme).withLoading(loading)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
internal fun getButtonColor(type: ButtonType, theme: Theme): Color {
|
|
113
|
+
return when (type) {
|
|
114
|
+
ButtonType.DISABLED -> theme.colors.text.disable
|
|
115
|
+
ButtonType.PRIMARY -> Colors.black_01
|
|
116
|
+
ButtonType.SECONDARY -> theme.colors.text.default
|
|
117
|
+
ButtonType.OUTLINE -> theme.colors.primary
|
|
118
|
+
ButtonType.TONAL -> theme.colors.primary
|
|
119
|
+
ButtonType.DANGER -> Colors.black_01
|
|
120
|
+
ButtonType.TEXT -> theme.colors.primary
|
|
124
121
|
}
|
|
125
122
|
}
|
|
126
123
|
|
|
124
|
+
|
|
127
125
|
@Composable
|
|
128
|
-
fun RenderTitle(size: Size, title: String = "", textColor: Color) {
|
|
126
|
+
internal fun RenderTitle(size: Size, title: String = "", textColor: Color) {
|
|
129
127
|
val style = remember(size) { getStyle(size) }
|
|
130
128
|
Text(
|
|
131
129
|
style = style,
|
|
@@ -137,6 +135,7 @@ fun RenderTitle(size: Size, title: String = "", textColor: Color) {
|
|
|
137
135
|
}
|
|
138
136
|
|
|
139
137
|
@Composable
|
|
138
|
+
@InternalApi
|
|
140
139
|
fun RenderIcon(
|
|
141
140
|
size: Size,
|
|
142
141
|
isIconLeft: Boolean,
|
|
@@ -186,6 +185,7 @@ private fun shouldLoadingOnLeft(iconLeft: String, iconRight: String): Boolean {
|
|
|
186
185
|
}
|
|
187
186
|
}
|
|
188
187
|
|
|
188
|
+
@InternalApi
|
|
189
189
|
@Composable
|
|
190
190
|
fun getTypeStyle(
|
|
191
191
|
type: ButtonType,
|
|
@@ -222,6 +222,7 @@ fun getTypeStyle(
|
|
|
222
222
|
}
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
+
@InternalApi
|
|
225
226
|
@Composable
|
|
226
227
|
fun getButtonBackgroundColor(
|
|
227
228
|
loading: Boolean,
|
|
@@ -242,7 +243,7 @@ fun getButtonBackgroundColor(
|
|
|
242
243
|
}
|
|
243
244
|
}
|
|
244
245
|
|
|
245
|
-
fun Color.withLoading(loading: Boolean): Color =
|
|
246
|
+
private fun Color.withLoading(loading: Boolean): Color =
|
|
246
247
|
this.copy(alpha = if (loading) 0.75f else 1f)
|
|
247
248
|
|
|
248
249
|
@Composable
|
|
@@ -8,13 +8,7 @@ import androidx.compose.foundation.layout.PaddingValues
|
|
|
8
8
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
9
9
|
import androidx.compose.foundation.pager.HorizontalPager
|
|
10
10
|
import androidx.compose.foundation.pager.rememberPagerState
|
|
11
|
-
import androidx.compose.runtime
|
|
12
|
-
import androidx.compose.runtime.LaunchedEffect
|
|
13
|
-
import androidx.compose.runtime.getValue
|
|
14
|
-
import androidx.compose.runtime.mutableStateOf
|
|
15
|
-
import androidx.compose.runtime.remember
|
|
16
|
-
import androidx.compose.runtime.setValue
|
|
17
|
-
import androidx.compose.runtime.snapshotFlow
|
|
11
|
+
import androidx.compose.runtime.*
|
|
18
12
|
import androidx.compose.ui.Modifier
|
|
19
13
|
import androidx.compose.ui.graphics.graphicsLayer
|
|
20
14
|
import androidx.compose.ui.unit.dp
|
|
@@ -24,6 +18,7 @@ import vn.momo.kits.application.IsShowBaseLineDebug
|
|
|
24
18
|
import vn.momo.kits.const.Colors
|
|
25
19
|
import vn.momo.kits.modifier.conditional
|
|
26
20
|
import kotlin.math.absoluteValue
|
|
21
|
+
import kotlin.time.Duration.Companion.milliseconds
|
|
27
22
|
|
|
28
23
|
@Composable
|
|
29
24
|
fun Carousel(
|
|
@@ -32,7 +27,6 @@ fun Carousel(
|
|
|
32
27
|
loop: Boolean = false,
|
|
33
28
|
autoplay: Boolean = false,
|
|
34
29
|
autoplayInterval: Long = 3000L,
|
|
35
|
-
enableSnap: Boolean = true,
|
|
36
30
|
scrollEnabled: Boolean = true,
|
|
37
31
|
inactiveSlideOpacity: Float = 1f,
|
|
38
32
|
inactiveSlideScale: Float = 1f,
|
|
@@ -48,18 +42,15 @@ fun Carousel(
|
|
|
48
42
|
|
|
49
43
|
val pagerState = rememberPagerState(initialPage = startPage) { virtualPageCount }
|
|
50
44
|
|
|
51
|
-
// Map virtual page to real index
|
|
52
45
|
val realIndex: (Int) -> Int = { page -> page % itemCount }
|
|
53
46
|
|
|
54
|
-
// Track user interaction for autoplay pause
|
|
55
47
|
var isUserScrolling by remember { mutableStateOf(false) }
|
|
56
48
|
|
|
57
|
-
// Autoplay
|
|
58
49
|
if (autoplay && itemCount > 1) {
|
|
59
50
|
LaunchedEffect(autoplayInterval, isUserScrolling) {
|
|
60
51
|
if (isUserScrolling) return@LaunchedEffect
|
|
61
52
|
while (isActive) {
|
|
62
|
-
delay(autoplayInterval)
|
|
53
|
+
delay(autoplayInterval.milliseconds)
|
|
63
54
|
if (!isUserScrolling) {
|
|
64
55
|
val nextPage = pagerState.currentPage + 1
|
|
65
56
|
if (nextPage < virtualPageCount) {
|
|
@@ -70,7 +61,6 @@ fun Carousel(
|
|
|
70
61
|
}
|
|
71
62
|
}
|
|
72
63
|
|
|
73
|
-
// Track scroll state for callbacks
|
|
74
64
|
LaunchedEffect(pagerState) {
|
|
75
65
|
snapshotFlow { pagerState.isScrollInProgress }.collect { scrolling ->
|
|
76
66
|
isUserScrolling = scrolling
|
|
@@ -22,7 +22,6 @@ import vn.momo.kits.const.Typography
|
|
|
22
22
|
import vn.momo.kits.modifier.activeOpacityClickable
|
|
23
23
|
import vn.momo.kits.modifier.conditional
|
|
24
24
|
|
|
25
|
-
// Pre-computed shape for performance
|
|
26
25
|
private val checkboxShape = RoundedCornerShape(Radius.XS)
|
|
27
26
|
|
|
28
27
|
@Composable
|
|
@@ -33,10 +32,8 @@ fun CheckBox(
|
|
|
33
32
|
indeterminate: Boolean = false,
|
|
34
33
|
title: String = "",
|
|
35
34
|
) {
|
|
36
|
-
// Cache theme access
|
|
37
35
|
val theme = AppTheme.current
|
|
38
36
|
|
|
39
|
-
// Memoize color calculations to avoid repeated conditional logic
|
|
40
37
|
val colors = remember(checked, disabled, theme) {
|
|
41
38
|
when {
|
|
42
39
|
disabled && checked -> Pair(theme.colors.background.tonal, theme.colors.background.tonal)
|
|
@@ -48,12 +45,10 @@ fun CheckBox(
|
|
|
48
45
|
|
|
49
46
|
val (borderColor, backgroundColor) = colors
|
|
50
47
|
|
|
51
|
-
// Memoize icon source to avoid repeated conditional check
|
|
52
48
|
val iconSource = remember(indeterminate) {
|
|
53
49
|
if (indeterminate) "navigation_minus" else "ic_checked"
|
|
54
50
|
}
|
|
55
51
|
|
|
56
|
-
// Memoize click handler to avoid lambda recreation
|
|
57
52
|
val onClickHandler = remember(onCheckedChange, checked) {
|
|
58
53
|
{ onCheckedChange(!checked) }
|
|
59
54
|
}
|
|
@@ -2,11 +2,7 @@ package vn.momo.kits.components
|
|
|
2
2
|
|
|
3
3
|
import androidx.compose.foundation.background
|
|
4
4
|
import androidx.compose.foundation.border
|
|
5
|
-
import androidx.compose.foundation.layout
|
|
6
|
-
import androidx.compose.foundation.layout.Row
|
|
7
|
-
import androidx.compose.foundation.layout.height
|
|
8
|
-
import androidx.compose.foundation.layout.padding
|
|
9
|
-
import androidx.compose.foundation.layout.wrapContentWidth
|
|
5
|
+
import androidx.compose.foundation.layout.*
|
|
10
6
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
11
7
|
import androidx.compose.runtime.Composable
|
|
12
8
|
import androidx.compose.runtime.Immutable
|
|
@@ -17,12 +13,8 @@ import androidx.compose.ui.graphics.Color
|
|
|
17
13
|
import androidx.compose.ui.text.style.TextAlign
|
|
18
14
|
import androidx.compose.ui.text.style.TextOverflow
|
|
19
15
|
import androidx.compose.ui.unit.dp
|
|
20
|
-
import vn.momo.kits.const.AppTheme
|
|
21
|
-
import vn.momo.kits.const.Colors
|
|
22
|
-
import vn.momo.kits.const.Radius
|
|
23
|
-
import vn.momo.kits.const.Typography
|
|
24
16
|
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
25
|
-
import vn.momo.kits.const
|
|
17
|
+
import vn.momo.kits.const.*
|
|
26
18
|
import vn.momo.kits.modifier.activeOpacityClickable
|
|
27
19
|
import vn.momo.kits.modifier.conditional
|
|
28
20
|
import vn.momo.kits.modifier.setAutomationId
|
|
@@ -111,7 +103,7 @@ fun Chip(
|
|
|
111
103
|
|
|
112
104
|
enum class ChipSize { SMALL, LARGE }
|
|
113
105
|
|
|
114
|
-
object ChipDefaults {
|
|
106
|
+
private object ChipDefaults {
|
|
115
107
|
@Immutable
|
|
116
108
|
data class Dimensions(
|
|
117
109
|
val height: Float,
|
|
@@ -7,20 +7,9 @@ import androidx.compose.animation.expandVertically
|
|
|
7
7
|
import androidx.compose.animation.shrinkVertically
|
|
8
8
|
import androidx.compose.foundation.background
|
|
9
9
|
import androidx.compose.foundation.border
|
|
10
|
-
import androidx.compose.foundation.layout
|
|
11
|
-
import androidx.compose.foundation.layout.Column
|
|
12
|
-
import androidx.compose.foundation.layout.Row
|
|
13
|
-
import androidx.compose.foundation.layout.Spacer
|
|
14
|
-
import androidx.compose.foundation.layout.fillMaxWidth
|
|
15
|
-
import androidx.compose.foundation.layout.padding
|
|
16
|
-
import androidx.compose.foundation.layout.size
|
|
17
|
-
import androidx.compose.foundation.layout.width
|
|
10
|
+
import androidx.compose.foundation.layout.*
|
|
18
11
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
19
|
-
import androidx.compose.runtime
|
|
20
|
-
import androidx.compose.runtime.getValue
|
|
21
|
-
import androidx.compose.runtime.mutableStateOf
|
|
22
|
-
import androidx.compose.runtime.remember
|
|
23
|
-
import androidx.compose.runtime.setValue
|
|
12
|
+
import androidx.compose.runtime.*
|
|
24
13
|
import androidx.compose.ui.Alignment
|
|
25
14
|
import androidx.compose.ui.Modifier
|
|
26
15
|
import androidx.compose.ui.draw.clip
|
|
@@ -29,11 +18,7 @@ import androidx.compose.ui.graphics.Color
|
|
|
29
18
|
import androidx.compose.ui.text.TextStyle
|
|
30
19
|
import androidx.compose.ui.unit.dp
|
|
31
20
|
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
32
|
-
import vn.momo.kits.const
|
|
33
|
-
import vn.momo.kits.const.Colors
|
|
34
|
-
import vn.momo.kits.const.Radius
|
|
35
|
-
import vn.momo.kits.const.Spacing
|
|
36
|
-
import vn.momo.kits.const.Typography
|
|
21
|
+
import vn.momo.kits.const.*
|
|
37
22
|
import vn.momo.kits.modifier.activeOpacityClickable
|
|
38
23
|
import vn.momo.kits.modifier.conditional
|
|
39
24
|
import vn.momo.kits.modifier.setAutomationId
|
|
@@ -42,8 +42,8 @@ import androidx.compose.ui.unit.toOffset
|
|
|
42
42
|
import androidx.compose.ui.unit.toSize
|
|
43
43
|
import kotlinx.coroutines.CoroutineScope
|
|
44
44
|
import kotlinx.coroutines.cancel
|
|
45
|
+
import kotlinx.coroutines.currentCoroutineContext
|
|
45
46
|
import kotlinx.coroutines.isActive
|
|
46
|
-
import kotlin.coroutines.coroutineContext
|
|
47
47
|
import kotlin.math.abs
|
|
48
48
|
import kotlin.math.sign
|
|
49
49
|
|
|
@@ -103,7 +103,7 @@ internal class CupertinoOverscrollEffect(
|
|
|
103
103
|
* end at the same time, which is not the case:
|
|
104
104
|
* Spring->Fling->Spring, Fling->Spring, Spring->Fling effects can have different timing per dimension
|
|
105
105
|
* (see Notes of https://github.com/JetBrains/compose-multiplatform-core/pull/609),
|
|
106
|
-
* which is not possible to express without changing API. Hence this effect will be fixed to latest
|
|
106
|
+
* which is not possible to express without changing API. Hence, this effect will be fixed to latest
|
|
107
107
|
* received delta.
|
|
108
108
|
*/
|
|
109
109
|
private var direction: CupertinoOverscrollDirection = CupertinoOverscrollDirection.UNKNOWN
|
|
@@ -151,7 +151,7 @@ internal class CupertinoOverscrollEffect(
|
|
|
151
151
|
override val node: DelegatableNode get() = overscrollNode
|
|
152
152
|
|
|
153
153
|
private fun onDraw() {
|
|
154
|
-
// Fix an issue where scrolling was
|
|
154
|
+
// Fix an issue where scrolling was canceled but the overscroll effect was not completed.
|
|
155
155
|
// Reset the overscroll effect when no ongoing animation or interaction is applied.
|
|
156
156
|
if (!drawCallScheduledByOffsetChange && isInProgress && overscrollNode.pointersDown == 0) {
|
|
157
157
|
overscrollOffsetState.value = Offset.Zero
|
|
@@ -289,7 +289,7 @@ internal class CupertinoOverscrollEffect(
|
|
|
289
289
|
}
|
|
290
290
|
|
|
291
291
|
private fun applyPullToRefresh() {
|
|
292
|
-
val (isRefresh, refresh, threshHold, _,
|
|
292
|
+
val (isRefresh, refresh, threshHold, _, _) = pullRefreshState ?: return
|
|
293
293
|
val overscrollY = overscrollOffset.y
|
|
294
294
|
if (isRefresh.value || overscrollY < threshHold.value * density) return
|
|
295
295
|
refresh.invoke()
|
|
@@ -398,7 +398,7 @@ internal class CupertinoOverscrollEffect(
|
|
|
398
398
|
}
|
|
399
399
|
|
|
400
400
|
springAnimationScope?.cancel()
|
|
401
|
-
springAnimationScope = CoroutineScope(
|
|
401
|
+
springAnimationScope = CoroutineScope(currentCoroutineContext())
|
|
402
402
|
springAnimationScope?.run {
|
|
403
403
|
AnimationState(
|
|
404
404
|
Float.VectorConverter,
|
|
@@ -414,7 +414,7 @@ internal class CupertinoOverscrollEffect(
|
|
|
414
414
|
} ?: (value * density).toOffset()
|
|
415
415
|
currentVelocity = velocity * density
|
|
416
416
|
|
|
417
|
-
// If it was
|
|
417
|
+
// If it was flung from overscroll, cancel animation and return velocity
|
|
418
418
|
if (reason == CupertinoSpringAnimationReason.FLING_FROM_OVERSCROLL &&
|
|
419
419
|
initialSign != 0f &&
|
|
420
420
|
sign(value) != initialSign
|
|
@@ -425,7 +425,7 @@ internal class CupertinoOverscrollEffect(
|
|
|
425
425
|
springAnimationScope = null
|
|
426
426
|
}
|
|
427
427
|
|
|
428
|
-
if (
|
|
428
|
+
if (currentCoroutineContext().isActive) {
|
|
429
429
|
// The spring is critically damped, so in case spring-fling-spring sequence is slightly
|
|
430
430
|
// offset and velocity is of the opposite sign, it will end up with no animation
|
|
431
431
|
overscrollOffset = Offset.Zero
|
|
@@ -447,8 +447,8 @@ internal class CupertinoOverscrollEffect(
|
|
|
447
447
|
val dpSize = scrollSize / density
|
|
448
448
|
|
|
449
449
|
return Offset(
|
|
450
|
-
rubberBandedValue(dpOffset.x, dpSize.width
|
|
451
|
-
rubberBandedValue(dpOffset.y, dpSize.height
|
|
450
|
+
rubberBandedValue(dpOffset.x, dpSize.width),
|
|
451
|
+
rubberBandedValue(dpOffset.y, dpSize.height)
|
|
452
452
|
) * density
|
|
453
453
|
}
|
|
454
454
|
|
|
@@ -456,8 +456,8 @@ internal class CupertinoOverscrollEffect(
|
|
|
456
456
|
* Maps raw delta offset [value] on an axis within scroll container with [dimension]
|
|
457
457
|
* to actual visible offset
|
|
458
458
|
*/
|
|
459
|
-
private fun rubberBandedValue(value: Float, dimension: Float
|
|
460
|
-
sign(value) * (1f - (1f / (abs(value) *
|
|
459
|
+
private fun rubberBandedValue(value: Float, dimension: Float) =
|
|
460
|
+
sign(value) * (1f - (1f / (abs(value) * RUBBER_BAND_COEFFICIENT / dimension + 1f))) * dimension
|
|
461
461
|
|
|
462
462
|
companion object Companion {
|
|
463
463
|
private const val RUBBER_BAND_COEFFICIENT = 0.55f
|
|
@@ -56,7 +56,7 @@ private val iconSizeMap = mapOf(
|
|
|
56
56
|
)
|
|
57
57
|
|
|
58
58
|
@Composable
|
|
59
|
-
fun getIconStyle(type: ButtonType, color: Color? = null): Modifier {
|
|
59
|
+
internal fun getIconStyle(type: ButtonType, color: Color? = null): Modifier {
|
|
60
60
|
val theme = AppTheme.current
|
|
61
61
|
|
|
62
62
|
return remember(type, color, theme) {
|
|
@@ -91,18 +91,10 @@ fun getIconStyle(type: ButtonType, color: Color? = null): Modifier {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
@Composable
|
|
94
|
-
fun getIconColor(type: ButtonType): Color {
|
|
94
|
+
internal fun getIconColor(type: ButtonType): Color {
|
|
95
95
|
val theme = AppTheme.current
|
|
96
96
|
return remember(type, theme) {
|
|
97
|
-
|
|
98
|
-
ButtonType.DISABLED -> theme.colors.text.disable
|
|
99
|
-
ButtonType.PRIMARY -> Colors.black_01
|
|
100
|
-
ButtonType.SECONDARY -> theme.colors.text.default
|
|
101
|
-
ButtonType.OUTLINE -> theme.colors.primary
|
|
102
|
-
ButtonType.TONAL -> theme.colors.primary
|
|
103
|
-
ButtonType.DANGER -> Colors.black_01
|
|
104
|
-
ButtonType.TEXT -> theme.colors.primary
|
|
105
|
-
}
|
|
97
|
+
getButtonColor(type, theme)
|
|
106
98
|
}
|
|
107
99
|
}
|
|
108
100
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
package vn.momo.kits.components
|
|
2
2
|
|
|
3
3
|
import androidx.compose.foundation.border
|
|
4
|
+
import androidx.compose.foundation.layout.Box
|
|
4
5
|
import androidx.compose.foundation.layout.BoxWithConstraints
|
|
6
|
+
import androidx.compose.foundation.layout.fillMaxSize
|
|
5
7
|
import androidx.compose.runtime.Composable
|
|
6
8
|
import androidx.compose.runtime.getValue
|
|
7
9
|
import androidx.compose.runtime.mutableStateOf
|
|
@@ -17,10 +19,12 @@ import androidx.compose.ui.semantics.contentDescription
|
|
|
17
19
|
import androidx.compose.ui.semantics.semantics
|
|
18
20
|
import androidx.compose.ui.platform.LocalDensity
|
|
19
21
|
import androidx.compose.ui.unit.dp
|
|
20
|
-
import coil3.compose.AsyncImage
|
|
22
|
+
import coil3.compose.AsyncImage as CoilAsyncImage
|
|
21
23
|
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
22
24
|
import vn.momo.kits.const.AppTheme
|
|
23
25
|
import vn.momo.kits.const.Colors
|
|
26
|
+
import vn.momo.kits.gifimage.GifImage
|
|
27
|
+
import vn.momo.kits.gifimage.GifImageState
|
|
24
28
|
import vn.momo.kits.modifier.conditional
|
|
25
29
|
|
|
26
30
|
data class Options(
|
|
@@ -73,6 +77,19 @@ private fun getHostFromUrl(url: String): String? {
|
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
|
|
80
|
+
private fun isGifUrl(url: String): Boolean {
|
|
81
|
+
val path = url.substringBefore('#').substringBefore('?')
|
|
82
|
+
return path.endsWith(".gif", ignoreCase = true)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private fun GifImageState.toImageState(): ImageState {
|
|
86
|
+
return when (this) {
|
|
87
|
+
GifImageState.Success -> ImageState.Success
|
|
88
|
+
GifImageState.Error -> ImageState.Error
|
|
89
|
+
GifImageState.Loading -> ImageState.Loading
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
76
93
|
// Optimized query parameter appending
|
|
77
94
|
private fun appendSizeQueryParam(url: String, value: String): String {
|
|
78
95
|
val fragmentIndex = url.indexOf('#')
|
|
@@ -95,12 +112,12 @@ fun Image(
|
|
|
95
112
|
modifier: Modifier = Modifier,
|
|
96
113
|
options: Options? = null,
|
|
97
114
|
loading: Boolean = true,
|
|
115
|
+
onStateChanged: (ImageState) -> Unit = {},
|
|
98
116
|
) {
|
|
99
117
|
val imageOptions = remember(options) {
|
|
100
118
|
options ?: Options()
|
|
101
119
|
}
|
|
102
120
|
|
|
103
|
-
var imageState by remember { mutableStateOf(ImageState.Loading) }
|
|
104
121
|
val density = LocalDensity.current
|
|
105
122
|
|
|
106
123
|
BoxWithConstraints(
|
|
@@ -121,34 +138,46 @@ fun Image(
|
|
|
121
138
|
processedUrl
|
|
122
139
|
}
|
|
123
140
|
}
|
|
124
|
-
else -> source
|
|
141
|
+
else -> source.toString()
|
|
125
142
|
}
|
|
126
143
|
}
|
|
127
144
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
145
|
+
var imageState by remember(urlToLoad) { mutableStateOf(ImageState.Loading) }
|
|
146
|
+
fun updateImageState(state: ImageState) {
|
|
147
|
+
imageState = state
|
|
148
|
+
onStateChanged(state)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (isGifUrl(urlToLoad)) {
|
|
152
|
+
GifImage(
|
|
153
|
+
modifier = Modifier.matchParentSize(),
|
|
154
|
+
url = urlToLoad,
|
|
155
|
+
contentDescription = null,
|
|
156
|
+
contentScale = imageOptions.contentScale,
|
|
157
|
+
alignment = imageOptions.alignment,
|
|
158
|
+
colorFilter = imageOptions.colorFilter,
|
|
159
|
+
alpha = imageOptions.alpha,
|
|
160
|
+
onStateChanged = { updateImageState(it.toImageState()) },
|
|
161
|
+
)
|
|
162
|
+
} else {
|
|
163
|
+
CoilAsyncImage(
|
|
164
|
+
modifier = Modifier.matchParentSize(),
|
|
165
|
+
model = urlToLoad,
|
|
166
|
+
contentDescription = null,
|
|
167
|
+
contentScale = imageOptions.contentScale,
|
|
168
|
+
alignment = imageOptions.alignment,
|
|
169
|
+
colorFilter = imageOptions.colorFilter,
|
|
170
|
+
alpha = imageOptions.alpha,
|
|
171
|
+
onLoading = { updateImageState(ImageState.Loading) },
|
|
172
|
+
onSuccess = { updateImageState(ImageState.Success) },
|
|
173
|
+
onError = { updateImageState(ImageState.Error) },
|
|
174
|
+
)
|
|
175
|
+
}
|
|
140
176
|
|
|
141
177
|
when (imageState) {
|
|
142
|
-
ImageState.Loading -> if (loading) Skeleton()
|
|
143
|
-
ImageState.Error -> {
|
|
144
|
-
val theme = AppTheme.current
|
|
145
|
-
Icon(
|
|
146
|
-
source = "media_fail",
|
|
147
|
-
color = theme.colors.text.disable,
|
|
148
|
-
modifier = Modifier.align(Alignment.Center)
|
|
149
|
-
)
|
|
150
|
-
}
|
|
151
178
|
ImageState.Success -> {}
|
|
179
|
+
ImageState.Error -> ImageError()
|
|
180
|
+
ImageState.Loading -> if (loading) Skeleton()
|
|
152
181
|
}
|
|
153
182
|
}
|
|
154
183
|
}
|
|
@@ -156,7 +185,7 @@ fun Image(
|
|
|
156
185
|
// Extracted URL processing logic for better performance
|
|
157
186
|
private fun processImageUrl(url: String, maxWidth: androidx.compose.ui.unit.Dp, density: androidx.compose.ui.unit.Density): String {
|
|
158
187
|
val host = getHostFromUrl(url)
|
|
159
|
-
return if (host != null && supportedDomains.contains(host)) {
|
|
188
|
+
return if (!isGifUrl(url) && host != null && supportedDomains.contains(host)) {
|
|
160
189
|
val widthPx = with(density) { maxWidth.roundToPx() }
|
|
161
190
|
val pixelRatio = density.density
|
|
162
191
|
val pixelFitForWidth = widthPx * pixelRatio
|
|
@@ -167,6 +196,20 @@ private fun processImageUrl(url: String, maxWidth: androidx.compose.ui.unit.Dp,
|
|
|
167
196
|
}
|
|
168
197
|
}
|
|
169
198
|
|
|
199
|
+
@Composable
|
|
200
|
+
private fun ImageError() {
|
|
201
|
+
val theme = AppTheme.current
|
|
202
|
+
Box(
|
|
203
|
+
modifier = Modifier.fillMaxSize(),
|
|
204
|
+
contentAlignment = Alignment.Center
|
|
205
|
+
) {
|
|
206
|
+
Icon(
|
|
207
|
+
source = "media_fail",
|
|
208
|
+
color = theme.colors.text.disable,
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
170
213
|
@Composable
|
|
171
214
|
fun Image(
|
|
172
215
|
source: Painter,
|
|
@@ -185,4 +228,4 @@ fun Image(
|
|
|
185
228
|
colorFilter = colorFilter,
|
|
186
229
|
alpha = alpha,
|
|
187
230
|
)
|
|
188
|
-
}
|
|
231
|
+
}
|
|
@@ -3,11 +3,7 @@ package vn.momo.kits.components
|
|
|
3
3
|
import androidx.compose.foundation.background
|
|
4
4
|
import androidx.compose.foundation.border
|
|
5
5
|
import androidx.compose.foundation.clickable
|
|
6
|
-
import androidx.compose.foundation.layout
|
|
7
|
-
import androidx.compose.foundation.layout.Row
|
|
8
|
-
import androidx.compose.foundation.layout.height
|
|
9
|
-
import androidx.compose.foundation.layout.padding
|
|
10
|
-
import androidx.compose.foundation.layout.width
|
|
6
|
+
import androidx.compose.foundation.layout.*
|
|
11
7
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
12
8
|
import androidx.compose.runtime.Composable
|
|
13
9
|
import androidx.compose.ui.Modifier
|