@momo-kits/native-kits 0.0.1-beta.4 → 0.89.1-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.
Files changed (195) hide show
  1. package/README.md +1 -0
  2. package/android/.gradle/8.0/checksums/checksums.lock +0 -0
  3. package/android/.gradle/8.0/dependencies-accessors/dependencies-accessors.lock +0 -0
  4. package/android/.gradle/8.0/dependencies-accessors/gc.properties +0 -0
  5. package/android/.gradle/8.0/fileChanges/last-build.bin +0 -0
  6. package/android/.gradle/8.0/fileHashes/fileHashes.lock +0 -0
  7. package/android/.gradle/8.0/gc.properties +0 -0
  8. package/android/.gradle/config.properties +2 -0
  9. package/android/.gradle/vcs-1/gc.properties +0 -0
  10. package/android/.idea/gradle.xml +12 -0
  11. package/android/.idea/migrations.xml +10 -0
  12. package/android/.idea/misc.xml +10 -0
  13. package/android/.idea/vcs.xml +6 -0
  14. package/android/.idea/workspace.xml +50 -0
  15. package/android/build.gradle +35 -69
  16. package/android/local.properties +8 -0
  17. package/android/proguard-rules.pro +21 -0
  18. package/android/src/main/AndroidManifest.xml +2 -2
  19. package/android/src/main/java/com/momoplatform/nativekits/foundations/Button.kt +16 -0
  20. package/android/src/main/java/com/momoplatform/nativekits/libs/Logo.kt +63 -0
  21. package/android/src/main/java/com/momoplatform/nativekits/libs/TrustBanner.kt +246 -0
  22. package/android/src/main/res/drawable/ic_launcher_background.xml +170 -0
  23. package/android/src/main/res/drawable-v24/ic_launcher_foreground.xml +30 -0
  24. package/android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +6 -0
  25. package/android/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +6 -0
  26. package/android/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
  27. package/android/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
  28. package/android/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
  29. package/android/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
  30. package/android/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
  31. package/android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
  32. package/android/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
  33. package/android/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
  34. package/android/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
  35. package/android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
  36. package/android/src/main/res/values/colors.xml +10 -0
  37. package/android/src/main/res/values/strings.xml +3 -0
  38. package/android/src/main/res/values/themes.xml +3 -0
  39. package/android/src/main/res/values-night/themes.xml +3 -0
  40. package/android/src/main/res/xml/backup_rules.xml +13 -0
  41. package/android/src/main/res/xml/data_extraction_rules.xml +19 -0
  42. package/build.gradle.kts +18 -0
  43. package/compose/build.gradle.kts +82 -0
  44. package/compose/src/androidMain/AndroidManifest.xml +2 -0
  45. package/compose/src/androidMain/kotlin/vn/momo/kits/utils/Platform.kt +3 -0
  46. package/compose/src/androidMain/kotlin/vn/momo/kits/utils/SetMaskFilter.kt +8 -0
  47. package/compose/src/androidMain/kotlin/vn/momo/kits/utils/Utils.android.kt +14 -0
  48. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Components.kt +194 -0
  49. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +197 -0
  50. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +133 -0
  51. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +62 -0
  52. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +27 -0
  53. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +288 -0
  54. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +80 -0
  55. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +23 -0
  56. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +42 -0
  57. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +126 -0
  58. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +51 -0
  59. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +299 -0
  60. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +246 -0
  61. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +223 -0
  62. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +244 -0
  63. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +281 -0
  64. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PromotionPopup.kt +72 -0
  65. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +65 -0
  66. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +64 -0
  67. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +63 -0
  68. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +73 -0
  69. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +42 -0
  70. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +150 -0
  71. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +12 -0
  72. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +13 -0
  73. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +173 -0
  74. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +242 -0
  75. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +2 -0
  76. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +2 -0
  77. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +2 -0
  78. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +50 -0
  79. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +1321 -0
  80. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Platform.kt +3 -0
  81. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/SetMaskFilter.kt +5 -0
  82. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +97 -0
  83. package/compose/src/iosMain/kotlin/vn/momo/kits/utils/Platform.kt +3 -0
  84. package/compose/src/iosMain/kotlin/vn/momo/kits/utils/SetMaskFilter.kt +9 -0
  85. package/compose/src/iosMain/kotlin/vn/momo/kits/utils/Utils.ios.kt +18 -0
  86. package/gradle.properties +19 -0
  87. package/gradlew +240 -0
  88. package/gradlew.bat +91 -0
  89. package/ios/Button/Button.swift +9 -2
  90. package/ios/CalculatorKeyboard/CalculatorKeyboard.swift +126 -0
  91. package/ios/Checkbox/Checkbox.swift +38 -0
  92. package/ios/{Colors+Spacing → Colors+Radius+Spacing}/Colors.swift +21 -19
  93. package/ios/Colors+Radius+Spacing/Radius.swift +22 -0
  94. package/ios/Image/Image.swift +60 -0
  95. package/ios/Input/Input.swift +88 -37
  96. package/ios/OTPKeyboard/KeyboardButton.swift +12 -4
  97. package/ios/OTPKeyboard/OTPKeyboard.swift +1 -1
  98. package/ios/Popup/PopupDisplay.swift +169 -0
  99. package/ios/Popup/PopupInput.swift +96 -0
  100. package/ios/Popup/PopupPromotion.swift +52 -0
  101. package/ios/PopupView/FullscreenPopup.swift +251 -0
  102. package/ios/{Popup → PopupView}/Modifiers.swift +6 -20
  103. package/ios/{Popup → PopupView}/PopupView.swift +38 -146
  104. package/ios/PopupView/Utils++.swift +281 -0
  105. package/ios/ScrollIndicator/ScrollIndicator.swift +79 -0
  106. package/ios/Switch/Switch.swift +44 -0
  107. package/ios/Template/Logo/Logo.swift +75 -0
  108. package/ios/Template/TrustBanner/TrustBanner.swift +189 -0
  109. package/ios/native-kits.podspec +2 -0
  110. package/local.properties +8 -0
  111. package/package.json +6 -6
  112. package/publish.sh +1 -10
  113. package/settings.gradle.kts +41 -0
  114. package/android/gradle.properties +0 -5
  115. package/android/src/main/java/com/momoplatform/nativekits/NativeKitsPackage.kt +0 -17
  116. package/android/src/main/java/com/momoplatform/nativekits/NativeKitsViewManager.kt +0 -20
  117. package/example/ios/Example/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -63
  118. package/example/ios/Example/Assets.xcassets/Background.colorset/Contents.json +0 -38
  119. package/example/ios/Example/Assets.xcassets/Border.colorset/Contents.json +0 -38
  120. package/example/ios/Example/Assets.xcassets/Card.colorset/Contents.json +0 -38
  121. package/example/ios/Example/Assets.xcassets/Contents.json +0 -6
  122. package/example/ios/Example/Assets.xcassets/Error.colorset/Contents.json +0 -38
  123. package/example/ios/Example/Assets.xcassets/Primary.colorset/Contents.json +0 -38
  124. package/example/ios/Example/Assets.xcassets/PrimaryDark.colorset/Contents.json +0 -38
  125. package/example/ios/Example/Assets.xcassets/PrimaryLight.colorset/Contents.json +0 -38
  126. package/example/ios/Example/Assets.xcassets/Secondary.colorset/Contents.json +0 -38
  127. package/example/ios/Example/Assets.xcassets/Success.colorset/Contents.json +0 -38
  128. package/example/ios/Example/Assets.xcassets/Text.colorset/Contents.json +0 -38
  129. package/example/ios/Example/Assets.xcassets/TextSecondary.colorset/Contents.json +0 -38
  130. package/example/ios/Example/Assets.xcassets/Warning.colorset/Contents.json +0 -38
  131. package/example/ios/Example/ComponentDetail.swift +0 -35
  132. package/example/ios/Example/ComponentItem.swift +0 -24
  133. package/example/ios/Example/ComponentModel.swift +0 -33
  134. package/example/ios/Example/ContentView.swift +0 -53
  135. package/example/ios/Example/Example.entitlements +0 -10
  136. package/example/ios/Example/Foundation/ButtonDemo.swift +0 -80
  137. package/example/ios/Example/Foundation/Popup/ActionSheets.swift +0 -136
  138. package/example/ios/Example/Foundation/Popup/Floats.swift +0 -127
  139. package/example/ios/Example/Foundation/Popup/Popups.swift +0 -101
  140. package/example/ios/Example/Foundation/PopupDemo.swift +0 -366
  141. package/example/ios/Example/Foundation/TextInputDemo.swift +0 -31
  142. package/example/ios/Example/Foundation/TypographyDemo.swift +0 -53
  143. package/example/ios/Example/Foundation.swift +0 -26
  144. package/example/ios/Example/Info.plist +0 -18
  145. package/example/ios/Example/Library/SwipeableDemo.swift +0 -105
  146. package/example/ios/Example/Library.swift +0 -26
  147. package/example/ios/Example/Main.swift +0 -11
  148. package/example/ios/Example/Overview.swift +0 -20
  149. package/example/ios/Example/Preview Content/Preview Assets.xcassets/Contents.json +0 -6
  150. package/example/ios/Example/Resource/SFProText-Black.ttf +0 -0
  151. package/example/ios/Example/Resource/SFProText-Bold.ttf +0 -0
  152. package/example/ios/Example/Resource/SFProText-Heavy.ttf +0 -0
  153. package/example/ios/Example/Resource/SFProText-Light.ttf +0 -0
  154. package/example/ios/Example/Resource/SFProText-Medium.ttf +0 -0
  155. package/example/ios/Example/Resource/SFProText-Regular.ttf +0 -0
  156. package/example/ios/Example/Resource/SFProText-Semibold.ttf +0 -0
  157. package/example/ios/Example/Resource/SFProText-Thin.ttf +0 -0
  158. package/example/ios/Example/Resource/SFProText-Ultralight.ttf +0 -0
  159. package/example/ios/Example/Resource/foundation.json +0 -33
  160. package/example/ios/Example/Resource/library.json +0 -8
  161. package/example/ios/Example/Utils.swift +0 -30
  162. package/example/ios/Example/ViewModifier/DarkViewModifier.swift +0 -22
  163. package/example/ios/Example.xcodeproj/project.pbxproj +0 -570
  164. package/example/ios/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  165. package/example/ios/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  166. package/example/ios/Example.xcodeproj/project.xcworkspace/xcuserdata/wem.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  167. package/example/ios/Example.xcodeproj/xcuserdata/wem.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  168. package/example/ios/Example.xcworkspace/contents.xcworkspacedata +0 -10
  169. package/example/ios/Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  170. package/example/ios/Example.xcworkspace/xcuserdata/wem.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  171. package/example/ios/Example.xcworkspace/xcuserdata/wem.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +0 -6
  172. package/example/ios/Podfile +0 -6
  173. package/example/ios/Podfile.lock +0 -16
  174. package/example/ios/Pods/Local Podspecs/MoMoUIKits.podspec.json +0 -29
  175. package/example/ios/Pods/Manifest.lock +0 -16
  176. package/example/ios/Pods/Pods.xcodeproj/project.pbxproj +0 -661
  177. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/wem.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +0 -58
  178. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/wem.xcuserdatad/xcschemes/Pods-Example.xcscheme +0 -58
  179. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/wem.xcuserdatad/xcschemes/xcschememanagement.plist +0 -25
  180. package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits-dummy.m +0 -5
  181. package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits-prefix.pch +0 -12
  182. package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits-umbrella.h +0 -16
  183. package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits.debug.xcconfig +0 -12
  184. package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits.modulemap +0 -6
  185. package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits.release.xcconfig +0 -12
  186. package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example-acknowledgements.markdown +0 -3
  187. package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example-acknowledgements.plist +0 -29
  188. package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example-dummy.m +0 -5
  189. package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example-umbrella.h +0 -16
  190. package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example.debug.xcconfig +0 -14
  191. package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example.modulemap +0 -6
  192. package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example.release.xcconfig +0 -14
  193. package/ios/Colors+Spacing/Radius.swift +0 -11
  194. package/ios/Popup/Utils++.swift +0 -163
  195. /package/ios/{Colors+Spacing → Colors+Radius+Spacing}/Spacing.swift +0 -0
@@ -0,0 +1,197 @@
1
+ package vn.momo.kits.application
2
+
3
+ import androidx.compose.foundation.background
4
+ import androidx.compose.foundation.clickable
5
+ import androidx.compose.foundation.interaction.MutableInteractionSource
6
+ import androidx.compose.foundation.layout.Box
7
+ import androidx.compose.foundation.layout.WindowInsets
8
+ import androidx.compose.foundation.layout.asPaddingValues
9
+ import androidx.compose.foundation.layout.fillMaxSize
10
+ import androidx.compose.foundation.layout.padding
11
+ import androidx.compose.foundation.layout.systemBars
12
+ import androidx.compose.material.ExperimentalMaterialApi
13
+ import androidx.compose.runtime.Composable
14
+ import androidx.compose.runtime.CompositionLocalProvider
15
+ import androidx.compose.runtime.remember
16
+ import androidx.compose.runtime.staticCompositionLocalOf
17
+ import androidx.compose.ui.Alignment
18
+ import androidx.compose.ui.Modifier
19
+ import androidx.compose.ui.graphics.Color
20
+ import androidx.compose.ui.unit.Dp
21
+ import androidx.compose.ui.unit.dp
22
+ import cafe.adriel.voyager.core.screen.Screen
23
+ import cafe.adriel.voyager.navigator.LocalNavigator
24
+ import cafe.adriel.voyager.navigator.bottomSheet.BottomSheetNavigator
25
+ import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
26
+ import cafe.adriel.voyager.navigator.currentOrThrow
27
+ import cafe.adriel.voyager.transitions.SlideTransition
28
+ import vn.momo.kits.const.AppStatusBar
29
+ import vn.momo.kits.const.AppTheme
30
+ import vn.momo.kits.const.Spacing
31
+ import vn.momo.kits.const.Theme
32
+ import vn.momo.kits.const.defaultTheme
33
+
34
+ val AppNavigator = staticCompositionLocalOf<Navigator> {
35
+ error("no navigator provided!")
36
+ }
37
+
38
+ class Navigator(
39
+ private val stack: cafe.adriel.voyager.navigator.Navigator,
40
+ private val sheet: BottomSheetNavigator,
41
+ ) {
42
+ fun push(content: @Composable () -> Unit) {
43
+ stack.push(StackScreen {
44
+ content()
45
+ })
46
+ }
47
+
48
+ fun present(content: @Composable () -> Unit) {
49
+
50
+ }
51
+
52
+ fun reset(content: @Composable () -> Unit) {
53
+
54
+ }
55
+
56
+ fun pop() {
57
+ if (sheet.isVisible) {
58
+ sheet.hide()
59
+ } else {
60
+ stack.pop()
61
+ }
62
+ }
63
+
64
+ fun replace(content: @Composable () -> Unit) {
65
+ stack.replace(StackScreen {
66
+ content()
67
+ })
68
+ }
69
+
70
+ fun popToTop() {
71
+ stack.popUntilRoot()
72
+ }
73
+
74
+ fun showModal(
75
+ onClose: () -> Unit = {},
76
+ canBackgroundClose: Boolean = true,
77
+ content: @Composable () -> Unit,
78
+ ) {
79
+ sheet.show(ModalScreen(onClose = onClose, barrierDismissible = canBackgroundClose) {
80
+ content()
81
+ })
82
+ }
83
+
84
+ fun showBottomSheet(content: @Composable () -> Unit) {
85
+ sheet.show(SheetScreen {
86
+ content()
87
+ })
88
+ }
89
+ }
90
+
91
+ @OptIn(ExperimentalMaterialApi::class)
92
+ @Composable
93
+ fun ApplicationContainer(
94
+ theme: Theme = defaultTheme,
95
+ statusBarHeight: Dp = WindowInsets.systemBars.asPaddingValues().calculateTopPadding(),
96
+ content: @Composable () -> Unit,
97
+ ) {
98
+ CompositionLocalProvider(
99
+ AppTheme provides theme,
100
+ AppStatusBar provides statusBarHeight,
101
+ ) {
102
+ BottomSheetNavigator(sheetBackgroundColor = Color.Transparent, sheetElevation = 0.dp) {
103
+ cafe.adriel.voyager.navigator.Navigator(MainScreen {
104
+ content()
105
+ }) {
106
+ SlideTransition(it)
107
+ }
108
+ }
109
+ }
110
+
111
+ }
112
+
113
+ class MainScreen(private val content: @Composable () -> Unit) : Screen {
114
+ @Composable
115
+ override fun Content() {
116
+ CompositionLocalProvider(
117
+ AppNavigator provides Navigator(
118
+ LocalNavigator.currentOrThrow,
119
+ LocalBottomSheetNavigator.current
120
+ ),
121
+ ) {
122
+ content()
123
+ }
124
+ }
125
+ }
126
+
127
+ class StackScreen(private val content: @Composable () -> Unit) : Screen {
128
+ @Composable
129
+ override fun Content() {
130
+ CompositionLocalProvider(
131
+ AppNavigator provides Navigator(
132
+ LocalNavigator.currentOrThrow,
133
+ LocalBottomSheetNavigator.current
134
+ ),
135
+ ) {
136
+ content()
137
+ }
138
+ }
139
+ }
140
+
141
+ class SheetScreen(private val content: @Composable () -> Unit) : Screen {
142
+ @Composable
143
+ override fun Content() {
144
+ CompositionLocalProvider(
145
+ AppNavigator provides Navigator(
146
+ LocalNavigator.currentOrThrow,
147
+ LocalBottomSheetNavigator.current
148
+ ),
149
+ ) {
150
+ content()
151
+ }
152
+ }
153
+ }
154
+
155
+ class ModalScreen(
156
+ private val onClose: () -> Unit,
157
+ private val barrierDismissible: Boolean = true,
158
+ private val content: @Composable () -> Unit,
159
+ ) :
160
+ Screen {
161
+ @Composable
162
+ override fun Content() {
163
+ val navigator = Navigator(
164
+ LocalNavigator.currentOrThrow,
165
+ LocalBottomSheetNavigator.current
166
+ )
167
+ CompositionLocalProvider(
168
+ AppNavigator provides navigator,
169
+ ) {
170
+ Box(
171
+ modifier = Modifier.fillMaxSize().padding(horizontal = Spacing.XL)
172
+ .background(Color.Transparent)
173
+ .clickable(
174
+ interactionSource = remember { MutableInteractionSource() },
175
+ indication = null,
176
+ onClick = {
177
+ if (barrierDismissible) {
178
+ navigator.pop()
179
+ onClose()
180
+ }
181
+ }
182
+ ),
183
+ contentAlignment = Alignment.Center
184
+ ) {
185
+ Box(
186
+ modifier = Modifier.clickable(
187
+ interactionSource = remember { MutableInteractionSource() },
188
+ indication = null
189
+ ) {},
190
+ contentAlignment = Alignment.Center
191
+ ) {
192
+ content()
193
+ }
194
+ }
195
+ }
196
+ }
197
+ }
@@ -0,0 +1,133 @@
1
+ package vn.momo.kits.application
2
+
3
+ import androidx.compose.foundation.background
4
+ import androidx.compose.foundation.gestures.detectTapGestures
5
+ import androidx.compose.foundation.layout.Arrangement
6
+ import androidx.compose.foundation.layout.Box
7
+ import androidx.compose.foundation.layout.Column
8
+ import androidx.compose.foundation.layout.WindowInsets
9
+ import androidx.compose.foundation.layout.asPaddingValues
10
+ import androidx.compose.foundation.layout.fillMaxSize
11
+ import androidx.compose.foundation.layout.fillMaxWidth
12
+ import androidx.compose.foundation.layout.ime
13
+ import androidx.compose.foundation.layout.offset
14
+ import androidx.compose.foundation.layout.padding
15
+ import androidx.compose.foundation.layout.systemBars
16
+ import androidx.compose.foundation.rememberScrollState
17
+ import androidx.compose.foundation.verticalScroll
18
+ import androidx.compose.runtime.Composable
19
+ import androidx.compose.ui.Alignment
20
+ import androidx.compose.ui.Modifier
21
+ import androidx.compose.ui.graphics.Color
22
+ import androidx.compose.ui.input.pointer.pointerInput
23
+ import androidx.compose.ui.platform.LocalSoftwareKeyboardController
24
+ import androidx.compose.ui.unit.dp
25
+ import androidx.compose.ui.unit.min
26
+ import vn.momo.kits.const.AppTheme
27
+ import vn.momo.kits.const.Colors
28
+ import vn.momo.kits.const.Spacing
29
+ import vn.momo.kits.modifier.shadow
30
+
31
+ enum class HeaderType {
32
+ DEFAULT,
33
+ SURFACE,
34
+ EXTENDED,
35
+ NONE
36
+ }
37
+
38
+ @Composable
39
+ fun Screen(
40
+ backgroundColor: Color = Color.Unspecified,
41
+ headerBackground: String? = null,
42
+ isBack: Boolean = true,
43
+ headerType: HeaderType = HeaderType.DEFAULT,
44
+ verticalArrangement: Arrangement.Vertical = Arrangement.Top,
45
+ horizontalAlignment: Alignment.Horizontal = Alignment.Start,
46
+ title: String = "Stack",
47
+ titlePosition: TitlePosition = TitlePosition.LEFT,
48
+ goBack: (() -> Unit) = { },
49
+ footer: @Composable (() -> Unit)? = null,
50
+ headerRight: @Composable (() -> Unit)? = null,
51
+ content: @Composable () -> Unit,
52
+ ) {
53
+ val keyboardController = LocalSoftwareKeyboardController.current
54
+ val keyboardHeight = WindowInsets.ime.asPaddingValues().calculateBottomPadding()
55
+ val avoidKeyboard = when {
56
+ keyboardHeight > 100.dp && footer == null -> keyboardHeight
57
+ keyboardHeight > 100.dp && footer != null -> keyboardHeight - 21.dp
58
+ else -> 0.dp
59
+ }
60
+
61
+ Box(
62
+ Modifier.fillMaxSize().background(AppTheme.current.colors.background.default)
63
+ ) {
64
+ HeaderImage(headerType, headerBackground ?: AppTheme.current.assets.headerBackground)
65
+ Column(
66
+ modifier = Modifier.fillMaxSize().pointerInput(Unit) {
67
+ detectTapGestures(onTap = {
68
+ keyboardController?.hide()
69
+ })
70
+ },
71
+ ) {
72
+ Header(
73
+ headerType = headerType,
74
+ title = title,
75
+ titlePosition = titlePosition,
76
+ backgroundColor = backgroundColor,
77
+ headerRight = headerRight,
78
+ isBack = isBack,
79
+ goBack = goBack,
80
+ )
81
+
82
+ Column(
83
+ Modifier.weight(1f).padding(bottom = avoidKeyboard)
84
+ .verticalScroll(rememberScrollState()),
85
+ verticalArrangement = verticalArrangement,
86
+ horizontalAlignment = horizontalAlignment
87
+ ) {
88
+ content()
89
+ }
90
+
91
+ footer?.let {
92
+ Footer(footer)
93
+ }
94
+ }
95
+ }
96
+ }
97
+
98
+ @Composable
99
+ fun Footer(footer: @Composable (() -> Unit)? = null) {
100
+ val indicator = WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()
101
+ val keyboardHeight = WindowInsets.ime.asPaddingValues().calculateBottomPadding()
102
+ Box(
103
+ Modifier
104
+ .offset(y = if (keyboardHeight > 150.dp) -keyboardHeight + 21.dp else 0.dp)
105
+ .padding(bottom = min(indicator, 21.dp))
106
+ .shadow(
107
+ Colors.black_20.copy(alpha = 0.1f),
108
+ borderRadius = 0.dp,
109
+ 10f,
110
+ offsetX = 0.dp,
111
+ offsetY = (-2).dp,
112
+ spread = 1.dp
113
+ )
114
+ .background(AppTheme.current.colors.background.surface)
115
+ ) {
116
+ Box(
117
+ Modifier
118
+ .fillMaxWidth()
119
+ .padding(vertical = Spacing.S, horizontal = Spacing.M)
120
+ )
121
+ {
122
+ footer?.invoke()
123
+ }
124
+ }
125
+ }
126
+
127
+
128
+
129
+
130
+
131
+
132
+
133
+
@@ -0,0 +1,62 @@
1
+ package vn.momo.kits.components
2
+
3
+ import androidx.compose.foundation.background
4
+ import androidx.compose.foundation.border
5
+ import androidx.compose.foundation.layout.Box
6
+ import androidx.compose.foundation.layout.height
7
+ import androidx.compose.foundation.layout.padding
8
+ import androidx.compose.foundation.layout.widthIn
9
+ import androidx.compose.foundation.shape.RoundedCornerShape
10
+ import androidx.compose.runtime.Composable
11
+ import androidx.compose.ui.Alignment
12
+ import androidx.compose.ui.Modifier
13
+ import androidx.compose.ui.graphics.Color
14
+ import androidx.compose.ui.unit.dp
15
+ import vn.momo.kits.const.AppTheme
16
+ import vn.momo.kits.const.Colors
17
+ import vn.momo.kits.const.Radius
18
+ import vn.momo.kits.const.Spacing
19
+ import vn.momo.kits.const.Typography
20
+ import vn.momo.kits.const.scaleSize
21
+ import vn.momo.kits.utils.primaryColors
22
+
23
+ @Composable
24
+ fun Badge(label: String = "Label", backgroundColor: Color? = null) {
25
+ fun isNumber(label: String): Boolean {
26
+ val numberRegex = "^\\d+$".toRegex()
27
+ return numberRegex.matches(label)
28
+ }
29
+
30
+ fun formatTitle(label: String): String {
31
+ if (isNumber(label) && label.toInt() > 99) {
32
+ return "99+"
33
+ }
34
+ return label
35
+ }
36
+
37
+ var badgeColor =
38
+ if (isNumber(label)) {
39
+ AppTheme.current.colors.error.primary
40
+ } else {
41
+ AppTheme.current.colors.warning.primary
42
+ }
43
+
44
+ if (backgroundColor != null && primaryColors.contains(backgroundColor)) {
45
+ badgeColor = backgroundColor
46
+ }
47
+
48
+ Box(
49
+ modifier = Modifier
50
+ .height(scaleSize(16.toFloat()).dp)
51
+ .widthIn(min = scaleSize(16.toFloat()).dp)
52
+ .background(color = badgeColor, shape = RoundedCornerShape(Radius.M))
53
+ .border(width = 1.dp, shape = RoundedCornerShape(Radius.M), color = Colors.black_01)
54
+ .padding(horizontal = Spacing.XS), contentAlignment = Alignment.Center
55
+ ) {
56
+ Text(
57
+ text = formatTitle(label),
58
+ color = Colors.black_01,
59
+ style = Typography.actionXxs
60
+ )
61
+ }
62
+ }
@@ -0,0 +1,27 @@
1
+ package vn.momo.kits.components
2
+
3
+ import androidx.compose.foundation.background
4
+ import androidx.compose.foundation.border
5
+ import androidx.compose.foundation.layout.Box
6
+ import androidx.compose.foundation.layout.size
7
+ import androidx.compose.foundation.shape.RoundedCornerShape
8
+ import androidx.compose.runtime.Composable
9
+ import androidx.compose.ui.Modifier
10
+ import androidx.compose.ui.unit.dp
11
+ import vn.momo.kits.const.Colors
12
+ import vn.momo.kits.const.Radius
13
+
14
+ enum class DotSize(val size: Int) {
15
+ Small(10),
16
+ Large(16)
17
+ }
18
+
19
+ @Composable
20
+ fun BadgeDot(size: DotSize = DotSize.Large) {
21
+ Box(
22
+ modifier = Modifier
23
+ .size(size.size.dp)
24
+ .border(width = 1.dp, color = Colors.black_01, shape = RoundedCornerShape(Radius.S))
25
+ .background(color = Colors.red_03, shape = RoundedCornerShape(Radius.S))
26
+ )
27
+ }
@@ -0,0 +1,288 @@
1
+ package vn.momo.kits.components
2
+
3
+ import androidx.compose.foundation.background
4
+ import androidx.compose.foundation.border
5
+ import androidx.compose.foundation.clickable
6
+ import androidx.compose.foundation.interaction.MutableInteractionSource
7
+ import androidx.compose.foundation.layout.Arrangement
8
+ import androidx.compose.foundation.layout.Box
9
+ import androidx.compose.foundation.layout.Row
10
+ import androidx.compose.foundation.layout.defaultMinSize
11
+ import androidx.compose.foundation.layout.fillMaxWidth
12
+ import androidx.compose.foundation.layout.height
13
+ import androidx.compose.foundation.layout.padding
14
+ import androidx.compose.foundation.layout.size
15
+ import androidx.compose.foundation.shape.RoundedCornerShape
16
+ import androidx.compose.material.ripple.rememberRipple
17
+ import androidx.compose.material3.CircularProgressIndicator
18
+ import androidx.compose.runtime.Composable
19
+ import androidx.compose.runtime.remember
20
+ import androidx.compose.ui.Alignment
21
+ import androidx.compose.ui.Modifier
22
+ import androidx.compose.ui.draw.clip
23
+ import androidx.compose.ui.graphics.Color
24
+ import androidx.compose.ui.text.TextStyle
25
+ import androidx.compose.ui.unit.Dp
26
+ import androidx.compose.ui.unit.dp
27
+ import vn.momo.kits.const.AppTheme
28
+ import vn.momo.kits.const.Colors
29
+ import vn.momo.kits.const.Radius
30
+ import vn.momo.kits.const.Spacing
31
+ import vn.momo.kits.const.Typography
32
+
33
+ enum class ButtonType {
34
+ PRIMARY,
35
+ SECONDARY,
36
+ TONAL,
37
+ OUTLINE,
38
+ DANGER,
39
+ TEXT,
40
+ DISABLED
41
+ }
42
+
43
+ data class ButtonSpecs(
44
+ val height: Dp,
45
+ val radius: Dp,
46
+ val padding: Dp,
47
+ val width: Dp,
48
+ )
49
+
50
+ enum class Size(val value: ButtonSpecs) {
51
+ LARGE(
52
+ ButtonSpecs(
53
+ height = 48.dp,
54
+ radius = Radius.S,
55
+ padding = Spacing.L,
56
+ width = 128.dp
57
+ )
58
+ ),
59
+ MEDIUM(
60
+ ButtonSpecs(
61
+ height = 36.dp,
62
+ radius = Radius.S,
63
+ padding = Spacing.M,
64
+ width = 80.dp
65
+ )
66
+ ),
67
+ SMALL(
68
+ ButtonSpecs(
69
+ height = 28.dp,
70
+ radius = 6.dp,
71
+ padding = Spacing.S,
72
+ width = 60.dp
73
+ )
74
+ )
75
+ }
76
+
77
+ fun getStyle(size: Size): TextStyle {
78
+ return when (size.name) {
79
+ Size.LARGE.name -> Typography.actionDefault
80
+ Size.MEDIUM.name -> Typography.actionS
81
+ Size.SMALL.name -> Typography.actionXs
82
+ else -> Typography.actionDefault
83
+ }
84
+ }
85
+
86
+ fun getIconSize(size: Size): Dp {
87
+ return when (size.name) {
88
+ Size.LARGE.name -> 24.dp
89
+ Size.MEDIUM.name -> 16.dp
90
+ Size.SMALL.name -> 16.dp
91
+ else -> 24.dp
92
+ }
93
+ }
94
+
95
+ fun getIconSpace(size: Size): Dp {
96
+ return when (size.name) {
97
+ Size.SMALL.name -> Spacing.XS
98
+ else -> Spacing.S
99
+ }
100
+ }
101
+
102
+ @Composable
103
+ fun getTextColor(type: ButtonType): Color {
104
+ return when (type) {
105
+ ButtonType.DISABLED -> AppTheme.current.colors.text.disable
106
+ ButtonType.PRIMARY -> Colors.black_01
107
+ ButtonType.SECONDARY -> AppTheme.current.colors.text.default
108
+ ButtonType.OUTLINE -> AppTheme.current.colors.primary
109
+ ButtonType.TONAL -> AppTheme.current.colors.primary
110
+ ButtonType.DANGER -> Colors.black_01
111
+ ButtonType.TEXT -> AppTheme.current.colors.primary
112
+ }
113
+ }
114
+
115
+ @Composable
116
+ fun RenderTitle(size: Size, title: String = "", type: ButtonType) {
117
+ val style = getStyle(size)
118
+ val color = getTextColor(type)
119
+ Text(style = style, text = title, color = color)
120
+ }
121
+
122
+ @Composable
123
+ fun RenderLeading(
124
+ loading: Boolean,
125
+ size: Size,
126
+ useTintColor: Boolean = true,
127
+ type: ButtonType,
128
+ iconLeft: String = "",
129
+ ) {
130
+ val iconSize = getIconSize(size)
131
+ val marginRight = getIconSpace(size)
132
+ val color = if (useTintColor) getTextColor(type) else Color.Unspecified
133
+ Row(
134
+ verticalAlignment = Alignment.CenterVertically,
135
+ horizontalArrangement = Arrangement.Center
136
+ ) {
137
+ if (loading) {
138
+ Box(Modifier.padding(end = marginRight)) {
139
+ CircularProgressIndicator(
140
+ modifier = Modifier.size(iconSize - 4.dp),
141
+ color = color,
142
+ trackColor = Color.Transparent,
143
+ strokeWidth = 2.dp
144
+ )
145
+ }
146
+
147
+ }
148
+ if (iconLeft.isNotEmpty()) {
149
+ Icon(
150
+ source = iconLeft,
151
+ color = color,
152
+ size = iconSize,
153
+ modifier = Modifier.padding(end = marginRight)
154
+ )
155
+ }
156
+ }
157
+ }
158
+
159
+ @Composable
160
+ fun RenderTrailing(
161
+ iconRight: String,
162
+ size: Size,
163
+ useTintColor: Boolean,
164
+ type: ButtonType,
165
+ ) {
166
+ val color = if (useTintColor) getTextColor(type) else Color.Unspecified
167
+ val marginLeft = getIconSpace(size)
168
+ if (iconRight.isNotEmpty()) {
169
+ val iconSize = getIconSize(size)
170
+ Icon(
171
+ source = iconRight,
172
+ color = color,
173
+ size = iconSize,
174
+ modifier = Modifier.padding(start = marginLeft)
175
+ )
176
+ }
177
+ }
178
+
179
+ @Composable
180
+ fun getTypeStyle(
181
+ type: ButtonType,
182
+ color: Color? = AppTheme.current.colors.primary,
183
+ size: Size,
184
+ ): Modifier {
185
+ val theme = AppTheme.current
186
+
187
+ return when (type) {
188
+ ButtonType.DISABLED -> Modifier.background(theme.colors.background.disable)
189
+ .border(0.dp, Color.Unspecified, RoundedCornerShape(size.value.radius))
190
+
191
+ ButtonType.PRIMARY -> Modifier.background(theme.colors.primary)
192
+ .border(0.dp, Color.Unspecified, RoundedCornerShape(size.value.radius))
193
+
194
+ ButtonType.SECONDARY -> Modifier
195
+ .background(theme.colors.background.surface)
196
+ .border(1.dp, theme.colors.border.default, RoundedCornerShape(size.value.radius))
197
+
198
+ ButtonType.OUTLINE -> Modifier
199
+ .background(theme.colors.background.surface)
200
+ .border(
201
+ 1.dp,
202
+ color ?: theme.colors.primary,
203
+ RoundedCornerShape(size.value.radius)
204
+ )
205
+
206
+ ButtonType.TONAL -> Modifier.background(theme.colors.background.tonal)
207
+ .border(0.dp, Color.Unspecified, RoundedCornerShape(size.value.radius))
208
+
209
+ ButtonType.DANGER -> Modifier.background(theme.colors.error.primary)
210
+ .border(0.dp, Color.Unspecified, RoundedCornerShape(size.value.radius))
211
+
212
+ ButtonType.TEXT -> Modifier
213
+ }
214
+ }
215
+
216
+ /**
217
+ * @param onClick called when this button is clicked
218
+ * @param type [ButtonType] that define the type of button.
219
+ * @param iconRight [String] the icon at the right of title
220
+ * @param iconLeft [String] the icon at the left of title
221
+ * @param title [String] title of button
222
+ * @param loading [Boolean] used when you want to use loading animation
223
+ * @param enabled controls the enabled state of this button. When `false`,
224
+ * this component will not respond to user input, and it will appear
225
+ * visually disabled and disabled to accessibility services.
226
+ * @param isRipple [Boolean] controls the ripple animation of button. When
227
+ * `false`, the button won't have ripple animation.
228
+ * @param useTintColor [Boolean] controls color of the icon.
229
+ */
230
+ @Composable
231
+ fun Button(
232
+ onClick: () -> Unit,
233
+ type: ButtonType = ButtonType.PRIMARY,
234
+ size: Size = Size.LARGE,
235
+ iconRight: String = "",
236
+ iconLeft: String = "",
237
+ title: String = "Button",
238
+ loading: Boolean = false,
239
+ enabled: Boolean = true,
240
+ isRipple: Boolean = true,
241
+ useTintColor: Boolean = true,
242
+ isFull: Boolean = true,
243
+ ) {
244
+ val customModifier = if (isFull) {
245
+ Modifier
246
+ .fillMaxWidth()
247
+ .clip(RoundedCornerShape(size.value.radius)).clickable(
248
+ interactionSource = remember { MutableInteractionSource() },
249
+ indication = if (isRipple) rememberRipple() else null,
250
+ enabled = enabled,
251
+ onClick = onClick
252
+ )
253
+
254
+ } else {
255
+ Modifier
256
+ .clip(RoundedCornerShape(size.value.radius)).clickable(
257
+ interactionSource = remember { MutableInteractionSource() },
258
+ indication = if (isRipple) rememberRipple() else null,
259
+ enabled = enabled,
260
+ onClick = onClick
261
+ )
262
+ }
263
+
264
+ Row(
265
+ modifier = customModifier.then(getTypeStyle(type, size = size))
266
+ .padding(horizontal = size.value.padding)
267
+ .defaultMinSize(
268
+ minWidth = size.value.width
269
+ ).height(size.value.height),
270
+ horizontalArrangement = Arrangement.Center,
271
+ verticalAlignment = Alignment.CenterVertically,
272
+ ) {
273
+ RenderLeading(
274
+ loading,
275
+ size,
276
+ useTintColor,
277
+ type,
278
+ iconLeft = iconLeft
279
+ )
280
+ RenderTitle(size, title, type = type)
281
+ RenderTrailing(
282
+ size = size,
283
+ useTintColor = useTintColor,
284
+ type = type,
285
+ iconRight = iconRight
286
+ )
287
+ }
288
+ }