@momo-kits/native-kits 0.113.3-beta.5 → 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.
@@ -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 = 1f,
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,18 +72,15 @@ 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
- Modifier.height(statusBarHeight + HEADER_HEIGHT.dp)
77
+ Modifier.height(statusBarHeight + 52.dp)
89
78
  .fillMaxWidth()
90
79
  .zIndex(10f),
91
80
  contentAlignment = Alignment.BottomCenter
92
81
  ) {
93
82
  Row(
94
- modifier = Modifier.height(HEADER_HEIGHT.dp)
83
+ modifier = Modifier.height(52.dp)
95
84
  .fillMaxWidth()
96
85
  .padding(horizontal = Spacing.M),
97
86
  verticalAlignment = Alignment.CenterVertically,
@@ -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
  }
@@ -140,7 +129,7 @@ fun Header(
140
129
 
141
130
  // Title
142
131
  Row(
143
- modifier = Modifier.height(HEADER_HEIGHT.dp)
132
+ modifier = Modifier.height(52.dp)
144
133
  .fillMaxWidth()
145
134
  .padding(horizontal = Spacing.M),
146
135
  verticalAlignment = Alignment.CenterVertically,
@@ -154,9 +143,9 @@ fun Header(
154
143
  Box(
155
144
  Modifier.weight(1f).graphicsLayer {
156
145
  alpha = if (useAnimationSearch) {
157
- 1f - (opacity)
146
+ 1f - (opacity ?: 1f)
158
147
  } else {
159
- if (animatedHeader !== null) opacity else 1f
148
+ if (animatedHeader !== null) opacity ?: 1f else 1f
160
149
  }
161
150
  },
162
151
  contentAlignment = if (titlePosition == TitlePosition.LEFT) Alignment.TopStart else Alignment.Center
@@ -172,13 +161,6 @@ fun Header(
172
161
  }
173
162
  }
174
163
  }
175
-
176
- if (searchAnimationEnable) {
177
- AnimationSearchInput(
178
- animations = animations,
179
- inputSearchProps = inputSearchProps!!
180
- )
181
- }
182
164
  }
183
165
  }
184
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,13 +35,17 @@ 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
 
40
47
  val opacityAni by animateFloatAsState(
41
- targetValue = (1 - (scrollState / HEADER_HEIGHT*1f)).coerceIn(0f, 1f),
48
+ targetValue = (1 - (scrollState / 52f)).coerceIn(0f, 1f),
42
49
  )
43
50
 
44
51
  val backgroundColor by animateColorAsState(
@@ -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
  )
@@ -24,7 +24,7 @@ fun HeaderDefault(
24
24
  opacityAni: Float,
25
25
  statusBarHeight: Dp,
26
26
  ) {
27
- val height = statusBarHeight + HEADER_HEIGHT.dp
27
+ val height = statusBarHeight + 52.dp
28
28
  Box(
29
29
  modifier = Modifier.fillMaxWidth().height(height)
30
30
  .background(AppTheme.current.colors.background.surface)
@@ -1,10 +1,18 @@
1
1
  package vn.momo.kits.application
2
2
 
3
+ import androidx.compose.animation.animateColorAsState
4
+ import androidx.compose.animation.core.animateFloatAsState
3
5
  import androidx.compose.foundation.background
4
6
  import androidx.compose.foundation.layout.Box
5
7
  import androidx.compose.foundation.layout.fillMaxWidth
6
8
  import androidx.compose.foundation.layout.height
9
+ import androidx.compose.foundation.layout.offset
10
+ import androidx.compose.foundation.layout.padding
11
+ import androidx.compose.foundation.layout.width
12
+ import androidx.compose.foundation.shape.RoundedCornerShape
7
13
  import androidx.compose.runtime.Composable
14
+ import androidx.compose.runtime.getValue
15
+ import androidx.compose.ui.Alignment
8
16
  import androidx.compose.ui.Modifier
9
17
  import androidx.compose.ui.draw.alpha
10
18
  import androidx.compose.ui.geometry.Offset
@@ -14,62 +22,115 @@ import androidx.compose.ui.layout.ContentScale
14
22
  import androidx.compose.ui.platform.LocalDensity
15
23
  import androidx.compose.ui.unit.Dp
16
24
  import androidx.compose.ui.unit.dp
25
+ import androidx.compose.ui.zIndex
17
26
  import vn.momo.kits.components.Image
27
+ import vn.momo.kits.components.InputSearch
28
+ import vn.momo.kits.components.InputSearchProps
18
29
  import vn.momo.kits.components.Options
19
30
  import vn.momo.kits.const.AppTheme
31
+ import vn.momo.kits.const.Colors
32
+ import vn.momo.kits.const.Radius
33
+ import vn.momo.kits.const.Spacing
34
+ import vn.momo.kits.platform.getScreenDimensions
20
35
  import vn.momo.kits.utils.bottomBorder
21
36
 
22
37
  @Composable
23
38
  fun HeaderExtended(
24
39
  opacityAni: Float,
40
+ inputSearchProps: InputSearchProps?,
41
+ useAnimationSearch: Boolean = true,
42
+ scrollState: Int,
43
+ headerRightWidth: Dp,
44
+ isBack: Boolean,
25
45
  statusBarHeight: Dp,
26
46
  backgroundColor: Color
27
47
  ) {
48
+ val animations = useHeaderSearchAnimation(
49
+ opacityAni = opacityAni,
50
+ scrollState = scrollState,
51
+ headerRightWidth = headerRightWidth,
52
+ statusBarHeight = statusBarHeight,
53
+ isBack = isBack
54
+ )
55
+
28
56
  Box(
29
- modifier = Modifier
30
- .fillMaxWidth()
31
- .height(154.dp)
32
- .alpha(opacityAni)
33
- .background(
34
- Brush.linearGradient(
35
- colors = listOf(
36
- Color(0xFFFDCADE),
37
- Color(0x00FDCADE)
38
- ),
39
- start = Offset(0f, 0f),
40
- end = Offset(0f, with(LocalDensity.current) { 154.dp.toPx() })
41
- )
42
- )
57
+ modifier = Modifier.fillMaxWidth()
58
+ .height(animations.height.dp)
43
59
  ) {
44
- if (AppTheme.current.assets.headerBackground != null) {
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) {
45
108
  Box(
46
109
  modifier = Modifier
47
- .fillMaxWidth()
48
- .background(backgroundColor)
110
+ .height(52.dp)
111
+ .offset(
112
+ x = animations.translateX.dp
113
+ )
114
+ .padding(vertical = Spacing.S)
115
+ .align(Alignment.BottomStart)
116
+ .zIndex(1f)
49
117
  ) {
50
- Image(
51
- loading = false,
52
- source = AppTheme.current.assets.headerBackground!!,
53
- modifier = Modifier.fillMaxWidth().height(154.dp),
54
- options = Options(
55
- contentScale = ContentScale.FillWidth
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
+ )
56
131
  )
57
- )
132
+ }
58
133
  }
59
134
  }
60
135
  }
61
-
62
- Box(
63
- modifier = Modifier
64
- .fillMaxWidth()
65
- .alpha(1f - opacityAni)
66
- .height(statusBarHeight + HEADER_HEIGHT.dp)
67
- .background(
68
- AppTheme.current.colors.background.surface
69
- )
70
- .bottomBorder(
71
- strokeWidth = 1.dp,
72
- color = AppTheme.current.colors.border.default
73
- )
74
- )
75
136
  }
@@ -47,8 +47,6 @@ enum class HeaderType {
47
47
  NONE
48
48
  }
49
49
 
50
- const val HEADER_HEIGHT = 52
51
-
52
50
  @Composable
53
51
  fun Screen(
54
52
  backgroundColor: Color? = null,
@@ -87,7 +85,7 @@ fun Screen(
87
85
  val bottomPadding = min(indicator, 21.dp)
88
86
 
89
87
  val opacity by animateFloatAsState(
90
- targetValue = ((scrollState.value / HEADER_HEIGHT*1f)).coerceIn(0f, 1f),
88
+ targetValue = ((scrollState.value / 52f)).coerceIn(0f, 1f),
91
89
  )
92
90
 
93
91
  val headerAnimated =
@@ -103,7 +101,10 @@ fun Screen(
103
101
  if (animatedHeader === null) {
104
102
  HeaderBackground(
105
103
  headerType = headerType,
106
- scrollState = scrollState.value
104
+ scrollState = scrollState.value,
105
+ inputSearchProps= inputSearchProps,
106
+ useAnimationSearch = useAnimationSearch,
107
+ headerRightWidth = headerRightWidth
107
108
  )
108
109
  } else {
109
110
  Box(
@@ -112,17 +113,21 @@ fun Screen(
112
113
  .graphicsLayer { alpha = opacity }
113
114
  ) {
114
115
  HeaderBackground(
116
+ isBack = isBack,
115
117
  headerType = headerType,
116
- scrollState = scrollState.value
118
+ scrollState = scrollState.value,
119
+ inputSearchProps= inputSearchProps,
120
+ useAnimationSearch = useAnimationSearch,
121
+ headerRightWidth = headerRightWidth
117
122
  )
118
123
  }
119
124
  }
125
+
120
126
  Header(
121
127
  headerType = headerType,
122
128
  title = title,
123
129
  titlePosition = titlePosition,
124
130
  headerRight = headerRight,
125
- headerRightWidth = headerRightWidth,
126
131
  goBack = goBack,
127
132
  opacity = opacity,
128
133
  animatedHeader = animatedHeader,
@@ -133,7 +138,7 @@ fun Screen(
133
138
 
134
139
  Column(
135
140
  modifier = Modifier.fillMaxSize()
136
- .padding(top = if (animatedHeader === null && headerType !== HeaderType.NONE) statusBarHeight + HEADER_HEIGHT.dp else 0.dp)
141
+ .padding(top = if (animatedHeader === null && headerType !== HeaderType.NONE) statusBarHeight + 52.dp else 0.dp)
137
142
  .pointerInput(Unit) {
138
143
  detectTapGestures(onTap = {
139
144
  keyboardController?.hide()
@@ -157,11 +162,11 @@ fun Screen(
157
162
  headerAnimated()
158
163
  Column {
159
164
  if (animatedHeader !== null) {
160
- Spacer(modifier = Modifier.padding(top = statusBarHeight + HEADER_HEIGHT.dp + layoutOffset))
165
+ Spacer(modifier = Modifier.padding(top = statusBarHeight + 52.dp + layoutOffset))
161
166
  }
162
167
 
163
168
  if (useAnimationSearch && inputSearchProps != null && headerType == HeaderType.EXTENDED) {
164
- Spacer(modifier = Modifier.padding(top = (HEADER_HEIGHT.dp + Spacing.M)))
169
+ Spacer(modifier = Modifier.padding(top = statusBarHeight))
165
170
  }
166
171
  content()
167
172
  }
@@ -16,7 +16,7 @@ data class HeaderAnimations(
16
16
  val backgroundSearch: Color,
17
17
  val translateX: Float,
18
18
  val width: Float,
19
- val translateY: Float
19
+ val height: Float
20
20
  )
21
21
 
22
22
  private const val SCREEN_PADDING = 12
@@ -27,39 +27,43 @@ 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 12.dp
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
  )
43
44
 
44
45
  val animatedTranslateX by animateFloatAsState(
45
- targetValue = (scrollState / HEADER_HEIGHT*1f).coerceIn(0f, 1f) * (leftPosition.value - 12) + 12,
46
+ targetValue = (scrollState / 52f).coerceIn(0f, 1f) * (leftPosition.value - 12) + 12,
46
47
  )
47
48
 
48
49
  val animatedWidth by animateFloatAsState(
49
- targetValue = (scrollState / HEADER_HEIGHT*1f).coerceIn(
50
+ targetValue = (scrollState / 52f).coerceIn(
50
51
  0f,
51
52
  1f
52
53
  ) * ((searchWidth - leftPosition.value - headerRightWidth.value + 12) - searchWidth) + searchWidth,
53
54
  )
54
55
 
55
- val animatedTranslateY by animateFloatAsState(
56
- targetValue = (1 - (scrollState / HEADER_HEIGHT* 1f).coerceIn(0f, 1f)) * HEADER_HEIGHT
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
- translateY = animatedTranslateY
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 ? .infinity : nil, alignment: titlePosition == .center ? .center : .leading)
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 = .center,
37
+ titlePosition: TitlePosition = .left,
38
38
  goBack: (() -> Void)? = nil,
39
39
  scrollable: Bool = true,
40
40
  onContentLayout: ((CGRect) -> Void)? = nil,
@@ -103,6 +103,8 @@ public struct PopupDisplay: View {
103
103
  }
104
104
  .background(Color.white.cornerRadius(15))
105
105
  .padding(.horizontal, 12)
106
+ .accessibilityElement(children: .ignore)
107
+ .accessibility(identifier: "popup_notify")
106
108
  }
107
109
 
108
110
  // MARK: Internal
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
- #Tue Apr 23 16:40:15 ICT 2024
8
- sdk.dir=/Users/hung.dao1/Library/Android/sdk
7
+ #Thu Jan 09 10:43:10 ICT 2025
8
+ sdk.dir=/Users/sophia/Library/Android/sdk
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.113.3-beta.5",
3
+ "version": "0.113.3-beta.6",
4
4
  "private": false,
5
5
  "dependencies": {},
6
6
  "devDependencies": {},
@@ -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(HEADER_HEIGHT.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
- }