@momo-kits/native-kits 0.89.30-nav.10 → 0.89.30-nav.12
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/compose/build.gradle.kts +2 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Components.kt +65 -32
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +14 -3
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +58 -47
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +30 -56
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +1 -0
- package/local.properties +2 -2
- package/package.json +1 -1
package/compose/build.gradle.kts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package vn.momo.kits.application
|
|
2
2
|
|
|
3
3
|
import androidx.compose.animation.animateColorAsState
|
|
4
|
+
import androidx.compose.animation.core.animateFloatAsState
|
|
4
5
|
import androidx.compose.foundation.background
|
|
5
6
|
import androidx.compose.foundation.border
|
|
6
7
|
import androidx.compose.foundation.clickable
|
|
@@ -24,6 +25,7 @@ import androidx.compose.runtime.setValue
|
|
|
24
25
|
import androidx.compose.runtime.snapshotFlow
|
|
25
26
|
import androidx.compose.ui.Alignment
|
|
26
27
|
import androidx.compose.ui.Modifier
|
|
28
|
+
import androidx.compose.ui.draw.alpha
|
|
27
29
|
import androidx.compose.ui.geometry.Offset
|
|
28
30
|
import androidx.compose.ui.graphics.Brush
|
|
29
31
|
import androidx.compose.ui.graphics.Color
|
|
@@ -40,6 +42,8 @@ import kotlinx.coroutines.flow.distinctUntilChanged
|
|
|
40
42
|
import kotlinx.coroutines.flow.map
|
|
41
43
|
import vn.momo.kits.components.Icon
|
|
42
44
|
import vn.momo.kits.components.Image
|
|
45
|
+
import vn.momo.kits.components.InputSearch
|
|
46
|
+
import vn.momo.kits.components.InputSearchProps
|
|
43
47
|
import vn.momo.kits.components.Options
|
|
44
48
|
import vn.momo.kits.components.Text
|
|
45
49
|
import vn.momo.kits.const.AppStatusBar
|
|
@@ -47,6 +51,7 @@ import vn.momo.kits.const.AppTheme
|
|
|
47
51
|
import vn.momo.kits.const.Colors
|
|
48
52
|
import vn.momo.kits.const.Spacing
|
|
49
53
|
import vn.momo.kits.const.Typography
|
|
54
|
+
import vn.momo.kits.modifier.shadow
|
|
50
55
|
import vn.momo.kits.platform.getStatusBarHeight
|
|
51
56
|
import vn.momo.kits.utils.bottomBorder
|
|
52
57
|
|
|
@@ -62,9 +67,15 @@ data class AnimatedHeader(
|
|
|
62
67
|
|
|
63
68
|
@Composable
|
|
64
69
|
fun HeaderBackground(
|
|
65
|
-
headerType: HeaderType = HeaderType.DEFAULT
|
|
70
|
+
headerType: HeaderType = HeaderType.DEFAULT,
|
|
71
|
+
useShadow: Boolean? = true,
|
|
72
|
+
scrollState: Int
|
|
66
73
|
) {
|
|
67
74
|
val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
|
|
75
|
+
val opacityAni by animateFloatAsState(
|
|
76
|
+
targetValue = (1 - (scrollState / 200f)).coerceIn(0f, 1f),
|
|
77
|
+
)
|
|
78
|
+
|
|
68
79
|
when (headerType) {
|
|
69
80
|
HeaderType.DEFAULT -> {
|
|
70
81
|
val height = statusBarHeight + 52.dp
|
|
@@ -82,8 +93,8 @@ fun HeaderBackground(
|
|
|
82
93
|
.background(
|
|
83
94
|
Brush.linearGradient(
|
|
84
95
|
colors = listOf(
|
|
85
|
-
Color(
|
|
86
|
-
Color(
|
|
96
|
+
Color(0xFFFDCADE),
|
|
97
|
+
Color(0x00FDCADE)
|
|
87
98
|
),
|
|
88
99
|
start = Offset(0f, 0f),
|
|
89
100
|
end = Offset(0f, with(LocalDensity.current) { 154.dp.toPx() })
|
|
@@ -106,6 +117,7 @@ fun HeaderBackground(
|
|
|
106
117
|
HeaderType.EXTENDED -> {
|
|
107
118
|
Box(
|
|
108
119
|
modifier = Modifier.fillMaxWidth().height(154.dp)
|
|
120
|
+
.alpha(opacityAni)
|
|
109
121
|
.background(
|
|
110
122
|
Brush.linearGradient(
|
|
111
123
|
colors = listOf(
|
|
@@ -116,10 +128,6 @@ fun HeaderBackground(
|
|
|
116
128
|
end = Offset(0f, with(LocalDensity.current) { 154.dp.toPx() })
|
|
117
129
|
)
|
|
118
130
|
)
|
|
119
|
-
.bottomBorder(
|
|
120
|
-
strokeWidth = 1.dp,
|
|
121
|
-
color = AppTheme.current.colors.border.default
|
|
122
|
-
)
|
|
123
131
|
) {
|
|
124
132
|
if (AppTheme.current.assets.headerBackground != null) {
|
|
125
133
|
Image(
|
|
@@ -131,6 +139,17 @@ fun HeaderBackground(
|
|
|
131
139
|
)
|
|
132
140
|
}
|
|
133
141
|
}
|
|
142
|
+
Box(
|
|
143
|
+
modifier = Modifier.fillMaxWidth().height(statusBarHeight + 52.dp)
|
|
144
|
+
.alpha(1 - opacityAni)
|
|
145
|
+
.background(Colors.black_01)
|
|
146
|
+
.then(
|
|
147
|
+
if (useShadow == true) Modifier.shadow() else Modifier.bottomBorder(
|
|
148
|
+
1.dp,
|
|
149
|
+
Colors.black_04
|
|
150
|
+
)
|
|
151
|
+
)
|
|
152
|
+
)
|
|
134
153
|
}
|
|
135
154
|
|
|
136
155
|
else -> {
|
|
@@ -149,11 +168,13 @@ fun Header(
|
|
|
149
168
|
goBack: (() -> Unit) = { },
|
|
150
169
|
opacity: Float? = null,
|
|
151
170
|
animatedHeader: AnimatedHeader? = null,
|
|
152
|
-
|
|
171
|
+
useSearchInput: Boolean? = false,
|
|
172
|
+
scrollState: Int = 0,
|
|
173
|
+
inputSearchProps: InputSearchProps?
|
|
153
174
|
) {
|
|
154
175
|
val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
|
|
155
176
|
val tintIconColor = AppTheme.current.colors.text.default
|
|
156
|
-
val backgroundButton = Colors.black_01.copy(alpha = 0.
|
|
177
|
+
val backgroundButton = Colors.black_01.copy(alpha = 0.6f)
|
|
157
178
|
|
|
158
179
|
var colorFraction by remember { mutableStateOf(0f) }
|
|
159
180
|
|
|
@@ -172,6 +193,14 @@ fun Header(
|
|
|
172
193
|
)
|
|
173
194
|
)
|
|
174
195
|
|
|
196
|
+
val backgroundSearch by animateColorAsState(
|
|
197
|
+
targetValue = animateColor(
|
|
198
|
+
Colors.black_01,
|
|
199
|
+
AppTheme.current.colors.background.default,
|
|
200
|
+
colorFraction
|
|
201
|
+
)
|
|
202
|
+
)
|
|
203
|
+
|
|
175
204
|
if (headerType != HeaderType.NONE) {
|
|
176
205
|
BoxWithConstraints(
|
|
177
206
|
Modifier.height(statusBarHeight + 52.dp)
|
|
@@ -193,8 +222,8 @@ fun Header(
|
|
|
193
222
|
.size(28.dp)
|
|
194
223
|
.then(
|
|
195
224
|
Modifier.border(
|
|
196
|
-
0.
|
|
197
|
-
Colors.black_20.copy(alpha = 0.
|
|
225
|
+
0.2.dp,
|
|
226
|
+
Colors.black_20.copy(alpha = 0.2f),
|
|
198
227
|
RoundedCornerShape(100)
|
|
199
228
|
)
|
|
200
229
|
)
|
|
@@ -212,17 +241,19 @@ fun Header(
|
|
|
212
241
|
contentAlignment = Alignment.Center
|
|
213
242
|
) {
|
|
214
243
|
Icon(
|
|
215
|
-
source = "
|
|
244
|
+
source = "arrow-back",
|
|
216
245
|
color = if (animatedHeader !== null) tintIconColorAnim else tintIconColor,
|
|
217
246
|
size = 20.dp,
|
|
218
247
|
)
|
|
219
248
|
}
|
|
220
249
|
}
|
|
221
250
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
251
|
+
if (useSearchInput == false) {
|
|
252
|
+
Box(Modifier.graphicsLayer {
|
|
253
|
+
alpha = if (animatedHeader !== null) opacity ?: 1f else 1f
|
|
254
|
+
}) {
|
|
255
|
+
headerRight?.invoke()
|
|
256
|
+
}
|
|
226
257
|
}
|
|
227
258
|
}
|
|
228
259
|
|
|
@@ -236,23 +267,25 @@ fun Header(
|
|
|
236
267
|
if (isBack) {
|
|
237
268
|
Spacer(Modifier.width(40.dp))
|
|
238
269
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
alpha = if (animatedHeader !== null) opacity ?: 1f else 1f
|
|
242
|
-
},
|
|
243
|
-
contentAlignment = if (titlePosition == TitlePosition.LEFT) Alignment.TopStart else Alignment.Center
|
|
244
|
-
) {
|
|
245
|
-
HeaderTitle(
|
|
246
|
-
title = title,
|
|
247
|
-
color = if (animatedHeader !== null) tintIconColorAnim else tintIconColor,
|
|
248
|
-
modifier = Modifier.semantics {
|
|
249
|
-
contentDescription = title
|
|
250
|
-
testTag = "title_navigation_header"
|
|
251
|
-
}
|
|
252
|
-
)
|
|
270
|
+
if (useSearchInput == true && inputSearchProps != null) {
|
|
271
|
+
InputSearch(inputSearchProps = inputSearchProps.copy(backgroundColor = backgroundSearch))
|
|
253
272
|
}
|
|
254
|
-
|
|
255
|
-
|
|
273
|
+
else{
|
|
274
|
+
Box(
|
|
275
|
+
Modifier.weight(1f).graphicsLayer {
|
|
276
|
+
alpha = if (animatedHeader !== null) opacity ?: 1f else 1f
|
|
277
|
+
},
|
|
278
|
+
contentAlignment = if (titlePosition == TitlePosition.LEFT) Alignment.TopStart else Alignment.Center
|
|
279
|
+
) {
|
|
280
|
+
HeaderTitle(
|
|
281
|
+
title = title,
|
|
282
|
+
color = if (animatedHeader !== null) tintIconColorAnim else tintIconColor,
|
|
283
|
+
modifier = Modifier.semantics {
|
|
284
|
+
contentDescription = title
|
|
285
|
+
testTag = "title_navigation_header"
|
|
286
|
+
}
|
|
287
|
+
)
|
|
288
|
+
}
|
|
256
289
|
}
|
|
257
290
|
}
|
|
258
291
|
}
|
|
@@ -32,6 +32,7 @@ import androidx.compose.ui.unit.Dp
|
|
|
32
32
|
import androidx.compose.ui.unit.dp
|
|
33
33
|
import androidx.compose.ui.unit.min
|
|
34
34
|
import androidx.compose.ui.zIndex
|
|
35
|
+
import vn.momo.kits.components.InputSearchProps
|
|
35
36
|
import vn.momo.kits.const.AppStatusBar
|
|
36
37
|
import vn.momo.kits.const.AppTheme
|
|
37
38
|
import vn.momo.kits.const.Colors
|
|
@@ -65,6 +66,9 @@ fun Screen(
|
|
|
65
66
|
fabProps: FabProps? = null,
|
|
66
67
|
animatedHeader: AnimatedHeader? = null,
|
|
67
68
|
layoutOffset: Dp = 56.dp,
|
|
69
|
+
useShadow: Boolean? = true,
|
|
70
|
+
useSearchInput: Boolean? = false,
|
|
71
|
+
inputSearchProps: InputSearchProps? = null,
|
|
68
72
|
content: @Composable () -> Unit,
|
|
69
73
|
) {
|
|
70
74
|
val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
|
|
@@ -93,14 +97,18 @@ fun Screen(
|
|
|
93
97
|
) {
|
|
94
98
|
|
|
95
99
|
if (animatedHeader === null) {
|
|
96
|
-
HeaderBackground(headerType)
|
|
100
|
+
HeaderBackground(headerType = headerType, scrollState = scrollState.value)
|
|
97
101
|
} else {
|
|
98
102
|
Box(
|
|
99
103
|
Modifier.zIndex(5f)
|
|
100
104
|
.background(Color.White.copy(alpha = opacity))
|
|
101
105
|
.graphicsLayer { alpha = opacity }
|
|
102
106
|
) {
|
|
103
|
-
HeaderBackground(
|
|
107
|
+
HeaderBackground(
|
|
108
|
+
headerType = headerType,
|
|
109
|
+
useShadow = useShadow,
|
|
110
|
+
scrollState = scrollState.value
|
|
111
|
+
)
|
|
104
112
|
}
|
|
105
113
|
}
|
|
106
114
|
|
|
@@ -113,6 +121,8 @@ fun Screen(
|
|
|
113
121
|
goBack = goBack,
|
|
114
122
|
opacity = opacity,
|
|
115
123
|
animatedHeader = animatedHeader,
|
|
124
|
+
useSearchInput = useSearchInput,
|
|
125
|
+
inputSearchProps = inputSearchProps,
|
|
116
126
|
scrollState = scrollState.value
|
|
117
127
|
)
|
|
118
128
|
|
|
@@ -159,7 +169,8 @@ fun Screen(
|
|
|
159
169
|
scrollPosition = fabProps.scrollState?.value ?: scrollState.value,
|
|
160
170
|
onClick = fabProps.onClick,
|
|
161
171
|
containerColor = AppTheme.current.colors.primary,
|
|
162
|
-
bottom = fabProps.bottom
|
|
172
|
+
bottom = fabProps.bottom
|
|
173
|
+
?: if (footer != null) bottomPadding + 76.dp else bottomPadding + 12.dp,
|
|
163
174
|
icon = fabProps.icon,
|
|
164
175
|
iconColor = fabProps.iconColor,
|
|
165
176
|
text = fabProps.label,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
package vn.momo.kits.components
|
|
2
2
|
|
|
3
3
|
import androidx.compose.foundation.background
|
|
4
|
-
import androidx.compose.foundation.border
|
|
5
4
|
import androidx.compose.foundation.clickable
|
|
6
5
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
|
7
6
|
import androidx.compose.foundation.layout.Arrangement
|
|
@@ -33,13 +32,19 @@ import androidx.compose.ui.text.input.KeyboardType
|
|
|
33
32
|
import androidx.compose.ui.unit.dp
|
|
34
33
|
import androidx.compose.ui.unit.sp
|
|
35
34
|
import vn.momo.kits.const.AppTheme
|
|
35
|
+
import vn.momo.kits.const.Colors
|
|
36
36
|
import vn.momo.kits.const.Radius
|
|
37
37
|
import vn.momo.kits.const.Spacing
|
|
38
38
|
import vn.momo.kits.const.Typography
|
|
39
39
|
import vn.momo.kits.utils.ifTrue
|
|
40
40
|
|
|
41
41
|
@Composable
|
|
42
|
-
fun RenderRightIconSearch(
|
|
42
|
+
fun RenderRightIconSearch(
|
|
43
|
+
loading: Boolean,
|
|
44
|
+
icon: String,
|
|
45
|
+
color: Color,
|
|
46
|
+
onClick: () -> Unit,
|
|
47
|
+
) {
|
|
43
48
|
if (loading) {
|
|
44
49
|
Box(Modifier.padding(horizontal = Spacing.S)) {
|
|
45
50
|
CircularProgressIndicator(
|
|
@@ -68,34 +73,41 @@ fun RenderRightIconSearch(loading: Boolean, icon: String, color: Color, onClick:
|
|
|
68
73
|
}
|
|
69
74
|
}
|
|
70
75
|
|
|
76
|
+
data class InputSearchProps(
|
|
77
|
+
val text: MutableState<String>,
|
|
78
|
+
val buttonText: String = "",
|
|
79
|
+
val showButtonText: Boolean = false,
|
|
80
|
+
val placeholder: String = "",
|
|
81
|
+
val onChangeText: (String) -> Unit = {},
|
|
82
|
+
val onPressButtonText: () -> Unit = {},
|
|
83
|
+
val disabled: Boolean = false,
|
|
84
|
+
val icon: String = "",
|
|
85
|
+
val iconColor: Color = Color(0xff),
|
|
86
|
+
val onRightIconPressed: () -> Unit = {},
|
|
87
|
+
val onFocus: () -> Unit = {},
|
|
88
|
+
val onBlur: () -> Unit = {},
|
|
89
|
+
val loading: Boolean = false,
|
|
90
|
+
val fontWeight: InputFontWeight = InputFontWeight.REGULAR,
|
|
91
|
+
val keyboardType: KeyboardType = KeyboardType.Text,
|
|
92
|
+
val backgroundColor: Color = Colors.black_01,
|
|
93
|
+
)
|
|
94
|
+
|
|
71
95
|
@Composable
|
|
72
96
|
fun InputSearch(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
onChangeText: (String) -> Unit = {},
|
|
79
|
-
onPressButtonText: () -> Unit = {},
|
|
80
|
-
error: String = "",
|
|
81
|
-
disabled: Boolean = false,
|
|
82
|
-
icon: String = "",
|
|
83
|
-
iconColor: Color = AppTheme.current.colors.text.default,
|
|
84
|
-
onRightIconPressed: () -> Unit = {},
|
|
85
|
-
onFocus: () -> Unit = {},
|
|
86
|
-
onBlur: () -> Unit = {},
|
|
87
|
-
loading: Boolean = false,
|
|
88
|
-
fontWeight: InputFontWeight = InputFontWeight.REGULAR,
|
|
89
|
-
keyboardType: KeyboardType = KeyboardType.Text,
|
|
97
|
+
inputSearchProps: InputSearchProps = InputSearchProps(
|
|
98
|
+
text = remember { mutableStateOf("") },
|
|
99
|
+
iconColor = AppTheme.current.colors.text.default
|
|
100
|
+
),
|
|
101
|
+
|
|
90
102
|
) {
|
|
91
103
|
var isFocused by remember { mutableStateOf(false) }
|
|
92
104
|
var isBlurred = false
|
|
93
105
|
val disabledColor = AppTheme.current.colors.text.disable
|
|
94
106
|
var textColor = AppTheme.current.colors.text.default
|
|
95
107
|
var placeholderColor = AppTheme.current.colors.text.hint
|
|
96
|
-
var iconTintColor = iconColor
|
|
108
|
+
var iconTintColor = inputSearchProps.iconColor
|
|
97
109
|
|
|
98
|
-
if (disabled) {
|
|
110
|
+
if (inputSearchProps.disabled) {
|
|
99
111
|
textColor = disabledColor
|
|
100
112
|
placeholderColor = disabledColor
|
|
101
113
|
iconTintColor = disabledColor
|
|
@@ -103,37 +115,31 @@ fun InputSearch(
|
|
|
103
115
|
|
|
104
116
|
Column {
|
|
105
117
|
BasicTextField(
|
|
106
|
-
enabled = !disabled,
|
|
118
|
+
enabled = !inputSearchProps.disabled,
|
|
107
119
|
singleLine = true,
|
|
108
|
-
value = text.value,
|
|
120
|
+
value = inputSearchProps.text.value,
|
|
109
121
|
textStyle = TextStyle(
|
|
110
122
|
color = textColor,
|
|
111
|
-
fontSize =
|
|
112
|
-
lineHeight =
|
|
113
|
-
fontWeight = fontWeight.value
|
|
123
|
+
fontSize = 14.sp,
|
|
124
|
+
lineHeight = 20.sp,
|
|
125
|
+
fontWeight = inputSearchProps.fontWeight.value
|
|
114
126
|
),
|
|
115
|
-
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = keyboardType),
|
|
127
|
+
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = inputSearchProps.keyboardType),
|
|
116
128
|
modifier = Modifier.height(36.dp).onFocusChanged {
|
|
117
129
|
isFocused = it.isFocused
|
|
118
130
|
if (it.isFocused) {
|
|
119
|
-
onFocus()
|
|
131
|
+
inputSearchProps.onFocus()
|
|
120
132
|
}
|
|
121
|
-
if (!it.isFocused && isBlurred) onBlur()
|
|
133
|
+
if (!it.isFocused && isBlurred) inputSearchProps.onBlur()
|
|
122
134
|
if (it.isFocused && !isBlurred) isBlurred = true
|
|
123
135
|
},
|
|
124
|
-
onValueChange = onChangeText,
|
|
136
|
+
onValueChange = inputSearchProps.onChangeText,
|
|
125
137
|
decorationBox = { innerTextField ->
|
|
126
|
-
//input box wrapper
|
|
127
138
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
128
139
|
Row(
|
|
129
|
-
modifier = Modifier.weight(showButtonText.ifTrue(8f, 1f))
|
|
140
|
+
modifier = Modifier.weight(inputSearchProps.showButtonText.ifTrue(8f, 1f))
|
|
130
141
|
.background(
|
|
131
|
-
|
|
132
|
-
RoundedCornerShape(Radius.XL)
|
|
133
|
-
)
|
|
134
|
-
.border(
|
|
135
|
-
showBorder.ifTrue(1.dp, 0.dp),
|
|
136
|
-
getBorderColor(isFocused, error, disabled),
|
|
142
|
+
inputSearchProps.backgroundColor,
|
|
137
143
|
RoundedCornerShape(Radius.XL)
|
|
138
144
|
),
|
|
139
145
|
horizontalArrangement = Arrangement.Start,
|
|
@@ -154,20 +160,20 @@ fun InputSearch(
|
|
|
154
160
|
color = AppTheme.current.colors.text.hint
|
|
155
161
|
)
|
|
156
162
|
Box(Modifier.weight(1f)) {
|
|
157
|
-
if (text.value.isEmpty()) {
|
|
163
|
+
if (inputSearchProps.text.value.isEmpty()) {
|
|
158
164
|
Text(
|
|
159
|
-
text = placeholder,
|
|
165
|
+
text = inputSearchProps.placeholder,
|
|
160
166
|
style = TextStyle(
|
|
161
167
|
fontSize = 16.sp,
|
|
162
168
|
lineHeight = 24.sp,
|
|
163
|
-
fontWeight = fontWeight.value
|
|
169
|
+
fontWeight = inputSearchProps.fontWeight.value
|
|
164
170
|
),
|
|
165
171
|
color = placeholderColor
|
|
166
172
|
)
|
|
167
173
|
}
|
|
168
174
|
innerTextField()
|
|
169
175
|
}
|
|
170
|
-
if (isFocused && text.value.isNotEmpty()) {
|
|
176
|
+
if (isFocused && inputSearchProps.text.value.isNotEmpty()) {
|
|
171
177
|
Row {
|
|
172
178
|
Spacer(Modifier.width(Spacing.XS))
|
|
173
179
|
Icon(
|
|
@@ -175,25 +181,30 @@ fun InputSearch(
|
|
|
175
181
|
size = 16.dp,
|
|
176
182
|
color = AppTheme.current.colors.text.hint,
|
|
177
183
|
modifier = Modifier.clickable(
|
|
178
|
-
onClick = { text.value = "" },
|
|
184
|
+
onClick = { inputSearchProps.text.value = "" },
|
|
179
185
|
interactionSource = remember { MutableInteractionSource() },
|
|
180
186
|
indication = null
|
|
181
187
|
)
|
|
182
188
|
)
|
|
183
189
|
}
|
|
184
190
|
}
|
|
185
|
-
RenderRightIconSearch(
|
|
191
|
+
RenderRightIconSearch(
|
|
192
|
+
inputSearchProps.loading,
|
|
193
|
+
inputSearchProps.icon,
|
|
194
|
+
iconTintColor,
|
|
195
|
+
inputSearchProps.onRightIconPressed
|
|
196
|
+
)
|
|
186
197
|
}
|
|
187
198
|
}
|
|
188
|
-
if (showButtonText) {
|
|
199
|
+
if (inputSearchProps.showButtonText) {
|
|
189
200
|
Text(
|
|
190
|
-
text = buttonText,
|
|
201
|
+
text = inputSearchProps.buttonText,
|
|
191
202
|
style = Typography.actionDefault,
|
|
192
203
|
color = AppTheme.current.colors.text.default,
|
|
193
204
|
modifier = Modifier.padding(start = Spacing.L).clickable(
|
|
194
205
|
interactionSource = remember { MutableInteractionSource() },
|
|
195
206
|
indication = null,
|
|
196
|
-
onClick = onPressButtonText
|
|
207
|
+
onClick = inputSearchProps.onPressButtonText
|
|
197
208
|
)
|
|
198
209
|
)
|
|
199
210
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
package vn.momo.kits.components
|
|
2
2
|
|
|
3
3
|
import androidx.compose.foundation.background
|
|
4
|
-
import androidx.compose.foundation.border
|
|
5
4
|
import androidx.compose.foundation.clickable
|
|
6
5
|
import androidx.compose.foundation.layout.Arrangement
|
|
7
6
|
import androidx.compose.foundation.layout.Column
|
|
@@ -9,9 +8,7 @@ import androidx.compose.foundation.layout.Row
|
|
|
9
8
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
10
9
|
import androidx.compose.foundation.layout.height
|
|
11
10
|
import androidx.compose.foundation.layout.padding
|
|
12
|
-
import androidx.compose.foundation.layout.size
|
|
13
11
|
import androidx.compose.foundation.layout.width
|
|
14
|
-
import androidx.compose.foundation.shape.CircleShape
|
|
15
12
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
16
13
|
import androidx.compose.material.Text
|
|
17
14
|
import androidx.compose.runtime.Composable
|
|
@@ -29,7 +26,11 @@ val defaultBanner = TrustBannerData(
|
|
|
29
26
|
"vi" to "Bảo mật thông tin & An toàn tài sản của bạn là ưu tiên hàng đầu của MoMo.",
|
|
30
27
|
"en" to "Your data security and money safety are MoMo's top priorities."
|
|
31
28
|
),
|
|
32
|
-
|
|
29
|
+
subContent = mapOf(
|
|
30
|
+
"vi" to "Tìm hiểu thêm",
|
|
31
|
+
"en" to "Learn more"
|
|
32
|
+
),
|
|
33
|
+
pciImage = "https://static.momocdn.net/app/img/kits/trustBanner/pci_dss.png",
|
|
33
34
|
sslImage = "https://static.momocdn.net/app/img/kits/trustBanner/ssl.png",
|
|
34
35
|
urlConfig = "login_and_security",
|
|
35
36
|
icons = listOf(
|
|
@@ -38,40 +39,23 @@ val defaultBanner = TrustBannerData(
|
|
|
38
39
|
"https://static.momocdn.net/app/img/kits/trustBanner/ic_vietcombank.png",
|
|
39
40
|
"https://static.momocdn.net/app/img/kits/trustBanner/ic_bidv.png"
|
|
40
41
|
),
|
|
41
|
-
momoImage = "https://static.momocdn.net/app/img/kits/trustBanner/
|
|
42
|
+
momoImage = "https://static.momocdn.net/app/img/kits/trustBanner/ic_secu.png"
|
|
42
43
|
)
|
|
43
44
|
|
|
44
|
-
const val borderColor = 0xFFE8E8E8
|
|
45
|
-
const val tonalColor = 0xFFFDEAF4
|
|
46
45
|
const val backgroundBlue = 0xFFF2F8FF
|
|
47
46
|
const val contentColor = 0xFF484848
|
|
48
|
-
const val
|
|
49
|
-
|
|
50
|
-
data class TrustBannerClass(
|
|
51
|
-
val trustBanner: TrustBannerData
|
|
52
|
-
)
|
|
47
|
+
const val subContentColor = 0xFFEB2F96
|
|
53
48
|
|
|
54
49
|
data class TrustBannerData(
|
|
55
50
|
val content: Map<String, String>,
|
|
51
|
+
val subContent: Map<String, String>,
|
|
56
52
|
val pciImage: String,
|
|
53
|
+
val momoImage: String,
|
|
57
54
|
val sslImage: String,
|
|
58
55
|
val icons: List<String>,
|
|
59
|
-
val momoImage: String,
|
|
60
56
|
val urlConfig: String
|
|
61
57
|
)
|
|
62
58
|
|
|
63
|
-
@Composable
|
|
64
|
-
fun Avatar(iconURL: String) {
|
|
65
|
-
Image(
|
|
66
|
-
source = iconURL,
|
|
67
|
-
modifier = Modifier
|
|
68
|
-
.size(24.dp)
|
|
69
|
-
.background(Color.White, CircleShape)
|
|
70
|
-
.border(width = 1.dp, color = Color(borderColor), CircleShape),
|
|
71
|
-
options = Options(contentScale = ContentScale.Fit)
|
|
72
|
-
)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
59
|
@Composable
|
|
76
60
|
fun TrustBanner(
|
|
77
61
|
trustBanner: TrustBannerData = defaultBanner,
|
|
@@ -80,6 +64,7 @@ fun TrustBanner(
|
|
|
80
64
|
onPress: ((Map<String, String>) -> Unit)? = null,
|
|
81
65
|
trackEvent: ((String, Map<String, String>) -> Unit)? = null,
|
|
82
66
|
language: String = "vi"
|
|
67
|
+
|
|
83
68
|
) {
|
|
84
69
|
val trackParams = mapOf(
|
|
85
70
|
"service_name" to serviceName,
|
|
@@ -123,12 +108,11 @@ fun TrustBanner(
|
|
|
123
108
|
modifier = Modifier
|
|
124
109
|
.width(64.dp)
|
|
125
110
|
.height(64.dp)
|
|
126
|
-
.padding(end = 8.dp),
|
|
127
|
-
options = Options(
|
|
128
|
-
contentScale = ContentScale.Fit,
|
|
129
|
-
)
|
|
130
111
|
)
|
|
131
|
-
Column
|
|
112
|
+
Column (
|
|
113
|
+
modifier = Modifier
|
|
114
|
+
.padding(start = 10.dp)
|
|
115
|
+
) {
|
|
132
116
|
Text(
|
|
133
117
|
text = trustBanner.content[language] ?: "",
|
|
134
118
|
modifier = Modifier.padding(bottom = 8.dp),
|
|
@@ -138,11 +122,26 @@ fun TrustBanner(
|
|
|
138
122
|
maxLines = 2
|
|
139
123
|
)
|
|
140
124
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
|
|
125
|
+
Row (
|
|
126
|
+
verticalAlignment = Alignment.CenterVertically,
|
|
127
|
+
) {
|
|
128
|
+
Text(
|
|
129
|
+
text = trustBanner.subContent[language] ?: "",
|
|
130
|
+
lineHeight = 16.sp,
|
|
131
|
+
fontSize = 12.sp,
|
|
132
|
+
color = Color(subContentColor),
|
|
133
|
+
maxLines = 2
|
|
134
|
+
)
|
|
135
|
+
Icon(
|
|
136
|
+
source = "https://img.mservice.io/momo_app_v2/new_version/img/appx_icon/16_arrow_chevron_right_small.png",
|
|
137
|
+
color = Color(subContentColor),
|
|
138
|
+
)
|
|
139
|
+
}
|
|
141
140
|
Row {
|
|
142
141
|
Image(
|
|
143
142
|
source = trustBanner.pciImage, modifier = Modifier
|
|
144
143
|
.padding(end = 4.dp)
|
|
145
|
-
.width(
|
|
144
|
+
.width(27.dp)
|
|
146
145
|
.height(20.dp)
|
|
147
146
|
,options = Options(
|
|
148
147
|
contentScale = ContentScale.Fit,
|
|
@@ -157,31 +156,6 @@ fun TrustBanner(
|
|
|
157
156
|
)
|
|
158
157
|
)
|
|
159
158
|
}
|
|
160
|
-
Row(
|
|
161
|
-
modifier = Modifier
|
|
162
|
-
.width(96.dp)
|
|
163
|
-
.height(24.dp),
|
|
164
|
-
horizontalArrangement = Arrangement.spacedBy((-6).dp)
|
|
165
|
-
) {
|
|
166
|
-
trustBanner.icons.forEach { iconURL ->
|
|
167
|
-
Avatar(iconURL = iconURL)
|
|
168
|
-
}
|
|
169
|
-
Row(
|
|
170
|
-
modifier = Modifier
|
|
171
|
-
.size(24.dp)
|
|
172
|
-
.background(color = Color(tonalColor), CircleShape)
|
|
173
|
-
.border(width = 1.dp, color = Color(borderColor), CircleShape),
|
|
174
|
-
verticalAlignment = Alignment.CenterVertically,
|
|
175
|
-
horizontalArrangement = Arrangement.Center
|
|
176
|
-
) {
|
|
177
|
-
Text(
|
|
178
|
-
text = "36+",
|
|
179
|
-
color = Color(primaryColor),
|
|
180
|
-
lineHeight = 14.sp,
|
|
181
|
-
fontSize = 10.sp
|
|
182
|
-
)
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
159
|
}
|
|
186
160
|
}
|
|
187
161
|
}
|
|
@@ -4,6 +4,7 @@ val Icons = mapOf(
|
|
|
4
4
|
"01.MoMo Copy" to "https://img.mservice.com.vn/app/img/kits/01.MoMo%20Copy.png",
|
|
5
5
|
"01.MoMo" to "https://img.mservice.com.vn/app/img/kits/01.MoMo.png",
|
|
6
6
|
"Phonebook" to "https://img.mservice.com.vn/app/img/kits/Phonebook.png",
|
|
7
|
+
"arrow-back" to "https://static.momocdn.net/app/img/kits/arrow-back.png",
|
|
7
8
|
"arrow_arrow-back" to "https://img.mservice.com.vn/app/img/kits/arrow_arrow-back.png",
|
|
8
9
|
"arrow_arrow-down" to "https://img.mservice.com.vn/app/img/kits/arrow_arrow-down.png",
|
|
9
10
|
"arrow_arrow-next" to "https://img.mservice.com.vn/app/img/kits/arrow_arrow-next.png",
|
package/local.properties
CHANGED
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
# Location of the SDK. This is only used by Gradle.
|
|
5
5
|
# For customization when using a Version Control System, please read the
|
|
6
6
|
# header note.
|
|
7
|
-
#
|
|
8
|
-
sdk.dir=/Users/
|
|
7
|
+
#Tue Apr 23 16:40:15 ICT 2024
|
|
8
|
+
sdk.dir=/Users/hung.dao1/Library/Android/sdk
|