@momo-kits/native-kits 0.113.3-beta.1 → 0.113.3-beta.2

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.
@@ -0,0 +1,58 @@
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
+ }
@@ -26,6 +26,7 @@ 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
29
30
  import androidx.compose.ui.unit.dp
30
31
  import androidx.compose.ui.zIndex
31
32
  import kotlinx.coroutines.flow.distinctUntilChanged
@@ -47,10 +48,11 @@ fun Header(
47
48
  title: String,
48
49
  headerRight: @Composable (() -> Unit)? = null,
49
50
  goBack: (() -> Unit)? = null,
50
- opacity: Float? = null,
51
+ opacity: Float = 1f,
51
52
  animatedHeader: AnimatedHeader? = null,
52
53
  scrollState: Int = 0,
53
54
  inputSearchProps: InputSearchProps? = null,
55
+ headerRightWidth: Dp = 0.dp,
54
56
  useAnimationSearch: Boolean = false
55
57
  ) {
56
58
  val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
@@ -65,6 +67,12 @@ fun Header(
65
67
  .distinctUntilChanged()
66
68
  .collect { fraction -> colorFraction = fraction }
67
69
  }
70
+ val animations = useHeaderSearchAnimation(
71
+ opacityAni = opacity,
72
+ scrollState = scrollState,
73
+ headerRightWidth = headerRightWidth,
74
+ isBack = goBack != null
75
+ )
68
76
 
69
77
  val backgroundSearch = animateColor(
70
78
  Colors.black_01,
@@ -72,6 +80,9 @@ fun Header(
72
80
  colorFraction
73
81
  )
74
82
 
83
+ val searchAnimationEnable =
84
+ inputSearchProps != null && useAnimationSearch && headerType == HeaderType.EXTENDED
85
+
75
86
  if (headerType != HeaderType.NONE) {
76
87
  BoxWithConstraints(
77
88
  Modifier.height(statusBarHeight + 52.dp)
@@ -120,7 +131,7 @@ fun Header(
120
131
 
121
132
  if (useAnimationSearch || inputSearchProps == null) {
122
133
  Box(Modifier.graphicsLayer {
123
- alpha = if (animatedHeader !== null) opacity ?: 1f else 1f
134
+ alpha = if (animatedHeader !== null) opacity else 1f
124
135
  }) {
125
136
  headerRight?.invoke()
126
137
  }
@@ -142,15 +153,10 @@ fun Header(
142
153
  } else {
143
154
  Box(
144
155
  Modifier.weight(1f).graphicsLayer {
145
- alpha = if (useAnimationSearch) {
146
- 1f - (opacity ?: 1f)
147
- } else {
148
- if (animatedHeader !== null) opacity ?: 1f else 1f
149
- }
156
+ alpha = if (searchAnimationEnable) 1f - (opacity) else 1f
150
157
  },
151
158
  contentAlignment = if (titlePosition == TitlePosition.LEFT) Alignment.TopStart else Alignment.Center
152
159
  ) {
153
-
154
160
  HeaderTitle(
155
161
  title = title,
156
162
  color = tintIconColor,
@@ -161,6 +167,13 @@ fun Header(
161
167
  }
162
168
  }
163
169
  }
170
+
171
+ if (searchAnimationEnable) {
172
+ AnimationSearchInput(
173
+ animations = animations,
174
+ inputSearchProps = inputSearchProps!!
175
+ )
176
+ }
164
177
  }
165
178
  }
166
179
  }
@@ -10,7 +10,6 @@ import androidx.compose.ui.Modifier
10
10
  import androidx.compose.ui.graphics.Color
11
11
  import androidx.compose.ui.unit.Dp
12
12
  import androidx.compose.ui.unit.dp
13
- import vn.momo.kits.components.InputSearchProps
14
13
  import vn.momo.kits.const.AppStatusBar
15
14
  import vn.momo.kits.const.AppTheme
16
15
  import vn.momo.kits.platform.getStatusBarHeight
@@ -35,12 +34,8 @@ fun animateColor(start: Color, stop: Color, fraction: Float): Color {
35
34
 
36
35
  @Composable
37
36
  fun HeaderBackground(
38
- isBack: Boolean = true,
39
37
  headerType: HeaderType = HeaderType.DEFAULT,
40
38
  scrollState: Int,
41
- inputSearchProps: InputSearchProps? = null,
42
- headerRightWidth: Dp = 0.dp,
43
- useAnimationSearch: Boolean = false
44
39
  ) {
45
40
  val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
46
41
 
@@ -66,12 +61,7 @@ fun HeaderBackground(
66
61
 
67
62
  HeaderType.EXTENDED -> {
68
63
  HeaderExtended(
69
- scrollState = scrollState,
70
- inputSearchProps = inputSearchProps,
71
- headerRightWidth = headerRightWidth,
72
- useAnimationSearch = useAnimationSearch,
73
64
  opacityAni = opacityAni,
74
- isBack = isBack,
75
65
  statusBarHeight = statusBarHeight,
76
66
  backgroundColor = backgroundColor,
77
67
  )
@@ -37,100 +37,54 @@ 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,
45
40
  statusBarHeight: Dp,
46
41
  backgroundColor: Color
47
42
  ) {
48
- val animations = useHeaderSearchAnimation(
49
- opacityAni = opacityAni,
50
- scrollState = scrollState,
51
- headerRightWidth = headerRightWidth,
52
- statusBarHeight = statusBarHeight,
53
- isBack = isBack
54
- )
55
-
56
43
  Box(
57
- modifier = Modifier.fillMaxWidth()
58
- .height(animations.height.dp)
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
44
+ modifier = Modifier
45
+ .fillMaxWidth()
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() })
105
56
  )
106
- )
107
- if (inputSearchProps != null && useAnimationSearch) {
57
+ )
58
+ ) {
59
+ if (AppTheme.current.assets.headerBackground != null) {
108
60
  Box(
109
61
  modifier = Modifier
110
- .height(52.dp)
111
- .offset(
112
- x = animations.translateX.dp
113
- )
114
- .padding(vertical = Spacing.S)
115
- .align(Alignment.BottomStart)
116
- .zIndex(1f)
62
+ .fillMaxWidth()
63
+ .background(backgroundColor)
117
64
  ) {
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
- )
65
+ Image(
66
+ loading = false,
67
+ source = AppTheme.current.assets.headerBackground!!,
68
+ modifier = Modifier.fillMaxWidth().height(154.dp),
69
+ options = Options(
70
+ contentScale = ContentScale.FillWidth
131
71
  )
132
- }
72
+ )
133
73
  }
134
74
  }
135
75
  }
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
+ )
136
90
  }
@@ -50,7 +50,6 @@ enum class HeaderType {
50
50
  @Composable
51
51
  fun Screen(
52
52
  backgroundColor: Color? = null,
53
- isBack: Boolean = true,
54
53
  headerType: HeaderType = HeaderType.DEFAULT,
55
54
  verticalArrangement: Arrangement.Vertical = Arrangement.Top,
56
55
  horizontalAlignment: Alignment.Horizontal = Alignment.Start,
@@ -64,8 +63,6 @@ fun Screen(
64
63
  footer: @Composable (() -> Unit)? = null,
65
64
  headerRight: @Composable (() -> Unit)? = { HeaderRight() },
66
65
  fabProps: FabProps? = null,
67
- animatedHeader: AnimatedHeader? = null,
68
- layoutOffset: Dp = 56.dp,
69
66
  inputSearchProps: InputSearchProps? = null,
70
67
  useAnimationSearch: Boolean = false,
71
68
  headerRightWidth: Dp = 0.dp,
@@ -88,49 +85,23 @@ fun Screen(
88
85
  targetValue = ((scrollState.value / 52f)).coerceIn(0f, 1f),
89
86
  )
90
87
 
91
- val headerAnimated =
92
- @Composable {
93
- animatedHeader?.composable?.invoke(scrollState.value)
94
- }
95
-
96
88
  Box(
97
89
  Modifier.fillMaxSize()
98
90
  .background(backgroundColor ?: AppTheme.current.colors.background.default)
99
91
  ) {
100
92
 
101
- if (animatedHeader === null) {
102
- HeaderBackground(
103
- headerType = headerType,
104
- scrollState = scrollState.value,
105
- inputSearchProps= inputSearchProps,
106
- useAnimationSearch = useAnimationSearch,
107
- headerRightWidth = headerRightWidth
108
- )
109
- } else {
110
- Box(
111
- Modifier.zIndex(2f)
112
- .background(Color.White.copy(alpha = opacity))
113
- .graphicsLayer { alpha = opacity }
114
- ) {
115
- HeaderBackground(
116
- isBack = isBack,
117
- headerType = headerType,
118
- scrollState = scrollState.value,
119
- inputSearchProps= inputSearchProps,
120
- useAnimationSearch = useAnimationSearch,
121
- headerRightWidth = headerRightWidth
122
- )
123
- }
124
- }
125
-
93
+ HeaderBackground(
94
+ headerType = headerType,
95
+ scrollState = scrollState.value,
96
+ )
126
97
  Header(
127
98
  headerType = headerType,
128
99
  title = title,
129
100
  titlePosition = titlePosition,
130
101
  headerRight = headerRight,
102
+ headerRightWidth = headerRightWidth,
131
103
  goBack = goBack,
132
104
  opacity = opacity,
133
- animatedHeader = animatedHeader,
134
105
  inputSearchProps = inputSearchProps,
135
106
  scrollState = scrollState.value,
136
107
  useAnimationSearch = useAnimationSearch,
@@ -138,7 +109,7 @@ fun Screen(
138
109
 
139
110
  Column(
140
111
  modifier = Modifier.fillMaxSize()
141
- .padding(top = if (animatedHeader === null && headerType !== HeaderType.NONE) statusBarHeight + 52.dp else 0.dp)
112
+ .padding(top = if (headerType !== HeaderType.NONE) statusBarHeight + 52.dp else 0.dp)
142
113
  .pointerInput(Unit) {
143
114
  detectTapGestures(onTap = {
144
115
  keyboardController?.hide()
@@ -146,7 +117,6 @@ fun Screen(
146
117
  }
147
118
  .zIndex(1f),
148
119
  ) {
149
-
150
120
  Column(
151
121
  modifier = Modifier
152
122
  .conditional(scrollable) { weight(1f) }
@@ -159,12 +129,7 @@ fun Screen(
159
129
  horizontalAlignment = horizontalAlignment
160
130
  ) {
161
131
  Box {
162
- headerAnimated()
163
132
  Column {
164
- if (animatedHeader !== null) {
165
- Spacer(modifier = Modifier.padding(top = statusBarHeight + 52.dp + layoutOffset))
166
- }
167
-
168
133
  if (useAnimationSearch && inputSearchProps != null && headerType == HeaderType.EXTENDED) {
169
134
  Spacer(modifier = Modifier.padding(top = statusBarHeight))
170
135
  }
@@ -16,7 +16,7 @@ data class HeaderAnimations(
16
16
  val backgroundSearch: Color,
17
17
  val translateX: Float,
18
18
  val width: Float,
19
- val height: Float
19
+ val translateY: Float
20
20
  )
21
21
 
22
22
  private const val SCREEN_PADDING = 12
@@ -27,17 +27,16 @@ fun useHeaderSearchAnimation(
27
27
  opacityAni: Float,
28
28
  scrollState: Int,
29
29
  headerRightWidth: Dp,
30
- statusBarHeight: Dp,
31
30
  isBack: Boolean
32
31
  ): HeaderAnimations {
33
32
  val screenWidth = getScreenDimensions().width
34
- val leftPosition = if (isBack) (BACK_WIDTH + 20).dp else 20.dp
33
+ val leftPosition = if (isBack) (BACK_WIDTH + 20).dp else 12.dp
35
34
  val searchWidth = screenWidth - (SCREEN_PADDING * 2)
36
35
 
37
36
  val backgroundSearch by animateColorAsState(
38
37
  targetValue = animateColor(
39
- AppTheme.current.colors.background.default,
40
38
  Colors.black_01,
39
+ AppTheme.current.colors.background.default,
41
40
  opacityAni
42
41
  ),
43
42
  )
@@ -53,17 +52,14 @@ fun useHeaderSearchAnimation(
53
52
  ) * ((searchWidth - leftPosition.value - headerRightWidth.value + 12) - searchWidth) + searchWidth,
54
53
  )
55
54
 
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),
55
+ val animatedTranslateY by animateFloatAsState(
56
+ targetValue = (1 - (scrollState / 52f).coerceIn(0f, 1f)) * 52
61
57
  )
62
58
  return HeaderAnimations(
63
59
  opacity = opacityAni,
64
60
  backgroundSearch = backgroundSearch,
65
61
  translateX = animatedTranslateX,
66
62
  width = animatedWidth,
67
- height = animatedHeight
63
+ translateY = animatedTranslateY
68
64
  )
69
65
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.113.3-beta.1",
3
+ "version": "0.113.3-beta.2",
4
4
  "private": false,
5
5
  "dependencies": {},
6
6
  "devDependencies": {},