@momo-kits/native-kits 0.89.19 → 0.89.20
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 +18 -14
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +22 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Components.kt +71 -25
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +200 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +47 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +7 -139
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +89 -22
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +17 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +6 -8
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +36 -17
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +54 -21
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +155 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +2 -20
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +185 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +0 -19
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +2 -18
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +58 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +37 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +65 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +43 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +0 -3
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +14 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +2 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +28 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +1 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +18 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +0 -23
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +33 -0
- package/package.json +1 -1
- package/settings.gradle.kts +1 -0
- package/compose/src/androidMain/kotlin/vn/momo/kits/utils/Platform.kt +0 -3
- package/compose/src/androidMain/kotlin/vn/momo/kits/utils/SetMaskFilter.kt +0 -8
- package/compose/src/androidMain/kotlin/vn/momo/kits/utils/Utils.android.kt +0 -14
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Platform.kt +0 -3
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/SetMaskFilter.kt +0 -5
- package/compose/src/iosMain/kotlin/vn/momo/kits/utils/Platform.kt +0 -3
- package/compose/src/iosMain/kotlin/vn/momo/kits/utils/SetMaskFilter.kt +0 -9
- package/compose/src/iosMain/kotlin/vn/momo/kits/utils/Utils.ios.kt +0 -18
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
package vn.momo.kits.components
|
|
2
|
+
|
|
3
|
+
import androidx.compose.foundation.background
|
|
4
|
+
import androidx.compose.foundation.border
|
|
5
|
+
import androidx.compose.foundation.clickable
|
|
6
|
+
import androidx.compose.foundation.layout.Box
|
|
7
|
+
import androidx.compose.foundation.layout.Column
|
|
8
|
+
import androidx.compose.foundation.layout.Row
|
|
9
|
+
import androidx.compose.foundation.layout.fillMaxWidth
|
|
10
|
+
import androidx.compose.foundation.layout.height
|
|
11
|
+
import androidx.compose.foundation.layout.offset
|
|
12
|
+
import androidx.compose.foundation.layout.padding
|
|
13
|
+
import androidx.compose.foundation.layout.wrapContentSize
|
|
14
|
+
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
15
|
+
import androidx.compose.runtime.Composable
|
|
16
|
+
import androidx.compose.runtime.MutableState
|
|
17
|
+
import androidx.compose.runtime.getValue
|
|
18
|
+
import androidx.compose.runtime.mutableStateOf
|
|
19
|
+
import androidx.compose.runtime.remember
|
|
20
|
+
import androidx.compose.runtime.setValue
|
|
21
|
+
import androidx.compose.ui.Alignment
|
|
22
|
+
import androidx.compose.ui.Modifier
|
|
23
|
+
import androidx.compose.ui.graphics.Color
|
|
24
|
+
import androidx.compose.ui.text.TextStyle
|
|
25
|
+
import androidx.compose.ui.unit.dp
|
|
26
|
+
import androidx.compose.ui.unit.sp
|
|
27
|
+
import androidx.compose.ui.zIndex
|
|
28
|
+
import vn.momo.kits.const.AppTheme
|
|
29
|
+
import vn.momo.kits.const.Spacing
|
|
30
|
+
import vn.momo.kits.const.Typography
|
|
31
|
+
|
|
32
|
+
@Composable
|
|
33
|
+
fun InputDropDown(
|
|
34
|
+
value: MutableState<String> = remember { mutableStateOf("") },
|
|
35
|
+
floatingValue: String = "",
|
|
36
|
+
floatingValueColor: Color = AppTheme.current.colors.text.hint,
|
|
37
|
+
floatingIcon: String = "",
|
|
38
|
+
floatingIconColor: Color = AppTheme.current.colors.text.default,
|
|
39
|
+
placeholder: String = "",
|
|
40
|
+
size: InputSize = InputSize.SMALL,
|
|
41
|
+
onPress: () -> Unit = {},
|
|
42
|
+
hintText: String = "",
|
|
43
|
+
error: String = "",
|
|
44
|
+
errorSpacing: Boolean = false,
|
|
45
|
+
disabled: Boolean = false,
|
|
46
|
+
icon: String = "arrow_chevron_down_small",
|
|
47
|
+
iconColor: Color = AppTheme.current.colors.text.default,
|
|
48
|
+
onRightIconPressed: () -> Unit = {},
|
|
49
|
+
leadingIcon: String = "",
|
|
50
|
+
leadingIconColor: Color = AppTheme.current.colors.text.hint,
|
|
51
|
+
loading: Boolean = false,
|
|
52
|
+
required: Boolean = false,
|
|
53
|
+
) {
|
|
54
|
+
var isFocused by remember { mutableStateOf(false) }
|
|
55
|
+
|
|
56
|
+
val disabledColor = AppTheme.current.colors.text.disable
|
|
57
|
+
var textColor = AppTheme.current.colors.text.default
|
|
58
|
+
var placeholderColor = AppTheme.current.colors.text.hint
|
|
59
|
+
var iconTintColor = iconColor
|
|
60
|
+
val floatingTitleColor = when {
|
|
61
|
+
disabled -> AppTheme.current.colors.text.disable
|
|
62
|
+
else -> floatingValueColor
|
|
63
|
+
}
|
|
64
|
+
val floatingIconTintColor = when {
|
|
65
|
+
disabled -> AppTheme.current.colors.text.disable
|
|
66
|
+
else -> floatingIconColor
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (disabled) {
|
|
70
|
+
textColor = disabledColor
|
|
71
|
+
placeholderColor = disabledColor
|
|
72
|
+
iconTintColor = disabledColor
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
Column(modifier = Modifier.clickable(enabled = !disabled, onClick = onPress)) {
|
|
77
|
+
Box {
|
|
78
|
+
if (floatingValue.isNotEmpty() || floatingIcon.isNotEmpty()) {
|
|
79
|
+
Box(
|
|
80
|
+
modifier = Modifier.wrapContentSize()
|
|
81
|
+
.offset(y = -Spacing.S, x = Spacing.S)
|
|
82
|
+
.background(AppTheme.current.colors.background.surface)
|
|
83
|
+
.zIndex(10f),
|
|
84
|
+
) {
|
|
85
|
+
Row(
|
|
86
|
+
modifier = Modifier
|
|
87
|
+
.padding(horizontal = Spacing.S),
|
|
88
|
+
verticalAlignment = Alignment.Bottom
|
|
89
|
+
) {
|
|
90
|
+
Text(
|
|
91
|
+
floatingValue,
|
|
92
|
+
style = Typography.labelS,
|
|
93
|
+
color = floatingTitleColor
|
|
94
|
+
)
|
|
95
|
+
if (required) {
|
|
96
|
+
Text(
|
|
97
|
+
"*",
|
|
98
|
+
style = Typography.labelS,
|
|
99
|
+
color = AppTheme.current.colors.error.primary,
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
if (floatingIcon.isNotEmpty()) {
|
|
103
|
+
Icon(
|
|
104
|
+
source = floatingIcon,
|
|
105
|
+
modifier = Modifier.padding(start = Spacing.XS),
|
|
106
|
+
size = 16.dp,
|
|
107
|
+
color = floatingIconTintColor
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
Box(
|
|
114
|
+
modifier = Modifier.fillMaxWidth()
|
|
115
|
+
.height(if (size == InputSize.SMALL) 48.dp else 56.dp)
|
|
116
|
+
.border(
|
|
117
|
+
1.dp,
|
|
118
|
+
getBorderColor(isFocused, error, disabled),
|
|
119
|
+
RoundedCornerShape(size.values.borderRadius)
|
|
120
|
+
),
|
|
121
|
+
contentAlignment = Alignment.CenterStart
|
|
122
|
+
) {
|
|
123
|
+
Row(
|
|
124
|
+
modifier = Modifier.padding(horizontal = Spacing.M),
|
|
125
|
+
verticalAlignment = Alignment.CenterVertically
|
|
126
|
+
) {
|
|
127
|
+
//leading icon
|
|
128
|
+
if (leadingIcon.isNotEmpty()) {
|
|
129
|
+
Icon(
|
|
130
|
+
source = leadingIcon,
|
|
131
|
+
modifier = Modifier.padding(end = Spacing.M),
|
|
132
|
+
size = if (size.name == InputSize.SMALL.name) 24.dp else 32.dp,
|
|
133
|
+
color = leadingIconColor
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
Box(Modifier.weight(1f)) {
|
|
137
|
+
Text(
|
|
138
|
+
text = value.value.ifEmpty { placeholder },
|
|
139
|
+
style = TextStyle(
|
|
140
|
+
fontSize = 16.sp,
|
|
141
|
+
lineHeight = 24.sp
|
|
142
|
+
),
|
|
143
|
+
color = if (value.value.isEmpty()) placeholderColor else textColor
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
RenderRightIcon(
|
|
147
|
+
loading, icon, iconTintColor,
|
|
148
|
+
onRightIconPressed
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
ErrorView(error, errorSpacing, hintText)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -69,6 +69,7 @@ fun InputMoney(
|
|
|
69
69
|
size: InputSize = InputSize.SMALL,
|
|
70
70
|
onChangeText: (String) -> Unit = {},
|
|
71
71
|
error: String = "",
|
|
72
|
+
errorSpacing: Boolean = false,
|
|
72
73
|
disabled: Boolean = false,
|
|
73
74
|
icon: String = "",
|
|
74
75
|
iconColor: Color = AppTheme.current.colors.text.default,
|
|
@@ -222,25 +223,6 @@ fun InputMoney(
|
|
|
222
223
|
}
|
|
223
224
|
},
|
|
224
225
|
)
|
|
225
|
-
|
|
226
|
-
if (error.isNotEmpty()) {
|
|
227
|
-
Row(
|
|
228
|
-
Modifier.padding(top = Spacing.XS),
|
|
229
|
-
verticalAlignment = Alignment.CenterVertically
|
|
230
|
-
) {
|
|
231
|
-
Icon(
|
|
232
|
-
size = 16.dp,
|
|
233
|
-
color = AppTheme.current.colors.error.primary,
|
|
234
|
-
source = "ic_error"
|
|
235
|
-
)
|
|
236
|
-
|
|
237
|
-
Text(
|
|
238
|
-
error,
|
|
239
|
-
style = Typography.descriptionS,
|
|
240
|
-
modifier = Modifier.padding(start = Spacing.XS),
|
|
241
|
-
color = AppTheme.current.colors.error.primary,
|
|
242
|
-
)
|
|
243
|
-
}
|
|
244
|
-
}
|
|
226
|
+
ErrorView(error, errorSpacing, "")
|
|
245
227
|
}
|
|
246
228
|
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
package vn.momo.kits.components
|
|
2
|
+
|
|
3
|
+
import androidx.compose.animation.core.LinearEasing
|
|
4
|
+
import androidx.compose.animation.core.RepeatMode
|
|
5
|
+
import androidx.compose.animation.core.animateFloat
|
|
6
|
+
import androidx.compose.animation.core.infiniteRepeatable
|
|
7
|
+
import androidx.compose.animation.core.rememberInfiniteTransition
|
|
8
|
+
import androidx.compose.animation.core.tween
|
|
9
|
+
import androidx.compose.foundation.background
|
|
10
|
+
import androidx.compose.foundation.border
|
|
11
|
+
import androidx.compose.foundation.layout.Arrangement
|
|
12
|
+
import androidx.compose.foundation.layout.Box
|
|
13
|
+
import androidx.compose.foundation.layout.Column
|
|
14
|
+
import androidx.compose.foundation.layout.Row
|
|
15
|
+
import androidx.compose.foundation.layout.Spacer
|
|
16
|
+
import androidx.compose.foundation.layout.fillMaxWidth
|
|
17
|
+
import androidx.compose.foundation.layout.height
|
|
18
|
+
import androidx.compose.foundation.layout.offset
|
|
19
|
+
import androidx.compose.foundation.layout.padding
|
|
20
|
+
import androidx.compose.foundation.layout.size
|
|
21
|
+
import androidx.compose.foundation.layout.width
|
|
22
|
+
import androidx.compose.foundation.layout.wrapContentSize
|
|
23
|
+
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
24
|
+
import androidx.compose.foundation.text.BasicTextField
|
|
25
|
+
import androidx.compose.foundation.text.KeyboardOptions
|
|
26
|
+
import androidx.compose.runtime.Composable
|
|
27
|
+
import androidx.compose.runtime.getValue
|
|
28
|
+
import androidx.compose.runtime.mutableStateOf
|
|
29
|
+
import androidx.compose.runtime.remember
|
|
30
|
+
import androidx.compose.runtime.setValue
|
|
31
|
+
import androidx.compose.ui.Alignment
|
|
32
|
+
import androidx.compose.ui.Modifier
|
|
33
|
+
import androidx.compose.ui.focus.onFocusChanged
|
|
34
|
+
import androidx.compose.ui.text.input.KeyboardType
|
|
35
|
+
import androidx.compose.ui.unit.dp
|
|
36
|
+
import androidx.compose.ui.zIndex
|
|
37
|
+
import vn.momo.kits.const.AppTheme
|
|
38
|
+
import vn.momo.kits.const.Radius
|
|
39
|
+
import vn.momo.kits.const.Spacing
|
|
40
|
+
import vn.momo.kits.const.Typography
|
|
41
|
+
import vn.momo.kits.const.scaleSize
|
|
42
|
+
|
|
43
|
+
@Composable
|
|
44
|
+
fun OTPCaret() {
|
|
45
|
+
val DURATION = 500
|
|
46
|
+
var backgroundColor = AppTheme.current.colors.primary
|
|
47
|
+
|
|
48
|
+
val infiniteTransition = rememberInfiniteTransition()
|
|
49
|
+
val alpha by infiniteTransition.animateFloat(
|
|
50
|
+
initialValue = 1f,
|
|
51
|
+
targetValue = 0f,
|
|
52
|
+
animationSpec = infiniteRepeatable(
|
|
53
|
+
animation = tween(
|
|
54
|
+
durationMillis = DURATION,
|
|
55
|
+
delayMillis = DURATION,
|
|
56
|
+
easing = LinearEasing
|
|
57
|
+
),
|
|
58
|
+
repeatMode = RepeatMode.Reverse
|
|
59
|
+
)
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
63
|
+
Box(
|
|
64
|
+
modifier = Modifier
|
|
65
|
+
.size(1.dp, scaleSize(12f).dp)
|
|
66
|
+
.background(backgroundColor.copy(alpha = alpha))
|
|
67
|
+
)
|
|
68
|
+
Text(
|
|
69
|
+
text = "-",
|
|
70
|
+
color = AppTheme.current.colors.text.hint,
|
|
71
|
+
style = Typography.descriptionDefault
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@Composable
|
|
77
|
+
fun InputOTP(
|
|
78
|
+
length: Int = 4,
|
|
79
|
+
errorMessage: String = "",
|
|
80
|
+
errorSpacing: Boolean = false,
|
|
81
|
+
floatingValue: String = "Label",
|
|
82
|
+
placeholder: String = "",
|
|
83
|
+
onChangeText: (String) -> Unit,
|
|
84
|
+
onFocus: () -> Unit = {},
|
|
85
|
+
onBlur: () -> Unit = {},
|
|
86
|
+
dataType: String = "number",
|
|
87
|
+
accessibilityLabel: String? = null,
|
|
88
|
+
) {
|
|
89
|
+
val MAX_LENGTH = 10
|
|
90
|
+
var value by remember { mutableStateOf("") }
|
|
91
|
+
var isFocused by remember { mutableStateOf(false) }
|
|
92
|
+
var isBlurred = false
|
|
93
|
+
|
|
94
|
+
val handleChangeText: (String) -> Unit = { text ->
|
|
95
|
+
if (text.length <= MAX_LENGTH && (text.length <= value.length || value.length < length) && (dataType != "number" || !text.any { !it.isDigit() })) {
|
|
96
|
+
value = text
|
|
97
|
+
onChangeText(text)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
Column {
|
|
103
|
+
BasicTextField(
|
|
104
|
+
value = value,
|
|
105
|
+
onValueChange = handleChangeText,
|
|
106
|
+
singleLine = true,
|
|
107
|
+
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = if (dataType == "number") KeyboardType.Number else KeyboardType.Ascii),
|
|
108
|
+
modifier = Modifier.height(56.dp).onFocusChanged {
|
|
109
|
+
isFocused = it.isFocused
|
|
110
|
+
if (it.isFocused) {
|
|
111
|
+
onFocus()
|
|
112
|
+
}
|
|
113
|
+
if (!it.isFocused && isBlurred) onBlur()
|
|
114
|
+
if (it.isFocused && !isBlurred) isBlurred = true
|
|
115
|
+
},
|
|
116
|
+
decorationBox = { innerTextField ->
|
|
117
|
+
Box {
|
|
118
|
+
if (floatingValue.isNotEmpty()) {
|
|
119
|
+
Box(
|
|
120
|
+
modifier = Modifier.wrapContentSize()
|
|
121
|
+
.offset(y = ((-56).dp / 2))
|
|
122
|
+
.align(Alignment.Center)
|
|
123
|
+
.background(AppTheme.current.colors.background.surface)
|
|
124
|
+
.zIndex(10f),
|
|
125
|
+
) {
|
|
126
|
+
Row(
|
|
127
|
+
modifier = Modifier
|
|
128
|
+
.padding(horizontal = Spacing.S),
|
|
129
|
+
verticalAlignment = Alignment.Bottom
|
|
130
|
+
) {
|
|
131
|
+
Text(
|
|
132
|
+
floatingValue,
|
|
133
|
+
style = Typography.labelS,
|
|
134
|
+
color = AppTheme.current.colors.text.hint
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
Box(
|
|
140
|
+
modifier = Modifier
|
|
141
|
+
.fillMaxWidth()
|
|
142
|
+
.height(56.dp)
|
|
143
|
+
.border(
|
|
144
|
+
1.dp,
|
|
145
|
+
getBorderColor(isFocused, errorMessage, false),
|
|
146
|
+
RoundedCornerShape(
|
|
147
|
+
Radius.S
|
|
148
|
+
)
|
|
149
|
+
), contentAlignment = Alignment.Center
|
|
150
|
+
) {
|
|
151
|
+
Row(
|
|
152
|
+
modifier = Modifier.padding(vertical = 8.dp),
|
|
153
|
+
horizontalArrangement = Arrangement.SpaceBetween,
|
|
154
|
+
verticalAlignment = Alignment.CenterVertically
|
|
155
|
+
) {
|
|
156
|
+
for (i in 0 until length) {
|
|
157
|
+
if (value.isEmpty() && !isFocused && placeholder.isNotEmpty()) {
|
|
158
|
+
return@BasicTextField Text(
|
|
159
|
+
text = placeholder,
|
|
160
|
+
color = AppTheme.current.colors.text.hint
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
if (isFocused && value.length == i) {
|
|
164
|
+
OTPCaret();
|
|
165
|
+
} else {
|
|
166
|
+
val textColor =
|
|
167
|
+
if (value.getOrNull(i) != null) AppTheme.current.colors.text.default else AppTheme.current.colors.text.hint
|
|
168
|
+
val typo =
|
|
169
|
+
if (value.getOrNull(i) != null) Typography.titleS else Typography.descriptionDefault
|
|
170
|
+
Text(
|
|
171
|
+
text = value.getOrNull(i)?.toString() ?: "-",
|
|
172
|
+
color = textColor,
|
|
173
|
+
style = typo
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
if (i != length - 1) Spacer(Modifier.width(Spacing.L))
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
ErrorView(errorMessage, errorSpacing, "")
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -200,24 +200,5 @@ fun InputSearch(
|
|
|
200
200
|
}
|
|
201
201
|
},
|
|
202
202
|
)
|
|
203
|
-
// show error
|
|
204
|
-
if (error.isNotEmpty()) {
|
|
205
|
-
Row(
|
|
206
|
-
Modifier.padding(top = Spacing.XS),
|
|
207
|
-
verticalAlignment = Alignment.CenterVertically
|
|
208
|
-
) {
|
|
209
|
-
Icon(
|
|
210
|
-
size = 16.dp,
|
|
211
|
-
color = AppTheme.current.colors.error.primary,
|
|
212
|
-
source = "ic_error"
|
|
213
|
-
)
|
|
214
|
-
Text(
|
|
215
|
-
error,
|
|
216
|
-
style = Typography.descriptionS,
|
|
217
|
-
modifier = Modifier.padding(start = Spacing.XS),
|
|
218
|
-
color = AppTheme.current.colors.error.primary,
|
|
219
|
-
)
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
203
|
}
|
|
223
204
|
}
|
|
@@ -53,6 +53,7 @@ fun InputTextArea(
|
|
|
53
53
|
size: InputSize = InputSize.SMALL,
|
|
54
54
|
onChangeText: (String) -> Unit = {},
|
|
55
55
|
error: String = "",
|
|
56
|
+
errorSpacing: Boolean = false,
|
|
56
57
|
disabled: Boolean = false,
|
|
57
58
|
icon: String = "",
|
|
58
59
|
iconColor: Color = AppTheme.current.colors.text.default,
|
|
@@ -222,23 +223,6 @@ fun InputTextArea(
|
|
|
222
223
|
},
|
|
223
224
|
)
|
|
224
225
|
// show error
|
|
225
|
-
|
|
226
|
-
Row(
|
|
227
|
-
Modifier.padding(top = Spacing.XS),
|
|
228
|
-
verticalAlignment = Alignment.CenterVertically
|
|
229
|
-
) {
|
|
230
|
-
Icon(
|
|
231
|
-
size = 16.dp,
|
|
232
|
-
color = AppTheme.current.colors.error.primary,
|
|
233
|
-
source = "ic_error"
|
|
234
|
-
)
|
|
235
|
-
Text(
|
|
236
|
-
error,
|
|
237
|
-
style = Typography.descriptionS,
|
|
238
|
-
modifier = Modifier.padding(start = Spacing.XS),
|
|
239
|
-
color = AppTheme.current.colors.error.primary,
|
|
240
|
-
)
|
|
241
|
-
}
|
|
242
|
-
}
|
|
226
|
+
ErrorView(error, errorSpacing, "")
|
|
243
227
|
}
|
|
244
228
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
package vn.momo.kits.components
|
|
2
|
+
|
|
3
|
+
import androidx.compose.foundation.background
|
|
4
|
+
import androidx.compose.foundation.layout.Box
|
|
5
|
+
import androidx.compose.foundation.layout.BoxWithConstraints
|
|
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.size
|
|
10
|
+
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
11
|
+
import androidx.compose.runtime.Composable
|
|
12
|
+
import androidx.compose.ui.Alignment
|
|
13
|
+
import androidx.compose.ui.Modifier
|
|
14
|
+
import androidx.compose.ui.draw.alpha
|
|
15
|
+
import androidx.compose.ui.draw.clip
|
|
16
|
+
import androidx.compose.ui.draw.clipToBounds
|
|
17
|
+
import androidx.compose.ui.graphics.Color
|
|
18
|
+
import androidx.compose.ui.unit.dp
|
|
19
|
+
import vn.momo.kits.const.AppTheme
|
|
20
|
+
import vn.momo.kits.const.Colors
|
|
21
|
+
import vn.momo.kits.const.Spacing
|
|
22
|
+
import vn.momo.kits.const.Typography
|
|
23
|
+
|
|
24
|
+
@Composable
|
|
25
|
+
fun Dot(active: Boolean = false, activeColor: Color, modifier: Modifier = Modifier) {
|
|
26
|
+
return if (active) {
|
|
27
|
+
Box(
|
|
28
|
+
modifier = modifier.size(width = 12.dp, height = 4.dp).background(
|
|
29
|
+
color = activeColor,
|
|
30
|
+
shape = RoundedCornerShape(4.dp)
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
} else {
|
|
34
|
+
Box(
|
|
35
|
+
modifier = modifier.size(4.dp)
|
|
36
|
+
.background(
|
|
37
|
+
color = AppTheme.current.colors.background.pressed,
|
|
38
|
+
shape = RoundedCornerShape(4.dp)
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@Composable
|
|
45
|
+
fun PaginationDot(
|
|
46
|
+
activeIndex: Int = 0,
|
|
47
|
+
dataLength: Int = 3
|
|
48
|
+
) {
|
|
49
|
+
Row {
|
|
50
|
+
for (i in 0 until dataLength) {
|
|
51
|
+
Dot(
|
|
52
|
+
i == activeIndex,
|
|
53
|
+
AppTheme.current.colors.primary,
|
|
54
|
+
modifier = Modifier.padding(end = if (i != dataLength - 1) Spacing.XS else 0.dp)
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
package vn.momo.kits.components
|
|
2
|
+
|
|
3
|
+
import androidx.compose.foundation.background
|
|
4
|
+
import androidx.compose.foundation.layout.Box
|
|
5
|
+
import androidx.compose.foundation.layout.BoxWithConstraints
|
|
6
|
+
import androidx.compose.foundation.layout.Row
|
|
7
|
+
import androidx.compose.foundation.layout.padding
|
|
8
|
+
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
9
|
+
import androidx.compose.runtime.Composable
|
|
10
|
+
import androidx.compose.ui.Alignment
|
|
11
|
+
import androidx.compose.ui.Modifier
|
|
12
|
+
import androidx.compose.ui.draw.alpha
|
|
13
|
+
import androidx.compose.ui.graphics.Color
|
|
14
|
+
import vn.momo.kits.const.Colors
|
|
15
|
+
import vn.momo.kits.const.Spacing
|
|
16
|
+
import vn.momo.kits.const.Typography
|
|
17
|
+
|
|
18
|
+
@Composable
|
|
19
|
+
fun PaginationNumber(
|
|
20
|
+
activeIndex: Int = 0,
|
|
21
|
+
dataLength: Int = 2
|
|
22
|
+
) {
|
|
23
|
+
BoxWithConstraints(
|
|
24
|
+
modifier = Modifier.background(
|
|
25
|
+
color = Color(0x33000000),
|
|
26
|
+
shape = RoundedCornerShape(Spacing.L)
|
|
27
|
+
),
|
|
28
|
+
contentAlignment = Alignment.Center
|
|
29
|
+
) {
|
|
30
|
+
Text(
|
|
31
|
+
modifier = Modifier.padding(horizontal = Spacing.S),
|
|
32
|
+
text = "${1 + activeIndex}/$dataLength",
|
|
33
|
+
color = Colors.black_01,
|
|
34
|
+
style = Typography.labelDefault
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
package vn.momo.kits.components
|
|
2
|
+
|
|
3
|
+
import androidx.compose.foundation.background
|
|
4
|
+
import androidx.compose.foundation.horizontalScroll
|
|
5
|
+
import androidx.compose.foundation.layout.Box
|
|
6
|
+
import androidx.compose.foundation.layout.Column
|
|
7
|
+
import androidx.compose.foundation.layout.Row
|
|
8
|
+
import androidx.compose.foundation.layout.fillMaxWidth
|
|
9
|
+
import androidx.compose.foundation.layout.height
|
|
10
|
+
import androidx.compose.foundation.layout.offset
|
|
11
|
+
import androidx.compose.foundation.layout.padding
|
|
12
|
+
import androidx.compose.foundation.layout.width
|
|
13
|
+
import androidx.compose.foundation.rememberScrollState
|
|
14
|
+
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
15
|
+
import androidx.compose.runtime.Composable
|
|
16
|
+
import androidx.compose.ui.Alignment
|
|
17
|
+
import androidx.compose.ui.Modifier
|
|
18
|
+
import androidx.compose.ui.draw.clip
|
|
19
|
+
import androidx.compose.ui.unit.Dp
|
|
20
|
+
import androidx.compose.ui.unit.dp
|
|
21
|
+
import vn.momo.kits.const.AppTheme
|
|
22
|
+
import vn.momo.kits.const.Spacing
|
|
23
|
+
|
|
24
|
+
val INDICATOR_WIDTH = 24.dp
|
|
25
|
+
val PROGRESS_WIDTH = 72.dp
|
|
26
|
+
|
|
27
|
+
fun calculateOffset(currentPosition: Int, maxBound: Int): Dp {
|
|
28
|
+
return (PROGRESS_WIDTH - INDICATOR_WIDTH).times(currentPosition / maxBound.toFloat())
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@Composable
|
|
32
|
+
fun PaginationScroll(
|
|
33
|
+
modifier: Modifier = Modifier,
|
|
34
|
+
content: @Composable () -> Unit
|
|
35
|
+
) {
|
|
36
|
+
val scrollOffset = rememberScrollState()
|
|
37
|
+
|
|
38
|
+
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
|
39
|
+
Row(
|
|
40
|
+
modifier = modifier.fillMaxWidth().padding(bottom = Spacing.L)
|
|
41
|
+
.horizontalScroll(scrollOffset)
|
|
42
|
+
) {
|
|
43
|
+
content()
|
|
44
|
+
}
|
|
45
|
+
Box(
|
|
46
|
+
modifier = Modifier.clip(
|
|
47
|
+
RoundedCornerShape(Spacing.XS)
|
|
48
|
+
).width(PROGRESS_WIDTH).height(4.dp)
|
|
49
|
+
.background(color = AppTheme.current.colors.background.pressed)
|
|
50
|
+
) {
|
|
51
|
+
Box(
|
|
52
|
+
modifier = Modifier.offset(
|
|
53
|
+
x = calculateOffset(
|
|
54
|
+
scrollOffset.value,
|
|
55
|
+
scrollOffset.maxValue
|
|
56
|
+
)
|
|
57
|
+
).clip(RoundedCornerShape(Spacing.XS))
|
|
58
|
+
.width(
|
|
59
|
+
INDICATOR_WIDTH
|
|
60
|
+
).height(4.dp)
|
|
61
|
+
.background(color = AppTheme.current.colors.primary)
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
package vn.momo.kits.components
|
|
2
|
+
|
|
3
|
+
import androidx.compose.foundation.background
|
|
4
|
+
import androidx.compose.foundation.layout.Box
|
|
5
|
+
import androidx.compose.foundation.layout.BoxWithConstraints
|
|
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.size
|
|
10
|
+
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
11
|
+
import androidx.compose.runtime.Composable
|
|
12
|
+
import androidx.compose.ui.Alignment
|
|
13
|
+
import androidx.compose.ui.Modifier
|
|
14
|
+
import androidx.compose.ui.draw.alpha
|
|
15
|
+
import androidx.compose.ui.draw.clip
|
|
16
|
+
import androidx.compose.ui.draw.clipToBounds
|
|
17
|
+
import androidx.compose.ui.graphics.Color
|
|
18
|
+
import androidx.compose.ui.unit.dp
|
|
19
|
+
import vn.momo.kits.const.AppTheme
|
|
20
|
+
import vn.momo.kits.const.Colors
|
|
21
|
+
import vn.momo.kits.const.Spacing
|
|
22
|
+
import vn.momo.kits.const.Typography
|
|
23
|
+
|
|
24
|
+
@Composable
|
|
25
|
+
fun PaginationWhiteDot(
|
|
26
|
+
activeIndex: Int = 0,
|
|
27
|
+
dataLength: Int = 3
|
|
28
|
+
) {
|
|
29
|
+
Row(
|
|
30
|
+
modifier = Modifier.background(
|
|
31
|
+
color = Color(0x33000000),
|
|
32
|
+
shape = RoundedCornerShape(Spacing.S)
|
|
33
|
+
).padding(Spacing.XS)
|
|
34
|
+
) {
|
|
35
|
+
for (i in 0 until dataLength) {
|
|
36
|
+
Dot(
|
|
37
|
+
i == activeIndex,
|
|
38
|
+
Colors.black_01,
|
|
39
|
+
modifier = Modifier.padding(end = if (i != dataLength - 1) Spacing.XS else 0.dp)
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -32,7 +32,6 @@ import androidx.compose.ui.semantics.semantics
|
|
|
32
32
|
import androidx.compose.ui.semantics.testTag
|
|
33
33
|
import androidx.compose.ui.text.TextLayoutResult
|
|
34
34
|
import androidx.compose.ui.unit.dp
|
|
35
|
-
import vn.momo.kits.application.AppNavigator
|
|
36
35
|
import vn.momo.kits.const.AppTheme
|
|
37
36
|
import vn.momo.kits.const.Radius
|
|
38
37
|
import vn.momo.kits.const.Spacing
|
|
@@ -63,7 +62,6 @@ fun PopupNotify(
|
|
|
63
62
|
) {
|
|
64
63
|
var isScroll by remember { mutableStateOf(false) }
|
|
65
64
|
val layoutResult = remember { mutableStateOf<TextLayoutResult?>(null) }
|
|
66
|
-
val navigator = AppNavigator.current
|
|
67
65
|
|
|
68
66
|
LaunchedEffect(layoutResult.value) {
|
|
69
67
|
if ((layoutResult.value?.lineCount ?: 0) > 3) {
|
|
@@ -95,7 +93,6 @@ fun PopupNotify(
|
|
|
95
93
|
}
|
|
96
94
|
|
|
97
95
|
fun onClose(callback: (() -> Unit)?) {
|
|
98
|
-
navigator.pop()
|
|
99
96
|
callback?.invoke()
|
|
100
97
|
}
|
|
101
98
|
|
|
@@ -16,7 +16,6 @@ import vn.momo.kits.const.Radius
|
|
|
16
16
|
import vn.momo.kits.const.Spacing
|
|
17
17
|
import vn.momo.kits.const.Typography
|
|
18
18
|
import vn.momo.kits.const.scaleSize
|
|
19
|
-
import vn.momo.kits.utils.primaryColors
|
|
20
19
|
|
|
21
20
|
enum class TagSize(val height: Float) {
|
|
22
21
|
Large(24.toFloat()),
|
|
@@ -40,6 +39,20 @@ fun Tag(
|
|
|
40
39
|
size: TagSize = TagSize.Large,
|
|
41
40
|
customColor: Color? = null,
|
|
42
41
|
) {
|
|
42
|
+
val primaryColors = listOf(
|
|
43
|
+
Color(0xFFF0F0F0),
|
|
44
|
+
Color(0xFFEB2F96),
|
|
45
|
+
Color(0xFF962AF0),
|
|
46
|
+
Color(0xFF4E4BFF),
|
|
47
|
+
Color(0xFF007AFF),
|
|
48
|
+
Color(0xFF13C2C2),
|
|
49
|
+
Color(0xFF34C759),
|
|
50
|
+
Color(0xFFA0D911),
|
|
51
|
+
Color(0xFFFFCC00),
|
|
52
|
+
Color(0xFFFA8C16),
|
|
53
|
+
Color(0xFFFA541C),
|
|
54
|
+
Color(0xFFF5222D)
|
|
55
|
+
)
|
|
43
56
|
var tagColor = color.backgroundColor
|
|
44
57
|
var labelColor = color.textColor
|
|
45
58
|
|