@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,100 +1,108 @@
1
1
  //
2
- // Foundation.swift
2
+ // ButtonDemo.swift
3
3
  // Example
4
4
  //
5
- // Created by Wem on 13/12/2022.
5
+ // Preview + Playground demo, mirroring Compose's ButtonUsage.kt.
6
6
  //
7
7
 
8
- import Foundation
9
- import Lottie
10
8
  import MoMoUIKits
11
9
  import SwiftUI
12
10
 
13
- // MARK: - ButtonDemo
14
-
15
11
  struct ButtonDemo: View {
16
- // MARK: Internal
17
-
18
12
  var body: some View {
19
- ScrollView {
20
- VStack {
21
- Toggle("Disabled", isOn: $disabled)
22
-
23
- Group {
24
- Button(title: "Button", action: onPress, type: disabled ? .disabled : .primary, size: .large,
25
- iconRight: AnyView(Image(systemName: "checkmark.circle")))
26
- Button(title: "Button", action: onPress, size: .small)
27
- }
28
-
29
- Group {
30
- Button(title: "Button", action: onPress, type: .danger,
31
- iconLeft: AnyView(Image(systemName: "checkmark.circle")))
32
- Button(title: "Button", action: onPress, type: .danger, size: .medium)
33
- Button(title: "Button", action: onPress, type: .danger, size: .small)
34
- }
35
-
36
- Group {
37
- Button(title: "Button", action: onPress, type: .danger, iconLeft: AnyView(Image(systemName: "checkmark.circle")), isFull: false)
38
- Button(title: "Button", action: onPress, type: .danger, size: .medium, isFull: false)
39
- Button(title: "Button", action: onPress, type: .danger, size: .small, isFull: false)
40
- }
41
-
42
-
43
- Group {
44
- Button(title: "Button", action: onPress, type: .tonal, size: .large)
45
- Button(title: "Button", action: onPress, type: .tonal, size: .medium)
46
- Button(title: "Button", action: onPress, type: .tonal, size: .small)
47
- }
48
-
49
- Group {
50
- Button(title: "Tinted icon", action: onPress, type: .primary,
51
- iconLeft: AnyView(Image(systemName: "checkmark.circle")), useTintColor: true)
52
- Button(title: "Original icon", action: onPress, type: .primary,
53
- iconLeft: AnyView(Image(systemName: "checkmark.circle")), useTintColor: false)
54
- }
55
-
56
- Group {
57
- Button(title: "Button", action: onPress, type: .secondary, size: .large)
58
- Button(title: "Button", action: onPress, type: .secondary, size: .medium)
59
- Button(title: "Button", action: onPress, type: .secondary, size: .small)
60
- }
13
+ if #available(iOS 16.0, *) {
14
+ DemoScreen(preview: { ButtonPreview() }, playground: { ButtonPlayground() })
15
+ } else {
16
+ Text("Requires iOS 16+").padding()
17
+ }
18
+ }
19
+ }
61
20
 
62
- Group {
63
- Button(title: "Button", action: onPress, type: .text, size: .large)
64
- Button(title: "Button", action: onPress, type: .text, size: .medium)
65
- Button(title: "Button", action: onPress, type: .text, size: .small)
66
- }
21
+ // MARK: - Preview
67
22
 
68
- Group {
69
- Button(title: "Button", action: onPress, type: .outline, size: .large)
70
- Button(title: "Button", action: onPress, type: .outline, size: .medium)
71
- Button(title: "Button", action: onPress, type: .outline, size: .small)
72
- }
23
+ private struct ButtonPreview: View {
24
+ private let url = "https://static-00.iconduck.com/assets.00/external-link-icon-512x512-h2zzryfc.png"
73
25
 
74
- Group {
75
- Button(title: "Button", action: onPress, type: .disabled, size: .large)
76
- Button(title: "Button", action: onPress, type: .disabled, size: .medium)
77
- Button(title: "Button", action: onPress, type: .disabled, size: .small)
78
- }
79
- Group {
80
- Button(title: "Button", action: onPress, type: .primary, size: .medium, loading: true)
81
- Button(title: "Button", action: onPress, type: .danger, size: .medium, iconLeft: AnyView(Image(systemName: "checkmark.circle")), loading: true)
82
- Button(title: "Button", action: onPress, type: .disabled, size: .medium, iconRight: AnyView(Image(systemName: "checkmark.circle")), loading: true)
83
- Button(title: "Button", action: onPress, type: .outline, size: .medium, iconLeft: AnyView(Image(systemName: "checkmark.circle")), iconRight: AnyView(Image(systemName: "checkmark.circle")), loading: true)
84
- Button(title: "Button", action: onPress, type: .secondary, size: .medium, loading: true)
85
- Button(title: "Button", action: onPress, type: .text, size: .medium, loading: true)
86
- Button(title: "Button", action: onPress, type: .tonal, size: .medium, loading: true)
87
- }
88
- }.padding(16)
89
- }.padding(.top)
26
+ var body: some View {
27
+ BasicColumnBox("Title") {
28
+ MoMoUIKits.Button(title: "Open", action: {})
29
+ }
30
+
31
+ BasicColumnBox("Type") {
32
+ MoMoUIKits.Button(title: "PRIMARY", action: {}, type: .primary)
33
+ MoMoUIKits.Button(title: "DANGER", action: {}, type: .danger)
34
+ MoMoUIKits.Button(title: "SECONDARY", action: {}, type: .secondary)
35
+ MoMoUIKits.Button(title: "TONAL", action: {}, type: .tonal)
36
+ MoMoUIKits.Button(title: "OUTLINE", action: {}, type: .outline)
37
+ MoMoUIKits.Button(title: "TEXT", action: {}, type: .text)
38
+ MoMoUIKits.Button(title: "DISABLED", action: {}, type: .disabled)
39
+ }
40
+
41
+ BasicColumnBox("Size") {
42
+ MoMoUIKits.Button(title: "LARGE", action: {}, size: .large)
43
+ MoMoUIKits.Button(title: "MEDIUM", action: {}, size: .medium)
44
+ MoMoUIKits.Button(title: "SMALL", action: {}, size: .small)
45
+ }
46
+
47
+ BasicColumnBox("Loading") {
48
+ MoMoUIKits.Button(title: "PRIMARY", action: {}, type: .primary, loading: true)
49
+ MoMoUIKits.Button(title: "DANGER", action: {}, type: .danger, loading: true)
50
+ MoMoUIKits.Button(title: "SECONDARY", action: {}, type: .secondary, loading: true)
51
+ MoMoUIKits.Button(title: "TONAL", action: {}, type: .tonal, loading: true)
52
+ MoMoUIKits.Button(title: "OUTLINE", action: {}, type: .outline, loading: true)
53
+ MoMoUIKits.Button(title: "TEXT", action: {}, type: .text, loading: true)
54
+ MoMoUIKits.Button(title: "DISABLED", action: {}, type: .disabled, loading: true)
55
+ }
56
+
57
+ BasicColumnBox("Icon Right") {
58
+ MoMoUIKits.Button(title: "Icon", action: {}, iconRight: url)
59
+ }
60
+
61
+ BasicColumnBox("Icon Left") {
62
+ MoMoUIKits.Button(title: "Icon", action: {}, iconLeft: url)
63
+ }
90
64
  }
65
+ }
91
66
 
92
- func onPress() {
93
- print("Button")
94
- }
67
+ // MARK: - Playground
95
68
 
96
- // MARK: Private
69
+ @available(iOS 16.0, *)
70
+ private struct ButtonPlayground: View {
71
+ @State private var title = "Button"
72
+ @State private var type: PlaygroundOption? = buttonTypeList.first { $0.key == "primary" }
73
+ @State private var size: PlaygroundOption? = buttonSizeList.first { $0.key == "large" }
74
+ @State private var iconRight: PlaygroundOption?
75
+ // Seeded (Compose leaves both nil) so the UseTintColor toggle has an icon to act on.
76
+ @State private var iconLeft: PlaygroundOption? = playgroundIcons.first { $0.key == "basic_home" }
77
+ @State private var full = true
78
+ @State private var loading = false
79
+ @State private var useTintColor = true
97
80
 
98
- @State private var value: String = ""
99
- @State private var disabled: Bool = false
81
+ var body: some View {
82
+ PlaygroundTab(
83
+ component: {
84
+ MoMoUIKits.Button(
85
+ title: title,
86
+ action: {},
87
+ type: (type?.value as? ButtonType) ?? .primary,
88
+ size: (size?.value as? ButtonSize) ?? .large,
89
+ iconLeft: (iconLeft?.value as? String) ?? "",
90
+ iconRight: (iconRight?.value as? String) ?? "",
91
+ isFull: full,
92
+ loading: loading,
93
+ useTintColor: useTintColor
94
+ )
95
+ },
96
+ params: [
97
+ .string("Children", $title),
98
+ .radio("Type", buttonTypeList, $type),
99
+ .radio("Size", buttonSizeList, $size),
100
+ .checkbox("Full", $full),
101
+ .option("IconRight", playgroundIcons, $iconRight),
102
+ .option("IconLeft", playgroundIcons, $iconLeft),
103
+ .checkbox("Loading", $loading),
104
+ .checkbox("UseTintColor", $useTintColor),
105
+ ]
106
+ )
107
+ }
100
108
  }
@@ -2,125 +2,95 @@
2
2
  // CarouselDemo.swift
3
3
  // Example
4
4
  //
5
+ // Preview + Playground demo (DemoScreen pattern).
6
+ //
5
7
 
6
- import SwiftUI
7
8
  import MoMoUIKits
9
+ import SwiftUI
8
10
 
9
- struct CarouselDemo: View {
10
- // MARK: - Playground state
11
- @State private var loop = false
12
- @State private var autoplay = false
13
- @State private var scrollEnabled = true
14
- @State private var inactiveOpacity: Double = 1.0
15
- @State private var inactiveScale: Double = 1.0
11
+ private let slideColors: [Color] = [
12
+ Colors.pink09, Colors.blue08, Colors.green08, Colors.orange08, Colors.mint08,
13
+ ]
16
14
 
17
- private let slideColors: [Color] = [
18
- Colors.pink09,
19
- Colors.blue08,
20
- Colors.green08,
21
- Colors.orange08,
22
- Colors.mint08,
23
- ]
15
+ @ViewBuilder
16
+ private func carouselSlide(_ index: Int) -> some View {
17
+ ZStack {
18
+ slideColors[index % slideColors.count]
19
+ Text("Slide \(index + 1)")
20
+ .font(.headline)
21
+ .foregroundColor(Colors.black01)
22
+ }
23
+ .frame(maxWidth: .infinity)
24
+ .frame(height: 160)
25
+ .cornerRadius(Radius.M)
26
+ }
24
27
 
28
+ struct CarouselDemo: View {
25
29
  var body: some View {
26
- ScrollView {
27
- VStack(alignment: .leading, spacing: Spacing.XL) {
28
- preview
29
- Divider()
30
- playground
31
- }
32
- .padding(Spacing.L)
30
+ if #available(iOS 16.0, *) {
31
+ DemoScreen(preview: { CarouselPreview() }, playground: { CarouselPlayground() })
32
+ } else {
33
+ Text("Requires iOS 16+").padding()
33
34
  }
34
35
  }
36
+ }
35
37
 
36
- // MARK: - Preview cases (mirror CarouselUsage.kt)
37
- private var preview: some View {
38
- VStack(alignment: .leading, spacing: Spacing.XL) {
39
- section("Basic (3 slides)") {
40
- Carousel(itemCount: 3) { index in slide(index) }
41
- .frame(height: 160)
42
- }
43
-
44
- section("Loop enabled") {
45
- Carousel(itemCount: 5, loop: true) { index in slide(index) }
46
- .frame(height: 160)
47
- }
48
-
49
- section("Autoplay (3s interval)") {
50
- Carousel(
51
- itemCount: 5,
52
- loop: true,
53
- autoplay: true,
54
- autoplayInterval: 3.0
55
- ) { index in slide(index) }
56
- .frame(height: 160)
57
- }
58
-
59
- section("Inactive slide effects (opacity=0.5, scale=0.9)") {
60
- Carousel(
61
- itemCount: 5,
62
- loop: true,
63
- inactiveSlideOpacity: 0.5,
64
- inactiveSlideScale: 0.9,
65
- contentPadding: 32
66
- ) { index in slide(index) }
67
- .frame(height: 160)
68
- }
38
+ // MARK: - Preview
69
39
 
70
- section("Scroll disabled") {
71
- Carousel(itemCount: 3, scrollEnabled: false) { index in slide(index) }
72
- .frame(height: 160)
73
- }
40
+ private struct CarouselPreview: View {
41
+ var body: some View {
42
+ BasicColumnBox("Basic (3 slides)", alignment: .leading) {
43
+ Carousel(itemCount: 3) { carouselSlide($0) }.frame(height: 160)
74
44
  }
75
- }
76
-
77
- // MARK: - Playground
78
- private var playground: some View {
79
- VStack(alignment: .leading, spacing: Spacing.M) {
80
- Text("Playground").font(.headline)
81
-
82
- Toggle("Loop", isOn: $loop)
83
- Toggle("Autoplay", isOn: $autoplay)
84
- Toggle("Scroll Enabled", isOn: $scrollEnabled)
85
-
86
- VStack(alignment: .leading) {
87
- Text("Inactive Opacity: \(String(format: "%.2f", inactiveOpacity))")
88
- Slider(value: $inactiveOpacity, in: 0 ... 1)
89
- }
90
- VStack(alignment: .leading) {
91
- Text("Inactive Scale: \(String(format: "%.2f", inactiveScale))")
92
- Slider(value: $inactiveScale, in: 0.5 ... 1)
93
- }
94
-
95
- Carousel(
96
- itemCount: 5,
97
- loop: loop,
98
- autoplay: autoplay,
99
- scrollEnabled: scrollEnabled,
100
- inactiveSlideOpacity: inactiveOpacity,
101
- inactiveSlideScale: inactiveScale
102
- ) { index in slide(index) }
45
+ BasicColumnBox("Loop enabled", alignment: .leading) {
46
+ Carousel(itemCount: 5, loop: true) { carouselSlide($0) }.frame(height: 160)
47
+ }
48
+ BasicColumnBox("Autoplay (3s)", alignment: .leading) {
49
+ Carousel(itemCount: 5, loop: true, autoplay: true, autoplayInterval: 3.0) { carouselSlide($0) }
103
50
  .frame(height: 160)
104
51
  }
105
- }
106
-
107
- // MARK: - Helpers
108
- private func section<Content: View>(_ title: String, @ViewBuilder content: () -> Content) -> some View {
109
- VStack(alignment: .leading, spacing: Spacing.S) {
110
- Text(title).font(.subheadline).bold()
111
- content()
52
+ BasicColumnBox("Inactive effects", alignment: .leading) {
53
+ Carousel(itemCount: 5, loop: true, inactiveSlideOpacity: 0.5, inactiveSlideScale: 0.9, contentPadding: 32) {
54
+ carouselSlide($0)
55
+ }
56
+ .frame(height: 160)
57
+ }
58
+ BasicColumnBox("Scroll disabled", alignment: .leading) {
59
+ Carousel(itemCount: 3, scrollEnabled: false) { carouselSlide($0) }.frame(height: 160)
112
60
  }
113
61
  }
62
+ }
114
63
 
115
- private func slide(_ index: Int) -> some View {
116
- ZStack {
117
- slideColors[index % slideColors.count]
118
- Text("Slide \(index + 1)")
119
- .font(.headline)
120
- .foregroundColor(Colors.black01)
121
- }
122
- .frame(maxWidth: .infinity)
123
- .frame(height: 160)
124
- .cornerRadius(Radius.M)
64
+ // MARK: - Playground
65
+
66
+ @available(iOS 16.0, *)
67
+ private struct CarouselPlayground: View {
68
+ @State private var loop = false
69
+ @State private var autoplay = false
70
+ @State private var scrollEnabled = true
71
+ @State private var inactiveOpacity: Double = 1.0
72
+ @State private var inactiveScale: Double = 1.0
73
+
74
+ var body: some View {
75
+ PlaygroundTab(
76
+ component: {
77
+ Carousel(
78
+ itemCount: 5,
79
+ loop: loop,
80
+ autoplay: autoplay,
81
+ scrollEnabled: scrollEnabled,
82
+ inactiveSlideOpacity: inactiveOpacity,
83
+ inactiveSlideScale: inactiveScale
84
+ ) { carouselSlide($0) }
85
+ .frame(height: 160)
86
+ },
87
+ params: [
88
+ .checkbox("Loop", $loop),
89
+ .checkbox("Autoplay", $autoplay),
90
+ .checkbox("ScrollEnabled", $scrollEnabled),
91
+ .slider("InactiveOpacity", $inactiveOpacity, min: 0, max: 1, step: 0.1),
92
+ .slider("InactiveScale", $inactiveScale, min: 0.5, max: 1, step: 0.1),
93
+ ]
94
+ )
125
95
  }
126
96
  }
@@ -1,63 +1,60 @@
1
1
  //
2
- // CheckBoxDemo.swift
2
+ // CheckboxDemo.swift
3
3
  // Example
4
4
  //
5
- // Created by dung.pham2 on 2/12/24.
5
+ // Preview + Playground demo for Checkbox.
6
6
  //
7
- import SwiftUI
7
+
8
8
  import MoMoUIKits
9
+ import SwiftUI
9
10
 
10
11
  struct CheckboxDemo: View {
11
- @State private var checked = false
12
-
13
12
  var body: some View {
14
- VStack(alignment: .leading, spacing: 20) {
15
- // Interactive checkbox
16
- Checkbox(
17
- $checked,
18
- onChange: { _ in checked = !checked },
19
- title: "Check Box"
20
- )
21
-
22
- // Unchecked checkbox
23
- Checkbox(.constant(false), onChange: { _ in }, title: "Check Box")
24
-
25
- // Indeterminate checkbox
26
- Checkbox(
27
- .constant(true),
28
- // disabled: (({ _ in }) != 0),
29
- onChange: { _ in },
30
- indeterminate: true,
31
- title: "Indeterminate"
32
- )
33
-
34
- // Disabled checkbox
35
- Checkbox(
36
- .constant(true),
37
- disabled: true,
38
- onChange: { _ in },
39
- title: "Disable"
40
- )
41
-
42
- // Disabled indeterminate checkbox
43
- Checkbox(
44
- .constant(true),
45
- disabled: true,
46
- onChange: {_ in },
47
- indeterminate: true,
48
- title: "Disable checked"
49
- )
50
-
51
- // Disabled unchecked checkbox
52
- Checkbox(
53
- .constant(false),
54
- disabled: true,
55
- onChange: { _ in },
56
- title: "Disable"
57
- )
13
+ if #available(iOS 16.0, *) {
14
+ DemoScreen(preview: { CheckboxPreview() }, playground: { CheckboxPlayground() })
15
+ } else {
16
+ Text("Requires iOS 16+").padding()
17
+ }
18
+ }
19
+ }
20
+
21
+ // MARK: - Preview
22
+
23
+ private struct CheckboxPreview: View {
24
+ var body: some View {
25
+ BasicColumnBox("States", alignment: .leading) {
26
+ Checkbox(.constant(true), onChange: { _ in }, title: "Checked")
27
+ Checkbox(.constant(false), onChange: { _ in }, title: "Unchecked")
28
+ Checkbox(.constant(true), onChange: { _ in }, indeterminate: true, title: "Indeterminate")
29
+ }
30
+ BasicColumnBox("Disabled", alignment: .leading) {
31
+ Checkbox(.constant(true), disabled: true, onChange: { _ in }, title: "Disabled checked")
32
+ Checkbox(.constant(true), disabled: true, onChange: { _ in }, indeterminate: true, title: "Disabled indeterminate")
33
+ Checkbox(.constant(false), disabled: true, onChange: { _ in }, title: "Disabled unchecked")
58
34
  }
59
- .padding()
60
35
  }
61
36
  }
62
37
 
38
+ // MARK: - Playground
39
+
40
+ @available(iOS 16.0, *)
41
+ private struct CheckboxPlayground: View {
42
+ @State private var checked = false
43
+ @State private var disabled = false
44
+ @State private var indeterminate = false
45
+ @State private var title = "Check Box"
63
46
 
47
+ var body: some View {
48
+ PlaygroundTab(
49
+ component: {
50
+ Checkbox($checked, disabled: disabled, indeterminate: indeterminate, title: title)
51
+ },
52
+ params: [
53
+ .checkbox("Checked", $checked),
54
+ .checkbox("Disabled", $disabled),
55
+ .checkbox("Indeterminate", $indeterminate),
56
+ .string("Title", $title),
57
+ ]
58
+ )
59
+ }
60
+ }
@@ -1,20 +1,76 @@
1
+ //
2
+ // ChipDemo.swift
3
+ // Example
4
+ //
5
+ // Preview + Playground demo for Chip.
6
+ //
1
7
 
2
- import SwiftUI
3
8
  import MoMoUIKits
9
+ import SwiftUI
10
+
11
+ private let chipSizeList: [PlaygroundOption] = [
12
+ .init("large", Chip.ChipSize.large),
13
+ .init("small", Chip.ChipSize.small),
14
+ ]
4
15
 
5
16
  struct ChipDemo: View {
6
-
7
17
  var body: some View {
8
- VStack(alignment: .leading, spacing: 8) {
9
- Chip(label: "Large", size: Chip.ChipSize.large)
10
- Chip(label: "Small", size: Chip.ChipSize.small)
18
+ if #available(iOS 16.0, *) {
19
+ DemoScreen(preview: { ChipPreview() }, playground: { ChipPlayground() })
20
+ } else {
21
+ Text("Requires iOS 16+").padding()
22
+ }
23
+ }
24
+ }
25
+
26
+ // MARK: - Preview
27
+
28
+ private struct ChipPreview: View {
29
+ var body: some View {
30
+ BasicColumnBox("Size", alignment: .leading) {
31
+ Chip(label: "Large", size: .large)
32
+ Chip(label: "Small", size: .small)
33
+ }
34
+ BasicColumnBox("Icons", alignment: .leading) {
11
35
  Chip(label: "Apple", iconLeft: "basic_home")
12
36
  Chip(label: "Banana", iconRight: "basic_home")
37
+ }
38
+ BasicColumnBox("State", alignment: .leading) {
13
39
  Chip(label: "Orange", backgroundColor: Colors.black01)
14
40
  Chip(label: "Grape", selected: true)
15
41
  Chip(label: "Grape", iconRight: "basic_home", selected: true, iconRightTint: Colors.black05)
16
- Chip(label: "Tagged", accessibilityLabel: "chip_tagged")
17
42
  }
18
- .padding()
43
+ }
44
+ }
45
+
46
+ // MARK: - Playground
47
+
48
+ @available(iOS 16.0, *)
49
+ private struct ChipPlayground: View {
50
+ @State private var label = "Chip"
51
+ @State private var size: PlaygroundOption? = chipSizeList.first { $0.key == "large" }
52
+ @State private var selected = false
53
+ @State private var iconLeft: PlaygroundOption?
54
+ @State private var iconRight: PlaygroundOption?
55
+
56
+ var body: some View {
57
+ PlaygroundTab(
58
+ component: {
59
+ Chip(
60
+ label: label,
61
+ iconLeft: iconLeft?.value as? String,
62
+ iconRight: iconRight?.value as? String,
63
+ selected: selected,
64
+ size: (size?.value as? Chip.ChipSize) ?? .large
65
+ )
66
+ },
67
+ params: [
68
+ .string("Label", $label),
69
+ .radio("Size", chipSizeList, $size),
70
+ .checkbox("Selected", $selected),
71
+ .option("IconLeft", playgroundIcons, $iconLeft),
72
+ .option("IconRight", playgroundIcons, $iconRight),
73
+ ]
74
+ )
19
75
  }
20
76
  }