@momo-kits/native-kits 0.162.30-debug → 0.162.31-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 (93) hide show
  1. package/CLAUDE.md +19 -0
  2. package/compose/build.gradle.kts +1 -1
  3. package/compose/compose.podspec +1 -1
  4. package/gradle.properties +1 -1
  5. package/ios/Application/ApplicationEnvironment.swift +14 -6
  6. package/ios/Application/LanguageSource.swift +93 -0
  7. package/ios/Application/Localize.swift +73 -4
  8. package/ios/Application/LocalizeModifier.swift +30 -0
  9. package/ios/Application/Navigation/NavigationContainer.swift +28 -18
  10. package/ios/Application/Navigation/Navigator.swift +121 -53
  11. package/ios/Application/Navigation/NavigatorManager.swift +49 -0
  12. package/ios/Application/Navigation/component/NavigationFooter.swift +90 -0
  13. package/ios/Application/StackScreen.swift +19 -28
  14. package/ios/Badge/Badge.swift +2 -1
  15. package/ios/Badge/BadgeRibbon.swift +6 -2
  16. package/ios/Button/Button.swift +41 -61
  17. package/ios/Chip/Chip.swift +6 -5
  18. package/ios/Icon/Icon.swift +13 -4
  19. package/ios/Input/ErrorView.swift +2 -1
  20. package/ios/Input/Input.swift +9 -2
  21. package/ios/Input/InputPhoneNumber.swift +2 -1
  22. package/ios/Input/InputSearch.swift +3 -2
  23. package/ios/Input/InputTextArea.swift +6 -1
  24. package/ios/InputMoney/InputMoney.swift +5 -2
  25. package/ios/InputOTP/InputOTP.swift +2 -1
  26. package/ios/Layout/GridContext.swift +30 -0
  27. package/ios/Layout/Item.swift +42 -0
  28. package/ios/Layout/Section.swift +134 -0
  29. package/ios/Popup/PopupNotify.swift +2 -1
  30. package/ios/ProgressInfo/ProgressInfo.swift +4 -3
  31. package/ios/Rating/Rating.swift +2 -1
  32. package/ios/Stepper/Stepper.swift +2 -1
  33. package/ios/SuggestAction/SuggestAction.swift +3 -2
  34. package/ios/Tag/Tag.swift +2 -1
  35. package/ios/Template/TrustBanner/TrustBanner.swift +4 -2
  36. package/ios/Title/Title.swift +3 -2
  37. package/ios/Tooltip/Tooltip.swift +2 -1
  38. package/ios/Typography/FontScale.swift +103 -0
  39. package/ios/Typography/FontScaleStore.swift +52 -13
  40. package/ios/Typography/Text.swift +12 -29
  41. package/ios/Typography/Typography.swift +66 -86
  42. package/ios/native-kits.podspec +2 -1
  43. package/ios-demo/MoMoUIKitsDemo.podspec +1 -1
  44. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AvatarDemo.swift +87 -73
  45. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BadgeDemo.swift +55 -249
  46. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ButtonDemo.swift +90 -82
  47. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CarouselDemo.swift +74 -104
  48. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CheckboxDemo.swift +47 -50
  49. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ChipDemo.swift +63 -7
  50. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CollapseDemo.swift +90 -81
  51. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DateTimePickerDemo.swift +73 -97
  52. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DemoScreen.swift +420 -0
  53. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DividerDemo.swift +46 -4
  54. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +54 -57
  55. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconButtonDemo.swift +80 -45
  56. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconDemo.swift +81 -0
  57. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ImageDemo.swift +49 -62
  58. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InformationDemo.swift +66 -116
  59. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDemo.swift +104 -98
  60. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDropDownDemo.swift +76 -118
  61. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputMoneyDemo.swift +73 -86
  62. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputOTPDemo.swift +69 -54
  63. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputPhoneNumberDemo.swift +74 -54
  64. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputSearchDemo.swift +73 -20
  65. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputTextAreaDemo.swift +68 -38
  66. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LoaderDemo.swift +55 -52
  67. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LocalizeDemo.swift +51 -4
  68. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +14 -2
  69. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PaginationDemo.swift +47 -51
  70. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PlaygroundData.swift +76 -0
  71. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +67 -93
  72. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +34 -43
  73. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ProgressInfoDemo.swift +83 -71
  74. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RadioDemo.swift +55 -23
  75. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RatingDemo.swift +58 -46
  76. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SectionDemo.swift +83 -0
  77. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SkeletonDemo.swift +41 -12
  78. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SliderDemo.swift +67 -127
  79. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SnackBarDemo.swift +54 -110
  80. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepperDemo.swift +69 -79
  81. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepsDemo.swift +78 -58
  82. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SuggestActionDemo.swift +76 -65
  83. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwipeDemo.swift +82 -127
  84. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwitchDemo.swift +44 -19
  85. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TabViewDemo.swift +92 -168
  86. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TagDemo.swift +79 -27
  87. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ThemeDemo.swift +0 -1
  88. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TitleDemo.swift +87 -92
  89. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TooltipDemo.swift +94 -163
  90. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TypographyDemo.swift +70 -70
  91. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/UploaderDemo.swift +68 -114
  92. package/ios-demo/Sources/MoMoUIKitsDemo/SwiftUIDemoBrowserView.swift +3 -1
  93. package/package.json +2 -2
@@ -1,93 +1,102 @@
1
- import SwiftUI
1
+ //
2
+ // CollapseDemo.swift
3
+ // Example
4
+ //
5
+ // Preview + Playground demo (DemoScreen pattern).
6
+ //
7
+
2
8
  import MoMoUIKits
9
+ import SwiftUI
10
+
11
+ private let collapseTitleSizeList: [PlaygroundOption] = [
12
+ .init("small", CollapseTitleSize.small),
13
+ .init("medium", CollapseTitleSize.medium),
14
+ .init("large", CollapseTitleSize.large),
15
+ ]
3
16
 
4
17
  struct CollapseDemo: View {
5
18
  var body: some View {
6
- ScrollView {
7
- VStack(alignment: .leading, spacing: 24) {
8
- section("Default") {
9
- Collapse(title: "Default collapse") {
10
- MomoText("This is the expanded content.", typography: .bodyDefaultRegular)
11
- .padding(Spacing.M)
12
- }
13
- }
14
-
15
- section("With Border") {
16
- Collapse(title: "With border", showBorder: true) {
17
- MomoText("Content inside a bordered collapse.", typography: .bodyDefaultRegular)
18
- .padding(Spacing.M)
19
- }
20
- }
21
-
22
- section("Expanded by Default") {
23
- Collapse(title: "Pre-expanded", expandDefault: true) {
24
- MomoText("This collapse starts expanded.", typography: .bodyDefaultRegular)
25
- .padding(Spacing.M)
26
- }
27
- }
28
-
29
- section("With Description") {
30
- Collapse(
31
- title: "Collapse with description",
32
- description: "A brief description below the title."
33
- ) {
34
- MomoText("Detailed content.", typography: .bodyDefaultRegular)
35
- .padding(Spacing.M)
36
- }
37
- }
38
-
39
- section("Title Sizes") {
40
- Collapse(title: "Small title", titleSize: .small) {
41
- MomoText("Content", typography: .bodyDefaultRegular).padding(Spacing.M)
42
- }
43
- Collapse(title: "Medium title", titleSize: .medium) {
44
- MomoText("Content", typography: .bodyDefaultRegular).padding(Spacing.M)
45
- }
46
- Collapse(title: "Large title", titleSize: .large) {
47
- MomoText("Content", typography: .bodyDefaultRegular).padding(Spacing.M)
48
- }
49
- }
50
-
51
- section("With SubTitle") {
52
- Collapse(title: "Collapse with subTitle", subTitle: "Sub") {
53
- MomoText("Content", typography: .bodyDefaultRegular).padding(Spacing.M)
54
- }
55
- }
56
-
57
- section("With Tag") {
58
- Collapse(title: "Collapse with tag", tagLabel: "New", tagColor: .red) {
59
- MomoText("Content", typography: .bodyDefaultRegular).padding(Spacing.M)
60
- }
61
- }
19
+ if #available(iOS 16.0, *) {
20
+ DemoScreen(preview: { CollapsePreview() }, playground: { CollapsePlayground() })
21
+ } else {
22
+ Text("Requires iOS 16+").padding()
23
+ }
24
+ }
25
+ }
62
26
 
63
- section("Background Collapse Button") {
64
- Collapse(title: "Tonal chevron button", useBackgroundCollapseButton: true) {
65
- MomoText("Chevron has tonal background.", typography: .bodyDefaultRegular)
66
- .padding(Spacing.M)
67
- }
68
- }
27
+ // MARK: - Preview
69
28
 
70
- section("With Image") {
71
- Collapse(
72
- title: "Collapse with image",
73
- image: "https://static.momocdn.net/img/momo_icon.png",
74
- imageSize: 40,
75
- showBorder: true
76
- ) {
77
- MomoText("Content with leading image.", typography: .bodyDefaultRegular)
78
- .padding(Spacing.M)
79
- }
80
- }
29
+ private struct CollapsePreview: View {
30
+ var body: some View {
31
+ BasicColumnBox("Default", alignment: .leading) {
32
+ Collapse(title: "Default collapse") {
33
+ MomoText("This is the expanded content.", typography: .bodyDefaultRegular).padding(Spacing.M)
34
+ }
35
+ }
36
+ BasicColumnBox("With Border", alignment: .leading) {
37
+ Collapse(title: "With border", showBorder: true) {
38
+ MomoText("Content inside a bordered collapse.", typography: .bodyDefaultRegular).padding(Spacing.M)
39
+ }
40
+ }
41
+ BasicColumnBox("Expanded by Default", alignment: .leading) {
42
+ Collapse(title: "Pre-expanded", expandDefault: true) {
43
+ MomoText("This collapse starts expanded.", typography: .bodyDefaultRegular).padding(Spacing.M)
44
+ }
45
+ }
46
+ BasicColumnBox("With Description", alignment: .leading) {
47
+ Collapse(title: "Collapse with description", description: "A brief description below the title.") {
48
+ MomoText("Detailed content.", typography: .bodyDefaultRegular).padding(Spacing.M)
49
+ }
50
+ }
51
+ BasicColumnBox("Title Sizes", alignment: .leading) {
52
+ Collapse(title: "Small title", titleSize: .small) {
53
+ MomoText("Content", typography: .bodyDefaultRegular).padding(Spacing.M)
54
+ }
55
+ Collapse(title: "Large title", titleSize: .large) {
56
+ MomoText("Content", typography: .bodyDefaultRegular).padding(Spacing.M)
57
+ }
58
+ }
59
+ BasicColumnBox("With Tag", alignment: .leading) {
60
+ Collapse(title: "Collapse with tag", tagLabel: "New", tagColor: .red) {
61
+ MomoText("Content", typography: .bodyDefaultRegular).padding(Spacing.M)
81
62
  }
82
- .padding()
83
63
  }
84
64
  }
65
+ }
85
66
 
86
- @ViewBuilder
87
- private func section<Content: View>(_ title: String, @ViewBuilder content: () -> Content) -> some View {
88
- VStack(alignment: .leading, spacing: 8) {
89
- Text(title).font(.headline)
90
- content()
91
- }
67
+ // MARK: - Playground
68
+
69
+ @available(iOS 16.0, *)
70
+ private struct CollapsePlayground: View {
71
+ @State private var title = "Collapse title"
72
+ @State private var description = ""
73
+ @State private var showBorder = false
74
+ @State private var expandDefault = false
75
+ @State private var titleSize: PlaygroundOption? = collapseTitleSizeList.first { $0.key == "medium" }
76
+ @State private var useBackgroundCollapseButton = false
77
+
78
+ var body: some View {
79
+ PlaygroundTab(
80
+ component: {
81
+ Collapse(
82
+ title: title,
83
+ description: description.isEmpty ? nil : description,
84
+ showBorder: showBorder,
85
+ expandDefault: expandDefault,
86
+ titleSize: (titleSize?.value as? CollapseTitleSize) ?? .medium,
87
+ useBackgroundCollapseButton: useBackgroundCollapseButton
88
+ ) {
89
+ MomoText("Expanded content.", typography: .bodyDefaultRegular).padding(Spacing.M)
90
+ }
91
+ },
92
+ params: [
93
+ .string("Title", $title),
94
+ .string("Description", $description),
95
+ .checkbox("ShowBorder", $showBorder),
96
+ .checkbox("ExpandDefault", $expandDefault),
97
+ .radio("TitleSize", collapseTitleSizeList, $titleSize),
98
+ .checkbox("BackgroundCollapseButton", $useBackgroundCollapseButton),
99
+ ]
100
+ )
92
101
  }
93
102
  }
@@ -2,123 +2,99 @@
2
2
  // DateTimePickerDemo.swift
3
3
  // Example
4
4
  //
5
+ // Preview + Playground demo (mirrors the Compose DemoScreen pattern).
6
+ //
5
7
 
6
- import Foundation
7
8
  import MoMoUIKits
8
9
  import SwiftUI
9
10
 
10
- // MARK: - DateTimePickerDemo
11
-
12
11
  struct DateTimePickerDemo: View {
12
+ var body: some View {
13
+ if #available(iOS 16.0, *) {
14
+ DemoScreen(preview: { DateTimePickerPreview() }, playground: { DateTimePickerPlayground() })
15
+ } else {
16
+ Text("Requires iOS 16+").padding()
17
+ }
18
+ }
19
+ }
20
+
21
+ // MARK: - Preview
22
+
23
+ private struct DateTimePickerPreview: View {
13
24
  @State private var selected1: Date?
14
25
  @State private var selected2: Date?
15
26
  @State private var selected3: Date?
16
27
  @State private var selected4: Date?
17
- @State private var selected5: Date?
18
- @State private var selected6: Date?
19
- @State private var selected7: Date? = DateTimePickerUtils.getCurrentDateTime()
20
28
 
21
29
  var body: some View {
22
- ScrollView {
23
- VStack(alignment: .leading, spacing: 24) {
24
- section("Format: DD-MM-YYYY") {
25
- DateTimePicker(
26
- format: "DD-MM-YYYY",
27
- onChange: { selected1 = $0 }
28
- )
29
- selectedLabel(selected1, format: "dd-MM-yyyy")
30
- }
31
-
32
- section("Format: DD-MM-YYYY HH:mm") {
33
- DateTimePicker(
34
- format: "DD-MM-YYYY HH:mm",
35
- onChange: { selected2 = $0 }
36
- )
37
- selectedLabel(selected2, format: "yyyy-MM-dd HH:mm")
38
- }
39
-
40
- section("Format: HH:mm") {
41
- DateTimePicker(
42
- format: "HH:mm",
43
- onChange: { selected3 = $0 }
44
- )
45
- selectedLabel(selected3, format: "HH:mm")
46
- }
47
-
48
- section("With minute interval (5 minutes)") {
49
- DateTimePicker(
50
- format: "DD-MM-YYYY HH:mm",
51
- minuteInterval: 5,
52
- onChange: { selected4 = $0 }
53
- )
54
- selectedLabel(selected4, format: "yyyy-MM-dd HH:mm")
55
- }
56
-
57
- section("With min/max date") {
58
- DateTimePicker(
59
- format: "DD-MM-YYYY",
60
- selectedValue: nil,
61
- minDate: DateTimePickerUtils.createRelativeDate(years: -1),
62
- maxDate: DateTimePickerUtils.createRelativeDate(years: 1),
63
- onChange: { selected5 = $0 }
64
- )
65
- selectedLabel(selected5, format: "dd-MM-yyyy")
66
- }
67
-
68
- section("With labels") {
69
- DateTimePicker(
70
- format: "DD-MM-YYYY HH:mm",
71
- arrayLabelTime: ["Day", "Month", "Year", "Hour", "Min"],
72
- onChange: { selected6 = $0 }
73
- )
74
- selectedLabel(selected6, format: "yyyy-MM-dd HH:mm")
75
- }
76
-
77
- section("With selected value") {
78
- DateTimePicker(
79
- format: "DD-MM-YYYY HH:mm",
80
- selectedValue: selected7,
81
- onChange: { selected7 = $0 }
82
- )
83
- selectedLabel(selected7, format: "yyyy-MM-dd HH:mm")
84
- }
85
- }
86
- .padding(.vertical, 16)
30
+ BasicColumnBox("Format: DD-MM-YYYY", alignment: .leading) {
31
+ DateTimePicker(format: "DD-MM-YYYY", onChange: { selected1 = $0 })
32
+ selectedLabel(selected1, format: "dd-MM-yyyy")
87
33
  }
88
- }
89
-
90
- // MARK: - Helpers
91
-
92
- @ViewBuilder
93
- private func selectedLabel(_ date: Date?, format: String) -> some View {
94
- if let date = date {
95
- MomoText(
96
- "Selected: \(DateTimePickerUtils.formatDate(date, format: format))",
97
- typography: .descriptionDefaultRegular,
98
- color: Colors.textSecondary
34
+ BasicColumnBox("Format: DD-MM-YYYY HH:mm", alignment: .leading) {
35
+ DateTimePicker(format: "DD-MM-YYYY HH:mm", onChange: { selected2 = $0 })
36
+ selectedLabel(selected2, format: "yyyy-MM-dd HH:mm")
37
+ }
38
+ BasicColumnBox("Format: HH:mm", alignment: .leading) {
39
+ DateTimePicker(format: "HH:mm", onChange: { selected3 = $0 })
40
+ selectedLabel(selected3, format: "HH:mm")
41
+ }
42
+ BasicColumnBox("With min/max date (±1 year)", alignment: .leading) {
43
+ DateTimePicker(
44
+ format: "DD-MM-YYYY",
45
+ selectedValue: nil,
46
+ minDate: DateTimePickerUtils.createRelativeDate(years: -1),
47
+ maxDate: DateTimePickerUtils.createRelativeDate(years: 1),
48
+ onChange: { selected4 = $0 }
99
49
  )
100
- .padding(.top, 8)
50
+ selectedLabel(selected4, format: "dd-MM-yyyy")
101
51
  }
102
52
  }
103
53
 
104
54
  @ViewBuilder
105
- private func section<Content: View>(
106
- _ title: String,
107
- @ViewBuilder content: () -> Content
108
- ) -> some View {
109
- VStack(alignment: .leading, spacing: 12) {
110
- Text(title)
111
- .font(.headline)
112
- content()
55
+ private func selectedLabel(_ date: Date?, format: String) -> some View {
56
+ if let date = date {
57
+ MomoText("Selected: \(DateTimePickerUtils.formatDate(date, format: format))",
58
+ typography: .descriptionDefaultRegular, color: Colors.textSecondary)
59
+ .padding(.top, Spacing.S)
113
60
  }
114
- .padding(.horizontal, 16)
115
61
  }
116
62
  }
117
63
 
118
- #if DEBUG
119
- struct DateTimePickerDemo_Previews: PreviewProvider {
120
- static var previews: some View {
121
- DateTimePickerDemo()
64
+ // MARK: - Playground
65
+
66
+ private let dateFormatList: [PlaygroundOption] = [
67
+ .init("DD-MM-YYYY", "DD-MM-YYYY"),
68
+ .init("DD-MM-YYYY HH:mm", "DD-MM-YYYY HH:mm"),
69
+ .init("HH:mm", "HH:mm"),
70
+ ]
71
+
72
+ @available(iOS 16.0, *)
73
+ private struct DateTimePickerPlayground: View {
74
+ @State private var format: PlaygroundOption? = dateFormatList.first { $0.key == "DD-MM-YYYY HH:mm" }
75
+ @State private var minuteInterval = 1.0
76
+ @State private var selected: Date?
77
+
78
+ var body: some View {
79
+ PlaygroundTab(
80
+ component: {
81
+ VStack(alignment: .leading, spacing: Spacing.S) {
82
+ DateTimePicker(
83
+ format: (format?.value as? String) ?? "DD-MM-YYYY HH:mm",
84
+ minuteInterval: Int(minuteInterval),
85
+ onChange: { selected = $0 }
86
+ )
87
+ .id("\(format?.key ?? "")-\(Int(minuteInterval))")
88
+ if let selected {
89
+ MomoText("Selected: \(DateTimePickerUtils.formatDate(selected, format: "yyyy-MM-dd HH:mm"))",
90
+ typography: .descriptionDefaultRegular, color: Colors.textSecondary)
91
+ }
92
+ }
93
+ },
94
+ params: [
95
+ .radio("Format", dateFormatList, $format),
96
+ .slider("MinuteInterval", $minuteInterval, min: 1, max: 30, step: 1),
97
+ ]
98
+ )
122
99
  }
123
100
  }
124
- #endif