@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.
Files changed (38) hide show
  1. package/compose/build.gradle.kts +18 -14
  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 -25
  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/Icon.kt +6 -8
  10. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +36 -17
  11. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +54 -21
  12. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +155 -0
  13. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +2 -20
  14. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +185 -0
  15. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +0 -19
  16. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +2 -18
  17. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +58 -0
  18. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +37 -0
  19. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +65 -0
  20. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +43 -0
  21. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +0 -3
  22. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +14 -1
  23. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +2 -2
  24. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +28 -0
  25. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +1 -2
  26. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +18 -0
  27. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +0 -23
  28. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +33 -0
  29. package/package.json +1 -1
  30. package/settings.gradle.kts +1 -0
  31. package/compose/src/androidMain/kotlin/vn/momo/kits/utils/Platform.kt +0 -3
  32. package/compose/src/androidMain/kotlin/vn/momo/kits/utils/SetMaskFilter.kt +0 -8
  33. package/compose/src/androidMain/kotlin/vn/momo/kits/utils/Utils.android.kt +0 -14
  34. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Platform.kt +0 -3
  35. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/SetMaskFilter.kt +0 -5
  36. package/compose/src/iosMain/kotlin/vn/momo/kits/utils/Platform.kt +0 -3
  37. package/compose/src/iosMain/kotlin/vn/momo/kits/utils/SetMaskFilter.kt +0 -9
  38. 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
- // 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
+ }
@@ -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