@momo-kits/native-kits 0.113.3-beta.4 → 0.113.3-beta.6
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/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +8 -21
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +12 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +84 -38
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +13 -4
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +10 -6
- package/ios/Application/Components.swift +3 -1
- package/ios/Application/Screen.swift +1 -1
- package/ios/Popup/PopupDisplay.swift +2 -0
- package/local.properties +2 -2
- package/package.json +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +0 -58
|
@@ -26,7 +26,6 @@ import androidx.compose.ui.Modifier
|
|
|
26
26
|
import androidx.compose.ui.graphics.graphicsLayer
|
|
27
27
|
import androidx.compose.ui.semantics.semantics
|
|
28
28
|
import androidx.compose.ui.semantics.testTag
|
|
29
|
-
import androidx.compose.ui.unit.Dp
|
|
30
29
|
import androidx.compose.ui.unit.dp
|
|
31
30
|
import androidx.compose.ui.zIndex
|
|
32
31
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
|
@@ -48,11 +47,10 @@ fun Header(
|
|
|
48
47
|
title: String,
|
|
49
48
|
headerRight: @Composable (() -> Unit)? = null,
|
|
50
49
|
goBack: (() -> Unit)? = null,
|
|
51
|
-
opacity: Float =
|
|
50
|
+
opacity: Float? = null,
|
|
52
51
|
animatedHeader: AnimatedHeader? = null,
|
|
53
52
|
scrollState: Int = 0,
|
|
54
53
|
inputSearchProps: InputSearchProps? = null,
|
|
55
|
-
headerRightWidth: Dp = 0.dp,
|
|
56
54
|
useAnimationSearch: Boolean = false
|
|
57
55
|
) {
|
|
58
56
|
val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
|
|
@@ -67,12 +65,6 @@ fun Header(
|
|
|
67
65
|
.distinctUntilChanged()
|
|
68
66
|
.collect { fraction -> colorFraction = fraction }
|
|
69
67
|
}
|
|
70
|
-
val animations = useHeaderSearchAnimation(
|
|
71
|
-
opacityAni = opacity,
|
|
72
|
-
scrollState = scrollState,
|
|
73
|
-
headerRightWidth = headerRightWidth,
|
|
74
|
-
isBack = goBack != null
|
|
75
|
-
)
|
|
76
68
|
|
|
77
69
|
val backgroundSearch = animateColor(
|
|
78
70
|
Colors.black_01,
|
|
@@ -80,9 +72,6 @@ fun Header(
|
|
|
80
72
|
colorFraction
|
|
81
73
|
)
|
|
82
74
|
|
|
83
|
-
val searchAnimationEnable =
|
|
84
|
-
inputSearchProps != null && useAnimationSearch && headerType == HeaderType.EXTENDED
|
|
85
|
-
|
|
86
75
|
if (headerType != HeaderType.NONE) {
|
|
87
76
|
BoxWithConstraints(
|
|
88
77
|
Modifier.height(statusBarHeight + 52.dp)
|
|
@@ -131,7 +120,7 @@ fun Header(
|
|
|
131
120
|
|
|
132
121
|
if (useAnimationSearch || inputSearchProps == null) {
|
|
133
122
|
Box(Modifier.graphicsLayer {
|
|
134
|
-
alpha = if (animatedHeader !== null) opacity else 1f
|
|
123
|
+
alpha = if (animatedHeader !== null) opacity ?: 1f else 1f
|
|
135
124
|
}) {
|
|
136
125
|
headerRight?.invoke()
|
|
137
126
|
}
|
|
@@ -153,10 +142,15 @@ fun Header(
|
|
|
153
142
|
} else {
|
|
154
143
|
Box(
|
|
155
144
|
Modifier.weight(1f).graphicsLayer {
|
|
156
|
-
alpha = if (
|
|
145
|
+
alpha = if (useAnimationSearch) {
|
|
146
|
+
1f - (opacity ?: 1f)
|
|
147
|
+
} else {
|
|
148
|
+
if (animatedHeader !== null) opacity ?: 1f else 1f
|
|
149
|
+
}
|
|
157
150
|
},
|
|
158
151
|
contentAlignment = if (titlePosition == TitlePosition.LEFT) Alignment.TopStart else Alignment.Center
|
|
159
152
|
) {
|
|
153
|
+
|
|
160
154
|
HeaderTitle(
|
|
161
155
|
title = title,
|
|
162
156
|
color = tintIconColor,
|
|
@@ -167,13 +161,6 @@ fun Header(
|
|
|
167
161
|
}
|
|
168
162
|
}
|
|
169
163
|
}
|
|
170
|
-
|
|
171
|
-
if (searchAnimationEnable) {
|
|
172
|
-
AnimationSearchInput(
|
|
173
|
-
animations = animations,
|
|
174
|
-
inputSearchProps = inputSearchProps!!
|
|
175
|
-
)
|
|
176
|
-
}
|
|
177
164
|
}
|
|
178
165
|
}
|
|
179
166
|
}
|
|
@@ -8,6 +8,9 @@ import androidx.compose.runtime.Composable
|
|
|
8
8
|
import androidx.compose.runtime.getValue
|
|
9
9
|
import androidx.compose.ui.Modifier
|
|
10
10
|
import androidx.compose.ui.graphics.Color
|
|
11
|
+
import androidx.compose.ui.unit.Dp
|
|
12
|
+
import androidx.compose.ui.unit.dp
|
|
13
|
+
import vn.momo.kits.components.InputSearchProps
|
|
11
14
|
import vn.momo.kits.const.AppStatusBar
|
|
12
15
|
import vn.momo.kits.const.AppTheme
|
|
13
16
|
import vn.momo.kits.platform.getStatusBarHeight
|
|
@@ -32,8 +35,12 @@ fun animateColor(start: Color, stop: Color, fraction: Float): Color {
|
|
|
32
35
|
|
|
33
36
|
@Composable
|
|
34
37
|
fun HeaderBackground(
|
|
38
|
+
isBack: Boolean = true,
|
|
35
39
|
headerType: HeaderType = HeaderType.DEFAULT,
|
|
36
40
|
scrollState: Int,
|
|
41
|
+
inputSearchProps: InputSearchProps? = null,
|
|
42
|
+
headerRightWidth: Dp = 0.dp,
|
|
43
|
+
useAnimationSearch: Boolean = false
|
|
37
44
|
) {
|
|
38
45
|
val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
|
|
39
46
|
|
|
@@ -59,7 +66,12 @@ fun HeaderBackground(
|
|
|
59
66
|
|
|
60
67
|
HeaderType.EXTENDED -> {
|
|
61
68
|
HeaderExtended(
|
|
69
|
+
scrollState = scrollState,
|
|
70
|
+
inputSearchProps = inputSearchProps,
|
|
71
|
+
headerRightWidth = headerRightWidth,
|
|
72
|
+
useAnimationSearch = useAnimationSearch,
|
|
62
73
|
opacityAni = opacityAni,
|
|
74
|
+
isBack = isBack,
|
|
63
75
|
statusBarHeight = statusBarHeight,
|
|
64
76
|
backgroundColor = backgroundColor,
|
|
65
77
|
)
|
|
@@ -37,54 +37,100 @@ import vn.momo.kits.utils.bottomBorder
|
|
|
37
37
|
@Composable
|
|
38
38
|
fun HeaderExtended(
|
|
39
39
|
opacityAni: Float,
|
|
40
|
+
inputSearchProps: InputSearchProps?,
|
|
41
|
+
useAnimationSearch: Boolean = true,
|
|
42
|
+
scrollState: Int,
|
|
43
|
+
headerRightWidth: Dp,
|
|
44
|
+
isBack: Boolean,
|
|
40
45
|
statusBarHeight: Dp,
|
|
41
46
|
backgroundColor: Color
|
|
42
47
|
) {
|
|
48
|
+
val animations = useHeaderSearchAnimation(
|
|
49
|
+
opacityAni = opacityAni,
|
|
50
|
+
scrollState = scrollState,
|
|
51
|
+
headerRightWidth = headerRightWidth,
|
|
52
|
+
statusBarHeight = statusBarHeight,
|
|
53
|
+
isBack = isBack
|
|
54
|
+
)
|
|
55
|
+
|
|
43
56
|
Box(
|
|
44
|
-
modifier = Modifier
|
|
45
|
-
.
|
|
46
|
-
.height(154.dp)
|
|
47
|
-
.alpha(opacityAni)
|
|
48
|
-
.background(
|
|
49
|
-
Brush.linearGradient(
|
|
50
|
-
colors = listOf(
|
|
51
|
-
Color(0xFFFDCADE),
|
|
52
|
-
Color(0x00FDCADE)
|
|
53
|
-
),
|
|
54
|
-
start = Offset(0f, 0f),
|
|
55
|
-
end = Offset(0f, with(LocalDensity.current) { 154.dp.toPx() })
|
|
56
|
-
)
|
|
57
|
-
)
|
|
57
|
+
modifier = Modifier.fillMaxWidth()
|
|
58
|
+
.height(animations.height.dp)
|
|
58
59
|
) {
|
|
59
|
-
|
|
60
|
+
Box(
|
|
61
|
+
modifier = Modifier
|
|
62
|
+
.fillMaxWidth()
|
|
63
|
+
.height(154.dp)
|
|
64
|
+
.alpha(opacityAni)
|
|
65
|
+
.background(
|
|
66
|
+
Brush.linearGradient(
|
|
67
|
+
colors = listOf(
|
|
68
|
+
Color(0xFFFDCADE),
|
|
69
|
+
Color(0x00FDCADE)
|
|
70
|
+
),
|
|
71
|
+
start = Offset(0f, 0f),
|
|
72
|
+
end = Offset(0f, with(LocalDensity.current) { 154.dp.toPx() })
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
) {
|
|
76
|
+
if (AppTheme.current.assets.headerBackground != null) {
|
|
77
|
+
Box(
|
|
78
|
+
modifier = Modifier
|
|
79
|
+
.fillMaxWidth()
|
|
80
|
+
.background(backgroundColor)
|
|
81
|
+
) {
|
|
82
|
+
Image(
|
|
83
|
+
loading = false,
|
|
84
|
+
source = AppTheme.current.assets.headerBackground!!,
|
|
85
|
+
modifier = Modifier.fillMaxWidth().height(154.dp),
|
|
86
|
+
options = Options(
|
|
87
|
+
contentScale = ContentScale.FillWidth
|
|
88
|
+
)
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
Box(
|
|
95
|
+
modifier = Modifier
|
|
96
|
+
.fillMaxWidth()
|
|
97
|
+
.alpha(1f - opacityAni)
|
|
98
|
+
.height(statusBarHeight + 52.dp)
|
|
99
|
+
.background(
|
|
100
|
+
AppTheme.current.colors.background.surface
|
|
101
|
+
)
|
|
102
|
+
.bottomBorder(
|
|
103
|
+
strokeWidth = 1.dp,
|
|
104
|
+
color = AppTheme.current.colors.border.default
|
|
105
|
+
)
|
|
106
|
+
)
|
|
107
|
+
if (inputSearchProps != null && useAnimationSearch) {
|
|
60
108
|
Box(
|
|
61
109
|
modifier = Modifier
|
|
62
|
-
.
|
|
63
|
-
.
|
|
110
|
+
.height(52.dp)
|
|
111
|
+
.offset(
|
|
112
|
+
x = animations.translateX.dp
|
|
113
|
+
)
|
|
114
|
+
.padding(vertical = Spacing.S)
|
|
115
|
+
.align(Alignment.BottomStart)
|
|
116
|
+
.zIndex(1f)
|
|
64
117
|
) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
118
|
+
Box(
|
|
119
|
+
modifier = Modifier
|
|
120
|
+
.width(animations.width.dp)
|
|
121
|
+
.background(
|
|
122
|
+
color = animations.backgroundSearch,
|
|
123
|
+
shape = RoundedCornerShape(Radius.XL)
|
|
124
|
+
)
|
|
125
|
+
) {
|
|
126
|
+
InputSearch(
|
|
127
|
+
inputSearchProps = inputSearchProps.copy(
|
|
128
|
+
showButtonText = false,
|
|
129
|
+
backgroundColor = Color.Transparent
|
|
130
|
+
)
|
|
71
131
|
)
|
|
72
|
-
|
|
132
|
+
}
|
|
73
133
|
}
|
|
74
134
|
}
|
|
75
135
|
}
|
|
76
|
-
|
|
77
|
-
Box(
|
|
78
|
-
modifier = Modifier
|
|
79
|
-
.fillMaxWidth()
|
|
80
|
-
.alpha(1f - opacityAni)
|
|
81
|
-
.height(statusBarHeight + 52.dp)
|
|
82
|
-
.background(
|
|
83
|
-
AppTheme.current.colors.background.surface
|
|
84
|
-
)
|
|
85
|
-
.bottomBorder(
|
|
86
|
-
strokeWidth = 1.dp,
|
|
87
|
-
color = AppTheme.current.colors.border.default
|
|
88
|
-
)
|
|
89
|
-
)
|
|
90
136
|
}
|
|
@@ -101,7 +101,10 @@ fun Screen(
|
|
|
101
101
|
if (animatedHeader === null) {
|
|
102
102
|
HeaderBackground(
|
|
103
103
|
headerType = headerType,
|
|
104
|
-
scrollState = scrollState.value
|
|
104
|
+
scrollState = scrollState.value,
|
|
105
|
+
inputSearchProps= inputSearchProps,
|
|
106
|
+
useAnimationSearch = useAnimationSearch,
|
|
107
|
+
headerRightWidth = headerRightWidth
|
|
105
108
|
)
|
|
106
109
|
} else {
|
|
107
110
|
Box(
|
|
@@ -110,19 +113,24 @@ fun Screen(
|
|
|
110
113
|
.graphicsLayer { alpha = opacity }
|
|
111
114
|
) {
|
|
112
115
|
HeaderBackground(
|
|
116
|
+
isBack = isBack,
|
|
113
117
|
headerType = headerType,
|
|
114
|
-
scrollState = scrollState.value
|
|
118
|
+
scrollState = scrollState.value,
|
|
119
|
+
inputSearchProps= inputSearchProps,
|
|
120
|
+
useAnimationSearch = useAnimationSearch,
|
|
121
|
+
headerRightWidth = headerRightWidth
|
|
115
122
|
)
|
|
116
123
|
}
|
|
117
124
|
}
|
|
125
|
+
|
|
118
126
|
Header(
|
|
119
127
|
headerType = headerType,
|
|
120
128
|
title = title,
|
|
121
129
|
titlePosition = titlePosition,
|
|
122
130
|
headerRight = headerRight,
|
|
123
|
-
headerRightWidth = headerRightWidth,
|
|
124
131
|
goBack = goBack,
|
|
125
132
|
opacity = opacity,
|
|
133
|
+
animatedHeader = animatedHeader,
|
|
126
134
|
inputSearchProps = inputSearchProps,
|
|
127
135
|
scrollState = scrollState.value,
|
|
128
136
|
useAnimationSearch = useAnimationSearch,
|
|
@@ -130,7 +138,7 @@ fun Screen(
|
|
|
130
138
|
|
|
131
139
|
Column(
|
|
132
140
|
modifier = Modifier.fillMaxSize()
|
|
133
|
-
.padding(top = if (headerType !== HeaderType.NONE) statusBarHeight + 52.dp else 0.dp)
|
|
141
|
+
.padding(top = if (animatedHeader === null && headerType !== HeaderType.NONE) statusBarHeight + 52.dp else 0.dp)
|
|
134
142
|
.pointerInput(Unit) {
|
|
135
143
|
detectTapGestures(onTap = {
|
|
136
144
|
keyboardController?.hide()
|
|
@@ -138,6 +146,7 @@ fun Screen(
|
|
|
138
146
|
}
|
|
139
147
|
.zIndex(1f),
|
|
140
148
|
) {
|
|
149
|
+
|
|
141
150
|
Column(
|
|
142
151
|
modifier = Modifier
|
|
143
152
|
.conditional(scrollable) { weight(1f) }
|
|
@@ -16,7 +16,7 @@ data class HeaderAnimations(
|
|
|
16
16
|
val backgroundSearch: Color,
|
|
17
17
|
val translateX: Float,
|
|
18
18
|
val width: Float,
|
|
19
|
-
val
|
|
19
|
+
val height: Float
|
|
20
20
|
)
|
|
21
21
|
|
|
22
22
|
private const val SCREEN_PADDING = 12
|
|
@@ -27,16 +27,17 @@ fun useHeaderSearchAnimation(
|
|
|
27
27
|
opacityAni: Float,
|
|
28
28
|
scrollState: Int,
|
|
29
29
|
headerRightWidth: Dp,
|
|
30
|
+
statusBarHeight: Dp,
|
|
30
31
|
isBack: Boolean
|
|
31
32
|
): HeaderAnimations {
|
|
32
33
|
val screenWidth = getScreenDimensions().width
|
|
33
|
-
val leftPosition = if (isBack) (BACK_WIDTH + 20).dp else
|
|
34
|
+
val leftPosition = if (isBack) (BACK_WIDTH + 20).dp else 20.dp
|
|
34
35
|
val searchWidth = screenWidth - (SCREEN_PADDING * 2)
|
|
35
36
|
|
|
36
37
|
val backgroundSearch by animateColorAsState(
|
|
37
38
|
targetValue = animateColor(
|
|
38
|
-
Colors.black_01,
|
|
39
39
|
AppTheme.current.colors.background.default,
|
|
40
|
+
Colors.black_01,
|
|
40
41
|
opacityAni
|
|
41
42
|
),
|
|
42
43
|
)
|
|
@@ -52,14 +53,17 @@ fun useHeaderSearchAnimation(
|
|
|
52
53
|
) * ((searchWidth - leftPosition.value - headerRightWidth.value + 12) - searchWidth) + searchWidth,
|
|
53
54
|
)
|
|
54
55
|
|
|
55
|
-
val
|
|
56
|
-
targetValue = (1 - (scrollState / 52f).coerceIn(
|
|
56
|
+
val animatedHeight by animateFloatAsState(
|
|
57
|
+
targetValue = (1 - (scrollState / 52f).coerceIn(
|
|
58
|
+
0f,
|
|
59
|
+
1f
|
|
60
|
+
)) * (statusBarHeight.value + 94 - (statusBarHeight.value + 52)) + (statusBarHeight.value + 52),
|
|
57
61
|
)
|
|
58
62
|
return HeaderAnimations(
|
|
59
63
|
opacity = opacityAni,
|
|
60
64
|
backgroundSearch = backgroundSearch,
|
|
61
65
|
translateX = animatedTranslateX,
|
|
62
66
|
width = animatedWidth,
|
|
63
|
-
|
|
67
|
+
height = animatedHeight
|
|
64
68
|
)
|
|
65
69
|
}
|
|
@@ -203,7 +203,9 @@ public struct Header: View {
|
|
|
203
203
|
Text(title)
|
|
204
204
|
.font(.headline)
|
|
205
205
|
.foregroundColor(tintIconColor)
|
|
206
|
-
.frame(maxWidth: titlePosition == .center ? .
|
|
206
|
+
.frame(maxWidth: titlePosition == .center ? UIScreen.main.bounds.width - 252 : nil)
|
|
207
|
+
.frame(maxWidth: titlePosition == .center ? .infinity : UIScreen.main.bounds.width - 172, alignment: titlePosition == .center ? .center : .leading)
|
|
208
|
+
.lineLimit(1)
|
|
207
209
|
}
|
|
208
210
|
Spacer()
|
|
209
211
|
}
|
|
@@ -34,7 +34,7 @@ public struct Screen<Content: View>: View {
|
|
|
34
34
|
verticalAlignment: VerticalAlignment = .top,
|
|
35
35
|
horizontalAlignment: HorizontalAlignment = .leading,
|
|
36
36
|
title: String = "Stack",
|
|
37
|
-
titlePosition: TitlePosition = .
|
|
37
|
+
titlePosition: TitlePosition = .left,
|
|
38
38
|
goBack: (() -> Void)? = nil,
|
|
39
39
|
scrollable: Bool = true,
|
|
40
40
|
onContentLayout: ((CGRect) -> Void)? = nil,
|
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
|
+
#Thu Jan 09 10:43:10 ICT 2025
|
|
8
|
+
sdk.dir=/Users/sophia/Library/Android/sdk
|
package/package.json
CHANGED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
package vn.momo.kits.application
|
|
2
|
-
|
|
3
|
-
import androidx.compose.foundation.background
|
|
4
|
-
import androidx.compose.foundation.layout.Box
|
|
5
|
-
import androidx.compose.foundation.layout.fillMaxWidth
|
|
6
|
-
import androidx.compose.foundation.layout.height
|
|
7
|
-
import androidx.compose.foundation.layout.offset
|
|
8
|
-
import androidx.compose.foundation.layout.padding
|
|
9
|
-
import androidx.compose.foundation.layout.width
|
|
10
|
-
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
11
|
-
import androidx.compose.runtime.Composable
|
|
12
|
-
import androidx.compose.ui.Modifier
|
|
13
|
-
import androidx.compose.ui.graphics.Color
|
|
14
|
-
import androidx.compose.ui.unit.dp
|
|
15
|
-
import androidx.compose.ui.zIndex
|
|
16
|
-
import vn.momo.kits.components.InputSearch
|
|
17
|
-
import vn.momo.kits.components.InputSearchProps
|
|
18
|
-
import vn.momo.kits.const.Radius
|
|
19
|
-
import vn.momo.kits.const.Spacing
|
|
20
|
-
|
|
21
|
-
@Composable
|
|
22
|
-
fun AnimationSearchInput(
|
|
23
|
-
animations: HeaderAnimations,
|
|
24
|
-
inputSearchProps: InputSearchProps
|
|
25
|
-
) {
|
|
26
|
-
Box(
|
|
27
|
-
modifier = Modifier
|
|
28
|
-
.fillMaxWidth()
|
|
29
|
-
.offset(
|
|
30
|
-
x = animations.translateX.dp,
|
|
31
|
-
y = animations.translateY.dp
|
|
32
|
-
)
|
|
33
|
-
) {
|
|
34
|
-
Box(
|
|
35
|
-
modifier = Modifier
|
|
36
|
-
.height(52.dp)
|
|
37
|
-
.padding(vertical = Spacing.S)
|
|
38
|
-
.zIndex(1f)
|
|
39
|
-
) {
|
|
40
|
-
Box(
|
|
41
|
-
modifier = Modifier
|
|
42
|
-
.width(animations.width.dp)
|
|
43
|
-
.background(
|
|
44
|
-
color = animations.backgroundSearch,
|
|
45
|
-
shape = RoundedCornerShape(Radius.XL)
|
|
46
|
-
)
|
|
47
|
-
) {
|
|
48
|
-
InputSearch(
|
|
49
|
-
inputSearchProps = inputSearchProps.copy(
|
|
50
|
-
showButtonText = false,
|
|
51
|
-
backgroundColor = Color.Transparent
|
|
52
|
-
)
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
}
|