@momo-kits/native-kits 0.156.10-debug → 0.156.11-debug
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compose/build.gradle.kts +1 -1
- package/compose/compose.podspec +1 -1
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +0 -3
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +12 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +19 -17
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +198 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +42 -51
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +14 -13
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +6 -7
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +0 -4
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +0 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +29 -12
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +4 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +2 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +15 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -3
- package/gradle.properties +1 -1
- package/ios/Image/Image.swift +5 -1
- package/ios/Input/Input.swift +2 -2
- package/ios/Input/InputPhoneNumber.swift +7 -3
- package/package.json +1 -1
package/compose/build.gradle.kts
CHANGED
package/compose/compose.podspec
CHANGED
|
@@ -10,11 +10,8 @@ import androidx.compose.foundation.layout.Box
|
|
|
10
10
|
import androidx.compose.runtime.Composable
|
|
11
11
|
import androidx.compose.runtime.getValue
|
|
12
12
|
import androidx.compose.ui.Modifier
|
|
13
|
-
import androidx.compose.ui.draw.drawBehind
|
|
14
13
|
import androidx.compose.ui.graphics.Color
|
|
15
14
|
import androidx.compose.ui.graphics.NativePaint
|
|
16
|
-
import androidx.compose.ui.graphics.Paint
|
|
17
|
-
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
|
|
18
15
|
import androidx.compose.ui.graphics.toArgb
|
|
19
16
|
import androidx.compose.ui.platform.LocalConfiguration
|
|
20
17
|
import androidx.compose.ui.unit.Dp
|
|
@@ -78,6 +78,14 @@ data class MiniAppContext(
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
@Immutable
|
|
82
|
+
data class ComponentInformation(
|
|
83
|
+
val componentName: String? = null,
|
|
84
|
+
val componentId: String? = null,
|
|
85
|
+
val params: Map<String,Any?>? = null,
|
|
86
|
+
val action: String? = null
|
|
87
|
+
)
|
|
88
|
+
|
|
81
89
|
var IsShowBaseLineDebug = false
|
|
82
90
|
|
|
83
91
|
val ApplicationContext = staticCompositionLocalOf<MiniAppContext?> {
|
|
@@ -92,4 +100,8 @@ val AppLanguage = staticCompositionLocalOf<String?> {
|
|
|
92
100
|
null
|
|
93
101
|
}
|
|
94
102
|
|
|
103
|
+
val LocalComponentInformation = staticCompositionLocalOf<ComponentInformation?> {
|
|
104
|
+
null
|
|
105
|
+
}
|
|
106
|
+
|
|
95
107
|
internal val ScaleSizeMaxRate = staticCompositionLocalOf<Float?> { null }
|
|
@@ -23,7 +23,7 @@ import vn.momo.kits.modifier.conditional
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
@Composable
|
|
26
|
-
fun Badge(label: String = "Label", backgroundColor: Color? = null) {
|
|
26
|
+
fun Badge(label: String = "Label", backgroundColor: Color? = null, modifier: Modifier? = null) {
|
|
27
27
|
val primaryColors = listOf(
|
|
28
28
|
Color(0xFFF0F0F0),
|
|
29
29
|
Color(0xFFEB2F96),
|
|
@@ -63,21 +63,23 @@ fun Badge(label: String = "Label", backgroundColor: Color? = null) {
|
|
|
63
63
|
}
|
|
64
64
|
val scaleSize = scaleSize(16f)
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
66
|
+
if (modifier != null) {
|
|
67
|
+
Box(
|
|
68
|
+
modifier = modifier
|
|
69
|
+
.height(scaleSize.dp)
|
|
70
|
+
.widthIn(min = scaleSize.dp)
|
|
71
|
+
.background(color = badgeColor, shape = RoundedCornerShape(Radius.M))
|
|
72
|
+
.border(width = 1.dp, shape = RoundedCornerShape(Radius.M), color = Colors.black_01)
|
|
73
|
+
.conditional(IsShowBaseLineDebug) {
|
|
74
|
+
border(1.dp, Colors.blue_03)
|
|
75
|
+
}
|
|
76
|
+
.padding(horizontal = Spacing.XS), contentAlignment = Alignment.Center
|
|
77
|
+
) {
|
|
78
|
+
Text(
|
|
79
|
+
text = formatTitle(label),
|
|
80
|
+
color = Colors.black_01,
|
|
81
|
+
style = Typography.actionXxsBold
|
|
82
|
+
)
|
|
83
|
+
}
|
|
82
84
|
}
|
|
83
85
|
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
package vn.momo.kits.components
|
|
2
|
+
|
|
3
|
+
import androidx.compose.foundation.Canvas
|
|
4
|
+
import androidx.compose.foundation.background
|
|
5
|
+
import androidx.compose.foundation.border
|
|
6
|
+
import androidx.compose.foundation.layout.Box
|
|
7
|
+
import androidx.compose.foundation.layout.WindowInsets
|
|
8
|
+
import androidx.compose.foundation.layout.asPaddingValues
|
|
9
|
+
import androidx.compose.foundation.layout.fillMaxHeight
|
|
10
|
+
import androidx.compose.foundation.layout.fillMaxSize
|
|
11
|
+
import androidx.compose.foundation.layout.fillMaxWidth
|
|
12
|
+
import androidx.compose.foundation.layout.height
|
|
13
|
+
import androidx.compose.foundation.layout.navigationBars
|
|
14
|
+
import androidx.compose.foundation.layout.padding
|
|
15
|
+
import androidx.compose.foundation.layout.width
|
|
16
|
+
import androidx.compose.runtime.Composable
|
|
17
|
+
import androidx.compose.ui.Alignment
|
|
18
|
+
import androidx.compose.ui.Modifier
|
|
19
|
+
import androidx.compose.ui.geometry.Offset
|
|
20
|
+
import androidx.compose.ui.graphics.Color
|
|
21
|
+
import androidx.compose.ui.graphics.PathEffect
|
|
22
|
+
import androidx.compose.ui.graphics.StrokeCap
|
|
23
|
+
import androidx.compose.ui.unit.dp
|
|
24
|
+
import io.ktor.util.Platform
|
|
25
|
+
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
26
|
+
import vn.momo.kits.const.Colors
|
|
27
|
+
import vn.momo.kits.modifier.conditional
|
|
28
|
+
import vn.momo.kits.platform.getPlatformName
|
|
29
|
+
import vn.momo.kits.platform.getStatusBarHeight
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A debug overlay that draws danger/warning baseline guides on top of the screen.
|
|
33
|
+
*
|
|
34
|
+
* Highlights safe-area boundaries, header regions, and bottom navigation zones
|
|
35
|
+
* using colored solid or dotted lines and semi-transparent red zones.
|
|
36
|
+
*
|
|
37
|
+
* @param enabled When `false` the composable renders nothing. Pass `false` when
|
|
38
|
+
* your QC automation flag is active to suppress the overlay.
|
|
39
|
+
*/
|
|
40
|
+
@Composable
|
|
41
|
+
fun BaselineView(enabled: Boolean = true) {
|
|
42
|
+
if (!enabled) return
|
|
43
|
+
|
|
44
|
+
val bottomInsetHeight = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()
|
|
45
|
+
val topInset = if (getPlatformName() == "Android") getStatusBarHeight() - 14.dp else getStatusBarHeight()
|
|
46
|
+
val bottomInset = if (getPlatformName() == "iOS") minOf(bottomInsetHeight, 21.dp) else bottomInsetHeight
|
|
47
|
+
|
|
48
|
+
Box(modifier = Modifier.fillMaxSize()) {
|
|
49
|
+
// Danger zones
|
|
50
|
+
Box(
|
|
51
|
+
modifier = Modifier
|
|
52
|
+
.fillMaxWidth()
|
|
53
|
+
.height(topInset)
|
|
54
|
+
.background(Color.Red.copy(alpha = 0.15f))
|
|
55
|
+
)
|
|
56
|
+
Box(
|
|
57
|
+
modifier = Modifier
|
|
58
|
+
.width(12.dp)
|
|
59
|
+
.fillMaxHeight()
|
|
60
|
+
.padding(top = topInset, bottom = bottomInset)
|
|
61
|
+
.background(Color.Red.copy(alpha = 0.15f))
|
|
62
|
+
)
|
|
63
|
+
Box(
|
|
64
|
+
modifier = Modifier
|
|
65
|
+
.width(12.dp)
|
|
66
|
+
.fillMaxHeight()
|
|
67
|
+
.padding(top = topInset, bottom = bottomInset)
|
|
68
|
+
.background(Color.Red.copy(alpha = 0.15f))
|
|
69
|
+
.align(Alignment.TopEnd)
|
|
70
|
+
)
|
|
71
|
+
Box(
|
|
72
|
+
modifier = Modifier
|
|
73
|
+
.fillMaxWidth()
|
|
74
|
+
.height(bottomInset)
|
|
75
|
+
.background(Color.Red.copy(alpha = 0.15f))
|
|
76
|
+
.align(Alignment.BottomCenter)
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
// Danger lines
|
|
80
|
+
BaselineDottedLine(
|
|
81
|
+
Modifier
|
|
82
|
+
.padding(top = topInset)
|
|
83
|
+
.fillMaxWidth(),
|
|
84
|
+
isDotted = false,
|
|
85
|
+
color = Color(0xFFE400FF)
|
|
86
|
+
)
|
|
87
|
+
BaselineDottedLine(
|
|
88
|
+
Modifier
|
|
89
|
+
.padding(top = topInset + 52.dp)
|
|
90
|
+
.fillMaxWidth(),
|
|
91
|
+
color = Color(0xFFE400FF)
|
|
92
|
+
)
|
|
93
|
+
BaselineDottedLine(
|
|
94
|
+
Modifier
|
|
95
|
+
.padding(top = topInset + 104.dp)
|
|
96
|
+
.fillMaxWidth(),
|
|
97
|
+
color = Color(0xFFE400FF)
|
|
98
|
+
)
|
|
99
|
+
BaselineDottedLine(
|
|
100
|
+
Modifier
|
|
101
|
+
.padding(bottom = bottomInset + 64.dp)
|
|
102
|
+
.fillMaxWidth()
|
|
103
|
+
.align(Alignment.BottomCenter),
|
|
104
|
+
color = Color(0xFFE400FF)
|
|
105
|
+
)
|
|
106
|
+
BaselineDottedLine(
|
|
107
|
+
Modifier
|
|
108
|
+
.padding(bottom = bottomInset)
|
|
109
|
+
.fillMaxWidth()
|
|
110
|
+
.align(Alignment.BottomCenter),
|
|
111
|
+
isDotted = false,
|
|
112
|
+
color = Color(0xFFE400FF)
|
|
113
|
+
)
|
|
114
|
+
BaselineDottedLine(
|
|
115
|
+
Modifier
|
|
116
|
+
.padding(start = 12.dp)
|
|
117
|
+
.fillMaxHeight(),
|
|
118
|
+
orientation = BaselineOrientation.Vertical,
|
|
119
|
+
isDotted = false,
|
|
120
|
+
color = Color(0xFFE400FF)
|
|
121
|
+
)
|
|
122
|
+
BaselineDottedLine(
|
|
123
|
+
Modifier
|
|
124
|
+
.padding(end = 12.dp)
|
|
125
|
+
.fillMaxHeight()
|
|
126
|
+
.align(Alignment.BottomEnd),
|
|
127
|
+
orientation = BaselineOrientation.Vertical,
|
|
128
|
+
isDotted = false,
|
|
129
|
+
color = Color(0xFFE400FF)
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
// Warning lines
|
|
133
|
+
BaselineDottedLine(
|
|
134
|
+
Modifier
|
|
135
|
+
.padding(top = topInset + 26.dp)
|
|
136
|
+
.fillMaxWidth(),
|
|
137
|
+
color = Color(0xFFFF7A00)
|
|
138
|
+
)
|
|
139
|
+
BaselineDottedLine(
|
|
140
|
+
Modifier
|
|
141
|
+
.padding(bottom = bottomInset + 56.dp)
|
|
142
|
+
.fillMaxWidth()
|
|
143
|
+
.align(Alignment.BottomCenter),
|
|
144
|
+
color = Color(0xFFFFCC00)
|
|
145
|
+
)
|
|
146
|
+
BaselineDottedLine(
|
|
147
|
+
Modifier
|
|
148
|
+
.padding(bottom = bottomInset + 8.dp)
|
|
149
|
+
.fillMaxWidth()
|
|
150
|
+
.align(Alignment.BottomCenter),
|
|
151
|
+
color = Color(0xFFFFCC00)
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
// Header background warning lines
|
|
155
|
+
BaselineDottedLine(
|
|
156
|
+
Modifier
|
|
157
|
+
.padding(start = 40.dp, top = topInset)
|
|
158
|
+
.height(52.dp),
|
|
159
|
+
color = Color(0xFF00C520),
|
|
160
|
+
orientation = BaselineOrientation.Vertical
|
|
161
|
+
)
|
|
162
|
+
BaselineDottedLine(
|
|
163
|
+
Modifier
|
|
164
|
+
.padding(start = 48.dp, top = topInset)
|
|
165
|
+
.height(52.dp),
|
|
166
|
+
color = Color(0xFF00C520),
|
|
167
|
+
orientation = BaselineOrientation.Vertical
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
enum class BaselineOrientation { Horizontal, Vertical }
|
|
173
|
+
|
|
174
|
+
@Composable
|
|
175
|
+
fun BaselineDottedLine(
|
|
176
|
+
modifier: Modifier = Modifier,
|
|
177
|
+
color: Color = Color.Red,
|
|
178
|
+
orientation: BaselineOrientation = BaselineOrientation.Horizontal,
|
|
179
|
+
isDotted: Boolean = true
|
|
180
|
+
) {
|
|
181
|
+
Canvas(modifier = modifier) {
|
|
182
|
+
val pathEffect = if (isDotted) PathEffect.dashPathEffect(floatArrayOf(8f, 8f)) else null
|
|
183
|
+
drawLine(
|
|
184
|
+
color = color,
|
|
185
|
+
start = if (orientation == BaselineOrientation.Horizontal) Offset(
|
|
186
|
+
0f,
|
|
187
|
+
size.height / 2
|
|
188
|
+
) else Offset(size.width / 2, 0f),
|
|
189
|
+
end = if (orientation == BaselineOrientation.Horizontal) Offset(
|
|
190
|
+
size.width,
|
|
191
|
+
size.height / 2
|
|
192
|
+
) else Offset(size.width / 2, size.height),
|
|
193
|
+
strokeWidth = 1.dp.toPx(),
|
|
194
|
+
pathEffect = pathEffect,
|
|
195
|
+
cap = StrokeCap.Round,
|
|
196
|
+
)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
@@ -11,17 +11,14 @@ import androidx.compose.foundation.interaction.collectIsPressedAsState
|
|
|
11
11
|
import androidx.compose.foundation.layout.Arrangement
|
|
12
12
|
import androidx.compose.foundation.layout.Box
|
|
13
13
|
import androidx.compose.foundation.layout.Row
|
|
14
|
-
import androidx.compose.foundation.layout.defaultMinSize
|
|
15
14
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
16
15
|
import androidx.compose.foundation.layout.height
|
|
17
16
|
import androidx.compose.foundation.layout.padding
|
|
18
17
|
import androidx.compose.foundation.layout.size
|
|
19
18
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
20
19
|
import androidx.compose.runtime.Composable
|
|
21
|
-
import androidx.compose.runtime.CompositionLocalProvider
|
|
22
20
|
import androidx.compose.runtime.getValue
|
|
23
21
|
import androidx.compose.runtime.remember
|
|
24
|
-
import androidx.compose.runtime.staticCompositionLocalOf
|
|
25
22
|
import androidx.compose.ui.Alignment
|
|
26
23
|
import androidx.compose.ui.Modifier
|
|
27
24
|
import androidx.compose.ui.draw.alpha
|
|
@@ -127,13 +124,12 @@ fun getTextColor(loading: Boolean, type: ButtonType): Color {
|
|
|
127
124
|
}
|
|
128
125
|
|
|
129
126
|
@Composable
|
|
130
|
-
fun RenderTitle(size: Size, title: String = "",
|
|
127
|
+
fun RenderTitle(size: Size, title: String = "", textColor: Color) {
|
|
131
128
|
val style = remember(size) { getStyle(size) }
|
|
132
|
-
val color = TextColor.current
|
|
133
129
|
Text(
|
|
134
130
|
style = style,
|
|
135
131
|
text = title,
|
|
136
|
-
color =
|
|
132
|
+
color = textColor,
|
|
137
133
|
overflow = TextOverflow.Ellipsis,
|
|
138
134
|
maxLines = 1
|
|
139
135
|
)
|
|
@@ -145,21 +141,20 @@ fun RenderIcon(
|
|
|
145
141
|
isIconLeft: Boolean,
|
|
146
142
|
useTintColor: Boolean = true,
|
|
147
143
|
icon: String = "",
|
|
148
|
-
forceLoading: Boolean = false
|
|
144
|
+
forceLoading: Boolean = false,
|
|
145
|
+
bgColor: Color? = null,
|
|
146
|
+
textColor: Color? = null,
|
|
149
147
|
) {
|
|
150
|
-
val bgColor = BackgroundColor.current
|
|
151
148
|
val iconSize = remember(size) { getIconSize(size) }
|
|
152
149
|
val margin = remember(size) { getIconSpace(size) }
|
|
153
|
-
val color = if (useTintColor)
|
|
154
|
-
|
|
155
|
-
val showLoading = forceLoading
|
|
150
|
+
val color = if (useTintColor) textColor else Color.Unspecified
|
|
156
151
|
|
|
157
152
|
val modifier = Modifier.padding(
|
|
158
153
|
start = if (isIconLeft) 0.dp else margin,
|
|
159
154
|
end = if (isIconLeft) margin else 0.dp
|
|
160
155
|
)
|
|
161
156
|
|
|
162
|
-
if (
|
|
157
|
+
if (forceLoading) {
|
|
163
158
|
Box(modifier) {
|
|
164
159
|
LottieAnimation(
|
|
165
160
|
modifier = Modifier.size(iconSize),
|
|
@@ -195,9 +190,9 @@ fun getTypeStyle(
|
|
|
195
190
|
type: ButtonType,
|
|
196
191
|
color: Color? = AppTheme.current.colors.primary,
|
|
197
192
|
size: Size,
|
|
193
|
+
bgColor: Color,
|
|
198
194
|
): Modifier {
|
|
199
195
|
val theme = AppTheme.current
|
|
200
|
-
val bgColor = BackgroundColor.current
|
|
201
196
|
val radius = remember(size) { size.value.radius }
|
|
202
197
|
val modifier = Modifier.background(bgColor)
|
|
203
198
|
|
|
@@ -304,45 +299,41 @@ fun Button(
|
|
|
304
299
|
.clip(RoundedCornerShape(radius))
|
|
305
300
|
}
|
|
306
301
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
302
|
+
val bgColor = getButtonBackgroundColor(loading, type)
|
|
303
|
+
val textColor = getTextColor(loading, type)
|
|
304
|
+
|
|
305
|
+
Row(
|
|
306
|
+
modifier = clickableModifier
|
|
307
|
+
.padding(horizontal = animatedPadding)
|
|
308
|
+
.clip(RoundedCornerShape(radius))
|
|
309
|
+
.then(getTypeStyle(type, size = size, bgColor = bgColor))
|
|
310
|
+
.conditional(IsShowBaseLineDebug) {
|
|
311
|
+
border(1.dp, Colors.blue_03)
|
|
312
|
+
}
|
|
313
|
+
.padding(horizontal = sizeSpecs.padding)
|
|
314
|
+
.height(sizeSpecs.height),
|
|
315
|
+
horizontalArrangement = Arrangement.Center,
|
|
316
|
+
verticalAlignment = Alignment.CenterVertically,
|
|
311
317
|
) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
)
|
|
332
|
-
RenderTitle(size, title, type = type)
|
|
333
|
-
RenderIcon(
|
|
334
|
-
size = size,
|
|
335
|
-
isIconLeft = false,
|
|
336
|
-
useTintColor = useTintColor,
|
|
337
|
-
icon = iconRight,
|
|
338
|
-
forceLoading = loading && !loadingOnLeft
|
|
339
|
-
)
|
|
340
|
-
}
|
|
318
|
+
RenderIcon(
|
|
319
|
+
size = size,
|
|
320
|
+
isIconLeft = true,
|
|
321
|
+
useTintColor = useTintColor,
|
|
322
|
+
icon = iconLeft,
|
|
323
|
+
forceLoading = loading && loadingOnLeft,
|
|
324
|
+
bgColor = bgColor,
|
|
325
|
+
textColor = textColor
|
|
326
|
+
)
|
|
327
|
+
RenderTitle(size, title, textColor = textColor)
|
|
328
|
+
RenderIcon(
|
|
329
|
+
size = size,
|
|
330
|
+
isIconLeft = false,
|
|
331
|
+
useTintColor = useTintColor,
|
|
332
|
+
icon = iconRight,
|
|
333
|
+
forceLoading = loading && !loadingOnLeft,
|
|
334
|
+
bgColor = bgColor,
|
|
335
|
+
textColor = textColor
|
|
336
|
+
)
|
|
341
337
|
}
|
|
342
338
|
}
|
|
343
339
|
|
|
344
|
-
|
|
345
|
-
private val IsLoading = staticCompositionLocalOf<Boolean> { false }
|
|
346
|
-
private val BackgroundColor = staticCompositionLocalOf<Color> { Color.Transparent }
|
|
347
|
-
private val TextColor = staticCompositionLocalOf<Color> { Color.Transparent }
|
|
348
|
-
|
|
@@ -43,11 +43,11 @@ import androidx.compose.ui.unit.TextUnit
|
|
|
43
43
|
import androidx.compose.ui.unit.dp
|
|
44
44
|
import androidx.compose.ui.unit.sp
|
|
45
45
|
import androidx.compose.ui.zIndex
|
|
46
|
+
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
46
47
|
import vn.momo.kits.const.AppTheme
|
|
48
|
+
import vn.momo.kits.const.Colors
|
|
47
49
|
import vn.momo.kits.const.Radius
|
|
48
50
|
import vn.momo.kits.const.Spacing
|
|
49
|
-
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
50
|
-
import vn.momo.kits.const.Colors
|
|
51
51
|
import vn.momo.kits.const.Typography
|
|
52
52
|
import vn.momo.kits.const.getFont
|
|
53
53
|
import vn.momo.kits.const.scaleSize
|
|
@@ -141,7 +141,7 @@ fun getBorderColor(isFocused: Boolean, error: String, disabled: Boolean): Color
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
@Composable
|
|
144
|
-
fun RenderRightIcon(loading: Boolean, icon: String, color: Color, onClick: () -> Unit) {
|
|
144
|
+
fun RenderRightIcon(loading: Boolean, icon: String, color: Color, onClick: () -> Unit, modifier: Modifier = Modifier) {
|
|
145
145
|
if (loading) {
|
|
146
146
|
Box {
|
|
147
147
|
CircularProgressIndicator(
|
|
@@ -157,7 +157,7 @@ fun RenderRightIcon(loading: Boolean, icon: String, color: Color, onClick: () ->
|
|
|
157
157
|
source = icon,
|
|
158
158
|
color = color,
|
|
159
159
|
size = 24.dp,
|
|
160
|
-
modifier =
|
|
160
|
+
modifier = modifier.clickable(
|
|
161
161
|
onClick = onClick,
|
|
162
162
|
interactionSource = remember { MutableInteractionSource() },
|
|
163
163
|
indication = null
|
|
@@ -224,6 +224,7 @@ fun Input(
|
|
|
224
224
|
fontWeight: InputFontWeight = InputFontWeight.REGULAR,
|
|
225
225
|
keyboardType: KeyboardType = KeyboardType.Text,
|
|
226
226
|
modifier: Modifier = Modifier,
|
|
227
|
+
inputModifier: Modifier = Modifier,
|
|
227
228
|
) {
|
|
228
229
|
// Consolidated state management
|
|
229
230
|
var inputState by remember { mutableStateOf(InputState()) }
|
|
@@ -253,10 +254,6 @@ fun Input(
|
|
|
253
254
|
if (disabled) theme.colors.text.disable else floatingIconColor
|
|
254
255
|
}
|
|
255
256
|
|
|
256
|
-
val testId = remember(disabled, floatingValue) {
|
|
257
|
-
if (disabled) "input_${floatingValue}_disabled" else "input_$floatingValue"
|
|
258
|
-
}
|
|
259
|
-
|
|
260
257
|
val fontSize = 14.sp
|
|
261
258
|
val lineHeight = 24.sp
|
|
262
259
|
val scaleFontSize = scaleSize(fontSize)
|
|
@@ -298,8 +295,7 @@ fun Input(
|
|
|
298
295
|
Column(modifier = modifier
|
|
299
296
|
.conditional(IsShowBaseLineDebug) {
|
|
300
297
|
border(1.dp, Colors.blue_03)
|
|
301
|
-
}
|
|
302
|
-
.setAutomationId(testId)) {
|
|
298
|
+
}) {
|
|
303
299
|
BasicTextField(
|
|
304
300
|
enabled = !disabled,
|
|
305
301
|
readOnly = readOnly,
|
|
@@ -308,7 +304,7 @@ fun Input(
|
|
|
308
304
|
textStyle = textStyle,
|
|
309
305
|
visualTransformation = visualTransformation,
|
|
310
306
|
keyboardOptions = keyboardOptionsConfig,
|
|
311
|
-
modifier =
|
|
307
|
+
modifier = inputModifier
|
|
312
308
|
.height(scaleSize(size.values.height.value, 1.1f).dp)
|
|
313
309
|
.onFocusChanged { focusState ->
|
|
314
310
|
val wasFocused = inputState.isFocused
|
|
@@ -417,7 +413,7 @@ fun Input(
|
|
|
417
413
|
},
|
|
418
414
|
interactionSource = remember { MutableInteractionSource() },
|
|
419
415
|
indication = null
|
|
420
|
-
)
|
|
416
|
+
).setAutomationId("ic_clear")
|
|
421
417
|
)
|
|
422
418
|
}
|
|
423
419
|
}
|
|
@@ -430,7 +426,12 @@ fun Input(
|
|
|
430
426
|
onRightIconPressed()
|
|
431
427
|
inputState = inputState.copy(passHidden = !inputState.passHidden)
|
|
432
428
|
}
|
|
433
|
-
RenderRightIcon(
|
|
429
|
+
RenderRightIcon(
|
|
430
|
+
loading = loading,
|
|
431
|
+
icon = iconName,
|
|
432
|
+
color = iconTintColor,
|
|
433
|
+
onClick = togglePassword,
|
|
434
|
+
modifier = Modifier.setAutomationId("ic_show_hide"))
|
|
434
435
|
}
|
|
435
436
|
else -> {
|
|
436
437
|
RenderRightIcon(loading, icon, iconTintColor, onRightIconPressed)
|
|
@@ -31,11 +31,11 @@ import androidx.compose.ui.text.TextStyle
|
|
|
31
31
|
import androidx.compose.ui.text.input.KeyboardType
|
|
32
32
|
import androidx.compose.ui.unit.Dp
|
|
33
33
|
import androidx.compose.ui.unit.dp
|
|
34
|
+
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
34
35
|
import vn.momo.kits.const.AppTheme
|
|
35
36
|
import vn.momo.kits.const.Colors
|
|
36
37
|
import vn.momo.kits.const.Radius
|
|
37
38
|
import vn.momo.kits.const.Spacing
|
|
38
|
-
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
39
39
|
import vn.momo.kits.const.Typography
|
|
40
40
|
import vn.momo.kits.const.scaleSize
|
|
41
41
|
import vn.momo.kits.modifier.conditional
|
|
@@ -98,6 +98,7 @@ fun InputPhoneNumber(
|
|
|
98
98
|
onBlur: () -> Unit = {},
|
|
99
99
|
loading: Boolean = false,
|
|
100
100
|
modifier: Modifier = Modifier,
|
|
101
|
+
inputModifier: Modifier = Modifier,
|
|
101
102
|
) {
|
|
102
103
|
// Consolidated state management
|
|
103
104
|
var inputState by remember { mutableStateOf(InputState()) }
|
|
@@ -113,23 +114,20 @@ fun InputPhoneNumber(
|
|
|
113
114
|
}
|
|
114
115
|
|
|
115
116
|
val (textColor, placeholderColor, iconTintColor) = colors
|
|
116
|
-
|
|
117
|
-
val testId = "input_phone_number"
|
|
118
|
-
|
|
119
117
|
val textStyle = scaleSize(size.values.textStyle.copy(color = textColor))
|
|
120
118
|
|
|
119
|
+
|
|
121
120
|
Column(modifier = modifier
|
|
122
121
|
.conditional(IsShowBaseLineDebug) {
|
|
123
122
|
border(1.dp, Colors.blue_03)
|
|
124
|
-
}
|
|
125
|
-
.setAutomationId(testId)) {
|
|
123
|
+
}) {
|
|
126
124
|
BasicTextField(
|
|
127
125
|
singleLine = true,
|
|
128
126
|
value = text.value,
|
|
129
127
|
textStyle = textStyle,
|
|
130
128
|
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
|
|
131
129
|
cursorBrush = SolidColor(AppTheme.current.colors.primary),
|
|
132
|
-
modifier =
|
|
130
|
+
modifier = inputModifier
|
|
133
131
|
.height(scaleSize(size.values.height.value, 1.1f).dp)
|
|
134
132
|
.onFocusChanged { focusState ->
|
|
135
133
|
val wasFocused = inputState.isFocused
|
|
@@ -218,6 +216,7 @@ fun InputPhoneNumber(
|
|
|
218
216
|
indication = null
|
|
219
217
|
)
|
|
220
218
|
.padding(horizontal = Spacing.S)
|
|
219
|
+
.setAutomationId("ic_clear")
|
|
221
220
|
)
|
|
222
221
|
}
|
|
223
222
|
}
|
|
@@ -180,10 +180,6 @@ val darkTheme = Theme(
|
|
|
180
180
|
|
|
181
181
|
val AppTheme = staticCompositionLocalOf { defaultTheme }
|
|
182
182
|
|
|
183
|
-
val AppThemeController = staticCompositionLocalOf<(Theme) -> Unit> {
|
|
184
|
-
error("No AppTheme controller provided")
|
|
185
|
-
}
|
|
186
|
-
|
|
187
183
|
val AppStatusBar = staticCompositionLocalOf { 0.dp }
|
|
188
184
|
|
|
189
185
|
val AppNavigationBar = staticCompositionLocalOf { 0.dp }
|
|
@@ -30,7 +30,6 @@ import vn.momo.kits.application.MiniAppContext
|
|
|
30
30
|
import vn.momo.kits.const.AppNavigationBar
|
|
31
31
|
import vn.momo.kits.const.AppStatusBar
|
|
32
32
|
import vn.momo.kits.const.AppTheme
|
|
33
|
-
import vn.momo.kits.const.AppThemeController
|
|
34
33
|
import vn.momo.kits.const.Theme
|
|
35
34
|
import vn.momo.kits.const.ThemeAssets
|
|
36
35
|
import vn.momo.kits.const.defaultTheme
|
|
@@ -80,7 +79,6 @@ fun NavigationContainer(
|
|
|
80
79
|
LocalNavigator provides navigator,
|
|
81
80
|
LocalMaxApi provides maxApi,
|
|
82
81
|
AppTheme provides theme.value,
|
|
83
|
-
AppThemeController provides { theme.value = it },
|
|
84
82
|
AppStatusBar provides statusBarHeight,
|
|
85
83
|
AppNavigationBar provides navigationBarHeight,
|
|
86
84
|
ApplicationContext provides mergedContext,
|
|
@@ -40,13 +40,15 @@ import vn.momo.kits.const.Colors
|
|
|
40
40
|
import vn.momo.kits.const.Radius
|
|
41
41
|
import vn.momo.kits.const.Spacing
|
|
42
42
|
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
43
|
+
import vn.momo.kits.components.BadgeDot
|
|
44
|
+
import vn.momo.kits.components.DotSize
|
|
43
45
|
import vn.momo.kits.const.Typography
|
|
44
46
|
import vn.momo.kits.modifier.conditional
|
|
45
47
|
import vn.momo.kits.modifier.noFeedbackClickable
|
|
46
48
|
import vn.momo.kits.platform.getScreenDimensions
|
|
47
49
|
|
|
48
50
|
val floatingButtonWidth = 75.dp
|
|
49
|
-
const val BOTTOM_TAB_BAR_HEIGHT =
|
|
51
|
+
const val BOTTOM_TAB_BAR_HEIGHT = 64
|
|
50
52
|
|
|
51
53
|
@Composable
|
|
52
54
|
fun BottomTabBar(
|
|
@@ -142,6 +144,18 @@ fun RowScope.renderTabBarItem(
|
|
|
142
144
|
|
|
143
145
|
@Composable
|
|
144
146
|
fun TabBarItem(item: BottomTabItem, selected: Boolean, onClick: () -> Unit) {
|
|
147
|
+
fun isNumber(label: String): Boolean {
|
|
148
|
+
val numberRegex = "^\\d+$".toRegex()
|
|
149
|
+
return numberRegex.matches(label)
|
|
150
|
+
}
|
|
151
|
+
fun formatLabel(label: String): String? {
|
|
152
|
+
if (isNumber(label) && label.toInt() == 0) {
|
|
153
|
+
return null
|
|
154
|
+
}
|
|
155
|
+
return label
|
|
156
|
+
}
|
|
157
|
+
val badgeLabel = item.badgeLabel?.let { formatLabel(it) }
|
|
158
|
+
|
|
145
159
|
Box(modifier = Modifier
|
|
146
160
|
.fillMaxSize()
|
|
147
161
|
.padding(horizontal = Spacing.XXS)
|
|
@@ -156,31 +170,34 @@ fun TabBarItem(item: BottomTabItem, selected: Boolean, onClick: () -> Unit) {
|
|
|
156
170
|
Column(
|
|
157
171
|
modifier = Modifier
|
|
158
172
|
.fillMaxSize()
|
|
159
|
-
.padding(horizontal = Spacing.
|
|
173
|
+
.padding(horizontal = Spacing.S, vertical = Spacing.S)
|
|
160
174
|
.noFeedbackClickable {
|
|
161
175
|
onClick()
|
|
162
176
|
},
|
|
163
177
|
horizontalAlignment = Alignment.CenterHorizontally,
|
|
164
|
-
verticalArrangement = Arrangement.
|
|
178
|
+
verticalArrangement = Arrangement.Center
|
|
165
179
|
) {
|
|
166
180
|
Icon(
|
|
167
181
|
source = item.icon,
|
|
168
|
-
|
|
182
|
+
size = 28.dp,
|
|
183
|
+
modifier = Modifier.padding(Spacing.XS),
|
|
169
184
|
color = if (selected) AppTheme.current.colors.primary else AppTheme.current.colors.text.hint)
|
|
170
185
|
Text(
|
|
171
186
|
text = item.label,
|
|
172
187
|
color = if (selected) AppTheme.current.colors.primary else AppTheme.current.colors.text.hint,
|
|
173
|
-
style = Typography.labelXsMedium,
|
|
188
|
+
style = if (selected) Typography.labelXsMedium else Typography.descriptionXsRegular,
|
|
174
189
|
maxLines = 1,
|
|
175
190
|
overflow = TextOverflow.Ellipsis
|
|
176
191
|
)
|
|
177
192
|
}
|
|
178
|
-
if(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
193
|
+
if (badgeLabel != null) {
|
|
194
|
+
if (badgeLabel.isEmpty())
|
|
195
|
+
BadgeDot(
|
|
196
|
+
size = DotSize.Small,
|
|
197
|
+
modifier = Modifier.offset(x = 50.dp, y = (-48).dp)
|
|
198
|
+
)
|
|
199
|
+
else
|
|
200
|
+
Badge(badgeLabel, modifier = Modifier.offset(x = 44.dp, y = (-42).dp))
|
|
184
201
|
}
|
|
185
202
|
}
|
|
186
203
|
}
|
|
@@ -190,7 +207,7 @@ fun FloatingButton(data: BottomTabFloatingButton) {
|
|
|
190
207
|
Column(
|
|
191
208
|
modifier = Modifier
|
|
192
209
|
.width(floatingButtonWidth)
|
|
193
|
-
.padding(horizontal = Spacing.XXS)
|
|
210
|
+
.padding(horizontal = Spacing.XXS, vertical = Spacing.S)
|
|
194
211
|
.conditional(IsShowBaseLineDebug) {
|
|
195
212
|
border(1.dp, Colors.blue_03)
|
|
196
213
|
}
|
|
@@ -35,6 +35,7 @@ import vn.momo.kits.application.IsShowBaseLineDebug
|
|
|
35
35
|
import vn.momo.kits.const.Spacing
|
|
36
36
|
import vn.momo.kits.modifier.activeOpacityClickable
|
|
37
37
|
import vn.momo.kits.modifier.conditional
|
|
38
|
+
import vn.momo.kits.modifier.setAutomationId
|
|
38
39
|
import vn.momo.kits.navigation.LocalHeaderRightWidthPx
|
|
39
40
|
import vn.momo.kits.navigation.LocalNavigator
|
|
40
41
|
import vn.momo.kits.navigation.LocalOptions
|
|
@@ -119,14 +120,15 @@ fun Header(onBackHandler: (() -> Unit)? = null) {
|
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
@Composable
|
|
122
|
-
fun BackButton(borderColor: Color, backgroundButton: Color, tintIconColor: Color, onBackHandler: () -> Unit){
|
|
123
|
+
private fun BackButton(borderColor: Color, backgroundButton: Color, tintIconColor: Color, onBackHandler: () -> Unit){
|
|
123
124
|
Box(
|
|
124
125
|
modifier = Modifier
|
|
125
126
|
.size(28.dp)
|
|
126
127
|
.background(backgroundButton, RoundedCornerShape(100))
|
|
127
128
|
.border(width = 0.2.dp, color = borderColor, shape = RoundedCornerShape(100))
|
|
128
129
|
.activeOpacityClickable(onClick = onBackHandler)
|
|
129
|
-
.padding(Spacing.XS)
|
|
130
|
+
.padding(Spacing.XS)
|
|
131
|
+
.setAutomationId("btn_navigation_back"),
|
|
130
132
|
contentAlignment = Alignment.Center
|
|
131
133
|
) {
|
|
132
134
|
Icon(
|
|
@@ -10,6 +10,7 @@ import androidx.compose.ui.unit.sp
|
|
|
10
10
|
import androidx.compose.ui.zIndex
|
|
11
11
|
import vn.momo.kits.components.Text
|
|
12
12
|
import vn.momo.kits.const.Typography
|
|
13
|
+
import vn.momo.kits.modifier.setAutomationId
|
|
13
14
|
|
|
14
15
|
@Composable
|
|
15
16
|
fun HeaderTitle(
|
|
@@ -17,7 +18,7 @@ fun HeaderTitle(
|
|
|
17
18
|
color: Color? = null,
|
|
18
19
|
) {
|
|
19
20
|
Text(
|
|
20
|
-
modifier = Modifier.fillMaxWidth().zIndex(1f),
|
|
21
|
+
modifier = Modifier.fillMaxWidth().zIndex(1f).setAutomationId("title_navigation_header"),
|
|
21
22
|
text = title,
|
|
22
23
|
textAlign = TextAlign.Start,
|
|
23
24
|
style = Typography.actionSBold.copy(
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
package vn.momo.kits.utils
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.Composable
|
|
4
|
+
import vn.momo.kits.application.LocalComponentInformation
|
|
5
|
+
|
|
6
|
+
@Composable
|
|
7
|
+
fun getComponentId(
|
|
8
|
+
componentName: String? = null,
|
|
9
|
+
accessibilityLabel: String? = null,
|
|
10
|
+
): String {
|
|
11
|
+
val componentInformation = LocalComponentInformation.current
|
|
12
|
+
if (accessibilityLabel != null) return accessibilityLabel
|
|
13
|
+
if (componentInformation?.componentId != null) return componentInformation.componentId
|
|
14
|
+
return ""
|
|
15
|
+
}
|
|
@@ -12,11 +12,8 @@ import androidx.compose.runtime.mutableStateOf
|
|
|
12
12
|
import androidx.compose.runtime.remember
|
|
13
13
|
import androidx.compose.runtime.setValue
|
|
14
14
|
import androidx.compose.ui.Modifier
|
|
15
|
-
import androidx.compose.ui.draw.drawBehind
|
|
16
15
|
import androidx.compose.ui.graphics.Color
|
|
17
16
|
import androidx.compose.ui.graphics.NativePaint
|
|
18
|
-
import androidx.compose.ui.graphics.Paint
|
|
19
|
-
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
|
|
20
17
|
import androidx.compose.ui.graphics.toArgb
|
|
21
18
|
import androidx.compose.ui.interop.UIKitView
|
|
22
19
|
import androidx.compose.ui.unit.Dp
|
package/gradle.properties
CHANGED
package/ios/Image/Image.swift
CHANGED
|
@@ -31,7 +31,11 @@ public struct ImageView: View {
|
|
|
31
31
|
.placeholder {
|
|
32
32
|
VStack(alignment: .center, content: {
|
|
33
33
|
if error {
|
|
34
|
-
Image(
|
|
34
|
+
Image("media_fail")
|
|
35
|
+
.resizable()
|
|
36
|
+
.renderingMode(.template)
|
|
37
|
+
.foregroundColor(Colors.black08)
|
|
38
|
+
.frame(width: 24, height: 24)
|
|
35
39
|
} else if placeholder != nil {
|
|
36
40
|
placeholder
|
|
37
41
|
}
|
package/ios/Input/Input.swift
CHANGED
|
@@ -174,7 +174,7 @@ public struct Input: View {
|
|
|
174
174
|
onChangeText?("")
|
|
175
175
|
}) {
|
|
176
176
|
Icon(source: "24_navigation_close_circle_full", size: 16, color: Colors.black12)
|
|
177
|
-
.padding(.leading, Spacing.S)
|
|
177
|
+
.padding(.leading, Spacing.S).accessibility(identifier: "ic_clear")
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
|
|
@@ -194,7 +194,7 @@ public struct Input: View {
|
|
|
194
194
|
size: 24,
|
|
195
195
|
color: rightIconColor
|
|
196
196
|
)
|
|
197
|
-
.padding(.leading, Spacing.S)
|
|
197
|
+
.padding(.leading, Spacing.S).accessibility(identifier: "ic_show_hide")
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
} else if !rightIcon.isEmpty {
|
|
@@ -21,6 +21,7 @@ public struct InputPhoneNumber: View {
|
|
|
21
21
|
public var onFocus: (() -> Void)?
|
|
22
22
|
public var onBlur: (() -> Void)?
|
|
23
23
|
public var onRightIconPressed: (() -> Void)?
|
|
24
|
+
public var accessibilityLabel: String?
|
|
24
25
|
|
|
25
26
|
@State private var isFocused: Bool = false
|
|
26
27
|
|
|
@@ -38,7 +39,8 @@ public struct InputPhoneNumber: View {
|
|
|
38
39
|
onChangeText: ((String) -> Void)? = nil,
|
|
39
40
|
onFocus: (() -> Void)? = nil,
|
|
40
41
|
onBlur: (() -> Void)? = nil,
|
|
41
|
-
onRightIconPressed: (() -> Void)? = nil
|
|
42
|
+
onRightIconPressed: (() -> Void)? = nil,
|
|
43
|
+
accessibilityLabel: String? = nil
|
|
42
44
|
) {
|
|
43
45
|
self._text = text
|
|
44
46
|
self.placeholder = placeholder
|
|
@@ -53,6 +55,7 @@ public struct InputPhoneNumber: View {
|
|
|
53
55
|
self.onFocus = onFocus
|
|
54
56
|
self.onBlur = onBlur
|
|
55
57
|
self.onRightIconPressed = onRightIconPressed
|
|
58
|
+
self.accessibilityLabel = accessibilityLabel
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
// MARK: - Body
|
|
@@ -86,7 +89,7 @@ public struct InputPhoneNumber: View {
|
|
|
86
89
|
MomoText(placeholder, typography: size == .small ? .headerSSemibold : .headerMBold, color: Colors.black12)
|
|
87
90
|
}
|
|
88
91
|
|
|
89
|
-
TextField(
|
|
92
|
+
TextField(placeholder, text: textBinding, onEditingChanged: { focused in
|
|
90
93
|
handleFocusChange(focused)
|
|
91
94
|
})
|
|
92
95
|
.keyboardType(.numberPad)
|
|
@@ -94,6 +97,7 @@ public struct InputPhoneNumber: View {
|
|
|
94
97
|
.foregroundColor(Colors.black17)
|
|
95
98
|
.applyPrimaryCursorColor()
|
|
96
99
|
.lineLimit(1)
|
|
100
|
+
.accessibility(identifier: accessibilityLabel ?? "")
|
|
97
101
|
}
|
|
98
102
|
|
|
99
103
|
// Clear button
|
|
@@ -103,7 +107,7 @@ public struct InputPhoneNumber: View {
|
|
|
103
107
|
onChangeText?("")
|
|
104
108
|
}) {
|
|
105
109
|
Icon(source: "24_navigation_close_circle_full", size: 16, color: Colors.black12)
|
|
106
|
-
.padding(.leading, Spacing.S)
|
|
110
|
+
.padding(.leading, Spacing.S).accessibility(identifier: "ic_clear")
|
|
107
111
|
}
|
|
108
112
|
}
|
|
109
113
|
|