@momo-kits/native-kits 0.152.4-scale.4 → 0.152.5-klib.1

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 (117) hide show
  1. package/README.md +175 -5
  2. package/ios/native-kits.podspec +18 -16
  3. package/package.json +2 -4
  4. package/CODE_OF_CONDUCT.md +0 -133
  5. package/CONTRIBUTING.md +0 -114
  6. package/LICENSE +0 -20
  7. package/build.gradle.kts +0 -32
  8. package/compose/MoMoComposeKits.podspec +0 -54
  9. package/compose/build.gradle.kts +0 -149
  10. package/compose/src/androidMain/AndroidManifest.xml +0 -2
  11. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +0 -105
  12. package/compose/src/commonMain/composeResources/files/lottie_circle_loader.json +0 -1
  13. package/compose/src/commonMain/composeResources/font/momosignature.otf +0 -0
  14. package/compose/src/commonMain/composeResources/font/momotrustdisplay.otf +0 -0
  15. package/compose/src/commonMain/composeResources/font/sfprotext_black.otf +0 -0
  16. package/compose/src/commonMain/composeResources/font/sfprotext_black.ttf +0 -0
  17. package/compose/src/commonMain/composeResources/font/sfprotext_bold.ttf +0 -0
  18. package/compose/src/commonMain/composeResources/font/sfprotext_heavy.ttf +0 -0
  19. package/compose/src/commonMain/composeResources/font/sfprotext_light.ttf +0 -0
  20. package/compose/src/commonMain/composeResources/font/sfprotext_medium.ttf +0 -0
  21. package/compose/src/commonMain/composeResources/font/sfprotext_regular.ttf +0 -0
  22. package/compose/src/commonMain/composeResources/font/sfprotext_semibold.ttf +0 -0
  23. package/compose/src/commonMain/composeResources/font/sfprotext_thin.otf +0 -0
  24. package/compose/src/commonMain/composeResources/font/sfprotext_thin.ttf +0 -0
  25. package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.otf +0 -0
  26. package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.ttf +0 -0
  27. package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +0 -57
  28. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +0 -201
  29. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +0 -222
  30. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +0 -48
  31. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +0 -86
  32. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +0 -76
  33. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +0 -76
  34. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +0 -308
  35. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +0 -33
  36. package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +0 -715
  37. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +0 -214
  38. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +0 -404
  39. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +0 -69
  40. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +0 -78
  41. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +0 -27
  42. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +0 -334
  43. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +0 -345
  44. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -90
  45. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +0 -133
  46. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +0 -543
  47. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +0 -23
  48. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +0 -69
  49. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +0 -143
  50. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +0 -179
  51. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +0 -111
  52. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +0 -395
  53. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +0 -164
  54. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +0 -234
  55. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +0 -226
  56. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +0 -227
  57. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +0 -241
  58. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +0 -235
  59. package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +0 -364
  60. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +0 -50
  61. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +0 -34
  62. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +0 -85
  63. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +0 -33
  64. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +0 -338
  65. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +0 -95
  66. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +0 -64
  67. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +0 -89
  68. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +0 -91
  69. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +0 -86
  70. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +0 -91
  71. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +0 -208
  72. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +0 -172
  73. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +0 -199
  74. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +0 -29
  75. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +0 -237
  76. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +0 -191
  77. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +0 -306
  78. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +0 -12
  79. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +0 -13
  80. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +0 -189
  81. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +0 -293
  82. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +0 -2
  83. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +0 -35
  84. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +0 -2
  85. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +0 -59
  86. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -68
  87. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +0 -11
  88. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +0 -49
  89. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +0 -51
  90. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +0 -232
  91. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +0 -111
  92. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +0 -94
  93. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +0 -159
  94. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +0 -302
  95. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScaleSizeScope.kt +0 -22
  96. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +0 -483
  97. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +0 -169
  98. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +0 -217
  99. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +0 -86
  100. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +0 -180
  101. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +0 -251
  102. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +0 -80
  103. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +0 -306
  104. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +0 -31
  105. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +0 -385
  106. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +0 -125
  107. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -38
  108. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +0 -1329
  109. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +0 -62
  110. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +0 -88
  111. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -144
  112. package/gradle.properties +0 -19
  113. package/gradlew +0 -240
  114. package/gradlew.bat +0 -91
  115. package/ios/Theme.md +0 -18
  116. package/local.properties +0 -8
  117. package/settings.gradle.kts +0 -25
@@ -1,217 +0,0 @@
1
- package vn.momo.kits.navigation.bottomtab
2
-
3
- import androidx.compose.animation.core.FastOutSlowInEasing
4
- import androidx.compose.animation.core.animateDpAsState
5
- import androidx.compose.animation.core.tween
6
- import androidx.compose.foundation.background
7
- import androidx.compose.foundation.border
8
- import androidx.compose.foundation.layout.Arrangement
9
- import androidx.compose.foundation.layout.Box
10
- import androidx.compose.foundation.layout.Column
11
- import androidx.compose.foundation.layout.Row
12
- import androidx.compose.foundation.layout.RowScope
13
- import androidx.compose.foundation.layout.Spacer
14
- import androidx.compose.foundation.layout.fillMaxSize
15
- import androidx.compose.foundation.layout.fillMaxWidth
16
- import androidx.compose.foundation.layout.height
17
- import androidx.compose.foundation.layout.offset
18
- import androidx.compose.foundation.layout.padding
19
- import androidx.compose.foundation.layout.size
20
- import androidx.compose.foundation.layout.width
21
- import androidx.compose.foundation.shape.CircleShape
22
- import androidx.compose.foundation.shape.RoundedCornerShape
23
- import androidx.compose.runtime.Composable
24
- import androidx.compose.runtime.getValue
25
- import androidx.compose.ui.Alignment
26
- import androidx.compose.ui.Modifier
27
- import androidx.compose.ui.draw.clip
28
- import androidx.compose.ui.graphics.Brush
29
- import androidx.compose.ui.graphics.Color
30
- import androidx.compose.ui.text.style.TextAlign
31
- import androidx.compose.ui.text.style.TextOverflow
32
- import androidx.compose.ui.unit.dp
33
- import androidx.navigation.NavController
34
- import androidx.navigation.compose.currentBackStackEntryAsState
35
- import vn.momo.kits.components.Badge
36
- import vn.momo.kits.components.Icon
37
- import vn.momo.kits.components.Text
38
- import vn.momo.kits.const.AppTheme
39
- import vn.momo.kits.const.Colors
40
- import vn.momo.kits.const.Radius
41
- import vn.momo.kits.const.Spacing
42
- import vn.momo.kits.const.Typography
43
- import vn.momo.kits.const.scaleSize
44
- import vn.momo.kits.modifier.noFeedbackClickable
45
- import vn.momo.kits.platform.getScreenDimensions
46
-
47
- val floatingButtonWidth = 75.dp
48
- const val BOTTOM_TAB_BAR_HEIGHT = 56
49
-
50
- @Composable
51
- fun BottomTabBar(
52
- items: List<BottomTabItem>,
53
- floatingButton: BottomTabFloatingButton? = null,
54
- navController: NavController,
55
- onTabSelected: (Int) -> Unit,
56
- ) {
57
- val currentRoute = navController.currentBackStackEntryAsState().value?.destination?.route
58
- val selectedIndex = items.indexOfFirst { "option${items.indexOf(it)}" == currentRoute }
59
-
60
- val screenWidth = getScreenDimensions().width.dp
61
- val mid = items.size / 2
62
-
63
- val tabWidth = if (floatingButton != null) {
64
- (screenWidth - floatingButtonWidth) / items.size
65
- } else {
66
- screenWidth / items.size
67
- }
68
- val adjustSize = if(floatingButton != null && selectedIndex >= mid) floatingButtonWidth else 0.dp
69
- val targetOffset = tabWidth * selectedIndex + tabWidth / 2 - screenWidth / 2 + adjustSize
70
-
71
- val indicatorOffsetX by animateDpAsState(
72
- targetValue = targetOffset,
73
- animationSpec = tween(durationMillis = 250, easing = FastOutSlowInEasing),
74
- label = "IndicatorX"
75
- )
76
- val bottomTabBarHeight = scaleSize(BOTTOM_TAB_BAR_HEIGHT.toFloat())
77
-
78
- Box(
79
- contentAlignment = Alignment.BottomCenter
80
- ) {
81
- Row(
82
- modifier = Modifier
83
- .fillMaxWidth()
84
- .height(BOTTOM_TAB_BAR_HEIGHT.dp)
85
- .background(AppTheme.current.colors.background.surface),
86
- horizontalArrangement = Arrangement.SpaceAround,
87
- ) {
88
- if (floatingButton == null) {
89
- renderTabBarItem(items, 0, items.size, selectedIndex, onTabSelected)
90
- } else {
91
- renderTabBarItem(items, 0, mid, selectedIndex, onTabSelected)
92
- Spacer(modifier = Modifier.width(floatingButtonWidth).padding(horizontal = Spacing.XXS))
93
- renderTabBarItem(items, mid, items.size, selectedIndex, onTabSelected)
94
- }
95
- }
96
-
97
- Box(modifier = Modifier
98
- .offset(x = indicatorOffsetX, y = (-BOTTOM_TAB_BAR_HEIGHT + 2).dp)
99
- .height(2.dp)
100
- .width(44.dp)
101
- .background(
102
- color = AppTheme.current.colors.primary ,
103
- shape = RoundedCornerShape(bottomStart = 2.dp, bottomEnd = 2.dp)
104
- )
105
- )
106
-
107
- Box(modifier = Modifier
108
- .fillMaxWidth()
109
- .height(6.dp)
110
- .offset(x = 0.dp, y = (-BOTTOM_TAB_BAR_HEIGHT).dp)
111
- .background(
112
- brush = Brush.verticalGradient(
113
- colors = listOf(Color.Transparent, Color.Black.copy(alpha = 0.05f))
114
- )
115
- )
116
- )
117
- floatingButton?.let { FloatingButton(it) }
118
- }
119
- }
120
-
121
- @Composable
122
- fun RowScope.renderTabBarItem(
123
- items: List<BottomTabItem>,
124
- fromIndex: Int,
125
- toIndex: Int,
126
- selectedIndex: Int,
127
- onTabSelected: (Int) -> Unit
128
- ){
129
- for (index in fromIndex until toIndex) {
130
- Box(modifier = Modifier.weight(1f)) {
131
- TabBarItem(
132
- item = items[index],
133
- selected = index == selectedIndex,
134
- onClick = { onTabSelected(index) }
135
- )
136
- }
137
- }
138
- }
139
-
140
- @Composable
141
- fun TabBarItem(item: BottomTabItem, selected: Boolean, onClick: () -> Unit) {
142
- Box(modifier = Modifier
143
- .fillMaxSize()
144
- .padding(horizontal = Spacing.XXS)
145
- .noFeedbackClickable {
146
- onClick()
147
- },
148
- contentAlignment = Alignment.BottomStart
149
- ){
150
- Column(
151
- modifier = Modifier
152
- .fillMaxSize()
153
- .padding(horizontal = Spacing.XXS)
154
- .noFeedbackClickable {
155
- onClick()
156
- },
157
- horizontalAlignment = Alignment.CenterHorizontally,
158
- verticalArrangement = Arrangement.Bottom
159
- ) {
160
- Icon(
161
- source = item.icon,
162
- modifier = Modifier.weight(1f),
163
- color = if (selected) AppTheme.current.colors.primary else AppTheme.current.colors.text.hint)
164
- Text(
165
- text = item.label,
166
- color = if (selected) AppTheme.current.colors.primary else AppTheme.current.colors.text.hint,
167
- style = Typography.labelXsMedium,
168
- maxLines = 1,
169
- overflow = TextOverflow.Ellipsis
170
- )
171
- }
172
- if(item.badgeLabel != null){
173
- Box(modifier = Modifier
174
- .offset(x = 44.dp, y = (-32).dp)
175
- ){
176
- Badge(item.badgeLabel)
177
- }
178
- }
179
- }
180
- }
181
-
182
- @Composable
183
- fun FloatingButton(data: BottomTabFloatingButton) {
184
- Column(
185
- modifier = Modifier
186
- .width(floatingButtonWidth)
187
- .padding(horizontal = Spacing.XXS)
188
- .noFeedbackClickable {
189
- data.onPress()
190
- },
191
- verticalArrangement = Arrangement.Bottom,
192
- horizontalAlignment = Alignment.CenterHorizontally
193
-
194
- ){
195
- CurvedContainer()
196
- Box(
197
- modifier = Modifier
198
- .size(48.dp)
199
- .clip(CircleShape)
200
- .background(AppTheme.current.colors.primary),
201
- contentAlignment = Alignment.Center
202
- ) {
203
- Icon(source = data.icon, color = Color.White, size = 28.dp)
204
- }
205
- Spacer(modifier = Modifier.height(4.dp))
206
- Text(
207
- text = data.label,
208
- style = Typography.labelXsMedium,
209
- color = Colors.black_01,
210
- textAlign = TextAlign.Center,
211
- modifier = Modifier
212
- .height(14.dp)
213
- .fillMaxWidth()
214
- .background(AppTheme.current.colors.primary, shape = RoundedCornerShape(size = Radius.XL))
215
- )
216
- }
217
- }
@@ -1,86 +0,0 @@
1
- package vn.momo.kits.navigation.bottomtab
2
-
3
- import androidx.compose.foundation.Canvas
4
- import androidx.compose.foundation.layout.Box
5
- import androidx.compose.foundation.layout.height
6
- import androidx.compose.foundation.layout.offset
7
- import androidx.compose.foundation.layout.width
8
- import androidx.compose.runtime.Composable
9
- import androidx.compose.ui.Alignment
10
- import androidx.compose.ui.Modifier
11
- import androidx.compose.ui.graphics.Path
12
- import androidx.compose.ui.platform.LocalDensity
13
- import androidx.compose.ui.unit.Dp
14
- import androidx.compose.ui.unit.IntOffset
15
- import androidx.compose.ui.unit.dp
16
- import androidx.compose.ui.zIndex
17
- import vn.momo.kits.const.AppTheme
18
-
19
- @Composable
20
- fun CurvedContainer(
21
- circleSize: Dp = 48.dp,
22
- tabBarItemIconSize: Dp = 28.dp,
23
- circleOverSize: Dp = 2.dp,
24
- width: Dp = 71.dp,
25
- height: Dp = 16.dp
26
- ) {
27
- val theme = AppTheme.current
28
- val density = LocalDensity.current
29
- val widthPx = with(density) { width.toPx()}
30
-
31
- val circleSizePx = with(density) { circleSize.toPx() }
32
- val tabBarItemIconSizePx = with(density) { tabBarItemIconSize.toPx() }
33
- val circleOverSizePx = with(density) { circleOverSize.toPx() }
34
-
35
- val circlePositionTop = circleSizePx - tabBarItemIconSizePx - 10f
36
- val circleOverTop = circlePositionTop + circleOverSizePx
37
- val circleR = circleSizePx / 2
38
- val circleOverR = circleR + circleOverSizePx
39
-
40
- val centerX = widthPx / 2
41
-
42
- val curvedPath = getPath(
43
- circleOverTop = circleOverTop,
44
- centerX = centerX,
45
- circleOverR = circleOverR,
46
- widthPx = widthPx
47
- )
48
-
49
- Box(
50
- contentAlignment = Alignment.BottomCenter
51
- ){
52
- Canvas(
53
- modifier = Modifier
54
- .width(width)
55
- .height(height)
56
- .offset{ IntOffset(x = 0, y = 24) }
57
- .zIndex(-1f)
58
- ) {
59
- drawPath(path = curvedPath, color = theme.colors.background.surface)
60
- }
61
- }
62
- }
63
-
64
- private fun getPath(circleOverTop: Float, centerX: Float, circleOverR: Float, widthPx: Float): Path{
65
- return Path().apply {
66
- moveTo(0f, circleOverTop)
67
- lineTo(centerX - circleOverR - 40f, circleOverTop)
68
-
69
- cubicTo(
70
- centerX - circleOverR, circleOverTop,
71
- centerX - circleOverR, 0f,
72
- centerX, 0f
73
- )
74
-
75
- cubicTo(
76
- centerX + circleOverR, 0f,
77
- centerX + circleOverR, circleOverTop,
78
- centerX + circleOverR + 40f, circleOverTop
79
- )
80
-
81
- lineTo(widthPx, circleOverTop)
82
- lineTo(widthPx, 60f)
83
- lineTo(0f, 60f)
84
- close()
85
- }
86
- }
@@ -1,180 +0,0 @@
1
- package vn.momo.kits.navigation.component
2
-
3
- import androidx.compose.animation.AnimatedVisibility
4
- import androidx.compose.animation.core.CubicBezierEasing
5
- import androidx.compose.animation.core.LinearEasing
6
- import androidx.compose.animation.core.animateDpAsState
7
- import androidx.compose.animation.core.tween
8
- import androidx.compose.animation.expandHorizontally
9
- import androidx.compose.animation.fadeIn
10
- import androidx.compose.animation.fadeOut
11
- import androidx.compose.animation.shrinkHorizontally
12
- import androidx.compose.foundation.ScrollState
13
- import androidx.compose.foundation.background
14
- import androidx.compose.foundation.interaction.MutableInteractionSource
15
- import androidx.compose.foundation.layout.Arrangement
16
- import androidx.compose.foundation.layout.Box
17
- import androidx.compose.foundation.layout.Row
18
- import androidx.compose.foundation.layout.Spacer
19
- import androidx.compose.foundation.layout.fillMaxSize
20
- import androidx.compose.foundation.layout.height
21
- import androidx.compose.foundation.layout.offset
22
- import androidx.compose.foundation.layout.padding
23
- import androidx.compose.foundation.layout.sizeIn
24
- import androidx.compose.foundation.layout.width
25
- import androidx.compose.material3.AlertDialogDefaults
26
- import androidx.compose.material3.FloatingActionButton
27
- import androidx.compose.material3.FloatingActionButtonDefaults
28
- import androidx.compose.material3.FloatingActionButtonElevation
29
- import androidx.compose.runtime.Composable
30
- import androidx.compose.runtime.LaunchedEffect
31
- import androidx.compose.runtime.getValue
32
- import androidx.compose.runtime.mutableStateOf
33
- import androidx.compose.runtime.remember
34
- import androidx.compose.runtime.rememberCoroutineScope
35
- import androidx.compose.runtime.saveable.rememberSaveable
36
- import androidx.compose.runtime.setValue
37
- import androidx.compose.ui.Alignment
38
- import androidx.compose.ui.Modifier
39
- import androidx.compose.ui.graphics.Color
40
- import androidx.compose.ui.unit.Dp
41
- import androidx.compose.ui.unit.dp
42
- import kotlinx.coroutines.delay
43
- import kotlinx.coroutines.flow.MutableStateFlow
44
- import kotlinx.coroutines.flow.collectLatest
45
- import kotlinx.coroutines.launch
46
- import vn.momo.kits.components.Icon
47
- import vn.momo.kits.components.Text
48
- import vn.momo.kits.const.Typography
49
-
50
- enum class FABSize { SMALL, DEFAULT }
51
- enum class FABPosition { END, CENTER }
52
-
53
- data class FloatingButtonProps(
54
- val icon: String,
55
- val iconColor: Color? = null,
56
- val label: String? = null,
57
- val onClick: () -> Unit,
58
- val size: FABSize = FABSize.DEFAULT,
59
- val bottom: Dp? = null,
60
- val scrollState: ScrollState? = null,
61
- val position: FABPosition? = FABPosition.END,
62
- )
63
-
64
- private val FabSmallSize = 36.dp
65
- private val FabDefaultSize = 48.dp
66
- private val FabExpandedWidth = 80.dp
67
- private val FabIconSizeSmall = 12.dp
68
- private val FabIconSizeDefault = 24.dp
69
- private val FabPaddingHorizontal = 12.dp
70
-
71
- @Composable
72
- fun FloatingButton(
73
- scrollPosition: Int,
74
- bottom: Dp,
75
- onClick: () -> Unit,
76
- containerColor: Color,
77
- contentColor: Color = containerColor,
78
- icon: String,
79
- iconColor: Color? = null,
80
- text: String? = null,
81
- elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(4.dp),
82
- size: FABSize = FABSize.DEFAULT,
83
- position: FABPosition = FABPosition.END,
84
- keyboardSize: Dp = 0.dp,
85
- ) {
86
- val scrollStateFlow = remember { MutableStateFlow(scrollPosition) }
87
- var lastScrollPosition by rememberSaveable { mutableStateOf(0) }
88
- var isExpanded by rememberSaveable { mutableStateOf(false) }
89
-
90
- val coroutineScope = rememberCoroutineScope()
91
-
92
- // Animations
93
- val baseSize = if (size == FABSize.SMALL) FabSmallSize else FabDefaultSize
94
- val width by animateDpAsState(
95
- targetValue = if (isExpanded && text != null) FabExpandedWidth else baseSize,
96
- animationSpec = tween(100, easing = CubicBezierEasing(0.2f, 0.2f, 0.2f, 0.2f))
97
- )
98
-
99
- // Scroll listener
100
- LaunchedEffect(text) {
101
- if (text != null) {
102
- coroutineScope.launch {
103
- scrollStateFlow.collectLatest { newScroll ->
104
- isExpanded = newScroll <= lastScrollPosition
105
- delay(100)
106
- lastScrollPosition = newScroll
107
- }
108
- }
109
- }
110
- }
111
-
112
- LaunchedEffect(scrollPosition) {
113
- scrollStateFlow.value = scrollPosition
114
- }
115
-
116
- Box(
117
- modifier = Modifier
118
- .fillMaxSize()
119
- .padding(end = 12.dp, bottom = bottom)
120
- .offset(y = -keyboardSize)
121
- .background(Color.Transparent),
122
- contentAlignment = if (position == FABPosition.END) Alignment.BottomEnd else Alignment.BottomCenter,
123
- ) {
124
- FloatingActionButton(
125
- onClick = onClick,
126
- shape = AlertDialogDefaults.shape,
127
- containerColor = containerColor,
128
- contentColor = contentColor,
129
- elevation = elevation,
130
- interactionSource = remember { MutableInteractionSource() },
131
- modifier = Modifier
132
- .sizeIn(minWidth = width)
133
- .height(baseSize)
134
- ) {
135
- Row(
136
- modifier = Modifier.padding(
137
- start = if (isExpanded) FabPaddingHorizontal else 0.dp,
138
- end = if (isExpanded) FabPaddingHorizontal else 0.dp,
139
- ),
140
- verticalAlignment = Alignment.CenterVertically,
141
- horizontalArrangement = if (isExpanded) Arrangement.Start else Arrangement.Center
142
- ) {
143
- Icon(
144
- source = icon,
145
- size = if (size == FABSize.SMALL) FabIconSizeSmall else FabIconSizeDefault,
146
- color = iconColor ?: Color.White
147
- )
148
-
149
- AnimatedVisibility(
150
- visible = isExpanded,
151
- enter = fadeInExpandAnimation,
152
- exit = fadeOutShrinkAnimation,
153
- ) {
154
- Row {
155
- Spacer(Modifier.width(12.dp))
156
- Text(
157
- text = text ?: "",
158
- color = Color.White,
159
- style = Typography.actionDefaultBold
160
- )
161
- }
162
- }
163
- }
164
- }
165
- }
166
- }
167
-
168
- private val fadeOutShrinkAnimation = fadeOut(
169
- animationSpec = tween(100, easing = LinearEasing)
170
- ) + shrinkHorizontally(
171
- animationSpec = tween(100, easing = LinearEasing),
172
- shrinkTowards = Alignment.Start
173
- )
174
-
175
- private val fadeInExpandAnimation = fadeIn(
176
- animationSpec = tween(100, easing = LinearEasing)
177
- ) + expandHorizontally(
178
- animationSpec = tween(100, easing = LinearEasing),
179
- expandFrom = Alignment.Start
180
- )