@momo-kits/native-kits 0.89.19 → 0.89.21

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.
Files changed (43) hide show
  1. package/compose/build.gradle.kts +11 -15
  2. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +22 -0
  3. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Components.kt +71 -27
  4. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +200 -0
  5. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +47 -0
  6. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +7 -139
  7. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +89 -22
  8. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +17 -1
  9. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +0 -7
  10. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -2
  11. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +6 -8
  12. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +0 -2
  13. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +37 -17
  14. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +54 -21
  15. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +155 -0
  16. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +2 -20
  17. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +185 -0
  18. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +0 -19
  19. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +2 -18
  20. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +58 -0
  21. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +37 -0
  22. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +65 -0
  23. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +43 -0
  24. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +0 -3
  25. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +0 -2
  26. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +14 -1
  27. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +2 -2
  28. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +28 -0
  29. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +1 -2
  30. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +18 -0
  31. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +0 -23
  32. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +33 -0
  33. package/gradle.properties +1 -1
  34. package/package.json +1 -1
  35. package/settings.gradle.kts +1 -0
  36. package/compose/src/androidMain/kotlin/vn/momo/kits/utils/Platform.kt +0 -3
  37. package/compose/src/androidMain/kotlin/vn/momo/kits/utils/SetMaskFilter.kt +0 -8
  38. package/compose/src/androidMain/kotlin/vn/momo/kits/utils/Utils.android.kt +0 -14
  39. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Platform.kt +0 -3
  40. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/SetMaskFilter.kt +0 -5
  41. package/compose/src/iosMain/kotlin/vn/momo/kits/utils/Platform.kt +0 -3
  42. package/compose/src/iosMain/kotlin/vn/momo/kits/utils/SetMaskFilter.kt +0 -9
  43. package/compose/src/iosMain/kotlin/vn/momo/kits/utils/Utils.ios.kt +0 -18
@@ -32,6 +32,8 @@ import androidx.compose.ui.graphics.Color
32
32
  import androidx.compose.ui.text.TextStyle
33
33
  import androidx.compose.ui.text.font.FontWeight
34
34
  import androidx.compose.ui.text.input.KeyboardType
35
+ import androidx.compose.ui.text.input.PasswordVisualTransformation
36
+ import androidx.compose.ui.text.input.VisualTransformation
35
37
  import androidx.compose.ui.unit.Dp
36
38
  import androidx.compose.ui.unit.dp
37
39
  import androidx.compose.ui.unit.sp
@@ -116,6 +118,36 @@ fun RenderRightIcon(loading: Boolean, icon: String, color: Color, onClick: () ->
116
118
  }
117
119
  }
118
120
 
121
+ @Composable
122
+ fun ErrorView(errorMessage: String, errorSpacing: Boolean, hintText: String) {
123
+ val errorColor = AppTheme.current.colors.error.primary
124
+ val hintColor = AppTheme.current.colors.text.hint
125
+ val hintTextDefault = hintText.ifEmpty { "Không thể chỉnh sửa" }
126
+
127
+ if (errorMessage.isNotEmpty() || hintText.isNotEmpty()) {
128
+ val color: Color =
129
+ if (errorMessage.isNotEmpty()) errorColor else hintColor
130
+ Row(
131
+ Modifier.padding(top = Spacing.XS),
132
+ verticalAlignment = Alignment.CenterVertically
133
+ ) {
134
+ Icon(
135
+ size = 16.dp,
136
+ color = color,
137
+ source = "ic_error"
138
+ )
139
+ Text(
140
+ errorMessage.ifEmpty { hintTextDefault },
141
+ style = Typography.descriptionS,
142
+ modifier = Modifier.padding(start = Spacing.XS),
143
+ color = color,
144
+ )
145
+ }
146
+ } else if (errorSpacing) {
147
+ Spacer(Modifier.padding(top = Spacing.XS).height(18.dp))
148
+ }
149
+ }
150
+
119
151
  @Composable
120
152
  fun Input(
121
153
  text: MutableState<String> = remember { mutableStateOf("") },
@@ -126,8 +158,12 @@ fun Input(
126
158
  placeholder: String = "",
127
159
  size: InputSize = InputSize.SMALL,
128
160
  onChangeText: (String) -> Unit = {},
161
+ hintText: String = "",
129
162
  error: String = "",
163
+ errorSpacing: Boolean = false,
130
164
  disabled: Boolean = false,
165
+ readOnly: Boolean = false,
166
+ secureTextEntry: Boolean = false,
131
167
  icon: String = "",
132
168
  iconColor: Color = AppTheme.current.colors.text.default,
133
169
  onRightIconPressed: () -> Unit = {},
@@ -141,6 +177,7 @@ fun Input(
141
177
  keyboardType: KeyboardType = KeyboardType.Text,
142
178
  ) {
143
179
  var isFocused by remember { mutableStateOf(false) }
180
+ var passHidden by remember { mutableStateOf(false) }
144
181
  var isBlurred = false
145
182
  val disabledColor = AppTheme.current.colors.text.disable
146
183
  var textColor = AppTheme.current.colors.text.default
@@ -164,6 +201,7 @@ fun Input(
164
201
  Column {
165
202
  BasicTextField(
166
203
  enabled = !disabled,
204
+ readOnly = readOnly,
167
205
  singleLine = true,
168
206
  value = text.value,
169
207
  textStyle = TextStyle(
@@ -172,7 +210,8 @@ fun Input(
172
210
  lineHeight = 24.sp,
173
211
  fontWeight = fontWeight.value
174
212
  ),
175
- keyboardOptions = KeyboardOptions.Default.copy(keyboardType = keyboardType),
213
+ visualTransformation = if (secureTextEntry && !passHidden) PasswordVisualTransformation() else VisualTransformation.None,
214
+ keyboardOptions = KeyboardOptions.Default.copy(keyboardType = if (secureTextEntry) KeyboardType.Ascii else keyboardType),
176
215
  modifier = Modifier.height(size.values.height).onFocusChanged {
177
216
  isFocused = it.isFocused
178
217
  if (it.isFocused) {
@@ -237,7 +276,7 @@ fun Input(
237
276
  if (leadingIcon.isNotEmpty()) {
238
277
  Icon(
239
278
  source = leadingIcon,
240
- modifier = Modifier.padding(end = Spacing.XS),
279
+ modifier = Modifier.padding(end = Spacing.M),
241
280
  size = if (size.name == InputSize.SMALL.name) 24.dp else 32.dp,
242
281
  color = leadingIconColor
243
282
  )
@@ -271,29 +310,23 @@ fun Input(
271
310
  )
272
311
  }
273
312
  }
274
- RenderRightIcon(loading, icon, iconTintColor, onRightIconPressed)
313
+ if (secureTextEntry && passHidden) {
314
+ val hidePassword = { onRightIconPressed(); passHidden = !passHidden}
315
+ RenderRightIcon(loading, "24_security_eye_open", iconTintColor,
316
+ hidePassword)
317
+ } else if (secureTextEntry && !passHidden) {
318
+ val showPassword = { onRightIconPressed(); passHidden = !passHidden}
319
+ RenderRightIcon(loading, "24_security_eye_off", iconTintColor,
320
+ showPassword)
321
+ } else {
322
+ RenderRightIcon(loading, icon, iconTintColor,
323
+ onRightIconPressed)
324
+ }
275
325
  }
276
326
  }
277
327
  },
278
328
  )
279
329
  // show error
280
- if (error.isNotEmpty()) {
281
- Row(
282
- Modifier.padding(top = Spacing.XS),
283
- verticalAlignment = Alignment.CenterVertically
284
- ) {
285
- Icon(
286
- size = 16.dp,
287
- color = AppTheme.current.colors.error.primary,
288
- source = "ic_error"
289
- )
290
- Text(
291
- error,
292
- style = Typography.descriptionS,
293
- modifier = Modifier.padding(start = Spacing.XS),
294
- color = AppTheme.current.colors.error.primary,
295
- )
296
- }
297
- }
330
+ ErrorView(error, errorSpacing, hintText)
298
331
  }
299
332
  }
@@ -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
- // show error
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
- if (error.isNotEmpty()) {
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
+ }