@momo-kits/native-kits 0.162.2-beta.26-debug → 0.162.2-beta.27-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 (197) hide show
  1. package/CLAUDE.md +1 -1
  2. package/compose/build.gradle.kts +1 -1
  3. package/compose/compose.podspec +1 -1
  4. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +0 -5
  5. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +1 -1
  6. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +0 -3
  7. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +55 -40
  8. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +0 -4
  9. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +2 -8
  10. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +75 -93
  11. package/gradle.properties +1 -1
  12. package/ios/Application/ApplicationEnvironment.swift +0 -11
  13. package/ios/Application/Components.swift +44 -34
  14. package/ios/Application/FloatingButton.swift +9 -10
  15. package/ios/Application/HeaderRight.swift +45 -79
  16. package/ios/Application/Screen.swift +1 -2
  17. package/ios/Badge/Badge.swift +14 -11
  18. package/ios/Badge/BadgeRibbon.swift +21 -12
  19. package/ios/Button/Button.swift +22 -61
  20. package/ios/Checkbox/Checkbox.swift +13 -14
  21. package/ios/Chip/Chip.swift +9 -23
  22. package/ios/Colors+Radius+Spacing/Colors.swift +12 -12
  23. package/ios/Extensions/Color++.swift +0 -32
  24. package/ios/Icon/Icon.swift +1 -6
  25. package/ios/Input/Input.swift +25 -41
  26. package/ios/Input/InputPhoneNumber.swift +19 -20
  27. package/ios/Input/InputSearch.swift +47 -100
  28. package/ios/Input/InputTextArea.swift +40 -66
  29. package/ios/Popup/PopupDisplay.swift +16 -8
  30. package/ios/Popup/PopupInput.swift +8 -2
  31. package/ios/Swipeable/SwipeCell.swift +0 -185
  32. package/ios/Swipeable/SwipeCellModel.swift +0 -21
  33. package/ios/Typography/Text.swift +5 -79
  34. package/ios/Typography/Typography.swift +0 -3
  35. package/ios/native-kits.podspec +8 -61
  36. package/package.json +1 -1
  37. package/publish.sh +0 -50
  38. package/.claude/settings.local.json +0 -39
  39. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/OsFontScale.android.kt +0 -7
  40. package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +0 -56
  41. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitFontScale.kt +0 -22
  42. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/OsFontScale.kt +0 -9
  43. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/OsFontScale.ios.kt +0 -66
  44. package/ios/Application/Navigation/BottomTab/BottomTab.swift +0 -103
  45. package/ios/Application/Navigation/BottomTab/BottomTabBar.swift +0 -215
  46. package/ios/Application/Navigation/BottomTab/CurvedContainer.swift +0 -65
  47. package/ios/Application/Navigation/HeaderBackProps.swift +0 -66
  48. package/ios/Application/Navigation/HeaderTitle.swift +0 -57
  49. package/ios/Application/Navigation/HeaderUser.swift +0 -209
  50. package/ios/Application/Navigation/NavigationContainer.swift +0 -176
  51. package/ios/Application/Navigation/NavigationOptions.swift +0 -109
  52. package/ios/Application/Navigation/Navigator.swift +0 -364
  53. package/ios/Application/Navigation/Overplay/BottomSheet.swift +0 -188
  54. package/ios/Application/Navigation/Overplay/ModalScreen.swift +0 -68
  55. package/ios/Application/Navigation/Overplay/SnackBar.swift +0 -144
  56. package/ios/Application/Navigation/component/Header.swift +0 -178
  57. package/ios/Application/Navigation/component/HeaderBackground.swift +0 -83
  58. package/ios/Application/Navigation/component/HeaderColor.swift +0 -65
  59. package/ios/Application/StackScreen.swift +0 -453
  60. package/ios/Avatar/Avatar.swift +0 -193
  61. package/ios/BaselineView/BaselineView.swift +0 -163
  62. package/ios/Carousel/Carousel.swift +0 -181
  63. package/ios/Collapse/Collapse.swift +0 -182
  64. package/ios/Colors+Radius+Spacing/Theme.swift +0 -295
  65. package/ios/DateTimePicker/DateTimePicker.swift +0 -210
  66. package/ios/DateTimePicker/DateTimePickerTypes.swift +0 -55
  67. package/ios/DateTimePicker/DateTimePickerUtils.swift +0 -167
  68. package/ios/DateTimePicker/WheelPicker.swift +0 -161
  69. package/ios/Divider/Divider.swift +0 -16
  70. package/ios/IconButton/IconButton.swift +0 -112
  71. package/ios/InputDropDown/InputDropDown.swift +0 -198
  72. package/ios/InputMoney/InputMoney.swift +0 -335
  73. package/ios/InputOTP/InputOTP.swift +0 -210
  74. package/ios/Loader/Loader.swift +0 -113
  75. package/ios/MoMoUIKits.podspec +0 -5
  76. package/ios/Pagination/PaginationDot.swift +0 -61
  77. package/ios/Pagination/PaginationNumber.swift +0 -35
  78. package/ios/Pagination/PaginationScroll.swift +0 -101
  79. package/ios/Pagination/PaginationWhiteDot.swift +0 -37
  80. package/ios/Popup/PopupNotify.swift +0 -219
  81. package/ios/ProgressInfo/ProgressInfo.swift +0 -294
  82. package/ios/Radio/Radio.swift +0 -70
  83. package/ios/Rating/Rating.swift +0 -82
  84. package/ios/Resources/MoMoUIKitsColors.xcassets/AccentColor.colorset/Contents.json +0 -11
  85. package/ios/Resources/MoMoUIKitsColors.xcassets/Background.colorset/Contents.json +0 -38
  86. package/ios/Resources/MoMoUIKitsColors.xcassets/Border.colorset/Contents.json +0 -38
  87. package/ios/Resources/MoMoUIKitsColors.xcassets/Card.colorset/Contents.json +0 -38
  88. package/ios/Resources/MoMoUIKitsColors.xcassets/Contents.json +0 -6
  89. package/ios/Resources/MoMoUIKitsColors.xcassets/Error.colorset/Contents.json +0 -38
  90. package/ios/Resources/MoMoUIKitsColors.xcassets/Primary.colorset/Contents.json +0 -38
  91. package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryDark.colorset/Contents.json +0 -38
  92. package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryLight.colorset/Contents.json +0 -38
  93. package/ios/Resources/MoMoUIKitsColors.xcassets/Secondary.colorset/Contents.json +0 -38
  94. package/ios/Resources/MoMoUIKitsColors.xcassets/Success.colorset/Contents.json +0 -38
  95. package/ios/Resources/MoMoUIKitsColors.xcassets/Text.colorset/Contents.json +0 -38
  96. package/ios/Resources/MoMoUIKitsColors.xcassets/TextSecondary.colorset/Contents.json +0 -38
  97. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/Contents.json +0 -9
  98. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-default.colorset/Contents.json +0 -38
  99. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-disable.colorset/Contents.json +0 -38
  100. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-pressed.colorset/Contents.json +0 -38
  101. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-selected.colorset/Contents.json +0 -38
  102. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-surface.colorset/Contents.json +0 -38
  103. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-tonal.colorset/Contents.json +0 -38
  104. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-default.colorset/Contents.json +0 -38
  105. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-disable.colorset/Contents.json +0 -38
  106. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/gradient.colorset/Contents.json +0 -38
  107. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/primary.colorset/Contents.json +0 -38
  108. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/secondary.colorset/Contents.json +0 -38
  109. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-container.colorset/Contents.json +0 -38
  110. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-primary.colorset/Contents.json +0 -38
  111. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-secondary.colorset/Contents.json +0 -38
  112. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-default.colorset/Contents.json +0 -38
  113. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-disable.colorset/Contents.json +0 -38
  114. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-hint.colorset/Contents.json +0 -38
  115. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-secondary.colorset/Contents.json +0 -38
  116. package/ios/Resources/MoMoUIKitsColors.xcassets/Warning.colorset/Contents.json +0 -38
  117. package/ios/Skeleton/Skeleton.swift +0 -99
  118. package/ios/Slider/Slider.swift +0 -237
  119. package/ios/Stepper/Stepper.swift +0 -220
  120. package/ios/Steps/Steps.swift +0 -451
  121. package/ios/SuggestAction/SuggestAction.swift +0 -97
  122. package/ios/TabView/TabView.swift +0 -530
  123. package/ios/Tag/Tag.swift +0 -98
  124. package/ios/Title/Title.swift +0 -269
  125. package/ios/Tooltip/Tooltip.swift +0 -482
  126. package/ios/Typography/FontScaleStore.swift +0 -19
  127. package/ios/Uploader/Uploader.swift +0 -183
  128. package/ios-demo/MoMoUIKitsDemo.podspec +0 -20
  129. package/ios-demo/README.md +0 -120
  130. package/ios-demo/Resources/dot_loading.json +0 -558
  131. package/ios-demo/Resources/icon.json +0 -4052
  132. package/ios-demo/Resources/lottie_circle_loader.json +0 -1
  133. package/ios-demo/Sources/MoMoUIKitsDemo/DemoScaffold.swift +0 -48
  134. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsBadgeDemoView.swift +0 -25
  135. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsButtonDemoView.swift +0 -26
  136. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsCheckboxDemoView.swift +0 -19
  137. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsChipDemoView.swift +0 -33
  138. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsInputDemoView.swift +0 -48
  139. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsPopupDemoView.swift +0 -21
  140. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsRadioDemoView.swift +0 -17
  141. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsTypographyDemoView.swift +0 -28
  142. package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoContext.swift +0 -31
  143. package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoFactory.swift +0 -24
  144. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AnimatedHeaderDemo.swift +0 -110
  145. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AvatarDemo.swift +0 -93
  146. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BadgeDemo.swift +0 -269
  147. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BaselineView.swift +0 -117
  148. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BottomTabDemo.swift +0 -89
  149. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ButtonDemo.swift +0 -100
  150. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CarouselDemo.swift +0 -126
  151. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CheckboxDemo.swift +0 -63
  152. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ChipDemo.swift +0 -20
  153. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CollapseDemo.swift +0 -93
  154. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +0 -107
  155. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DateTimePickerDemo.swift +0 -124
  156. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DividerDemo.swift +0 -14
  157. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/HeaderUserDemo.swift +0 -49
  158. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +0 -278
  159. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconButtonDemo.swift +0 -58
  160. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ImageDemo.swift +0 -78
  161. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InformationDemo.swift +0 -138
  162. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDemo.swift +0 -111
  163. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDropDownDemo.swift +0 -136
  164. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputMoneyDemo.swift +0 -107
  165. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputOTPDemo.swift +0 -73
  166. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputPhoneNumberDemo.swift +0 -100
  167. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputSearchDemo.swift +0 -32
  168. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputTextAreaDemo.swift +0 -57
  169. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LoaderDemo.swift +0 -70
  170. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +0 -227
  171. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PaginationDemo.swift +0 -72
  172. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +0 -175
  173. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +0 -121
  174. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +0 -76
  175. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ProgressInfoDemo.swift +0 -89
  176. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RadioDemo.swift +0 -32
  177. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RatingDemo.swift +0 -56
  178. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SkeletonDemo.swift +0 -32
  179. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SliderDemo.swift +0 -150
  180. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SnackBarDemo.swift +0 -138
  181. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepperDemo.swift +0 -103
  182. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepsDemo.swift +0 -94
  183. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SuggestActionDemo.swift +0 -79
  184. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwipeDemo.swift +0 -152
  185. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwitchDemo.swift +0 -33
  186. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TabViewDemo.swift +0 -190
  187. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TagDemo.swift +0 -34
  188. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ThemeDemo.swift +0 -182
  189. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TitleDemo.swift +0 -109
  190. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TooltipDemo.swift +0 -187
  191. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TypographyDemo.swift +0 -87
  192. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/UploaderDemo.swift +0 -131
  193. package/ios-demo/Sources/MoMoUIKitsDemo/SwiftUIDemoBrowserView.swift +0 -51
  194. package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoModels.swift +0 -15
  195. package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoRegistry.swift +0 -73
  196. package/local.properties +0 -8
  197. package/scripts/gen-ios-color.mjs +0 -136
@@ -1,167 +0,0 @@
1
- import Foundation
2
-
3
- // MARK: - DateTimePickerUtils
4
-
5
- /// Pure helper functions mirroring Compose `DateTimePickerUtils.kt`.
6
- public enum DateTimePickerUtils {
7
-
8
- /// Time mode list for 12-hour clock (only-hour format).
9
- public static let timeMode: [String] = ["AM", "PM"]
10
-
11
- /// Pad a number with a leading zero if it's less than 10.
12
- public static func paddingNum(_ num: Int) -> String {
13
- return num > 9 ? String(num) : "0\(num)"
14
- }
15
-
16
- /// Format a `Date` into a string, matching Compose `formatLocalDateTime`.
17
- public static func formatDate(
18
- _ date: Date,
19
- format: String = "yyyy-MM-dd HH:mm",
20
- calendar: Calendar = Calendar.current
21
- ) -> String {
22
- let c = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: date)
23
- let year = c.year ?? 0
24
- let month = c.month ?? 1
25
- let day = c.day ?? 1
26
- let hour = c.hour ?? 0
27
- let minute = c.minute ?? 0
28
-
29
- switch format {
30
- case "yyyy-MM-dd HH:mm":
31
- return "\(year)-\(paddingNum(month))-\(paddingNum(day)) \(paddingNum(hour)):\(paddingNum(minute))"
32
- case "dd-MM-yyyy":
33
- return "\(paddingNum(day))-\(paddingNum(month))-\(year)"
34
- case "HH:mm":
35
- return "\(paddingNum(hour)):\(paddingNum(minute))"
36
- default:
37
- return "\(year)-\(paddingNum(month))-\(paddingNum(day)) \(paddingNum(hour)):\(paddingNum(minute))"
38
- }
39
- }
40
-
41
- /// Number of days in a given month/year.
42
- private static func daysInMonth(year: Int, month: Int) -> Int {
43
- switch month {
44
- case 1, 3, 5, 7, 8, 10, 12: return 31
45
- case 4, 6, 9, 11: return 30
46
- case 2: return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? 29 : 28
47
- default: return 31
48
- }
49
- }
50
-
51
- /// Get a list of day strings constrained by min/max date.
52
- public static func getDaysInMonth(
53
- year: Int,
54
- month: Int,
55
- minDate: DateComponents,
56
- maxDate: DateComponents
57
- ) -> [String] {
58
- let maxDay = daysInMonth(year: year, month: month)
59
- var startDay = 1
60
- var endDay = maxDay
61
-
62
- if year == minDate.year && month == minDate.month {
63
- startDay = minDate.day ?? 1
64
- }
65
- if year == maxDate.year && month == maxDate.month {
66
- endDay = maxDate.day ?? maxDay
67
- }
68
-
69
- guard startDay <= endDay else { return [paddingNum(startDay)] }
70
- return (startDay...endDay).map { paddingNum($0) }
71
- }
72
-
73
- /// Get a list of month strings constrained by min/max date for a year.
74
- public static func getMonths(
75
- minDate: DateComponents,
76
- maxDate: DateComponents,
77
- currentYear: Int
78
- ) -> [String] {
79
- var startMonth = 1
80
- var endMonth = 12
81
-
82
- if currentYear == minDate.year {
83
- startMonth = minDate.month ?? 1
84
- }
85
- if currentYear == maxDate.year {
86
- endMonth = maxDate.month ?? 12
87
- }
88
-
89
- guard startMonth <= endMonth else { return [paddingNum(startMonth)] }
90
- return (startMonth...endMonth).map { paddingNum($0) }
91
- }
92
-
93
- /// Get a list of year strings between min and max date.
94
- public static func getYears(minDate: DateComponents, maxDate: DateComponents) -> [String] {
95
- let startYear = minDate.year ?? 0
96
- let endYear = maxDate.year ?? 0
97
- guard startYear <= endYear else { return [String(startYear)] }
98
- return (startYear...endYear).map { String($0) }
99
- }
100
-
101
- /// Get a list of hours for either a 12-hour or 24-hour clock.
102
- public static func getHours(hourMode: Int) -> [String] {
103
- var hours: [String] = []
104
- for i in 0..<hourMode {
105
- let hour = hourMode == 12 ? i + 1 : i
106
- hours.append(paddingNum(hour))
107
- }
108
- return hours
109
- }
110
-
111
- /// Get a list of minutes stepped by `interval`.
112
- public static func getMinutes(interval: Int) -> [String] {
113
- let step = max(1, interval)
114
- var minutes: [String] = []
115
- var min = 0
116
- while min < 60 {
117
- minutes.append(paddingNum(min))
118
- min += step
119
- }
120
- return minutes
121
- }
122
-
123
- /// Today's date.
124
- public static func getCurrentDateTime() -> Date {
125
- return Date()
126
- }
127
-
128
- /// Create a date a certain number of years before/after now.
129
- public static func createRelativeDate(years: Int, calendar: Calendar = Calendar.current) -> Date {
130
- let now = Date()
131
- return calendar.date(byAdding: .year, value: years, to: now) ?? now
132
- }
133
-
134
- /// Resolve the wheel columns from a format string. Mirrors Compose `getDateComponents`.
135
- public static func getDateComponents(
136
- format: String,
137
- currentData: DateTimePickerData,
138
- minDate: DateComponents,
139
- maxDate: DateComponents,
140
- minuteInterval: Int
141
- ) -> [DateTimePickerComponent] {
142
- let formatParts = format.split(whereSeparator: { !$0.isLetter }).map { String($0) }
143
- let isOnlyHour = formatParts.count == 1 && formatParts[0] == "HH"
144
-
145
- let dayData = getDaysInMonth(year: currentData.year, month: currentData.month, minDate: minDate, maxDate: maxDate)
146
- let monthData = getMonths(minDate: minDate, maxDate: maxDate, currentYear: currentData.year)
147
- let yearData = getYears(minDate: minDate, maxDate: maxDate)
148
- let hourData = getHours(hourMode: isOnlyHour ? 12 : 24)
149
- let minData = getMinutes(interval: minuteInterval)
150
-
151
- var components: [DateTimePickerComponent] = []
152
- for part in formatParts {
153
- switch part {
154
- case "DD": components.append(DateTimePickerComponent(name: "day", data: dayData))
155
- case "MM": components.append(DateTimePickerComponent(name: "month", data: monthData))
156
- case "YYYY": components.append(DateTimePickerComponent(name: "year", data: yearData))
157
- case "HH": components.append(DateTimePickerComponent(name: "hour", data: hourData))
158
- case "mm": components.append(DateTimePickerComponent(name: "minute", data: minData))
159
- default: break
160
- }
161
- }
162
- if isOnlyHour {
163
- components.append(DateTimePickerComponent(name: "timeMode", data: timeMode))
164
- }
165
- return components
166
- }
167
- }
@@ -1,161 +0,0 @@
1
- import SwiftUI
2
-
3
- // MARK: - Constants
4
-
5
- private let wheelItemHeight: CGFloat = 42
6
- private let wheelVisibleCount: Int = 5
7
- private let wheelPickerBorderWidth: CGFloat = 1
8
-
9
- // MARK: - WheelPicker
10
-
11
- /// A reusable single-column wheel picker, mirroring Compose `WheelPicker.kt`.
12
- ///
13
- /// The data is padded with two empty rows at the top and bottom so the first/last
14
- /// real value can be centered. The currently centered row is reported back via
15
- /// `onChange(name, value)`.
16
- public struct WheelPicker: View {
17
- // MARK: Lifecycle
18
-
19
- public init(
20
- name: String,
21
- data: [String],
22
- selectedData: String,
23
- onChange: @escaping (String, String) -> Void
24
- ) {
25
- self.name = name
26
- self.data = data
27
- self.selectedData = selectedData
28
- self.onChange = onChange
29
- }
30
-
31
- // MARK: Public
32
-
33
- public var body: some View {
34
- let paddedData = ["", ""] + data + ["", ""]
35
-
36
- return GeometryReader { geo in
37
- let height = geo.size.height
38
- ScrollViewReader { proxy in
39
- ScrollView(.vertical, showsIndicators: false) {
40
- LazyVStack(spacing: 0) {
41
- ForEach(Array(paddedData.enumerated()), id: \.offset) { index, text in
42
- WheelPickerItem(
43
- text: text,
44
- isSelected: index == selectedIndex,
45
- index: index,
46
- scrollOffset: scrollOffset,
47
- viewportHeight: height
48
- )
49
- .frame(height: wheelItemHeight)
50
- .id(index)
51
- }
52
- }
53
- .background(
54
- GeometryReader { inner in
55
- Color.clear.preference(
56
- key: WheelOffsetKey.self,
57
- value: inner.frame(in: .named(scrollSpace)).minY
58
- )
59
- }
60
- )
61
- }
62
- .coordinateSpace(name: scrollSpace)
63
- .onPreferenceChange(WheelOffsetKey.self) { value in
64
- scrollOffset = value
65
- updateSelection(paddedData: paddedData, viewportHeight: height)
66
- }
67
- .onAppear {
68
- let initial = max(paddedData.firstIndex(of: selectedData) ?? 2, 2)
69
- selectedIndex = initial
70
- DispatchQueue.main.async {
71
- proxy.scrollTo(initial, anchor: .center)
72
- }
73
- }
74
- }
75
- }
76
- .frame(height: wheelItemHeight * CGFloat(wheelVisibleCount))
77
- .overlay(
78
- RoundedRectangle(cornerRadius: Radius.S)
79
- .stroke(Colors.border, lineWidth: wheelPickerBorderWidth)
80
- )
81
- .background(Colors.background.clipShape(RoundedRectangle(cornerRadius: Radius.S)))
82
- .overlay(
83
- // Centered translucent selection band.
84
- Rectangle()
85
- .fill(Colors.blue10)
86
- .opacity(0.2)
87
- .frame(height: wheelItemHeight)
88
- .allowsHitTesting(false)
89
- )
90
- .clipShape(RoundedRectangle(cornerRadius: Radius.S))
91
- }
92
-
93
- // MARK: Internal
94
-
95
- let name: String
96
- let data: [String]
97
- let selectedData: String
98
- let onChange: (String, String) -> Void
99
-
100
- @State private var selectedIndex: Int = 0
101
- @State private var scrollOffset: CGFloat = 0
102
-
103
- private let scrollSpace = "wheelScroll"
104
-
105
- /// Map the current scroll offset to the centered index and report changes.
106
- private func updateSelection(paddedData: [String], viewportHeight: CGFloat) {
107
- // `scrollOffset` is the top of the content relative to the viewport (<= 0 when scrolled).
108
- let centerY = viewportHeight / 2
109
- let contentCenter = -scrollOffset + centerY
110
- let rawIndex = Int((contentCenter / wheelItemHeight).rounded()) - 1
111
- let clamped = max(2, min(rawIndex, paddedData.count - 3))
112
- guard clamped != selectedIndex else { return }
113
- selectedIndex = clamped
114
- let value = paddedData[clamped]
115
- if !value.isEmpty {
116
- onChange(name, value)
117
- }
118
- }
119
- }
120
-
121
- // MARK: - WheelPickerItem
122
-
123
- private struct WheelPickerItem: View {
124
- let text: String
125
- let isSelected: Bool
126
- let index: Int
127
- let scrollOffset: CGFloat
128
- let viewportHeight: CGFloat
129
-
130
- var body: some View {
131
- let itemCenterInContent = CGFloat(index) * wheelItemHeight + wheelItemHeight / 2
132
- let itemCenterInViewport = itemCenterInContent + scrollOffset
133
- let distanceFromCenter = abs(itemCenterInViewport - viewportHeight / 2) / wheelItemHeight
134
-
135
- let alpha: Double
136
- switch distanceFromCenter {
137
- case ..<1: alpha = 1.0
138
- case ..<2: alpha = 0.8
139
- default: alpha = 0.4
140
- }
141
-
142
- let scale: CGFloat = isSelected ? 1.0 : 0.87
143
-
144
- return ZStack {
145
- MomoText(text, typography: .actionSBold, color: Colors.text)
146
- .scaleEffect(scale)
147
- }
148
- .frame(maxWidth: .infinity)
149
- .frame(height: wheelItemHeight)
150
- .opacity(alpha)
151
- }
152
- }
153
-
154
- // MARK: - WheelOffsetKey
155
-
156
- private struct WheelOffsetKey: PreferenceKey {
157
- static var defaultValue: CGFloat = 0
158
- static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
159
- value = nextValue()
160
- }
161
- }
@@ -1,16 +0,0 @@
1
- import Foundation
2
- import SwiftUI
3
-
4
- public struct MomoDivider: View {
5
- @Environment(\.appTheme) private var theme
6
-
7
- public init() {}
8
-
9
- public var body: some View {
10
- Rectangle()
11
- .fill(theme.colors.border.default)
12
- .frame(maxWidth: .infinity)
13
- .frame(height: 1)
14
- .padding(.vertical, Spacing.XS)
15
- }
16
- }
@@ -1,112 +0,0 @@
1
- import Foundation
2
- import SwiftUI
3
-
4
- // MARK: - IconSize
5
-
6
- public enum IconSize {
7
- case large
8
- case small
9
-
10
- /// Container width/height of the button.
11
- var containerSize: CGFloat {
12
- switch self {
13
- case .large: return 48
14
- case .small: return 40
15
- }
16
- }
17
-
18
- /// Glyph size of the icon inside the button.
19
- var iconSize: CGFloat {
20
- switch self {
21
- case .large: return 24
22
- case .small: return 16
23
- }
24
- }
25
-
26
- var radius: CGFloat {
27
- Radius.XL
28
- }
29
- }
30
-
31
- // MARK: - IconButton
32
-
33
- public struct IconButton: View {
34
- @Environment(\.appTheme) private var theme
35
-
36
- var icon: String
37
- var onClick: () -> Void
38
- var type: ButtonType
39
- var size: IconSize
40
- var color: Color?
41
-
42
- public init(
43
- icon: String = "",
44
- onClick: @escaping () -> Void,
45
- type: ButtonType = .primary,
46
- size: IconSize = .small,
47
- color: Color? = nil
48
- ) {
49
- self.icon = icon
50
- self.onClick = onClick
51
- self.type = type
52
- self.size = size
53
- self.color = color
54
- }
55
-
56
- private var isEnabled: Bool {
57
- type != .disabled
58
- }
59
-
60
- public var body: some View {
61
- let bg = backgroundColor
62
- let fg = contentColor
63
- // OUTLINE allows an override color for its border, mirroring Compose `color ?? theme.colors.primary`.
64
- let border: Color? = type == .outline ? (color ?? theme.colors.primary) : borderColor
65
- let borderWidth = type.borderWidth
66
-
67
- SwiftUI.Button(action: {
68
- if isEnabled {
69
- onClick()
70
- }
71
- }) {
72
- Icon(source: icon, size: size.iconSize, color: fg)
73
- .frame(width: size.containerSize, height: size.containerSize)
74
- .background(bg)
75
- .clipShape(RoundedRectangle(cornerRadius: size.radius))
76
- .overlay(
77
- RoundedRectangle(cornerRadius: size.radius)
78
- .stroke(border ?? .clear, lineWidth: border != nil ? borderWidth : 0)
79
- )
80
- }
81
- .buttonStyle(.plain)
82
- .disabled(!isEnabled)
83
- }
84
-
85
- private var backgroundColor: Color {
86
- switch type {
87
- case .disabled: return theme.colors.background.disable
88
- case .primary: return theme.colors.primary
89
- case .secondary, .outline: return theme.colors.background.surface
90
- case .tonal: return theme.colors.background.tonal
91
- case .danger: return theme.colors.error.primary
92
- case .text: return .clear
93
- }
94
- }
95
-
96
- private var contentColor: Color {
97
- switch type {
98
- case .disabled: return theme.colors.text.disable
99
- case .primary, .danger: return Colors.black01
100
- case .secondary: return theme.colors.text.default
101
- case .outline, .tonal, .text: return theme.colors.primary
102
- }
103
- }
104
-
105
- private var borderColor: Color? {
106
- switch type {
107
- case .secondary: return theme.colors.border.default
108
- case .outline: return color ?? theme.colors.primary
109
- default: return nil
110
- }
111
- }
112
- }
@@ -1,198 +0,0 @@
1
- //
2
- // InputDropDown.swift
3
- // Pods
4
- //
5
- // Hand-written SwiftUI reimplementation of Compose `InputDropDown`.
6
- //
7
-
8
- import SwiftUI
9
-
10
- // MARK: - RenderRightIcon (mirrors Compose RenderRightIcon for InputDropDown)
11
-
12
- private struct RenderRightIcon: View {
13
- let loading: Bool
14
- let icon: String
15
- let color: Color
16
- let onPressed: () -> Void
17
-
18
- var body: some View {
19
- if loading {
20
- ActivityIndicator(isAnimating: .constant(true), style: .medium)
21
- .frame(width: 16, height: 16)
22
- } else if !icon.isEmpty {
23
- SwiftUI.Button(action: onPressed) {
24
- Icon(source: icon, size: 24, color: color)
25
- }
26
- }
27
- }
28
- }
29
-
30
- // MARK: - InputDropDown
31
-
32
- public struct InputDropDown: View {
33
- @Environment(\.appTheme) private var theme
34
- @Binding public var value: String
35
-
36
- public var floatingValue: String
37
- public var floatingValueColor: Color?
38
- public var floatingIcon: String
39
- public var floatingIconColor: Color?
40
- public var placeholder: String
41
- public var size: InputSize
42
- public var onPress: () -> Void
43
- public var hintText: String
44
- public var error: String
45
- public var errorSpacing: Bool
46
- public var disabled: Bool
47
- public var icon: String
48
- public var iconColor: Color?
49
- public var onRightIconPressed: () -> Void
50
- public var leadingIcon: String
51
- public var leadingIconColor: Color?
52
- public var loading: Bool
53
- public var required: Bool
54
-
55
- public init(
56
- value: Binding<String>,
57
- floatingValue: String = "",
58
- floatingValueColor: Color? = nil,
59
- floatingIcon: String = "",
60
- floatingIconColor: Color? = nil,
61
- placeholder: String = "",
62
- size: InputSize = .small,
63
- onPress: @escaping () -> Void = {},
64
- hintText: String = "",
65
- error: String = "",
66
- errorSpacing: Bool = false,
67
- disabled: Bool = false,
68
- icon: String = "arrow_chevron_down_small",
69
- iconColor: Color? = nil,
70
- onRightIconPressed: @escaping () -> Void = {},
71
- leadingIcon: String = "",
72
- leadingIconColor: Color? = nil,
73
- loading: Bool = false,
74
- required: Bool = false
75
- ) {
76
- self._value = value
77
- self.floatingValue = floatingValue
78
- self.floatingValueColor = floatingValueColor
79
- self.floatingIcon = floatingIcon
80
- self.floatingIconColor = floatingIconColor
81
- self.placeholder = placeholder
82
- self.size = size
83
- self.onPress = onPress
84
- self.hintText = hintText
85
- self.error = error
86
- self.errorSpacing = errorSpacing
87
- self.disabled = disabled
88
- self.icon = icon
89
- self.iconColor = iconColor
90
- self.onRightIconPressed = onRightIconPressed
91
- self.leadingIcon = leadingIcon
92
- self.leadingIconColor = leadingIconColor
93
- self.loading = loading
94
- self.required = required
95
- }
96
-
97
- public var body: some View {
98
- VStack(alignment: .leading, spacing: 4) {
99
- ZStack(alignment: .topLeading) {
100
- // Floating label
101
- if !floatingValue.isEmpty || !floatingIcon.isEmpty {
102
- HStack(spacing: 0) {
103
- MomoText(floatingValue, typography: .labelSMedium, color: floatingTitleColor)
104
- if required {
105
- MomoText("*", typography: .labelSMedium, color: theme.colors.error.primary)
106
- }
107
- if !floatingIcon.isEmpty {
108
- Icon(source: floatingIcon, size: 16, color: floatingIconTintColor)
109
- .padding(.leading, Spacing.XS)
110
- }
111
- }
112
- .padding(.horizontal, Spacing.S)
113
- .background(theme.colors.background.surface)
114
- .offset(x: Spacing.S, y: -8)
115
- .zIndex(10)
116
- }
117
-
118
- // Input container
119
- HStack(alignment: .center, spacing: 0) {
120
- if !leadingIcon.isEmpty {
121
- Icon(source: leadingIcon, size: size == .small ? 24 : 32, color: leadingIconTintColor)
122
- .padding(.trailing, Spacing.M)
123
- }
124
-
125
- MomoText(
126
- value.isEmpty ? placeholder : value,
127
- typography: .bodyDefaultRegular,
128
- color: value.isEmpty ? placeholderColor : textColor
129
- )
130
- .frame(maxWidth: .infinity, alignment: .leading)
131
-
132
- RenderRightIcon(
133
- loading: loading,
134
- icon: icon,
135
- color: iconTintColor,
136
- onPressed: onRightIconPressed
137
- )
138
- }
139
- .padding(.horizontal, Spacing.M)
140
- .frame(height: size == .small ? 48 : 56)
141
- .overlay(
142
- RoundedRectangle(cornerRadius: Radius.S)
143
- .stroke(getBorderColor(isFocused: false, error: error, disabled: disabled), lineWidth: 1)
144
- )
145
- }
146
- .contentShape(Rectangle())
147
- .onTapGesture {
148
- if !disabled { onPress() }
149
- }
150
-
151
- ErrorView(
152
- errorMessage: error,
153
- errorSpacing: errorSpacing,
154
- hintText: hintText
155
- )
156
- }
157
- .accessibilityElement(children: .combine)
158
- .accessibility(label: Text(floatingValue))
159
- }
160
-
161
- // MARK: - Computed colors
162
-
163
- private var textColor: Color {
164
- disabled ? theme.colors.text.disable : theme.colors.text.default
165
- }
166
-
167
- private var placeholderColor: Color {
168
- disabled ? theme.colors.text.disable : theme.colors.text.hint
169
- }
170
-
171
- private var iconTintColor: Color {
172
- disabled ? theme.colors.text.disable : (iconColor ?? theme.colors.text.default)
173
- }
174
-
175
- private var floatingTitleColor: Color {
176
- disabled ? theme.colors.text.disable : (floatingValueColor ?? theme.colors.text.hint)
177
- }
178
-
179
- private var floatingIconTintColor: Color {
180
- disabled ? theme.colors.text.disable : (floatingIconColor ?? theme.colors.text.default)
181
- }
182
-
183
- private var leadingIconTintColor: Color {
184
- disabled ? theme.colors.text.disable : (leadingIconColor ?? theme.colors.text.hint)
185
- }
186
-
187
- private func getBorderColor(isFocused: Bool, error: String, disabled: Bool) -> Color {
188
- if disabled {
189
- return theme.colors.border.disable
190
- } else if !error.isEmpty {
191
- return theme.colors.error.primary
192
- } else if isFocused {
193
- return theme.colors.primary
194
- } else {
195
- return theme.colors.border.default
196
- }
197
- }
198
- }