@momo-kits/native-kits 0.152.4-beta.3 → 0.152.5

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 (155) hide show
  1. package/package.json +7 -6
  2. package/shared/build.gradle.kts +74 -0
  3. package/CODE_OF_CONDUCT.md +0 -133
  4. package/CONTRIBUTING.md +0 -114
  5. package/LICENSE +0 -20
  6. package/README.md +0 -7
  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 -306
  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 -236
  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 -77
  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 -131
  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 -384
  53. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +0 -160
  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 -223
  56. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +0 -232
  57. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +0 -236
  58. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +0 -228
  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 -84
  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 -191
  81. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +0 -258
  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 -232
  95. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScaleSizeScope.kt +0 -17
  96. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +0 -459
  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 -216
  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/platform/Platform.kt +0 -38
  107. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +0 -1329
  108. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +0 -62
  109. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +0 -88
  110. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -144
  111. package/gradle.properties +0 -19
  112. package/gradlew +0 -240
  113. package/gradlew.bat +0 -91
  114. package/ios/Application/ApplicationEnvironment.swift +0 -50
  115. package/ios/Application/Components.swift +0 -263
  116. package/ios/Application/ComposeApi.swift +0 -22
  117. package/ios/Application/FloatingButton.swift +0 -172
  118. package/ios/Application/HeaderRight.swift +0 -271
  119. package/ios/Application/Screen.swift +0 -249
  120. package/ios/Badge/BadgeDot.swift +0 -31
  121. package/ios/Button/Button.swift +0 -211
  122. package/ios/CalculatorKeyboard/CalculatorKeyboard.swift +0 -126
  123. package/ios/Checkbox/Checkbox.swift +0 -81
  124. package/ios/Chip/Chip.swift +0 -96
  125. package/ios/Colors+Radius+Spacing/Colors.swift +0 -172
  126. package/ios/Colors+Radius+Spacing/Radius.swift +0 -22
  127. package/ios/Colors+Radius+Spacing/Spacing.swift +0 -12
  128. package/ios/Extensions/Color++.swift +0 -25
  129. package/ios/Icon/Icon.swift +0 -51
  130. package/ios/Image/Image.swift +0 -70
  131. package/ios/Input/Input.swift +0 -207
  132. package/ios/Input/InputPhoneNumber.swift +0 -176
  133. package/ios/Input/InputSearch.swift +0 -238
  134. package/ios/Input/InputTextArea.swift +0 -242
  135. package/ios/Lottie/LottieView.swift +0 -86
  136. package/ios/OTPKeyboard/KeyboardButton.swift +0 -41
  137. package/ios/OTPKeyboard/OTPKeyboard.swift +0 -145
  138. package/ios/Popup/PopupDisplay.swift +0 -284
  139. package/ios/Popup/PopupInput.swift +0 -96
  140. package/ios/Popup/PopupPromotion.swift +0 -73
  141. package/ios/PopupView/FullscreenPopup.swift +0 -251
  142. package/ios/PopupView/Modifiers.swift +0 -158
  143. package/ios/PopupView/PopupView.swift +0 -289
  144. package/ios/PopupView/Utils++.swift +0 -281
  145. package/ios/ScrollIndicator/ScrollIndicator.swift +0 -110
  146. package/ios/Swipeable/SwipeCell.swift +0 -278
  147. package/ios/Swipeable/SwipeCellModel.swift +0 -86
  148. package/ios/Switch/Switch.swift +0 -44
  149. package/ios/Template/Logo/Logo.swift +0 -75
  150. package/ios/Template/TrustBanner/TrustBanner.swift +0 -120
  151. package/ios/Theme.md +0 -18
  152. package/ios/Typography/Text.swift +0 -140
  153. package/ios/Typography/Typography.swift +0 -95
  154. package/ios/native-kits.podspec +0 -18
  155. package/settings.gradle.kts +0 -25
@@ -1,22 +0,0 @@
1
- import SwiftUI
2
- import Foundation
3
-
4
- public enum Radius {
5
- public static let XXS: CGFloat = 2
6
- public static let XS: CGFloat = 4
7
- public static let S: CGFloat = 8
8
- public static let M: CGFloat = 12
9
- public static let L: CGFloat = 16
10
- public static let XL: CGFloat = 24
11
- }
12
-
13
- public struct RoundedCorner: Shape {
14
-
15
- var radius: CGFloat = .infinity
16
- var corners: UIRectCorner = .allCorners
17
-
18
- public func path(in rect: CGRect) -> Path {
19
- let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
20
- return Path(path.cgPath)
21
- }
22
- }
@@ -1,12 +0,0 @@
1
- import Foundation
2
-
3
- public enum Spacing {
4
- public static let XXS: CGFloat = 2
5
- public static let XS: CGFloat = 4
6
- public static let S: CGFloat = 8
7
- public static let M: CGFloat = 12
8
- public static let L: CGFloat = 16
9
- public static let XL: CGFloat = 24
10
- public static let XXL: CGFloat = 32
11
- public static let XXXL: CGFloat = 48
12
- }
@@ -1,25 +0,0 @@
1
- import SwiftUI
2
-
3
- public extension Color {
4
- init(hex: UInt, alpha: Double = 1) {
5
- self.init(
6
- .sRGB,
7
- red: Double((hex >> 16) & 0xFF) / 255,
8
- green: Double((hex >> 08) & 0xFF) / 255,
9
- blue: Double((hex >> 00) & 0xFF) / 255,
10
- opacity: alpha
11
- )
12
- }
13
-
14
- init(hex: String) {
15
- let scanner = Scanner(string: hex)
16
- var rgbValue: UInt64 = 0
17
- scanner.scanHexInt64(&rgbValue)
18
-
19
- let r = (rgbValue & 0xff0000) >> 16
20
- let g = (rgbValue & 0xff00) >> 8
21
- let b = rgbValue & 0xff
22
-
23
- self.init(red: Double(r) / 0xff, green: Double(g) / 0xff, blue: Double(b) / 0xff)
24
- }
25
- }
@@ -1,51 +0,0 @@
1
- import SwiftUI
2
-
3
- struct IconSource: Codable {
4
- let uri: String
5
- }
6
-
7
- func loadIconSources() -> [String: IconSource] {
8
- guard let url = Bundle.main.url(forResource: "icon", withExtension: "json") else {
9
- print("Error: icon.json not found")
10
- return [:]
11
- }
12
-
13
- do {
14
- let data = try Data(contentsOf: url)
15
- let decoded = try JSONDecoder().decode([String: IconSource].self, from: data)
16
- return decoded
17
- } catch {
18
- print("Error decoding icon.json: \(error)")
19
- return [:]
20
- }
21
- }
22
-
23
- // Load the JSON data into a global variable
24
- let iconSources: [String: IconSource] = loadIconSources()
25
-
26
- // Icon ViewModel
27
- public struct Icon: View {
28
- var source: String
29
- var size: CGFloat
30
- var color: Color?
31
- var accessibilityLabel: String?
32
-
33
- public init(
34
- source: String,
35
- size: CGFloat = 24,
36
- color: Color? = nil,
37
- accessibilityLabel: String? = nil
38
- ) {
39
- self.source = source
40
- self.size = size
41
- self.color = color
42
- self.accessibilityLabel = accessibilityLabel
43
- }
44
-
45
- public var body: some View {
46
- if let uri = iconSources[source]?.uri {
47
- ImageView(uri, color: color).frame(width: size, height: size)
48
- }
49
- }
50
- }
51
-
@@ -1,70 +0,0 @@
1
-
2
-
3
- import Foundation
4
- import SDWebImageSwiftUI
5
- import SkeletonUI
6
- import SwiftUI
7
-
8
- public struct ImageView: View {
9
- // MARK: Lifecycle
10
-
11
- public init(_ url: String, aspectRatio: CGFloat? = nil, contentMode: ContentMode = ContentMode.fit, placeholder: AnyView? = nil, color: Color? = nil) {
12
- self.url = url
13
- self.aspectRatio = aspectRatio
14
- self.contentMode = contentMode
15
- self.placeholder = placeholder
16
- self.color = color
17
- }
18
-
19
- // MARK: Public
20
-
21
- public var body: some View {
22
- return WebImage(url: URL(string: url), isAnimating: .constant(true))
23
- .onFailure { _ in
24
- error = true
25
- }
26
- .onSuccess { _, _, _ in
27
- error = false
28
- }
29
- .resizable()
30
- .renderingMode(color != nil ? .template : .original)
31
- .placeholder {
32
- VStack(alignment: .center, content: {
33
- if error {
34
- Image(systemName: "photo.badge.exclamationmark").frame(width: 24, height: 24)
35
- } else if placeholder != nil {
36
- placeholder
37
- }
38
- })
39
- .frame(maxWidth: .infinity, maxHeight: .infinity)
40
- .skeleton(with: !error && placeholder == nil)
41
- .shape(type: .rectangle)
42
- }
43
- .scaledToFit()
44
- .transition(.fade)
45
- .aspectRatio(aspectRatio, contentMode: contentMode)
46
- .foregroundColor(color)
47
- }
48
-
49
- // MARK: Internal
50
-
51
- var aspectRatio: CGFloat?
52
- var contentMode: ContentMode
53
- var placeholder: AnyView?
54
- var color: Color?
55
-
56
- @State var error: Bool = false
57
- var url: String
58
- }
59
-
60
- private struct ColorMultiplyModifier: ViewModifier {
61
- let color: Color?
62
-
63
- func body(content: Content) -> some View {
64
- if let color {
65
- content.colorMultiply(color)
66
- } else {
67
- content
68
- }
69
- }
70
- }
@@ -1,207 +0,0 @@
1
- import Foundation
2
- import SwiftUI
3
-
4
-
5
- fileprivate struct FloatingComponent: View {
6
- var floatingValue: String
7
- var floatingIcon: AnyView?
8
-
9
- public init (_ floatingValue: String = "", floatingIcon: AnyView? = nil){
10
- self.floatingValue = floatingValue
11
- self.floatingIcon = floatingIcon
12
- }
13
-
14
- public var body: some View {
15
- return HStack {
16
- Text(floatingValue)
17
- .font(.paragraph)
18
- .foregroundColor(Colors.black09)
19
- .font(.system(size: 12))
20
- .padding(.leading, 8)
21
- .padding(.trailing, 8)
22
- floatingIcon
23
- }
24
- .background(Colors.black01)
25
- .offset(x: 16, y:-8)
26
- .zIndex(10)
27
- }
28
- }
29
-
30
- struct DotTextField: View{
31
- @Binding var value: String
32
- @State var isHide: Bool = true
33
-
34
-
35
- func onToggle(){
36
- isHide.toggle()
37
- }
38
-
39
- public var body: some View {
40
- return HStack {
41
- if (isHide){
42
- SecureField("", text: $value)
43
- }
44
- else {
45
- TextField("", text: $value)
46
- }
47
-
48
- SwiftButton(action: onToggle){
49
- Image(systemName: isHide ? "eye.slash" : "eye")
50
- .foregroundColor(Colors.text)
51
- .frame(width: 16, height: 16)
52
- .padding(.leading, -4)
53
- }
54
-
55
-
56
- }
57
-
58
- }
59
- }
60
-
61
- public struct Input: View {
62
- @Binding var value: String
63
- @State var focused: Bool = false
64
-
65
- var placeholder: String
66
- var floatingValue: String
67
- var errorMessage: String
68
- var isSecure: Bool
69
- var keyboardType: UIKeyboardType
70
- var floatingIcon: AnyView?
71
- var rightIcon: AnyView?
72
- var onChange: ((String) -> Void)?
73
- var onBlur: (() -> Void)?
74
- var floatingIconURL: String?
75
- var floatingIconColor: Color?
76
- var size: InputSize
77
- var fontWeight: InputFontWeight
78
- var disabled: Bool
79
- var leadingIcon: String?
80
- var leadingIconColor: Color?
81
- var loading: Bool
82
- var required: Bool
83
- var hintText: String?
84
-
85
- func onCancel(){
86
- self.value.removeAll()
87
- }
88
-
89
- public init(_ value: Binding<String>, placeholder: String = "", floatingValue: String = "", multilines: Bool = false, errorMessage: String = "", isSecure: Bool = false, keyboardType: UIKeyboardType = .default, floatingIcon: AnyView? = nil, rightIcon: AnyView? = nil, onChange: ((String)->Void)? = nil, onBlur: (()->Void)? = nil, floatingIconURL: String? = nil, floatingIconColor: Color? = Colors.pink03, size: InputSize = .small, fontWeight: InputFontWeight = .regular, disabled: Bool = false, leadingIcon: String? = nil, leadingIconColor: Color? = Colors.pink03, loading: Bool = false, required: Bool = false, hintText: String? = nil){
90
- self.placeholder = placeholder
91
- self.floatingValue = floatingValue
92
- self.errorMessage = errorMessage
93
- self.isSecure = isSecure
94
- self._value = value
95
- self.keyboardType = keyboardType
96
- self.rightIcon = rightIcon
97
- self.floatingIcon = floatingIcon
98
- self.onChange = onChange
99
- self.floatingIconURL = floatingIconURL
100
- self.floatingIconColor = floatingIconColor
101
- self.size = size
102
- self.fontWeight = fontWeight
103
- self.disabled = disabled
104
- self.leadingIcon = leadingIcon
105
- self.leadingIconColor = leadingIconColor
106
- self.loading = loading
107
- self.required = required
108
- self.hintText = hintText
109
- }
110
-
111
- func onChangeText(value: String){
112
- onChange?(value)
113
- }
114
-
115
- public var body: some View {
116
- VStack(alignment: .leading, spacing: 4) {
117
- ZStack(alignment: .topLeading) {
118
- HStack(alignment: .center) {
119
- if let leadingIcon = leadingIcon {
120
- Icon(source: leadingIcon, size: 16, color: leadingIconColor)
121
- }
122
-
123
- if !isSecure {
124
- TextField("", text: $value, onEditingChanged: { isChange in
125
- self.focused = isChange
126
- })
127
- .disabled(disabled)
128
- .font(fontWeight == .bold ? .headline : .body)
129
- } else {
130
- DotTextField(value: $value)
131
- .disabled(disabled)
132
- }
133
-
134
- if loading {
135
- ActivityIndicator(isAnimating: .constant(true), style: .medium)
136
- .frame(width: 20, height: 20)
137
- } else if !value.isEmpty {
138
- SwiftButton(action: onCancel){
139
- Image(systemName: "x.circle.fill")
140
- .foregroundColor(Colors.text)
141
- .frame(width: 16, height: 16)
142
- .padding(.leading, -4)
143
- .padding(.trailing, 8)
144
- }
145
- }
146
-
147
- rightIcon
148
- }
149
- .padding(.horizontal, 12)
150
- .frame(height: size == .small ? 40 : 48)
151
- .background(disabled ? Colors.black01 : Color.white)
152
- .overlay(RoundedRectangle(cornerRadius: 8).stroke(focused ? Colors.pink03 : Colors.border, lineWidth: 1))
153
-
154
- if value.isEmpty {
155
- Text(placeholder + (required ? " *" : ""))
156
- .foregroundColor(Colors.black09)
157
- .padding(.horizontal, leadingIcon == nil ? 12 : 32)
158
- .padding(.top, 12)
159
- .allowsHitTesting(false)
160
- }
161
-
162
- if !floatingValue.isEmpty {
163
- FloatingComponent(floatingValue, floatingIcon: floatingIconURL.map { url in
164
- AnyView(
165
- Icon(source: url, size: 16, color: floatingIconColor)
166
- )
167
- })
168
-
169
- }
170
- }
171
-
172
- if !errorMessage.isEmpty {
173
- Text(errorMessage)
174
- .foregroundColor(.red)
175
- .font(.caption)
176
- } else if let hint = hintText {
177
- Text(hint)
178
- .foregroundColor(Colors.black09)
179
- .font(.caption)
180
- }
181
- }
182
- }
183
- }
184
-
185
-
186
- struct ActivityIndicator: UIViewRepresentable {
187
- @Binding var isAnimating: Bool
188
- let style: UIActivityIndicatorView.Style
189
-
190
- func makeUIView(context: UIViewRepresentableContext<ActivityIndicator>) -> UIActivityIndicatorView {
191
- return UIActivityIndicatorView(style: style)
192
- }
193
-
194
- func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext<ActivityIndicator>) {
195
- isAnimating ? uiView.startAnimating() : uiView.stopAnimating()
196
- }
197
- }
198
-
199
- public enum InputSize {
200
- case small
201
- case large
202
- }
203
-
204
- public enum InputFontWeight {
205
- case regular
206
- case bold
207
- }
@@ -1,176 +0,0 @@
1
- //
2
- // InputPhoneNumber.swift
3
- // Pods
4
- //
5
- // Created by sophia on 20/10/25.
6
- //
7
-
8
- import SwiftUI
9
-
10
- public struct InputPhoneNumber: View {
11
- @Binding public var text: String
12
-
13
- public var placeholder: String
14
- public var size: InputSize
15
- public var hintText: String
16
- public var error: String
17
- public var loading: Bool
18
- public var rightIcon: String
19
- public var rightIconColor: Color
20
- public var onFocus: (() -> Void)?
21
- public var onBlur: (() -> Void)?
22
- public var onRightIconPressed: (() -> Void)?
23
-
24
- @State private var isFocused: Bool = false
25
-
26
- public init(
27
- text: Binding<String>,
28
- placeholder: String = "0123456789",
29
- size: InputSize = .small,
30
- hintText: String = "",
31
- error: String = "",
32
- loading: Bool = false,
33
- required: Bool = false,
34
- rightIcon: String = "",
35
- rightIconColor: Color = Colors.black12,
36
- onFocus: (() -> Void)? = nil,
37
- onBlur: (() -> Void)? = nil,
38
- onRightIconPressed: (() -> Void)? = nil
39
- ) {
40
- self._text = text
41
- self.placeholder = placeholder
42
- self.size = size
43
- self.hintText = hintText
44
- self.error = error
45
- self.loading = loading
46
- self.rightIcon = rightIcon
47
- self.rightIconColor = rightIconColor
48
- self.onFocus = onFocus
49
- self.onBlur = onBlur
50
- self.onRightIconPressed = onRightIconPressed
51
- }
52
-
53
- // MARK: - Body
54
- public var body: some View {
55
- VStack(alignment: .leading, spacing: 4) {
56
- HStack(spacing: 0) {
57
- // 🇻🇳 Flag
58
- ImageView("https://static.momocdn.net/app/img/icon/ic-qrcode-package/ic_vn_flag.png")
59
- .frame(width: 24, height: 24)
60
- .padding(.trailing, Spacing.XS)
61
-
62
- MomoText("+84", typography: size == .small ? .headerSSemibold : .headerMBold)
63
- .foregroundColor(Colors.black17)
64
-
65
- Rectangle()
66
- .fill(Colors.black04)
67
- .frame(width: 1, height: size == .small ? 24 : 32)
68
- .padding(.horizontal, Spacing.M)
69
-
70
- // Text input
71
- ZStack(alignment: .leading) {
72
- if text.isEmpty {
73
- Text(placeholder)
74
- .foregroundColor(Colors.black12)
75
- .font(size == .small ? .header_s_semibold : .header_m_bold)
76
- }
77
-
78
- TextField("", text: $text, onEditingChanged: { focused in
79
- handleFocusChange(focused)
80
- })
81
- .keyboardType(.numberPad)
82
- .font(size == .small ? .header_s_semibold : .header_m_bold)
83
- .foregroundColor(Colors.black17)
84
- .applyPrimaryCursorColor()
85
- .lineLimit(1)
86
-
87
- }
88
-
89
- // Clear button
90
- if isFocused && !text.isEmpty {
91
- SwiftUI.Button(action: { text = "" }) {
92
- Icon(source: "24_navigation_close_circle_full", size: 16, color: Colors.black12)
93
- .padding(.leading, Spacing.S)
94
- }
95
- }
96
-
97
- // Loading indicator
98
- if loading {
99
- if #available(iOS 14.0, *) {
100
- ProgressView()
101
- .progressViewStyle(CircularProgressViewStyle(tint: Colors.black17))
102
- .frame(width: 16, height: 16)
103
- .padding(.leading, Spacing.S)
104
- } else {
105
- Image(systemName: "clock")
106
- .rotationEffect(.degrees(isFocused ? 360 : 0))
107
- .animation(Animation.linear(duration: 1).repeatForever(autoreverses: false))
108
- .frame(width: 16, height: 16)
109
- .padding(.leading, Spacing.S)
110
- }
111
- }
112
-
113
- // ✅ Right icon
114
- if !rightIcon.isEmpty {
115
- SwiftUI.Button(action: { onRightIconPressed?() }) {
116
- Icon(source: rightIcon, size: 24, color: rightIconColor)
117
- .padding(.leading, Spacing.S)
118
- }
119
- }
120
- }
121
- .padding(.horizontal, Spacing.M)
122
- .frame(height: size == .small ? 48 : 56)
123
- .overlay(
124
- RoundedRectangle(cornerRadius: Radius.S)
125
- .stroke(borderColor(), lineWidth: isFocused ? 1.5 : 1)
126
- )
127
-
128
- // Error or hint
129
- if (!error.isEmpty || !hintText.isEmpty) {
130
- HStack(spacing: 4) {
131
- Icon(source: "ic_error", size: 16, color: errorColor())
132
- MomoText(
133
- error.isEmpty ? (hintText.isEmpty ? "Không thể chỉnh sửa" : hintText) : error,
134
- typography: .descriptionDefaultRegular,
135
- color: errorColor()
136
- )
137
- }
138
- .padding(.top, Spacing.XS)
139
- }
140
- }
141
- }
142
-
143
- // MARK: - Helpers
144
-
145
- private func handleFocusChange(_ focused: Bool) {
146
- isFocused = focused
147
- if focused {
148
- onFocus?()
149
- } else {
150
- onBlur?()
151
- }
152
- }
153
-
154
- private func borderColor() -> Color {
155
- if !error.isEmpty { return Colors.red03 }
156
- if isFocused { return Colors.primary }
157
- return Colors.black04
158
- }
159
-
160
- private func errorColor() -> Color {
161
- !error.isEmpty ? Colors.red03 : Colors.black12
162
- }
163
- }
164
-
165
- private extension View {
166
- func applyPrimaryCursorColor() -> some View {
167
- if #available(iOS 15.0, *) {
168
- // Modern SwiftUI: use .tint() for cursor
169
- return self.tint(Colors.primary)
170
- } else {
171
- // iOS 13–14: return unchanged (no tint support)
172
- return self
173
- }
174
- }
175
- }
176
-