@momo-kits/native-kits 0.89.33 → 0.110.1-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compose/build.gradle.kts +2 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Components.kt +35 -33
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +53 -40
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +10 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +12 -8
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +108 -91
- package/local.properties +2 -2
- package/package.json +1 -1
package/compose/build.gradle.kts
CHANGED
|
@@ -3,6 +3,7 @@ plugins {
|
|
|
3
3
|
alias(libs.plugins.jetbrains.kotlin.multiplatform)
|
|
4
4
|
alias(libs.plugins.compose)
|
|
5
5
|
alias(libs.plugins.kotlin.compose.compiler)
|
|
6
|
+
kotlin("plugin.serialization")
|
|
6
7
|
id("maven-publish")
|
|
7
8
|
}
|
|
8
9
|
|
|
@@ -39,6 +40,7 @@ kotlin {
|
|
|
39
40
|
implementation(libs.coil.multiplatform.compose)
|
|
40
41
|
implementation(libs.coil.multiplatform.core)
|
|
41
42
|
implementation(libs.coil.multiplatform.network.ktor)
|
|
43
|
+
implementation(libs.jetbrains.serialization.json)
|
|
42
44
|
}
|
|
43
45
|
}
|
|
44
46
|
val androidMain by getting {
|
|
@@ -50,7 +50,6 @@ import vn.momo.kits.const.AppTheme
|
|
|
50
50
|
import vn.momo.kits.const.Colors
|
|
51
51
|
import vn.momo.kits.const.Spacing
|
|
52
52
|
import vn.momo.kits.const.Typography
|
|
53
|
-
import vn.momo.kits.modifier.shadow
|
|
54
53
|
import vn.momo.kits.platform.getStatusBarHeight
|
|
55
54
|
import vn.momo.kits.utils.bottomBorder
|
|
56
55
|
|
|
@@ -67,7 +66,6 @@ data class AnimatedHeader(
|
|
|
67
66
|
@Composable
|
|
68
67
|
fun HeaderBackground(
|
|
69
68
|
headerType: HeaderType = HeaderType.DEFAULT,
|
|
70
|
-
useShadow: Boolean? = true,
|
|
71
69
|
scrollState: Int
|
|
72
70
|
) {
|
|
73
71
|
val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
|
|
@@ -75,11 +73,19 @@ fun HeaderBackground(
|
|
|
75
73
|
targetValue = (1 - (scrollState / 200f)).coerceIn(0f, 1f),
|
|
76
74
|
)
|
|
77
75
|
|
|
76
|
+
val backgroundColor = if (scrollState == 0) {
|
|
77
|
+
Color.Transparent
|
|
78
|
+
} else {
|
|
79
|
+
AppTheme.current.colors.background.surface
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
78
83
|
when (headerType) {
|
|
79
84
|
HeaderType.DEFAULT -> {
|
|
80
85
|
val height = statusBarHeight + 52.dp
|
|
81
86
|
Box(
|
|
82
87
|
modifier = Modifier.fillMaxWidth().height(height)
|
|
88
|
+
.background(backgroundColor)
|
|
83
89
|
.bottomBorder(
|
|
84
90
|
strokeWidth = 1.dp,
|
|
85
91
|
color = AppTheme.current.colors.border.default
|
|
@@ -103,6 +109,7 @@ fun HeaderBackground(
|
|
|
103
109
|
)
|
|
104
110
|
if (AppTheme.current.assets.headerBackground != null) {
|
|
105
111
|
Image(
|
|
112
|
+
loading = false,
|
|
106
113
|
source = AppTheme.current.assets.headerBackground!!,
|
|
107
114
|
modifier = Modifier.fillMaxWidth().height(height),
|
|
108
115
|
options = Options(
|
|
@@ -115,6 +122,7 @@ fun HeaderBackground(
|
|
|
115
122
|
}
|
|
116
123
|
|
|
117
124
|
HeaderType.EXTENDED -> {
|
|
125
|
+
|
|
118
126
|
Box(
|
|
119
127
|
modifier = Modifier.fillMaxWidth().height(154.dp)
|
|
120
128
|
.alpha(opacityAni)
|
|
@@ -130,31 +138,28 @@ fun HeaderBackground(
|
|
|
130
138
|
)
|
|
131
139
|
) {
|
|
132
140
|
if (AppTheme.current.assets.headerBackground != null) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
141
|
+
Box(
|
|
142
|
+
modifier = Modifier.fillMaxWidth()
|
|
143
|
+
.background(backgroundColor)
|
|
144
|
+
) {
|
|
145
|
+
Image(
|
|
146
|
+
loading = false,
|
|
147
|
+
source = AppTheme.current.assets.headerBackground!!,
|
|
148
|
+
modifier = Modifier.fillMaxWidth().height(154.dp),
|
|
149
|
+
options = Options(
|
|
150
|
+
contentScale = ContentScale.FillWidth
|
|
151
|
+
)
|
|
138
152
|
)
|
|
139
|
-
|
|
153
|
+
}
|
|
140
154
|
}
|
|
141
155
|
}
|
|
142
156
|
}
|
|
157
|
+
|
|
143
158
|
else -> {
|
|
144
159
|
Box(modifier = Modifier.fillMaxWidth())
|
|
145
160
|
}
|
|
146
161
|
}
|
|
147
|
-
|
|
148
|
-
modifier = Modifier.fillMaxWidth().height(statusBarHeight + 52.dp)
|
|
149
|
-
.alpha(1 - opacityAni)
|
|
150
|
-
.background(Colors.black_01)
|
|
151
|
-
.then(
|
|
152
|
-
if (useShadow == true) Modifier.shadow() else Modifier.bottomBorder(
|
|
153
|
-
1.dp,
|
|
154
|
-
Colors.black_04
|
|
155
|
-
)
|
|
156
|
-
)
|
|
157
|
-
)
|
|
162
|
+
|
|
158
163
|
}
|
|
159
164
|
|
|
160
165
|
@Composable
|
|
@@ -163,10 +168,9 @@ fun Header(
|
|
|
163
168
|
titlePosition: TitlePosition,
|
|
164
169
|
title: String,
|
|
165
170
|
headerRight: @Composable (() -> Unit)? = null,
|
|
166
|
-
goBack: (() -> Unit)
|
|
171
|
+
goBack: (() -> Unit)? = null,
|
|
167
172
|
opacity: Float? = null,
|
|
168
173
|
animatedHeader: AnimatedHeader? = null,
|
|
169
|
-
useSearchInput: Boolean? = false,
|
|
170
174
|
scrollState: Int = 0,
|
|
171
175
|
inputSearchProps: InputSearchProps?
|
|
172
176
|
) {
|
|
@@ -206,7 +210,7 @@ fun Header(
|
|
|
206
210
|
horizontalArrangement = Arrangement.SpaceBetween
|
|
207
211
|
) {
|
|
208
212
|
Box {
|
|
209
|
-
if (goBack
|
|
213
|
+
if (goBack != null) {
|
|
210
214
|
Box(
|
|
211
215
|
modifier = Modifier
|
|
212
216
|
.size(28.dp)
|
|
@@ -238,12 +242,11 @@ fun Header(
|
|
|
238
242
|
}
|
|
239
243
|
}
|
|
240
244
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
245
|
+
|
|
246
|
+
Box(Modifier.graphicsLayer {
|
|
247
|
+
alpha = if (animatedHeader !== null) opacity ?: 1f else 1f
|
|
248
|
+
}) {
|
|
249
|
+
headerRight?.invoke()
|
|
247
250
|
}
|
|
248
251
|
}
|
|
249
252
|
|
|
@@ -254,13 +257,12 @@ fun Header(
|
|
|
254
257
|
.padding(horizontal = Spacing.M),
|
|
255
258
|
verticalAlignment = Alignment.CenterVertically,
|
|
256
259
|
) {
|
|
257
|
-
if (goBack
|
|
260
|
+
if (goBack != null && titlePosition == TitlePosition.LEFT) {
|
|
258
261
|
Spacer(Modifier.width(40.dp))
|
|
259
262
|
}
|
|
260
|
-
if (
|
|
263
|
+
if (inputSearchProps != null) {
|
|
261
264
|
InputSearch(inputSearchProps = inputSearchProps.copy(backgroundColor = backgroundSearch))
|
|
262
|
-
}
|
|
263
|
-
else{
|
|
265
|
+
} else {
|
|
264
266
|
Box(
|
|
265
267
|
Modifier.weight(1f).graphicsLayer {
|
|
266
268
|
alpha = if (animatedHeader !== null) opacity ?: 1f else 1f
|
|
@@ -292,7 +294,7 @@ fun HeaderTitle(
|
|
|
292
294
|
modifier = Modifier.then(modifier).zIndex(1f),
|
|
293
295
|
text = title,
|
|
294
296
|
textAlign = textAlign,
|
|
295
|
-
style = Typography.
|
|
297
|
+
style = Typography.actionS,
|
|
296
298
|
color = color,
|
|
297
299
|
maxLines = 1
|
|
298
300
|
)
|
|
@@ -1,64 +1,77 @@
|
|
|
1
1
|
package vn.momo.kits.application
|
|
2
2
|
|
|
3
|
-
import androidx.compose.foundation.layout.WindowInsets
|
|
4
|
-
import androidx.compose.foundation.layout.asPaddingValues
|
|
5
|
-
import androidx.compose.foundation.layout.systemBars
|
|
6
3
|
import androidx.compose.runtime.Composable
|
|
7
4
|
import androidx.compose.runtime.CompositionLocalProvider
|
|
5
|
+
import androidx.compose.runtime.LaunchedEffect
|
|
6
|
+
import androidx.compose.runtime.getValue
|
|
7
|
+
import androidx.compose.runtime.mutableStateOf
|
|
8
|
+
import androidx.compose.runtime.remember
|
|
9
|
+
import androidx.compose.runtime.rememberCoroutineScope
|
|
10
|
+
import androidx.compose.runtime.setValue
|
|
8
11
|
import androidx.compose.runtime.staticCompositionLocalOf
|
|
12
|
+
import androidx.compose.ui.unit.Dp
|
|
13
|
+
import kotlinx.coroutines.launch
|
|
14
|
+
import kotlinx.serialization.json.Json
|
|
15
|
+
import kotlinx.serialization.json.jsonObject
|
|
16
|
+
import kotlinx.serialization.json.jsonPrimitive
|
|
9
17
|
import vn.momo.kits.const.AppStatusBar
|
|
10
18
|
import vn.momo.kits.const.AppTheme
|
|
11
19
|
import vn.momo.kits.const.Theme
|
|
20
|
+
import vn.momo.kits.const.ThemeAssets
|
|
12
21
|
import vn.momo.kits.const.defaultTheme
|
|
13
22
|
import vn.momo.kits.platform.disableOverscroll
|
|
14
23
|
import vn.momo.kits.platform.getStatusBarHeight
|
|
15
24
|
|
|
16
|
-
val
|
|
17
|
-
error("no navigator provided!")
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
class Navigator {
|
|
21
|
-
fun push(content: @Composable () -> Unit) {
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
fun present(content: @Composable () -> Unit) {
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
fun reset(content: @Composable () -> Unit) {
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
fun pop() {
|
|
33
|
-
}
|
|
25
|
+
val PlatformApi = staticCompositionLocalOf<Any?> { null }
|
|
34
26
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
fun
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
fun showModal(
|
|
42
|
-
onClose: () -> Unit = {},
|
|
43
|
-
canBackgroundClose: Boolean = true,
|
|
44
|
-
content: @Composable () -> Unit,
|
|
45
|
-
) {
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
fun showBottomSheet(content: @Composable () -> Unit) {
|
|
49
|
-
}
|
|
27
|
+
interface ComposeApi {
|
|
28
|
+
fun request(funcName: String, params: String?): String
|
|
29
|
+
fun request(funcName: String, params: String?, onResponse: ((String) -> Unit)?): String
|
|
30
|
+
fun requestCallback(funcName: String, params: String?, onResponse: ((String) -> Unit)?)
|
|
31
|
+
fun removeCallback(id: String)
|
|
50
32
|
}
|
|
51
33
|
|
|
52
34
|
@Composable
|
|
53
35
|
fun ApplicationContainer(
|
|
54
36
|
theme: Theme = defaultTheme,
|
|
55
|
-
|
|
37
|
+
composeApi: ComposeApi? = null,
|
|
38
|
+
statusBarHeight: Dp? = AppStatusBar.current ?: getStatusBarHeight(),
|
|
39
|
+
content: @Composable () -> Unit
|
|
56
40
|
) {
|
|
41
|
+
var appTheme by remember { mutableStateOf(theme) }
|
|
42
|
+
val coroutineScope = rememberCoroutineScope()
|
|
43
|
+
|
|
44
|
+
LaunchedEffect(Unit) {
|
|
45
|
+
try {
|
|
46
|
+
composeApi?.request("getConfig", "DESIGN_SYSTEM") {
|
|
47
|
+
val json = Json { ignoreUnknownKeys = true }
|
|
48
|
+
val response = json.parseToJsonElement(it).jsonObject["response"]
|
|
49
|
+
val headerBar = response
|
|
50
|
+
?.jsonObject
|
|
51
|
+
?.get("headerBar")
|
|
52
|
+
?.jsonPrimitive
|
|
53
|
+
?.content
|
|
54
|
+
if (headerBar != null && appTheme.assets.headerBackground == null) {
|
|
55
|
+
coroutineScope.launch {
|
|
56
|
+
appTheme = appTheme.copy(
|
|
57
|
+
assets = ThemeAssets(
|
|
58
|
+
headerBackground = headerBar
|
|
59
|
+
)
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch (e: Exception) {
|
|
66
|
+
print("@@ == NavigationContainer fetch config error $e")
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
57
70
|
disableOverscroll()
|
|
58
71
|
CompositionLocalProvider(
|
|
59
|
-
AppTheme provides
|
|
60
|
-
|
|
61
|
-
AppStatusBar provides
|
|
72
|
+
AppTheme provides appTheme,
|
|
73
|
+
PlatformApi provides composeApi,
|
|
74
|
+
AppStatusBar provides statusBarHeight,
|
|
62
75
|
) {
|
|
63
76
|
content()
|
|
64
77
|
}
|
|
@@ -56,7 +56,7 @@ fun Screen(
|
|
|
56
56
|
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
|
|
57
57
|
title: String = "Stack",
|
|
58
58
|
titlePosition: TitlePosition = TitlePosition.LEFT,
|
|
59
|
-
goBack: (() -> Unit) =
|
|
59
|
+
goBack: (() -> Unit)? = null,
|
|
60
60
|
scrollable: Boolean = true,
|
|
61
61
|
scrollState: ScrollState = rememberScrollState(),
|
|
62
62
|
onContentLayout: ((LayoutCoordinates) -> Unit)? = null,
|
|
@@ -66,8 +66,6 @@ fun Screen(
|
|
|
66
66
|
fabProps: FabProps? = null,
|
|
67
67
|
animatedHeader: AnimatedHeader? = null,
|
|
68
68
|
layoutOffset: Dp = 56.dp,
|
|
69
|
-
useShadow: Boolean? = true,
|
|
70
|
-
useSearchInput: Boolean? = false,
|
|
71
69
|
inputSearchProps: InputSearchProps? = null,
|
|
72
70
|
content: @Composable () -> Unit,
|
|
73
71
|
) {
|
|
@@ -89,7 +87,9 @@ fun Screen(
|
|
|
89
87
|
)
|
|
90
88
|
|
|
91
89
|
val headerAnimated =
|
|
92
|
-
@Composable {
|
|
90
|
+
@Composable {
|
|
91
|
+
animatedHeader?.composable?.invoke(scrollState.value)
|
|
92
|
+
}
|
|
93
93
|
|
|
94
94
|
Box(
|
|
95
95
|
Modifier.fillMaxSize()
|
|
@@ -97,17 +97,19 @@ fun Screen(
|
|
|
97
97
|
) {
|
|
98
98
|
|
|
99
99
|
if (animatedHeader === null) {
|
|
100
|
-
HeaderBackground(
|
|
100
|
+
HeaderBackground(
|
|
101
|
+
headerType = headerType,
|
|
102
|
+
scrollState = scrollState.value,
|
|
103
|
+
)
|
|
101
104
|
} else {
|
|
102
105
|
Box(
|
|
103
|
-
Modifier.zIndex(
|
|
106
|
+
Modifier.zIndex(2f)
|
|
104
107
|
.background(Color.White.copy(alpha = opacity))
|
|
105
108
|
.graphicsLayer { alpha = opacity }
|
|
106
109
|
) {
|
|
107
110
|
HeaderBackground(
|
|
108
111
|
headerType = headerType,
|
|
109
|
-
|
|
110
|
-
scrollState = scrollState.value
|
|
112
|
+
scrollState = scrollState.value,
|
|
111
113
|
)
|
|
112
114
|
}
|
|
113
115
|
}
|
|
@@ -120,7 +122,6 @@ fun Screen(
|
|
|
120
122
|
goBack = goBack,
|
|
121
123
|
opacity = opacity,
|
|
122
124
|
animatedHeader = animatedHeader,
|
|
123
|
-
useSearchInput = useSearchInput,
|
|
124
125
|
inputSearchProps = inputSearchProps,
|
|
125
126
|
scrollState = scrollState.value
|
|
126
127
|
)
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
package vn.momo.kits.components
|
|
2
2
|
|
|
3
|
+
import androidx.compose.foundation.layout.Box
|
|
3
4
|
import androidx.compose.foundation.layout.size
|
|
4
5
|
import androidx.compose.runtime.Composable
|
|
5
6
|
import androidx.compose.ui.Modifier
|
|
6
7
|
import androidx.compose.ui.graphics.Color
|
|
7
8
|
import androidx.compose.ui.graphics.ColorFilter
|
|
8
9
|
import androidx.compose.ui.layout.ContentScale
|
|
10
|
+
import androidx.compose.ui.semantics.contentDescription
|
|
11
|
+
import androidx.compose.ui.semantics.semantics
|
|
9
12
|
import androidx.compose.ui.unit.Dp
|
|
10
13
|
import androidx.compose.ui.unit.dp
|
|
14
|
+
import coil3.compose.AsyncImage
|
|
11
15
|
import vn.momo.kits.const.AppTheme
|
|
12
16
|
import vn.momo.kits.utils.Icons
|
|
13
17
|
|
|
@@ -23,14 +27,14 @@ fun Icon(
|
|
|
23
27
|
} else {
|
|
24
28
|
Icons[source] ?: ""
|
|
25
29
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
Box(modifier = modifier.size(size).semantics {contentDescription = "img|$icon"}) {
|
|
31
|
+
AsyncImage(
|
|
32
|
+
modifier = Modifier.matchParentSize(),
|
|
33
|
+
model = icon,
|
|
34
|
+
contentDescription = null,
|
|
31
35
|
contentScale = ContentScale.Fit,
|
|
32
|
-
colorFilter = color?.let { ColorFilter.tint(it) }
|
|
33
|
-
)
|
|
34
|
-
|
|
36
|
+
colorFilter = color?.let { ColorFilter.tint(it) },
|
|
37
|
+
)
|
|
38
|
+
}
|
|
35
39
|
}
|
|
36
40
|
|
|
@@ -15,6 +15,7 @@ import androidx.compose.foundation.layout.size
|
|
|
15
15
|
import androidx.compose.foundation.layout.width
|
|
16
16
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
17
17
|
import androidx.compose.foundation.text.BasicTextField
|
|
18
|
+
import androidx.compose.foundation.text.KeyboardActions
|
|
18
19
|
import androidx.compose.foundation.text.KeyboardOptions
|
|
19
20
|
import androidx.compose.material3.CircularProgressIndicator
|
|
20
21
|
import androidx.compose.runtime.Composable
|
|
@@ -29,6 +30,7 @@ import androidx.compose.ui.focus.onFocusChanged
|
|
|
29
30
|
import androidx.compose.ui.graphics.Color
|
|
30
31
|
import androidx.compose.ui.text.TextStyle
|
|
31
32
|
import androidx.compose.ui.text.input.KeyboardType
|
|
33
|
+
import androidx.compose.ui.text.style.TextOverflow
|
|
32
34
|
import androidx.compose.ui.unit.dp
|
|
33
35
|
import androidx.compose.ui.unit.sp
|
|
34
36
|
import vn.momo.kits.const.AppTheme
|
|
@@ -44,6 +46,7 @@ fun RenderRightIconSearch(
|
|
|
44
46
|
icon: String,
|
|
45
47
|
color: Color,
|
|
46
48
|
onClick: () -> Unit,
|
|
49
|
+
iconModifier: Modifier = Modifier
|
|
47
50
|
) {
|
|
48
51
|
if (loading) {
|
|
49
52
|
Box(Modifier.padding(horizontal = Spacing.S)) {
|
|
@@ -64,7 +67,7 @@ fun RenderRightIconSearch(
|
|
|
64
67
|
source = icon,
|
|
65
68
|
color = color,
|
|
66
69
|
size = 24.dp,
|
|
67
|
-
modifier =
|
|
70
|
+
modifier = iconModifier.padding(start = Spacing.S, end = 0.dp).clickable(
|
|
68
71
|
onClick = onClick,
|
|
69
72
|
interactionSource = remember { MutableInteractionSource() },
|
|
70
73
|
indication = null
|
|
@@ -90,6 +93,12 @@ data class InputSearchProps(
|
|
|
90
93
|
val fontWeight: InputFontWeight = InputFontWeight.REGULAR,
|
|
91
94
|
val keyboardType: KeyboardType = KeyboardType.Text,
|
|
92
95
|
val backgroundColor: Color = Colors.black_01,
|
|
96
|
+
val clearCondition: (() -> Boolean)? = null,
|
|
97
|
+
val keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
|
|
98
|
+
val keyboardActions: KeyboardActions = KeyboardActions.Default,
|
|
99
|
+
val modifier: Modifier = Modifier,
|
|
100
|
+
val iconModifier: Modifier = Modifier,
|
|
101
|
+
val onClearPress: () -> Unit = {}
|
|
93
102
|
)
|
|
94
103
|
|
|
95
104
|
@Composable
|
|
@@ -98,7 +107,6 @@ fun InputSearch(
|
|
|
98
107
|
text = remember { mutableStateOf("") },
|
|
99
108
|
iconColor = AppTheme.current.colors.text.default
|
|
100
109
|
),
|
|
101
|
-
|
|
102
110
|
) {
|
|
103
111
|
var isFocused by remember { mutableStateOf(false) }
|
|
104
112
|
var isBlurred = false
|
|
@@ -113,103 +121,112 @@ fun InputSearch(
|
|
|
113
121
|
iconTintColor = disabledColor
|
|
114
122
|
}
|
|
115
123
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
124
|
+
BasicTextField(
|
|
125
|
+
enabled = !inputSearchProps.disabled,
|
|
126
|
+
singleLine = true,
|
|
127
|
+
value = inputSearchProps.text.value,
|
|
128
|
+
textStyle = TextStyle(
|
|
129
|
+
color = textColor,
|
|
130
|
+
fontSize = 14.sp,
|
|
131
|
+
lineHeight = 20.sp,
|
|
132
|
+
fontWeight = inputSearchProps.fontWeight.value
|
|
133
|
+
),
|
|
134
|
+
keyboardOptions = inputSearchProps.keyboardOptions.copy(keyboardType = inputSearchProps.keyboardType),
|
|
135
|
+
keyboardActions = inputSearchProps.keyboardActions,
|
|
136
|
+
modifier = inputSearchProps.modifier.height(36.dp).onFocusChanged {
|
|
137
|
+
isFocused = it.isFocused
|
|
138
|
+
if (it.isFocused) {
|
|
139
|
+
inputSearchProps.onFocus()
|
|
140
|
+
}
|
|
141
|
+
if (!it.isFocused && isBlurred) inputSearchProps.onBlur()
|
|
142
|
+
if (it.isFocused && !isBlurred) isBlurred = true
|
|
143
|
+
},
|
|
144
|
+
onValueChange = inputSearchProps.onChangeText,
|
|
145
|
+
decorationBox = { innerTextField ->
|
|
146
|
+
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
147
|
+
Row(
|
|
148
|
+
modifier = Modifier.weight(
|
|
149
|
+
inputSearchProps.showButtonText.ifTrue(
|
|
150
|
+
8f,
|
|
151
|
+
1f
|
|
152
|
+
)
|
|
153
|
+
)
|
|
154
|
+
.background(
|
|
155
|
+
inputSearchProps.backgroundColor,
|
|
156
|
+
RoundedCornerShape(Radius.XL)
|
|
157
|
+
),
|
|
158
|
+
horizontalArrangement = Arrangement.Start,
|
|
159
|
+
verticalAlignment = Alignment.CenterVertically
|
|
160
|
+
) {
|
|
139
161
|
Row(
|
|
140
|
-
modifier = Modifier.
|
|
141
|
-
.
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
),
|
|
145
|
-
horizontalArrangement = Arrangement.Start,
|
|
162
|
+
modifier = Modifier.padding(
|
|
163
|
+
horizontal = Spacing.M,
|
|
164
|
+
vertical = Spacing.S
|
|
165
|
+
),
|
|
146
166
|
verticalAlignment = Alignment.CenterVertically
|
|
147
167
|
) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
fontSize = 16.sp,
|
|
168
|
-
lineHeight = 24.sp,
|
|
169
|
-
fontWeight = inputSearchProps.fontWeight.value
|
|
170
|
-
),
|
|
171
|
-
color = placeholderColor
|
|
172
|
-
)
|
|
173
|
-
}
|
|
174
|
-
innerTextField()
|
|
168
|
+
Icon(
|
|
169
|
+
source = "navigation_search",
|
|
170
|
+
modifier = Modifier.padding(end = Spacing.XS),
|
|
171
|
+
size = 24.dp,
|
|
172
|
+
color = AppTheme.current.colors.text.hint
|
|
173
|
+
)
|
|
174
|
+
Box(Modifier.weight(1f)) {
|
|
175
|
+
if (inputSearchProps.text.value.isEmpty()) {
|
|
176
|
+
Text(
|
|
177
|
+
text = inputSearchProps.placeholder,
|
|
178
|
+
style = TextStyle(
|
|
179
|
+
fontSize = 14.sp,
|
|
180
|
+
lineHeight = 20.sp,
|
|
181
|
+
fontWeight = inputSearchProps.fontWeight.value
|
|
182
|
+
),
|
|
183
|
+
maxLines = 1,
|
|
184
|
+
color = placeholderColor,
|
|
185
|
+
overflow = TextOverflow.Ellipsis
|
|
186
|
+
)
|
|
175
187
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
+
innerTextField()
|
|
189
|
+
}
|
|
190
|
+
if (inputSearchProps.clearCondition?.invoke() == true || (isFocused && inputSearchProps.text.value.isNotEmpty())) {
|
|
191
|
+
Row {
|
|
192
|
+
Spacer(Modifier.width(Spacing.XS))
|
|
193
|
+
Icon(
|
|
194
|
+
source = "24_navigation_close_circle_full",
|
|
195
|
+
size = 16.dp,
|
|
196
|
+
color = AppTheme.current.colors.text.hint,
|
|
197
|
+
modifier = Modifier.clickable(
|
|
198
|
+
onClick = {
|
|
199
|
+
inputSearchProps.text.value = ""
|
|
200
|
+
inputSearchProps.onClearPress.invoke()
|
|
201
|
+
},
|
|
202
|
+
interactionSource = remember { MutableInteractionSource() },
|
|
203
|
+
indication = null
|
|
188
204
|
)
|
|
189
|
-
|
|
205
|
+
)
|
|
190
206
|
}
|
|
191
|
-
RenderRightIconSearch(
|
|
192
|
-
inputSearchProps.loading,
|
|
193
|
-
inputSearchProps.icon,
|
|
194
|
-
iconTintColor,
|
|
195
|
-
inputSearchProps.onRightIconPressed
|
|
196
|
-
)
|
|
197
207
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
modifier = Modifier.padding(start = Spacing.L).clickable(
|
|
205
|
-
interactionSource = remember { MutableInteractionSource() },
|
|
206
|
-
indication = null,
|
|
207
|
-
onClick = inputSearchProps.onPressButtonText
|
|
208
|
-
)
|
|
208
|
+
RenderRightIconSearch(
|
|
209
|
+
inputSearchProps.loading,
|
|
210
|
+
inputSearchProps.icon,
|
|
211
|
+
iconTintColor,
|
|
212
|
+
inputSearchProps.onRightIconPressed,
|
|
213
|
+
iconModifier = inputSearchProps.iconModifier
|
|
209
214
|
)
|
|
210
215
|
}
|
|
211
216
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
217
|
+
if (inputSearchProps.showButtonText) {
|
|
218
|
+
Text(
|
|
219
|
+
text = inputSearchProps.buttonText,
|
|
220
|
+
style = Typography.actionDefault,
|
|
221
|
+
color = AppTheme.current.colors.text.default,
|
|
222
|
+
modifier = Modifier.padding(start = Spacing.L).clickable(
|
|
223
|
+
interactionSource = remember { MutableInteractionSource() },
|
|
224
|
+
indication = null,
|
|
225
|
+
onClick = inputSearchProps.onPressButtonText
|
|
226
|
+
)
|
|
227
|
+
)
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
)
|
|
215
232
|
}
|
package/local.properties
CHANGED
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
# Location of the SDK. This is only used by Gradle.
|
|
5
5
|
# For customization when using a Version Control System, please read the
|
|
6
6
|
# header note.
|
|
7
|
-
#
|
|
8
|
-
sdk.dir=/Users/
|
|
7
|
+
#Tue Apr 23 16:40:15 ICT 2024
|
|
8
|
+
sdk.dir=/Users/hung.dao1/Library/Android/sdk
|