@momo-kits/native-kits 0.167.1-beta.9 → 0.167.1-duo-search.1-debug

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 (196) hide show
  1. package/CLAUDE.md +36 -0
  2. package/build.gradle.kts +11 -0
  3. package/compose/build.gradle.kts +204 -0
  4. package/compose/build.gradle.kts.backup +204 -0
  5. package/compose/compose.podspec +47 -0
  6. package/compose/src/androidMain/kotlin/vn/momo/kits/const/HostFont.android.kt +19 -0
  7. package/compose/src/androidMain/kotlin/vn/momo/kits/navigation/ScrollToTop.android.kt +6 -0
  8. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/BackGesture.android.kt +12 -0
  9. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/OsFontScale.android.kt +7 -0
  10. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +153 -0
  11. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/ReservedRegions.android.kt +6 -0
  12. package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +52 -0
  13. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +124 -0
  14. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +183 -0
  15. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +207 -0
  16. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +39 -0
  17. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +86 -0
  18. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +76 -0
  19. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +76 -0
  20. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +293 -0
  21. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +33 -0
  22. package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +833 -0
  23. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Localize.kt +269 -0
  24. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +110 -0
  25. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +378 -0
  26. package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +56 -0
  27. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +69 -0
  28. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Avatar.kt +157 -0
  29. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +82 -0
  30. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +32 -0
  31. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +338 -0
  32. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +175 -0
  33. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +356 -0
  34. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +113 -0
  35. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +89 -0
  36. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +128 -0
  37. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +209 -0
  38. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +542 -0
  39. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +49 -0
  40. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +76 -0
  41. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +125 -0
  42. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +231 -0
  43. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +189 -0
  44. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +475 -0
  45. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +114 -0
  46. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +266 -0
  47. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +240 -0
  48. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +223 -0
  49. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +264 -0
  50. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +185 -0
  51. package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +343 -0
  52. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Loader.kt +108 -0
  53. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +56 -0
  54. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +41 -0
  55. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +84 -0
  56. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +40 -0
  57. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +361 -0
  58. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +108 -0
  59. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +310 -0
  60. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +59 -0
  61. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Rating.kt +87 -0
  62. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +21 -0
  63. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +90 -0
  64. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +323 -0
  65. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +220 -0
  66. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +473 -0
  67. package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +122 -0
  68. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +199 -0
  69. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +91 -0
  70. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +552 -0
  71. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +88 -0
  72. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +125 -0
  73. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +207 -0
  74. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +498 -0
  75. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +176 -0
  76. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +182 -0
  77. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +193 -0
  78. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +29 -0
  79. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +234 -0
  80. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +188 -0
  81. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +325 -0
  82. package/compose/src/commonMain/kotlin/vn/momo/kits/const/HostFont.kt +16 -0
  83. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitDesignSystem.kt +18 -0
  84. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitFontScale.kt +22 -0
  85. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +12 -0
  86. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +16 -0
  87. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +188 -0
  88. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +297 -0
  89. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +54 -0
  90. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +50 -0
  91. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/ScreenLayout.kt +232 -0
  92. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +41 -0
  93. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +52 -0
  94. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +66 -0
  95. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +11 -0
  96. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +104 -0
  97. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +48 -0
  98. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +51 -0
  99. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +338 -0
  100. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/HostBackGestureBridge.kt +58 -0
  101. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +137 -0
  102. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +106 -0
  103. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +205 -0
  104. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +393 -0
  105. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScrollToTop.kt +8 -0
  106. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +708 -0
  107. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackTransition.kt +148 -0
  108. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/SwipeBackHaptic.kt +35 -0
  109. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +203 -0
  110. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +232 -0
  111. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +86 -0
  112. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoBarCompression.kt +98 -0
  113. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoTabBar.kt +312 -0
  114. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +169 -0
  115. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +408 -0
  116. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +92 -0
  117. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderJourney.kt +105 -0
  118. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderLocation.kt +74 -0
  119. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +366 -0
  120. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +37 -0
  121. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +363 -0
  122. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SideBar.kt +185 -0
  123. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +132 -0
  124. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +127 -0
  125. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/BackGesture.kt +12 -0
  126. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +91 -0
  127. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/OsFontScale.kt +9 -0
  128. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +74 -0
  129. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ReservedRegions.kt +13 -0
  130. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +1329 -0
  131. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +55 -0
  132. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +15 -0
  133. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +118 -0
  134. package/compose/src/iosMain/kotlin/vn/momo/kits/const/HostFont.ios.kt +40 -0
  135. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/HostBackGesture.ios.kt +45 -0
  136. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +32 -0
  137. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/BackGesture.ios.kt +38 -0
  138. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/OsFontScale.ios.kt +66 -0
  139. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +217 -0
  140. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/ReservedRegions.ios.kt +86 -0
  141. package/gradle/libs.versions.toml +69 -0
  142. package/gradle/wrapper/gradle-wrapper.jar +0 -0
  143. package/gradle/wrapper/gradle-wrapper.properties +8 -0
  144. package/gradle.properties +26 -0
  145. package/gradlew +252 -0
  146. package/gradlew.bat +94 -0
  147. package/ios/Application/ApplicationEnvironment.swift +6 -0
  148. package/ios/Application/Components.swift +1 -3
  149. package/ios/Application/HeaderRight.swift +32 -14
  150. package/ios/Application/Layout/ScreenLayout.swift +312 -0
  151. package/ios/Application/Navigation/BottomTab/BottomTab.swift +67 -10
  152. package/ios/Application/Navigation/BottomTab/BottomTabBar.swift +5 -2
  153. package/ios/Application/Navigation/BottomTab/DuoBarCompression.swift +105 -0
  154. package/ios/Application/Navigation/BottomTab/DuoTabBar.swift +304 -0
  155. package/ios/Application/Navigation/HeaderUser.swift +4 -4
  156. package/ios/Application/Navigation/NavigationContainer.swift +48 -42
  157. package/ios/Application/Navigation/Navigator.swift +122 -29
  158. package/ios/Application/Navigation/NavigatorManager.swift +13 -6
  159. package/ios/Application/Navigation/Overplay/BottomSheet.swift +41 -4
  160. package/ios/Application/Navigation/Overplay/ModalScreen.swift +7 -0
  161. package/ios/Application/Navigation/component/DuoScrollGradient.swift +54 -0
  162. package/ios/Application/Navigation/component/Header.swift +11 -6
  163. package/ios/Application/Navigation/component/HeaderBackground.swift +3 -2
  164. package/ios/Application/Navigation/component/NavigationFooter.swift +1 -1
  165. package/ios/Application/Navigation/component/NavigationHeaderRight.swift +93 -9
  166. package/ios/Application/Navigation/component/SideBar.swift +155 -0
  167. package/ios/Application/StackScreen.swift +175 -18
  168. package/ios/CalculatorKeyboard/CalculatorKeyboard.swift +59 -5
  169. package/ios/Colors+Radius+Spacing/Colors.swift +1 -1
  170. package/ios/Extensions/Color++.swift +20 -9
  171. package/ios/Extensions/OptionalEnvironmentObject.swift +12 -0
  172. package/ios/Icon/Icon.swift +14 -22
  173. package/ios/Icon/Icons.swift +1329 -0
  174. package/ios/Image/Image.swift +16 -5
  175. package/ios/Lottie/LottieView.swift +4 -2
  176. package/ios/Popup/PopupDisplay.swift +84 -67
  177. package/ios/Popup/PopupLayout.swift +45 -0
  178. package/ios/Popup/PopupNotify.swift +44 -26
  179. package/ios/Popup/PopupPromotion.swift +18 -6
  180. package/ios/Resources/dot_loading.json +558 -0
  181. package/ios/Resources/lottie_circle_loader.json +1 -0
  182. package/ios/Template/TrustBanner/TrustBanner.swift +69 -31
  183. package/ios/Typography/FontScale.swift +3 -3
  184. package/ios/native-kits.podspec +1 -1
  185. package/ios-demo/MoMoUIKitsDemo.podspec +1 -1
  186. package/ios-demo/README.md +120 -0
  187. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DuoTabDemo.swift +80 -0
  188. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +2 -0
  189. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IPhoneDuoDemo.swift +173 -0
  190. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +1 -0
  191. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +2 -2
  192. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +2 -0
  193. package/local.properties +8 -0
  194. package/package.json +1 -1
  195. package/scripts/gen-ios-icons.mjs +36 -0
  196. package/settings.gradle.kts +64 -0
@@ -12,14 +12,14 @@ import SDWebImageSwiftUI
12
12
  let jsonUrl = "https://static.momocdn.net/app/json/component-kits/design_system.json"
13
13
 
14
14
  public struct TrustBannerData: Decodable {
15
- let content: [String: String]
16
- let subContent: [String: String]
17
- let pciImage: String
18
- let sslImage: String
19
- let urlConfig: String
20
- let icons: [String]
21
- let momoImage: String
22
-
15
+ public let content: [String: String]
16
+ public let subContent: [String: String]
17
+ public let pciImage: String?
18
+ public let momoImage: String?
19
+ public let sslImage: String?
20
+ public let icons: [String]?
21
+ public let urlConfig: String
22
+
23
23
  enum CodingKeys: String, CodingKey {
24
24
  case content
25
25
  case subContent
@@ -29,6 +29,38 @@ public struct TrustBannerData: Decodable {
29
29
  case momoImage
30
30
  case urlConfig = "url_config"
31
31
  }
32
+
33
+ public init(
34
+ content: [String: String] = ["vi": "", "en": ""],
35
+ subContent: [String: String] = ["vi": "", "en": ""],
36
+ pciImage: String? = nil,
37
+ momoImage: String? = nil,
38
+ sslImage: String? = nil,
39
+ icons: [String]? = nil,
40
+ urlConfig: String = ""
41
+ ) {
42
+ self.content = content
43
+ self.subContent = subContent
44
+ self.pciImage = pciImage
45
+ self.momoImage = momoImage
46
+ self.sslImage = sslImage
47
+ self.icons = icons
48
+ self.urlConfig = urlConfig
49
+ }
50
+
51
+ // Missing keys fall back to the init defaults, like the Compose data class.
52
+ public init(from decoder: Decoder) throws {
53
+ let container = try decoder.container(keyedBy: CodingKeys.self)
54
+ self.init(
55
+ content: try container.decodeIfPresent([String: String].self, forKey: .content) ?? ["vi": "", "en": ""],
56
+ subContent: try container.decodeIfPresent([String: String].self, forKey: .subContent) ?? ["vi": "", "en": ""],
57
+ pciImage: try container.decodeIfPresent(String.self, forKey: .pciImage),
58
+ momoImage: try container.decodeIfPresent(String.self, forKey: .momoImage),
59
+ sslImage: try container.decodeIfPresent(String.self, forKey: .sslImage),
60
+ icons: try container.decodeIfPresent([String].self, forKey: .icons),
61
+ urlConfig: try container.decodeIfPresent(String.self, forKey: .urlConfig) ?? ""
62
+ )
63
+ }
32
64
  }
33
65
 
34
66
  let defaultBanner = TrustBannerData(
@@ -39,15 +71,15 @@ let defaultBanner = TrustBannerData(
39
71
  "en": "Learn more"
40
72
  ],
41
73
  pciImage: "https://static.momocdn.net/app/img/kits/trustBanner/pci.png",
74
+ momoImage: "https://static.momocdn.net/app/img/kits/trustBanner/ic_secu.png",
42
75
  sslImage: "https://static.momocdn.net/app/img/kits/trustBanner/ssl.png",
43
- urlConfig: "login_and_security",
44
76
  icons: [
45
77
  "https://static.momocdn.net/app/img/kits/trustBanner/ic_viettinbank.png",
46
78
  "https://static.momocdn.net/app/img/kits/trustBanner/ic_agribank.png",
47
79
  "https://static.momocdn.net/app/img/kits/trustBanner/ic_vietcombank.png",
48
80
  "https://static.momocdn.net/app/img/kits/trustBanner/ic_bidv.png"
49
81
  ],
50
- momoImage: "https://static.momocdn.net/app/img/kits/trustBanner/ic_secu.png"
82
+ urlConfig: "login_and_security"
51
83
  )
52
84
 
53
85
  public struct TrustBanner: View {
@@ -60,22 +92,25 @@ public struct TrustBanner: View {
60
92
  self.onPress = onPress
61
93
  }
62
94
 
95
+ private var banner: TrustBannerData {
96
+ applicationEnvironment.config?.trustBanner ?? defaultBanner
97
+ }
98
+
63
99
  func onPressSecurity() {
64
- if (onPress != nil) {
65
- onPress!(applicationEnvironment.config?.trustBanner?.urlConfig ?? defaultBanner.urlConfig)
66
- }
100
+ onPress?(banner.urlConfig)
67
101
  }
68
-
69
-
102
+
103
+
70
104
  public var body: some View {
71
105
  HStack(alignment: .center, spacing: 8) {
72
- WebImage(url: URL(string: applicationEnvironment.config?.trustBanner?.momoImage ?? defaultBanner.momoImage))
73
- .resizable()
74
- .scaledToFit()
75
- .frame(width: 64, height: 64)
106
+ if let momoImage = banner.momoImage {
107
+ WebImage(url: URL(string: momoImage))
108
+ .resizable()
109
+ .scaledToFit()
110
+ .frame(width: 64, height: 64)
111
+ }
76
112
  VStack(alignment: .leading){
77
- Text(applicationEnvironment.config?.trustBanner?.content[localize.currentLanguage]
78
- ?? localize.translateData(defaultBanner.content))
113
+ Text(localize.translateData(banner.content))
79
114
  .foregroundColor(Color(hex: "484848"))
80
115
  .lineLimit(2)
81
116
  .font(.system(size: 13, weight: Font.Weight.regular))
@@ -84,8 +119,7 @@ public struct TrustBanner: View {
84
119
  .padding(.bottom, 8)
85
120
  HStack {
86
121
  HStack(spacing: 0) {
87
- Text(applicationEnvironment.config?.trustBanner?.subContent[localize.currentLanguage]
88
- ?? localize.translateData(defaultBanner.subContent))
122
+ Text(localize.translateData(banner.subContent))
89
123
  .foregroundColor(Colors.pink03)
90
124
  .font(.system(size: 13, weight: .bold))
91
125
  .ignoreBoldTextSetting()
@@ -98,14 +132,18 @@ public struct TrustBanner: View {
98
132
 
99
133
  Spacer()
100
134
  HStack{
101
- WebImage(url: URL(string: applicationEnvironment.config?.trustBanner?.pciImage ?? defaultBanner.pciImage))
102
- .resizable()
103
- .scaledToFit()
104
- .frame(width: 24, height: 20)
105
- WebImage(url: URL(string: applicationEnvironment.config?.trustBanner?.sslImage ?? defaultBanner.sslImage))
106
- .resizable()
107
- .scaledToFit()
108
- .frame(width: 52, height: 20)
135
+ if let pciImage = banner.pciImage {
136
+ WebImage(url: URL(string: pciImage))
137
+ .resizable()
138
+ .scaledToFit()
139
+ .frame(width: 24, height: 20)
140
+ }
141
+ if let sslImage = banner.sslImage {
142
+ WebImage(url: URL(string: sslImage))
143
+ .resizable()
144
+ .scaledToFit()
145
+ .frame(width: 52, height: 20)
146
+ }
109
147
  }
110
148
  }
111
149
 
@@ -30,9 +30,9 @@ public struct FontScale: Equatable {
30
30
  public func callAsFunction(_ size: CGFloat) -> CGFloat {
31
31
  guard useOSScaleRate else { return size * userScaleRate }
32
32
 
33
- // Device width is read live rather than snapshotted, matching Compose's
34
- // getScreenDimensions() read inside scaleSize(), so a rotation or split-view resize counts.
35
- let deviceScale = UIScreen.main.bounds.width / Self.defaultScreenSize
33
+ // Short side, not width: landscape must not inflate every font (and so every popup's height).
34
+ let bounds = UIScreen.main.bounds.size
35
+ let deviceScale = min(bounds.width, bounds.height) / Self.defaultScreenSize
36
36
 
37
37
  var deviceScaled = size
38
38
  var osScaled = size
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |s|
2
2
  s.name = 'MoMoUIKits'
3
- s.version = '0.167.1-beta.9'
3
+ s.version = '0.167.1-duo-search.1'
4
4
  s.summary = 'MoMoUIKits for iOS'
5
5
  s.homepage = 'https://momo.vn'
6
6
  s.license = { :type => 'MIT' }
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |s|
2
2
  s.name = 'MoMoUIKitsDemo'
3
- s.version = '0.167.1-beta.9'
3
+ s.version = '0.167.1-duo-search.1'
4
4
  s.summary = 'Demo browser for MoMoUIKits SwiftUI components'
5
5
  s.homepage = 'https://momo.vn'
6
6
  s.license = { :type => 'MIT' }
@@ -0,0 +1,120 @@
1
+ # MoMoUIKitsDemo
2
+
3
+ SwiftUI demo browser for `MoMoUIKits`.
4
+
5
+ The package can optionally host a Compose UIKits screen by receiving a
6
+ `UIViewController` factory from the host app. It does not import the KMP
7
+ `shared` module directly.
8
+
9
+ SwiftUI mode reuses the full demo screen set from
10
+ `sample/iosApp/iosApp/Demo`, including the sample `HomeView` registry and demo
11
+ screens for all currently available components.
12
+
13
+ ## CocoaPods
14
+
15
+ In the host app `Podfile`, include both local pods:
16
+
17
+ ```ruby
18
+ pod 'MoMoUIKits', :path => '../momo-native-kits/ios/native-kits.podspec'
19
+ pod 'MoMoUIKitsDemo', :path => '../momo-native-kits/ios-demo'
20
+ ```
21
+
22
+ Adjust the relative paths to match the host app checkout.
23
+
24
+ ## Host App Usage
25
+
26
+ ```swift
27
+ import MoMoUIKitsDemo
28
+ import shared
29
+
30
+ class UIKitsViewController: BaseComposeAppViewController {
31
+ override func getViewController() -> UIViewController? {
32
+ let params = self.application.data as? [String: Any]
33
+
34
+ return MoMoUIKitsDemoViewControllerFactory.make(
35
+ context: MoMoUIKitsDemoContext(
36
+ appId: params?["appId"] as? String ?? "",
37
+ appCode: params?["code"] as? String ?? "",
38
+ appName: params?["name"] as? String,
39
+ appIcon: params?["icon"] as? String ?? ""
40
+ ),
41
+ composeViewController: {
42
+ UIKitsScreenComposeViewControllerKt.UIKitsScreenComposeViewController(
43
+ params: params
44
+ )
45
+ }
46
+ )
47
+ }
48
+
49
+ override func viewDidDisappear(_ animated: Bool) {
50
+ super.viewDidDisappear(animated)
51
+ composeViewController = nil
52
+ }
53
+ }
54
+ ```
55
+
56
+ If the host does not pass `composeViewController`, the demo opens directly in
57
+ SwiftUI mode.
58
+
59
+ ## Included SwiftUI Demos
60
+
61
+ The pod includes the sample demo screens for:
62
+
63
+ - Animated Header
64
+ - Avatar
65
+ - Badge
66
+ - Baseline View
67
+ - Bottom Tab
68
+ - Button
69
+ - Carousel
70
+ - Checkbox
71
+ - Chip
72
+ - Collapse
73
+ - DateTimePicker
74
+ - Divider
75
+ - Header User
76
+ - Icon Button
77
+ - Image
78
+ - Information
79
+ - Input
80
+ - Input DropDown
81
+ - Input Money
82
+ - Input OTP
83
+ - Input Phone Number
84
+ - Input Search
85
+ - Input TextArea
86
+ - Loader
87
+ - Navigation
88
+ - Pagination
89
+ - Popup Display
90
+ - Popup Notify
91
+ - Popup Promotion
92
+ - Progress Info
93
+ - Radio
94
+ - Rating
95
+ - Skeleton
96
+ - Slider
97
+ - SnackBar
98
+ - Stepper
99
+ - Steps
100
+ - Suggest Action
101
+ - Swipe
102
+ - Switch
103
+ - TabView
104
+ - Tag
105
+ - Theme
106
+ - Title
107
+ - Tooltip
108
+ - Typography
109
+ - Uploader
110
+
111
+ ## Validation Notes
112
+
113
+ Validated locally with:
114
+
115
+ ```sh
116
+ pod ipc spec ios/MoMoUIKits.podspec
117
+ pod ipc spec ios-demo/MoMoUIKitsDemo.podspec
118
+ pod lib lint ios/MoMoUIKits.podspec --allow-warnings --skip-import-validation
119
+ pod lib lint ios-demo/MoMoUIKitsDemo.podspec --allow-warnings --skip-import-validation --include-podspecs=ios/MoMoUIKits.podspec
120
+ ```
@@ -0,0 +1,80 @@
1
+ //
2
+ // DuoTabDemo.swift
3
+ // Example
4
+ //
5
+ // Mirrors RN `app/screens/IPhoneDuo/DuoTabUsage`: glass rail in the Duo side bar, floating
6
+ // glass bar when unfolded portrait. `useShortcut` gives the tallest side bar header, for the
7
+ // overlap review; `compressTabBar` folds the tab bar instead of the toolbar when the side bar
8
+ // is short (HIG "Tab bar compressed").
9
+ //
10
+
11
+ import MoMoUIKits
12
+ import SwiftUI
13
+
14
+ private let swatches = [Colors.pink03, Colors.orange03, Colors.green03]
15
+ private let history = (1...18).map { "Giao dịch #\($0)" }
16
+
17
+ struct DuoTabDemo: View {
18
+ let useShortcut: Bool
19
+ var compressTabBar = false
20
+
21
+ var body: some View {
22
+ if #available(iOS 16.0, *) {
23
+ DuoTabDemoContent(useShortcut: useShortcut, compressTabBar: compressTabBar)
24
+ } else {
25
+ Text("Requires iOS 16+").padding()
26
+ }
27
+ }
28
+ }
29
+
30
+ @available(iOS 16.0, *)
31
+ private struct DuoTabDemoContent: View {
32
+ let useShortcut: Bool
33
+ let compressTabBar: Bool
34
+
35
+ var body: some View {
36
+ BottomTab(
37
+ items: [
38
+ tab("DuoMoMo", label: "MoMo", icon: "basic_home", title: "MoMo"),
39
+ tab("DuoPromotion", label: "Ưu đãi", icon: "shopping_coupon", title: "Ưu đãi", badge: ""),
40
+ tab("DuoHistory", label: "Lịch sử GD", icon: "time_clock_reset", title: "Lịch sử giao dịch", badge: "3"),
41
+ tab("DuoMe", label: "Tôi", icon: "basic_person", title: "Tôi"),
42
+ ],
43
+ floatingButton: BottomTabFloatingButton(icon: "navigation_full_screen", label: "Quét mọi QR", onPress: {}),
44
+ compressionBehavior: compressTabBar ? .tabBar : .toolbar
45
+ )
46
+ }
47
+
48
+ private func tab(_ name: String, label: String, icon: String, title: String, badge: String? = nil) -> BottomTabItem {
49
+ BottomTabItem(
50
+ name: name,
51
+ label: label,
52
+ icon: icon,
53
+ badgeLabel: badge,
54
+ options: NavigationOptions(title: title, headerRightData: HeaderRightData(useShortcut: useShortcut)),
55
+ screen: { DuoTabList() }
56
+ )
57
+ }
58
+ }
59
+
60
+ private struct DuoTabList: View {
61
+ var body: some View {
62
+ VStack(spacing: 0) {
63
+ ForEach(history.indices, id: \.self) { index in
64
+ if index > 0 { MomoDivider() }
65
+ HStack(spacing: Spacing.M) {
66
+ RoundedRectangle(cornerRadius: Radius.S)
67
+ .fill(swatches[index % swatches.count])
68
+ .frame(width: Spacing.XL, height: Spacing.XL)
69
+ MomoText(history[index], typography: .bodyDefaultRegular)
70
+ Spacer()
71
+ }
72
+ .padding(.vertical, Spacing.M)
73
+ }
74
+ }
75
+ .padding(.horizontal, Spacing.M)
76
+ .background(Colors.black01)
77
+ .clipShape(RoundedRectangle(cornerRadius: Radius.M))
78
+ .padding(Spacing.M)
79
+ }
80
+ }
@@ -51,6 +51,7 @@ public let ScreenUsages: [ScreenUsage] = [
51
51
  ScreenUsage(title: "InputTextArea", destination: AnyView(InputTextAreaDemo()), icon: getIcon(icon: "FormInput"), hostsOwnChrome: true),
52
52
  ScreenUsage(title: "InputSearch", destination: AnyView(InputSearchDemo()), icon: getIcon(icon: "FormInput"), hostsOwnChrome: true),
53
53
  ScreenUsage(title: "PopupNotify", destination: AnyView(PopupNotifyDemo()), icon: getIcon(icon: "Popup"), hostsOwnChrome: true),
54
+ ScreenUsage(title: "PopupDisplay", destination: AnyView(PopupDisplayDemo()), icon: getIcon(icon: "Popup"), hostsOwnChrome: true),
54
55
  ScreenUsage(title: "PopupPromotion", destination: AnyView(PopupPromotionDemo()), icon: getIcon(icon: "Popup"), hostsOwnChrome: true),
55
56
  ScreenUsage(title: "SnackBar", destination: AnyView(SnackBarDemo()), icon: getIcon(icon: "Popup"), hostsOwnChrome: true),
56
57
  ScreenUsage(title: "Switch", destination: AnyView(SwitchDemo()), icon: getIcon(icon: "Toggle"), hostsOwnChrome: true),
@@ -84,6 +85,7 @@ public let ScreenUsages: [ScreenUsage] = [
84
85
  ScreenUsage(title: "DateTimePicker", destination: AnyView(DateTimePickerDemo()), icon: getIcon(icon: "Layout"), hostsOwnChrome: true),
85
86
  ScreenUsage(title: "Navigation", destination: AnyView(NavigationDemo()), icon: getIcon(icon: "Layout")),
86
87
  ScreenUsage(title: "Bottom Tab", destination: AnyView(BottomTabDemo()), icon: getIcon(icon: "Layout"), hostsOwnChrome: true),
88
+ ScreenUsage(title: "iPhone Duo", destination: AnyView(IPhoneDuoDemo()), icon: getIcon(icon: "Layout")),
87
89
  ScreenUsage(title: "Animated Header", destination: AnyView(AnimatedHeaderDemo()), icon: getIcon(icon: "Layout")),
88
90
  ScreenUsage(title: "Theme", destination: AnyView(ThemeDemo()), icon: getIcon(icon: "Typography")),
89
91
  ScreenUsage(title: "Localize", destination: AnyView(LocalizeDemo()), icon: getIcon(icon: "Typography")),
@@ -0,0 +1,173 @@
1
+ //
2
+ // IPhoneDuoDemo.swift
3
+ // Example
4
+ //
5
+ // Mirrors RN `app/screens/IPhoneDuo`: the live screen layout, an extended header + search
6
+ // + footer screen, the Duo tab bars, the popup / bottom sheet behaviour and a grid to scroll.
7
+ //
8
+
9
+ import MoMoUIKits
10
+ import SwiftUI
11
+
12
+ private let gridRows: [[Int]] = [[12], [6, 6], [4, 4, 4], [3, 3, 3, 3]]
13
+
14
+ // enough rows to scroll, so the header glass and side bar can be checked
15
+ private let scrollRows: [[Int]] = Array(repeating: gridRows, count: 4).flatMap { $0 }
16
+
17
+ struct IPhoneDuoDemo: View {
18
+ var body: some View {
19
+ if #available(iOS 16.0, *) {
20
+ IPhoneDuoDemoContent()
21
+ } else {
22
+ Text("Requires iOS 16+").padding()
23
+ }
24
+ }
25
+ }
26
+
27
+ @available(iOS 16.0, *)
28
+ private struct IPhoneDuoDemoContent: View {
29
+ @EnvironmentObject private var navigator: Navigator
30
+ @Environment(\.screenLayout) private var layout
31
+
32
+ var body: some View {
33
+ VStack(alignment: .leading, spacing: Spacing.M) {
34
+ VStack(spacing: 0) {
35
+ ForEach(info, id: \.0) { label, value in
36
+ HStack {
37
+ MomoText(label, typography: .bodyDefaultRegular)
38
+ Spacer()
39
+ MomoText(value, typography: .headerSSemibold)
40
+ }
41
+ .padding(.vertical, Spacing.XS)
42
+ }
43
+ }
44
+ .padding(.horizontal, Spacing.M)
45
+
46
+ VStack(spacing: Spacing.S) {
47
+ demoButton("Extended header + footer") {
48
+ navigator.push({ DuoGridScreen() }, options: extendedOptions)
49
+ }
50
+ demoButton("Glass tab bar") {
51
+ navigator.push({ DuoTabDemo(useShortcut: false) }, options: tabOptions)
52
+ }
53
+ demoButton("Glass tab bar + useShortcut") {
54
+ navigator.push({ DuoTabDemo(useShortcut: true) }, options: tabOptions)
55
+ }
56
+ demoButton("Glass tab bar + compress tab bar") {
57
+ navigator.push({ DuoTabDemo(useShortcut: true, compressTabBar: true) }, options: tabOptions)
58
+ }
59
+ demoButton("Bottom sheet: iPhone Duo safe area") {
60
+ navigator.showBottomSheet({ BottomSheetSafeArea() }, isSurface: true, header: .title("Safe area"))
61
+ }
62
+ demoButton("PopupNotify") {
63
+ navigator.showModal {
64
+ PopupNotify(props: PopupNotifyProps(
65
+ image: "https://static.momocdn.net/app/img/popup_permission/img_permission_popup_camera.png",
66
+ title: "Title",
67
+ description: String(repeating: "Check lại một nhịp auto chuyển sang dạng CTA. ", count: 8),
68
+ primary: PopupAction(title: "Đồng ý", onPress: { navigator.hideOverplay() }),
69
+ secondary: PopupAction(title: "Đóng", onPress: { navigator.hideOverplay() }),
70
+ onIconClose: { navigator.hideOverplay() }
71
+ ))
72
+ }
73
+ }
74
+ }
75
+ .padding(.horizontal, Spacing.M)
76
+
77
+ DuoGrid()
78
+ }
79
+ .padding(.vertical, Spacing.M)
80
+ }
81
+
82
+ private var info: [(String, String)] {
83
+ let insets = layout.insets
84
+ return [
85
+ ("iPhone Duo", layout.isIPhoneDuo ? "yes" : "no"),
86
+ ("Window", "\(Int(layout.width)) x \(Int(layout.height))"),
87
+ ("Safe area (T R B L)", "\(Int(insets.top)) \(Int(insets.trailing)) \(Int(insets.bottom)) \(Int(insets.leading))"),
88
+ ("Content inset (L R)", "\(Int(layout.insetLeft)) \(Int(layout.insetRight))"),
89
+ ("Content width", "\(Int(layout.contentWidth))"),
90
+ ("Header height", "\(Int(layout.headerHeight))"),
91
+ ("Side bar", layout.sideBar.map { "\($0.edge == .left ? "left" : "right"), \(Int($0.width))pt, top \(Int($0.top))" } ?? "none"),
92
+ ]
93
+ }
94
+
95
+ private var extendedOptions: NavigationOptions {
96
+ NavigationOptions(
97
+ title: "Extended",
98
+ headerType: .extended,
99
+ headerRightData: HeaderRightData(useShortcut: true),
100
+ footer: { AnyView(MoMoUIKits.Button(title: "Footer action", action: {}, size: .large)) }
101
+ )
102
+ }
103
+
104
+ private var tabOptions: NavigationOptions {
105
+ NavigationOptions(title: "Duo tabs", headerType: .none, scrollable: false)
106
+ }
107
+
108
+ private func demoButton(_ title: String, action: @escaping () -> Void) -> some View {
109
+ MoMoUIKits.Button(title: title, action: action, type: .secondary, size: .small)
110
+ }
111
+ }
112
+
113
+ private struct DuoGridScreen: View {
114
+ var body: some View {
115
+ DuoGrid().padding(.vertical, Spacing.M)
116
+ }
117
+ }
118
+
119
+ private struct DuoGrid: View {
120
+ var body: some View {
121
+ VStack(spacing: Spacing.M) {
122
+ ForEach(scrollRows.indices, id: \.self) { row in
123
+ SectionView {
124
+ ForEach(scrollRows[row].indices, id: \.self) { index in
125
+ let span = scrollRows[row][index]
126
+ ItemView(widthSpan: span) {
127
+ MomoText("span \(span)", typography: .descriptionDefaultRegular)
128
+ .frame(maxWidth: .infinity)
129
+ .frame(height: 48)
130
+ .background(Colors.black04)
131
+ .clipShape(RoundedRectangle(cornerRadius: Radius.S))
132
+ }
133
+ }
134
+ }
135
+ }
136
+ }
137
+ }
138
+ }
139
+
140
+ /// Markers on the content edges show the side safe area inside the sheet.
141
+ private struct BottomSheetSafeArea: View {
142
+ @Environment(\.screenLayout) private var layout
143
+
144
+ var body: some View {
145
+ VStack(alignment: .leading, spacing: Spacing.XS) {
146
+ HStack {
147
+ marker("← content edge")
148
+ Spacer()
149
+ marker("content edge →")
150
+ }
151
+ .padding(.bottom, Spacing.S)
152
+ MomoText("Window: \(Int(layout.width)) × \(Int(layout.height))", typography: .bodyDefaultRegular)
153
+ MomoText(
154
+ "Insets: top \(Int(layout.insets.top)) · right \(Int(layout.insets.trailing)) · bottom \(Int(layout.insets.bottom)) · left \(Int(layout.insets.leading))",
155
+ typography: .bodyDefaultRegular
156
+ )
157
+ MomoText(
158
+ "On iPhone Duo: the outer display keeps a full-width sheet with content inside the side safe area; the inner display centers the sheet, still attached to the bottom edge. Other devices are unchanged.",
159
+ typography: .descriptionDefaultRegular,
160
+ color: Colors.black12
161
+ )
162
+ }
163
+ .padding(.vertical, Spacing.M)
164
+ }
165
+
166
+ private func marker(_ text: String) -> some View {
167
+ MomoText(text, typography: .labelSMedium, color: Colors.pink03)
168
+ .padding(.vertical, Spacing.XS)
169
+ .padding(.horizontal, Spacing.S)
170
+ .background(Colors.black04)
171
+ .clipShape(RoundedRectangle(cornerRadius: Radius.XS))
172
+ }
173
+ }
@@ -160,6 +160,7 @@ private struct PopupDisplayDemoContent: View {
160
160
  errorCode: errorCode,
161
161
  isShowCloseIcon: showCloseIcon
162
162
  )
163
+ .padding(.horizontal, Spacing.M)
163
164
  }
164
165
  }
165
166
  }
@@ -26,7 +26,7 @@ private struct PopupNotifyPreview: View {
26
26
  private func show() {
27
27
  navigator.showModal {
28
28
  PopupNotify(props: PopupNotifyProps(
29
- image: "https://i.imgur.com/s70S9s9.png",
29
+ image: "https://static.momocdn.net/app/img/popup_permission/img_permission_popup_camera.png",
30
30
  title: "Title",
31
31
  description: "Check lại một nhịp auto chuyển sang dạng CTA.",
32
32
  error: "9004",
@@ -50,7 +50,7 @@ private let popupDirectionList: [PlaygroundOption] = [
50
50
  @available(iOS 16.0, *)
51
51
  private struct PopupNotifyPlayground: View {
52
52
  @EnvironmentObject private var navigator: Navigator
53
- @State private var image = "https://i.imgur.com/s70S9s9.png"
53
+ @State private var image = "https://static.momocdn.net/app/img/popup_permission/img_permission_popup_camera.png"
54
54
  @State private var title = "Title"
55
55
  @State private var description = "Check lại một nhịp auto chuyển sang dạng CTA."
56
56
  @State private var error = "9004"
@@ -37,6 +37,7 @@ private struct PopupPromotionPreview: View {
37
37
  private func show(_ url: String) {
38
38
  navigator.showModal {
39
39
  PopupPromotion(imageUrl: url, onIconClose: { navigator.hideOverplay() }, onAction: { navigator.hideOverplay() })
40
+ .padding(.horizontal, Spacing.M)
40
41
  }
41
42
  }
42
43
  }
@@ -62,6 +63,7 @@ private struct PopupPromotionPlayground: View {
62
63
  private func show() {
63
64
  navigator.showModal {
64
65
  PopupPromotion(imageUrl: imageUrl, onIconClose: { navigator.hideOverplay() }, onAction: { navigator.hideOverplay() })
66
+ .padding(.horizontal, Spacing.M)
65
67
  }
66
68
  }
67
69
  }
@@ -0,0 +1,8 @@
1
+ ## This file must *NOT* be checked into Version Control Systems,
2
+ # as it contains information specific to your local configuration.
3
+ #
4
+ # Location of the SDK. This is only used by Gradle.
5
+ # For customization when using a Version Control System, please read the
6
+ # header note.
7
+ #Tue Oct 06 18:08:41 GMT+07:00 2026
8
+ sdk.dir=/Users/vu.nguyen15/Library/Android/sdk
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.167.1-beta.9",
3
+ "version": "0.167.1-duo-search.1-debug",
4
4
  "private": false,
5
5
  "dependeNavigationncies": {},
6
6
  "devDependencies": {},