@momo-kits/native-kits 0.113.1-beta.5 → 0.113.1-beta.7

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 (27) hide show
  1. package/compose/src/commonMain/kotlin/vn/momo/kits/application/{Components.kt → Header.kt} +16 -136
  2. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +70 -0
  3. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +63 -0
  4. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +102 -0
  5. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +261 -0
  6. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +27 -0
  7. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +57 -60
  8. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +14 -3
  9. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +61 -0
  10. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +2 -2
  11. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +3 -3
  12. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +3 -1
  13. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +1 -1
  14. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +47 -37
  15. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +6 -1
  16. package/ios/Application/ApplicationEnvironment.swift +34 -0
  17. package/ios/Application/Components.swift +6 -70
  18. package/ios/Application/ComposeApi.swift +22 -0
  19. package/ios/Application/HeaderRight.swift +249 -0
  20. package/ios/Application/Screen.swift +18 -32
  21. package/ios/Badge/BadgeDot.swift +31 -0
  22. package/ios/Button/Button.swift +2 -1
  23. package/ios/Icon/Icon.swift +1 -3
  24. package/ios/Image/Image.swift +17 -1
  25. package/ios/Popup/PopupDisplay.swift +10 -14
  26. package/local.properties +2 -2
  27. package/package.json +1 -1
@@ -1,7 +1,6 @@
1
1
  package vn.momo.kits.application
2
2
 
3
3
  import androidx.compose.animation.animateColorAsState
4
- import androidx.compose.animation.core.animateFloatAsState
5
4
  import androidx.compose.foundation.background
6
5
  import androidx.compose.foundation.border
7
6
  import androidx.compose.foundation.clickable
@@ -25,144 +24,33 @@ import androidx.compose.runtime.setValue
25
24
  import androidx.compose.runtime.snapshotFlow
26
25
  import androidx.compose.ui.Alignment
27
26
  import androidx.compose.ui.Modifier
28
- import androidx.compose.ui.draw.alpha
29
- import androidx.compose.ui.geometry.Offset
30
- import androidx.compose.ui.graphics.Brush
31
27
  import androidx.compose.ui.graphics.Color
32
28
  import androidx.compose.ui.graphics.graphicsLayer
33
- import androidx.compose.ui.layout.ContentScale
34
- import androidx.compose.ui.platform.LocalDensity
35
29
  import androidx.compose.ui.semantics.semantics
36
30
  import androidx.compose.ui.semantics.testTag
37
- import androidx.compose.ui.text.style.TextAlign
38
31
  import androidx.compose.ui.unit.dp
39
32
  import androidx.compose.ui.zIndex
40
33
  import kotlinx.coroutines.flow.distinctUntilChanged
41
34
  import kotlinx.coroutines.flow.map
42
35
  import vn.momo.kits.components.Icon
43
- import vn.momo.kits.components.Image
44
36
  import vn.momo.kits.components.InputSearch
45
37
  import vn.momo.kits.components.InputSearchProps
46
- import vn.momo.kits.components.Options
47
- import vn.momo.kits.components.Text
48
38
  import vn.momo.kits.const.AppStatusBar
49
39
  import vn.momo.kits.const.AppTheme
50
40
  import vn.momo.kits.const.Colors
51
41
  import vn.momo.kits.const.Spacing
52
- import vn.momo.kits.const.Typography
53
42
  import vn.momo.kits.modifier.setAutomationId
54
43
  import vn.momo.kits.platform.getStatusBarHeight
55
- import vn.momo.kits.utils.bottomBorder
56
44
 
57
45
  enum class TitlePosition {
58
46
  LEFT, CENTER,
59
47
  }
60
48
 
61
-
62
49
  data class AnimatedHeader(
63
50
  val type: HeaderType = HeaderType.DEFAULT,
64
51
  val composable: @Composable (scrollState: Int) -> Unit = {}
65
52
  )
66
53
 
67
- @Composable
68
- fun HeaderBackground(
69
- headerType: HeaderType = HeaderType.DEFAULT,
70
- scrollState: Int
71
- ) {
72
- val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
73
- val opacityAni by animateFloatAsState(
74
- targetValue = (1 - (scrollState / 200f)).coerceIn(0f, 1f),
75
- )
76
-
77
- val backgroundColor = if (scrollState == 0) {
78
- Color.Transparent
79
- } else {
80
- AppTheme.current.colors.background.surface
81
- }
82
-
83
-
84
- when (headerType) {
85
- HeaderType.DEFAULT -> {
86
- val height = statusBarHeight + 52.dp
87
- Box(
88
- modifier = Modifier.fillMaxWidth().height(height)
89
- .background(backgroundColor)
90
- .bottomBorder(
91
- strokeWidth = 1.dp,
92
- color = AppTheme.current.colors.border.default
93
- )
94
- ) {
95
- Box(
96
- modifier = Modifier
97
- .height(height)
98
- .fillMaxWidth()
99
- .alpha(opacityAni)
100
- .background(
101
- Brush.linearGradient(
102
- colors = listOf(
103
- Color(0xFFFDCADE),
104
- Color(0x00FDCADE)
105
- ),
106
- start = Offset(0f, 0f),
107
- end = Offset(0f, with(LocalDensity.current) { 154.dp.toPx() })
108
- )
109
- )
110
- )
111
- if (AppTheme.current.assets.headerBackground != null) {
112
- Image(
113
- loading = false,
114
- source = AppTheme.current.assets.headerBackground!!,
115
- modifier = Modifier.fillMaxWidth().height(height),
116
- options = Options(
117
- contentScale = ContentScale.FillWidth
118
- )
119
- )
120
- }
121
- }
122
-
123
- }
124
-
125
- HeaderType.EXTENDED -> {
126
-
127
- Box(
128
- modifier = Modifier.fillMaxWidth().height(154.dp)
129
- .alpha(opacityAni)
130
- .background(
131
- Brush.linearGradient(
132
- colors = listOf(
133
- Color(0xFFFDCADE),
134
- Color(0x00FDCADE)
135
- ),
136
- start = Offset(0f, 0f),
137
- end = Offset(0f, with(LocalDensity.current) { 154.dp.toPx() })
138
- )
139
- )
140
- ) {
141
- if (AppTheme.current.assets.headerBackground != null) {
142
- Box(
143
- modifier = Modifier.fillMaxWidth()
144
- .background(backgroundColor)
145
- ) {
146
- Image(
147
- loading = false,
148
- source = AppTheme.current.assets.headerBackground!!,
149
- modifier = Modifier.fillMaxWidth().height(154.dp),
150
- options = Options(
151
- contentScale = ContentScale.FillWidth
152
- )
153
- )
154
- }
155
- }
156
- }
157
- }
158
-
159
- else -> {
160
- Box(modifier = Modifier.fillMaxWidth())
161
- }
162
- }
163
-
164
- }
165
-
166
54
  @Composable
167
55
  fun Header(
168
56
  headerType: HeaderType = HeaderType.DEFAULT,
@@ -173,11 +61,13 @@ fun Header(
173
61
  opacity: Float? = null,
174
62
  animatedHeader: AnimatedHeader? = null,
175
63
  scrollState: Int = 0,
176
- inputSearchProps: InputSearchProps?
64
+ inputSearchProps: InputSearchProps? = null,
65
+ useAnimationSearch: Boolean = false
177
66
  ) {
178
67
  val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
179
68
  val tintIconColor = AppTheme.current.colors.text.default
180
69
  val backgroundButton = Colors.black_01.copy(alpha = 0.6f)
70
+ val miniAppContext = ApplicationContext.current
181
71
 
182
72
  var colorFraction by remember { mutableStateOf(0f) }
183
73
 
@@ -242,10 +132,12 @@ fun Header(
242
132
  }
243
133
  }
244
134
 
245
- Box(Modifier.graphicsLayer {
246
- alpha = if (animatedHeader !== null) opacity ?: 1f else 1f
247
- }) {
248
- headerRight?.invoke()
135
+ if (inputSearchProps == null && miniAppContext != null) {
136
+ Box(Modifier.graphicsLayer {
137
+ alpha = if (animatedHeader !== null) opacity ?: 1f else 1f
138
+ }) {
139
+ headerRight?.invoke()
140
+ }
249
141
  }
250
142
  }
251
143
 
@@ -259,12 +151,16 @@ fun Header(
259
151
  if (goBack != null && titlePosition == TitlePosition.LEFT) {
260
152
  Spacer(Modifier.width(40.dp))
261
153
  }
262
- if (inputSearchProps != null) {
154
+ if (inputSearchProps != null && !useAnimationSearch) {
263
155
  InputSearch(inputSearchProps = inputSearchProps.copy(backgroundColor = backgroundSearch))
264
156
  } else {
265
157
  Box(
266
158
  Modifier.weight(1f).graphicsLayer {
267
- alpha = if (animatedHeader !== null) opacity ?: 1f else 1f
159
+ alpha = if (useAnimationSearch && inputSearchProps != null) {
160
+ 1f - (opacity ?: 1f)
161
+ } else {
162
+ if (animatedHeader !== null) opacity ?: 1f else 1f
163
+ }
268
164
  },
269
165
  contentAlignment = if (titlePosition == TitlePosition.LEFT) Alignment.TopStart else Alignment.Center
270
166
  ) {
@@ -282,22 +178,6 @@ fun Header(
282
178
  }
283
179
  }
284
180
 
285
- @Composable
286
- fun HeaderTitle(
287
- title: String = "",
288
- modifier: Modifier = Modifier,
289
- textAlign: TextAlign = TextAlign.Start,
290
- color: Color? = null,
291
- ) {
292
- Text(
293
- modifier = Modifier.then(modifier).zIndex(1f),
294
- text = title,
295
- textAlign = textAlign,
296
- style = Typography.actionS,
297
- color = color,
298
- maxLines = 1
299
- )
300
- }
301
181
 
302
182
  fun animateColor(start: Color, stop: Color, fraction: Float): Color {
303
183
  return Color(
@@ -306,4 +186,4 @@ fun animateColor(start: Color, stop: Color, fraction: Float): Color {
306
186
  blue = start.blue + fraction * (stop.blue - start.blue),
307
187
  alpha = start.alpha + fraction * (stop.alpha - start.alpha)
308
188
  )
309
- }
189
+ }
@@ -0,0 +1,70 @@
1
+ package vn.momo.kits.application
2
+
3
+ import androidx.compose.foundation.layout.Box
4
+ import androidx.compose.foundation.layout.fillMaxWidth
5
+ import androidx.compose.runtime.Composable
6
+ import androidx.compose.ui.Modifier
7
+ import androidx.compose.ui.graphics.Color
8
+ import androidx.compose.ui.unit.Dp
9
+ import androidx.compose.ui.unit.dp
10
+ import vn.momo.kits.components.InputSearchProps
11
+ import vn.momo.kits.const.AppStatusBar
12
+ import vn.momo.kits.const.AppTheme
13
+ import vn.momo.kits.platform.getScreenDimensions
14
+ import vn.momo.kits.platform.getStatusBarHeight
15
+
16
+ private const val SCREEN_PADDING = 12
17
+ private const val BACK_WIDTH = 28
18
+
19
+ @Composable
20
+ fun HeaderBackground(
21
+ isBack: Boolean = true,
22
+ headerType: HeaderType = HeaderType.DEFAULT,
23
+ scrollState: Int,
24
+ inputSearchProps: InputSearchProps? = null,
25
+ headerRightWidth: Dp = 0.dp,
26
+ useAnimationSearch: Boolean = false
27
+ ) {
28
+ val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
29
+ val screenWidth = getScreenDimensions().width
30
+ val leftPosition = if (isBack) (BACK_WIDTH + 20).dp else 20.dp
31
+ val searchWidth = screenWidth - (SCREEN_PADDING * 2)
32
+
33
+ val animations = useHeaderSearchAnimation(
34
+ scrollState = scrollState,
35
+ statusBarHeight = statusBarHeight,
36
+ leftPosition = leftPosition,
37
+ searchWidth = searchWidth,
38
+ headerRightWidth = headerRightWidth
39
+ )
40
+
41
+ val backgroundColor = if (scrollState == 0) {
42
+ Color.Transparent
43
+ } else {
44
+ AppTheme.current.colors.background.surface
45
+ }
46
+
47
+ when (headerType) {
48
+ HeaderType.DEFAULT -> {
49
+ val height = statusBarHeight + 52.dp
50
+ HeaderDefault(
51
+ height = height,
52
+ animations = animations,
53
+ backgroundColor = backgroundColor
54
+ )
55
+ }
56
+
57
+ HeaderType.EXTENDED -> {
58
+ HeaderExtended(
59
+ animations = animations,
60
+ inputSearchProps = inputSearchProps,
61
+ useAnimationSearch = useAnimationSearch,
62
+ backgroundColor = backgroundColor
63
+ )
64
+ }
65
+
66
+ else -> {
67
+ Box(modifier = Modifier.fillMaxWidth())
68
+ }
69
+ }
70
+ }
@@ -0,0 +1,63 @@
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.runtime.Composable
8
+ import androidx.compose.ui.Modifier
9
+ import androidx.compose.ui.draw.alpha
10
+ import androidx.compose.ui.geometry.Offset
11
+ import androidx.compose.ui.graphics.Brush
12
+ import androidx.compose.ui.graphics.Color
13
+ import androidx.compose.ui.layout.ContentScale
14
+ import androidx.compose.ui.platform.LocalDensity
15
+ import androidx.compose.ui.unit.Dp
16
+ import androidx.compose.ui.unit.dp
17
+ import vn.momo.kits.components.Image
18
+ import vn.momo.kits.components.Options
19
+ import vn.momo.kits.const.AppTheme
20
+ import vn.momo.kits.utils.bottomBorder
21
+
22
+ @Composable
23
+ fun HeaderDefault(
24
+ height: Dp,
25
+ backgroundColor: Color,
26
+ animations: HeaderAnimations
27
+ ) {
28
+ Box(
29
+ modifier = Modifier.fillMaxWidth().height(height)
30
+ .background(backgroundColor)
31
+ .bottomBorder(
32
+ strokeWidth = 1.dp,
33
+ color = AppTheme.current.colors.border.default
34
+ )
35
+ ) {
36
+ Box(
37
+ modifier = Modifier
38
+ .height(height)
39
+ .fillMaxWidth()
40
+ .alpha(animations.opacity)
41
+ .background(
42
+ Brush.linearGradient(
43
+ colors = listOf(
44
+ Color(0xFFFDCADE),
45
+ Color(0x00FDCADE)
46
+ ),
47
+ start = Offset(0f, 0f),
48
+ end = Offset(0f, with(LocalDensity.current) { 154.dp.toPx() })
49
+ )
50
+ )
51
+ )
52
+ if (AppTheme.current.assets.headerBackground != null) {
53
+ Image(
54
+ loading = false,
55
+ source = AppTheme.current.assets.headerBackground!!,
56
+ modifier = Modifier.fillMaxWidth().height(height),
57
+ options = Options(
58
+ contentScale = ContentScale.FillWidth
59
+ )
60
+ )
61
+ }
62
+ }
63
+ }
@@ -0,0 +1,102 @@
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.Alignment
13
+ import androidx.compose.ui.Modifier
14
+ import androidx.compose.ui.draw.alpha
15
+ import androidx.compose.ui.geometry.Offset
16
+ import androidx.compose.ui.graphics.Brush
17
+ import androidx.compose.ui.graphics.Color
18
+ import androidx.compose.ui.layout.ContentScale
19
+ import androidx.compose.ui.platform.LocalDensity
20
+ import androidx.compose.ui.unit.dp
21
+ import vn.momo.kits.components.Image
22
+ import vn.momo.kits.components.InputSearch
23
+ import vn.momo.kits.components.InputSearchProps
24
+ import vn.momo.kits.components.Options
25
+ import vn.momo.kits.const.AppTheme
26
+ import vn.momo.kits.const.Radius
27
+ import vn.momo.kits.const.Spacing
28
+
29
+ @Composable
30
+ fun HeaderExtended(
31
+ animations: HeaderAnimations,
32
+ inputSearchProps: InputSearchProps? = null,
33
+ useAnimationSearch: Boolean = false,
34
+ backgroundColor: Color = Color.Transparent
35
+ ){
36
+ Box(
37
+ modifier = Modifier.fillMaxWidth().height(animations.height.dp)
38
+ ) {
39
+ Box(
40
+ modifier = Modifier
41
+ .fillMaxWidth()
42
+ .height(154.dp)
43
+ .alpha(animations.opacity)
44
+ .background(
45
+ Brush.linearGradient(
46
+ colors = listOf(
47
+ Color(0xFFFDCADE),
48
+ Color(0x00FDCADE)
49
+ ),
50
+ start = Offset(0f, 0f),
51
+ end = Offset(0f, with(LocalDensity.current) { 154.dp.toPx() })
52
+ )
53
+ )
54
+ ) {
55
+ if (AppTheme.current.assets.headerBackground != null) {
56
+ Box(
57
+ modifier = Modifier
58
+ .fillMaxWidth()
59
+ .background(backgroundColor)
60
+ ) {
61
+ Image(
62
+ loading = false,
63
+ source = AppTheme.current.assets.headerBackground!!,
64
+ modifier = Modifier.fillMaxWidth().height(154.dp),
65
+ options = Options(
66
+ contentScale = ContentScale.FillWidth
67
+ )
68
+ )
69
+ }
70
+ }
71
+ }
72
+
73
+ if (inputSearchProps != null && useAnimationSearch) {
74
+ Box(
75
+ modifier = Modifier
76
+ .height(52.dp)
77
+ .offset(
78
+ x = animations.translateX.dp
79
+ )
80
+ .padding(vertical = Spacing.S)
81
+ .align(Alignment.BottomStart)
82
+ ) {
83
+ Box(
84
+ modifier = Modifier
85
+ .width(animations.width.dp)
86
+ .background(
87
+ color = animations.backgroundSearch,
88
+ shape = RoundedCornerShape(Radius.XL)
89
+ )
90
+ ) {
91
+ InputSearch(
92
+ inputSearchProps = inputSearchProps.copy(
93
+ showButtonText = false,
94
+ backgroundColor = Color.Transparent
95
+ )
96
+ )
97
+ }
98
+ }
99
+ }
100
+ }
101
+ }
102
+