@momo-kits/native-kits 0.163.1-sp.8-debug → 0.163.1-sp.9-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 (55) hide show
  1. package/.claude/settings.local.json +3 -1
  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/Navigation/Navigator.swift +30 -24
  6. package/ios/Application/StackScreen.swift +1 -7
  7. package/ios/native-kits.podspec +1 -1
  8. package/ios-demo/MoMoUIKitsDemo.podspec +1 -1
  9. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AvatarDemo.swift +87 -73
  10. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BadgeDemo.swift +55 -249
  11. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ButtonDemo.swift +89 -82
  12. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CarouselDemo.swift +74 -104
  13. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CheckboxDemo.swift +47 -51
  14. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ChipDemo.swift +63 -7
  15. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CollapseDemo.swift +90 -81
  16. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DateTimePickerDemo.swift +73 -97
  17. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DemoScreen.swift +418 -0
  18. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DividerDemo.swift +46 -4
  19. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +51 -47
  20. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconButtonDemo.swift +80 -45
  21. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconDemo.swift +67 -90
  22. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ImageDemo.swift +49 -62
  23. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InformationDemo.swift +66 -116
  24. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDemo.swift +104 -98
  25. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDropDownDemo.swift +76 -118
  26. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputMoneyDemo.swift +73 -86
  27. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputOTPDemo.swift +69 -54
  28. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputPhoneNumberDemo.swift +74 -54
  29. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputSearchDemo.swift +73 -20
  30. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputTextAreaDemo.swift +68 -38
  31. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LoaderDemo.swift +55 -52
  32. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PaginationDemo.swift +47 -51
  33. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PlaygroundData.swift +76 -0
  34. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +67 -93
  35. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +34 -43
  36. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ProgressInfoDemo.swift +83 -71
  37. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RadioDemo.swift +55 -23
  38. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RatingDemo.swift +58 -46
  39. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SectionDemo.swift +57 -74
  40. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SkeletonDemo.swift +41 -12
  41. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SliderDemo.swift +67 -127
  42. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SnackBarDemo.swift +54 -110
  43. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepperDemo.swift +69 -79
  44. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepsDemo.swift +78 -58
  45. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SuggestActionDemo.swift +76 -65
  46. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwipeDemo.swift +82 -127
  47. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwitchDemo.swift +44 -19
  48. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TabViewDemo.swift +92 -168
  49. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TagDemo.swift +79 -27
  50. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ThemeDemo.swift +0 -1
  51. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TitleDemo.swift +87 -92
  52. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TooltipDemo.swift +94 -163
  53. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TypographyDemo.swift +70 -70
  54. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/UploaderDemo.swift +68 -114
  55. package/package.json +2 -2
@@ -4,135 +4,79 @@ import SwiftUI
4
4
  struct SnackBarDemo: View {
5
5
  var body: some View {
6
6
  if #available(iOS 16.0, *) {
7
- SnackBarDemoContent()
7
+ DemoScreen(preview: { SnackBarPreview() }, playground: { SnackBarPlayground() })
8
8
  } else {
9
- MomoText("SnackBar demo requires iOS 16+")
10
- .padding()
9
+ Text("Requires iOS 16+").padding()
11
10
  }
12
11
  }
13
12
  }
14
13
 
14
+ // MARK: - Preview
15
+
15
16
  @available(iOS 16.0, *)
16
- private struct SnackBarDemoContent: View {
17
+ private struct SnackBarPreview: View {
17
18
  @EnvironmentObject private var navigator: Navigator
18
19
 
19
- @State private var duration = "1000"
20
- @State private var undefinedDuration = false
21
- @State private var showFooter = true
22
-
23
- private var snackBarDuration: TimeInterval? {
24
- if undefinedDuration {
25
- return nil
26
- }
27
- guard let milliseconds = Double(duration) else {
28
- return nil
20
+ var body: some View {
21
+ BasicColumnBox("SnackBar", alignment: .leading) {
22
+ MoMoUIKits.Button(title: "Show snack bar", action: { showSnack(1) }, size: .large)
23
+ MoMoUIKits.Button(title: "Show toast", action: { navigator.showSnackBar(.toast(duration: 1)) }, type: .secondary, size: .large)
24
+ MoMoUIKits.Button(title: "Hide snack bar", action: { navigator.hideSnackBar() }, type: .text, size: .large)
29
25
  }
30
- return milliseconds / 1000
31
26
  }
32
27
 
33
- var body: some View {
34
- VStack(spacing: 0) {
35
- ScrollView {
36
- VStack(alignment: .leading, spacing: Spacing.M) {
37
- Input(
38
- text: $duration,
39
- placeholder: "Duration",
40
- floatingValue: "Duration",
41
- keyboardType: .numberPad
42
- )
43
-
44
- Checkbox(
45
- Binding(
46
- get: { undefinedDuration },
47
- set: { checked in
48
- undefinedDuration = checked
49
- if checked {
50
- duration = ""
51
- } else if duration.isEmpty {
52
- duration = "1000"
53
- }
54
- }
55
- ),
56
- title: "Undefined"
57
- )
28
+ private func showSnack(_ duration: TimeInterval?) {
29
+ navigator.showSnackBar(.custom(duration: duration) {
30
+ HStack {
31
+ MomoText("Snack bar !!!", color: Colors.black01)
32
+ Spacer()
33
+ }
34
+ .padding(.horizontal, 20)
35
+ .frame(height: 80)
36
+ .frame(maxWidth: .infinity)
37
+ .background(Colors.black17)
38
+ .clipShape(RoundedRectangle(cornerRadius: Radius.M))
39
+ .padding(.horizontal, Spacing.M)
40
+ })
41
+ }
42
+ }
58
43
 
59
- HStack(spacing: Spacing.M) {
60
- MoMoUIKits.Switch($showFooter)
61
- MomoText("Footer")
62
- }
44
+ // MARK: - Playground
63
45
 
64
- MoMoUIKits.Button(
65
- title: "Show snack bar",
66
- action: showSnackBar,
67
- size: .large
68
- )
46
+ @available(iOS 16.0, *)
47
+ private struct SnackBarPlayground: View {
48
+ @EnvironmentObject private var navigator: Navigator
49
+ @State private var duration = "1000"
69
50
 
70
- MoMoUIKits.Button(
71
- title: "Show toast",
72
- action: { navigator.showSnackBar(.toast(duration: snackBarDuration)) },
73
- type: .secondary,
74
- size: .large
75
- )
51
+ private var seconds: TimeInterval? { Double(duration).map { $0 / 1000 } }
76
52
 
77
- MoMoUIKits.Button(
78
- title: "Hide snack bar",
79
- action: { navigator.hideSnackBar() },
80
- type: .text,
81
- size: .large
82
- )
53
+ var body: some View {
54
+ PlaygroundTab(
55
+ component: {
56
+ VStack(spacing: Spacing.S) {
57
+ MoMoUIKits.Button(title: "Show snack bar", action: { showSnack(seconds) }, size: .large)
58
+ MoMoUIKits.Button(title: "Show toast", action: { navigator.showSnackBar(.toast(duration: seconds)) }, type: .secondary, size: .large)
59
+ MoMoUIKits.Button(title: "Hide snack bar", action: { navigator.hideSnackBar() }, type: .text, size: .large)
83
60
  }
84
- .padding(Spacing.L)
85
- }
86
-
87
- if showFooter {
88
- footer
89
- }
90
- }
91
- }
92
-
93
- private var footer: some View {
94
- VStack(spacing: 0) {
95
- MoMoUIKits.Button(
96
- title: "Footer",
97
- action: {},
98
- size: .large
99
- )
100
- .padding(.vertical, Spacing.S)
101
- .padding(.horizontal, Spacing.M)
102
- }
103
- .frame(maxWidth: .infinity)
104
- .background(Colors.black01)
105
- .overlay(
106
- Rectangle()
107
- .fill(Colors.black20.opacity(0.1))
108
- .frame(height: 4)
109
- .shadow(color: Colors.black20.opacity(0.2), radius: 10, y: -2),
110
- alignment: .top
61
+ },
62
+ params: [
63
+ .number("Duration (ms)", $duration),
64
+ ]
111
65
  )
112
66
  }
113
67
 
114
- private func showSnackBar() {
115
- navigator.showSnackBar(
116
- .custom(duration: snackBarDuration) {
117
- HStack {
118
- MomoText("Snack bar !!!", color: Colors.black01)
119
- Spacer()
120
- }
121
- .padding(.horizontal, 20)
122
- .frame(height: 80)
123
- .frame(maxWidth: .infinity)
124
- .background(Colors.black17)
125
- .clipShape(RoundedRectangle(cornerRadius: Radius.M))
126
- .padding(.horizontal, Spacing.M)
68
+ private func showSnack(_ duration: TimeInterval?) {
69
+ navigator.showSnackBar(.custom(duration: duration) {
70
+ HStack {
71
+ MomoText("Snack bar !!!", color: Colors.black01)
72
+ Spacer()
127
73
  }
128
- )
129
- }
130
- }
131
-
132
- #if DEBUG
133
- struct SnackBarDemo_Previews: PreviewProvider {
134
- static var previews: some View {
135
- SnackBarDemo()
74
+ .padding(.horizontal, 20)
75
+ .frame(height: 80)
76
+ .frame(maxWidth: .infinity)
77
+ .background(Colors.black17)
78
+ .clipShape(RoundedRectangle(cornerRadius: Radius.M))
79
+ .padding(.horizontal, Spacing.M)
80
+ })
136
81
  }
137
82
  }
138
- #endif
@@ -2,102 +2,92 @@
2
2
  // StepperDemo.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: - StepperDemo
11
-
12
11
  struct StepperDemo: View {
12
+ var body: some View {
13
+ if #available(iOS 16.0, *) {
14
+ DemoScreen(preview: { StepperPreview() }, playground: { StepperPlayground() })
15
+ } else {
16
+ Text("Requires iOS 16+").padding()
17
+ }
18
+ }
19
+ }
20
+
21
+ // MARK: - Preview
22
+
23
+ private struct StepperPreview: View {
13
24
  @State private var sizeLarge = 5
14
25
  @State private var sizeSmall = 5
15
-
16
- @State private var def0 = 0
17
26
  @State private var def50 = 50
18
- @State private var def100 = 100
19
-
20
27
  @State private var customStep5 = 0
21
- @State private var customStep10 = 10
22
-
23
- @State private var editableLarge = 5
24
- @State private var editableSmall = 5
25
-
26
- @State private var disabledAllLarge = 5
27
- @State private var disabledAllSmall = 5
28
-
28
+ @State private var editable = 5
29
+ @State private var disabledAll = 5
29
30
  @State private var disabledMinus = 5
30
31
  @State private var disabledPlus = 5
31
-
32
- @State private var boundLow = 0
33
- @State private var boundHigh = 10
32
+ @State private var bound = 0
34
33
 
35
34
  var body: some View {
36
- ScrollView {
37
- VStack(alignment: .leading, spacing: 24) {
38
- section("Size") {
39
- MomoStepper(value: $sizeLarge, size: .large)
40
- MomoStepper(value: $sizeSmall, size: .small)
41
- }
42
-
43
- section("Default (min=0, max=100, step=1)") {
44
- MomoStepper(value: $def0)
45
- MomoStepper(value: $def50)
46
- MomoStepper(value: $def100)
47
- }
48
-
49
- section("Custom step") {
50
- MomoStepper(value: $customStep5, min: 0, max: 50, step: 5)
51
- MomoStepper(value: $customStep10, min: 0, max: 100, step: 10)
52
- }
53
-
54
- section("Editable") {
55
- MomoStepper(value: $editableLarge, editable: true)
56
- MomoStepper(value: $editableSmall, size: .small, editable: true)
57
- }
58
-
59
- section("Disabled — all") {
60
- MomoStepper(value: $disabledAllLarge, disabled: true)
61
- MomoStepper(value: $disabledAllSmall, size: .small, disabled: true)
62
- }
63
-
64
- section("Disabled — minus only") {
65
- MomoStepper(value: $disabledMinus, disabled: StepperDisabled(minus: true, plus: false))
66
- }
67
-
68
- section("Disabled — plus only") {
69
- MomoStepper(value: $disabledPlus, disabled: StepperDisabled(minus: false, plus: true))
70
- }
71
-
72
- section("Auto-disabled at bounds") {
73
- MomoStepper(value: $boundLow, min: 0, max: 10)
74
- MomoStepper(value: $boundHigh, min: 0, max: 10)
75
- }
76
- }
77
- .padding(.vertical, 16)
35
+ BasicColumnBox("Size", alignment: .leading) {
36
+ MomoStepper(value: $sizeLarge, size: .large)
37
+ MomoStepper(value: $sizeSmall, size: .small)
78
38
  }
79
- }
80
-
81
- // MARK: - Helpers
82
-
83
- @ViewBuilder
84
- private func section<Content: View>(
85
- _ title: String,
86
- @ViewBuilder content: () -> Content
87
- ) -> some View {
88
- VStack(alignment: .leading, spacing: 12) {
89
- Text(title)
90
- .font(.headline)
91
- content()
39
+ BasicColumnBox("Default (min=0, max=100, step=1)", alignment: .leading) {
40
+ MomoStepper(value: $def50)
41
+ }
42
+ BasicColumnBox("Custom step (5)", alignment: .leading) {
43
+ MomoStepper(value: $customStep5, min: 0, max: 50, step: 5)
44
+ }
45
+ BasicColumnBox("Editable", alignment: .leading) {
46
+ MomoStepper(value: $editable, editable: true)
47
+ }
48
+ BasicColumnBox("Disabled — all", alignment: .leading) {
49
+ MomoStepper(value: $disabledAll, disabled: true)
50
+ }
51
+ BasicColumnBox("Disabled — minus / plus only", alignment: .leading) {
52
+ MomoStepper(value: $disabledMinus, disabled: StepperDisabled(minus: true, plus: false))
53
+ MomoStepper(value: $disabledPlus, disabled: StepperDisabled(minus: false, plus: true))
54
+ }
55
+ BasicColumnBox("Auto-disabled at bounds (0…10)", alignment: .leading) {
56
+ MomoStepper(value: $bound, min: 0, max: 10)
92
57
  }
93
- .padding(.horizontal, 16)
94
58
  }
95
59
  }
96
60
 
97
- #if DEBUG
98
- struct StepperDemo_Previews: PreviewProvider {
99
- static var previews: some View {
100
- StepperDemo()
61
+ // MARK: - Playground
62
+
63
+ @available(iOS 16.0, *)
64
+ private struct StepperPlayground: View {
65
+ @State private var value = 5
66
+ @State private var small = false
67
+ @State private var editable = false
68
+ @State private var disabled = false
69
+ @State private var step = 1.0
70
+
71
+ var body: some View {
72
+ PlaygroundTab(
73
+ component: {
74
+ MomoStepper(
75
+ value: $value,
76
+ min: 0,
77
+ max: 100,
78
+ step: Int(step),
79
+ size: small ? .small : .large,
80
+ disabled: StepperDisabled(disabled),
81
+ editable: editable
82
+ )
83
+ .id("\(small)-\(editable)-\(disabled)-\(Int(step))")
84
+ },
85
+ params: [
86
+ .checkbox("Small", $small),
87
+ .checkbox("Editable", $editable),
88
+ .checkbox("Disabled", $disabled),
89
+ .slider("Step", $step, min: 1, max: 10, step: 1),
90
+ ]
91
+ )
101
92
  }
102
93
  }
103
- #endif
@@ -2,9 +2,7 @@
2
2
  // StepsDemo.swift
3
3
  // Example
4
4
  //
5
- // Usage demo for the Steps progress indicator. Mirrors Compose's `StepsUsage`
6
- // preview cases: vertical/horizontal, sizes, error, use-number, alignments,
7
- // disabled and time labels.
5
+ // Preview + Playground demo, mirroring Compose's StepsUsage.kt.
8
6
  //
9
7
 
10
8
  import MoMoUIKits
@@ -29,66 +27,88 @@ private let stepsWithError: [StepItem] = [
29
27
  StepItem(title: "Complete"),
30
28
  ]
31
29
 
30
+ private let stepsSizeList: [PlaygroundOption] = [
31
+ .init("large", StepsSize.large),
32
+ .init("small", StepsSize.small),
33
+ ]
34
+
35
+ private let stepsAlignList: [PlaygroundOption] = [
36
+ .init("center", StepsAlign.center),
37
+ .init("left", StepsAlign.left),
38
+ .init("right", StepsAlign.right),
39
+ .init("stretch", StepsAlign.stretch),
40
+ ]
41
+
32
42
  struct StepsDemo: View {
33
43
  var body: some View {
34
- ScrollView {
35
- VStack(alignment: .leading, spacing: 24) {
36
- section("Vertical — Large (default)") {
37
- Steps(steps: sampleSteps, activeIndex: 1)
38
- }
39
- section("Vertical — Small") {
40
- Steps(steps: sampleSteps, activeIndex: 2, size: .small)
41
- }
42
- section("Vertical — With error") {
43
- Steps(steps: stepsWithError, activeIndex: 1)
44
- }
45
- section("Vertical — Use number") {
46
- Steps(steps: shortSteps, activeIndex: 1, useNumber: true)
47
- }
48
- section("Vertical — Disabled") {
49
- Steps(steps: sampleSteps, activeIndex: 1, disabled: true)
50
- }
51
- section("Horizontal — Center (default)") {
52
- Steps(steps: shortSteps, activeIndex: 1, horizontal: true)
53
- }
54
- section("Horizontal — With time") {
55
- Steps(steps: sampleSteps, activeIndex: 2, horizontal: true)
56
- }
57
- section("Horizontal — Align Left") {
58
- Steps(steps: shortSteps, activeIndex: 0, horizontal: true, align: .left)
59
- }
60
- section("Horizontal — Align Right") {
61
- Steps(steps: shortSteps, activeIndex: 2, horizontal: true, align: .right)
62
- }
63
- section("Horizontal — Align Stretch") {
64
- Steps(steps: shortSteps, activeIndex: 1, horizontal: true, align: .stretch)
65
- }
66
- section("Horizontal — Small + Use number") {
67
- Steps(
68
- steps: shortSteps,
69
- activeIndex: 1,
70
- horizontal: true,
71
- size: .small,
72
- useNumber: true
73
- )
74
- }
75
- section("Horizontal — With error") {
76
- Steps(steps: stepsWithError, activeIndex: 1, horizontal: true)
77
- }
78
- }
79
- .padding(16)
44
+ if #available(iOS 16.0, *) {
45
+ DemoScreen(preview: { StepsPreview() }, playground: { StepsPlayground() })
46
+ } else {
47
+ Text("Requires iOS 16+").padding()
80
48
  }
81
49
  }
50
+ }
82
51
 
83
- @ViewBuilder
84
- private func section<Content: View>(
85
- _ title: String,
86
- @ViewBuilder content: () -> Content
87
- ) -> some View {
88
- VStack(alignment: .leading, spacing: 12) {
89
- MomoText(title, typography: .headerSSemibold, color: Colors.text)
90
- content()
52
+ // MARK: - Preview
53
+
54
+ private struct StepsPreview: View {
55
+ var body: some View {
56
+ BasicColumnBox("Vertical — Large (default)", alignment: .leading) {
57
+ Steps(steps: sampleSteps, activeIndex: 1)
58
+ }
59
+ BasicColumnBox("Vertical — Small", alignment: .leading) {
60
+ Steps(steps: sampleSteps, activeIndex: 2, size: .small)
61
+ }
62
+ BasicColumnBox("Vertical — With error", alignment: .leading) {
63
+ Steps(steps: stepsWithError, activeIndex: 1)
64
+ }
65
+ BasicColumnBox("Vertical — Use number", alignment: .leading) {
66
+ Steps(steps: shortSteps, activeIndex: 1, useNumber: true)
91
67
  }
92
- .frame(maxWidth: .infinity, alignment: .leading)
68
+ BasicColumnBox("Horizontal — Center", alignment: .leading) {
69
+ Steps(steps: shortSteps, activeIndex: 1, horizontal: true)
70
+ }
71
+ BasicColumnBox("Horizontal — With time", alignment: .leading) {
72
+ Steps(steps: sampleSteps, activeIndex: 2, horizontal: true)
73
+ }
74
+ BasicColumnBox("Horizontal — With error", alignment: .leading) {
75
+ Steps(steps: stepsWithError, activeIndex: 1, horizontal: true)
76
+ }
77
+ }
78
+ }
79
+
80
+ // MARK: - Playground
81
+
82
+ @available(iOS 16.0, *)
83
+ private struct StepsPlayground: View {
84
+ @State private var activeIndex: Double = 1
85
+ @State private var size: PlaygroundOption? = stepsSizeList.first { $0.key == "large" }
86
+ @State private var align: PlaygroundOption? = stepsAlignList.first { $0.key == "center" }
87
+ @State private var horizontal = false
88
+ @State private var useNumber = false
89
+ @State private var disabled = false
90
+
91
+ var body: some View {
92
+ PlaygroundTab(
93
+ component: {
94
+ Steps(
95
+ steps: sampleSteps,
96
+ activeIndex: Int(activeIndex),
97
+ horizontal: horizontal,
98
+ size: (size?.value as? StepsSize) ?? .large,
99
+ useNumber: useNumber,
100
+ align: (align?.value as? StepsAlign) ?? .center,
101
+ disabled: disabled
102
+ )
103
+ },
104
+ params: [
105
+ .slider("ActiveIndex", $activeIndex, min: 0, max: 3, step: 1),
106
+ .radio("Size", stepsSizeList, $size),
107
+ .radio("Align", stepsAlignList, $align),
108
+ .checkbox("Horizontal", $horizontal),
109
+ .checkbox("UseNumber", $useNumber),
110
+ .checkbox("Disabled", $disabled),
111
+ ]
112
+ )
93
113
  }
94
114
  }
@@ -1,79 +1,90 @@
1
- import SwiftUI
2
1
  import MoMoUIKits
2
+ import SwiftUI
3
3
 
4
4
  struct SuggestActionDemo: View {
5
+ var body: some View {
6
+ if #available(iOS 16.0, *) {
7
+ DemoScreen(preview: { SuggestActionPreview() }, playground: { SuggestActionPlayground() })
8
+ } else {
9
+ Text("Requires iOS 16+").padding()
10
+ }
11
+ }
12
+ }
13
+
14
+ // MARK: - Preview
15
+
16
+ private struct SuggestActionPreview: View {
5
17
  @State private var visible1 = true
6
18
  @State private var visible2 = true
7
19
  @State private var visible3 = true
8
- @State private var visible4 = true
9
20
 
10
21
  var body: some View {
11
- ScrollView {
12
- VStack(alignment: .leading, spacing: 24) {
13
- section("Default") {
14
- SuggestAction(
15
- message: "You have a new suggestion available for you.",
16
- buttonTitle: "View",
17
- visible: visible1,
18
- onClose: { visible1 = false },
19
- onPressButton: { visible1 = false }
20
- )
21
- }
22
-
23
- section("With bold message") {
24
- SuggestAction(
25
- message: "You have a new suggestion available for you.",
26
- buttonTitle: "View",
27
- boldMessage: "new suggestion",
28
- visible: visible2,
29
- onClose: { visible2 = false },
30
- onPressButton: { visible2 = false }
31
- )
32
- }
22
+ BasicColumnBox("Default", alignment: .leading) {
23
+ SuggestAction(
24
+ message: "You have a new suggestion available for you.",
25
+ buttonTitle: "View",
26
+ visible: visible1,
27
+ onClose: { visible1 = false },
28
+ onPressButton: { visible1 = false }
29
+ )
30
+ }
31
+ BasicColumnBox("With bold message", alignment: .leading) {
32
+ SuggestAction(
33
+ message: "You have a new suggestion available for you.",
34
+ buttonTitle: "View",
35
+ boldMessage: "new suggestion",
36
+ visible: visible2,
37
+ onClose: { visible2 = false },
38
+ onPressButton: { visible2 = false }
39
+ )
40
+ }
41
+ BasicColumnBox("With image", alignment: .leading) {
42
+ SuggestAction(
43
+ message: "Complete your profile to unlock more features.",
44
+ buttonTitle: "Go",
45
+ boldMessage: "Complete",
46
+ image: "https://static.momocdn.net/app/img/kits/trustBanner/ic_secu.png",
47
+ visible: visible3,
48
+ onClose: { visible3 = false },
49
+ onPressButton: { visible3 = false }
50
+ )
51
+ }
52
+ MoMoUIKits.Button(
53
+ title: "Reset all",
54
+ action: { visible1 = true; visible2 = true; visible3 = true },
55
+ type: .primary,
56
+ isFull: false
57
+ )
58
+ }
59
+ }
33
60
 
34
- section("With image") {
35
- SuggestAction(
36
- message: "Complete your profile to unlock more features.",
37
- buttonTitle: "Go",
38
- boldMessage: "Complete",
39
- image: "https://static.momocdn.net/app/img/kits/trustBanner/ic_secu.png",
40
- visible: visible3,
41
- onClose: { visible3 = false },
42
- onPressButton: { visible3 = false }
43
- )
44
- }
61
+ // MARK: - Playground
45
62
 
46
- section("Short message") {
47
- SuggestAction(
48
- message: "Update available.",
49
- buttonTitle: "Update",
50
- visible: visible4,
51
- onClose: { visible4 = false },
52
- onPressButton: { visible4 = false }
53
- )
54
- }
63
+ @available(iOS 16.0, *)
64
+ private struct SuggestActionPlayground: View {
65
+ @State private var message = "You have a new suggestion available for you."
66
+ @State private var buttonTitle = "View"
67
+ @State private var boldMessage = "suggestion"
68
+ @State private var visible = true
55
69
 
56
- Button(
57
- title: "Reset all",
58
- action: {
59
- visible1 = true
60
- visible2 = true
61
- visible3 = true
62
- visible4 = true
63
- },
64
- type: .primary,
65
- isFull: false
70
+ var body: some View {
71
+ PlaygroundTab(
72
+ component: {
73
+ SuggestAction(
74
+ message: message,
75
+ buttonTitle: buttonTitle,
76
+ boldMessage: boldMessage,
77
+ visible: visible,
78
+ onClose: { visible = false },
79
+ onPressButton: { visible = false }
66
80
  )
67
- }
68
- .padding()
69
- }
70
- }
71
-
72
- @ViewBuilder
73
- private func section<Content: View>(_ title: String, @ViewBuilder content: () -> Content) -> some View {
74
- VStack(alignment: .leading, spacing: 8) {
75
- MomoText(title, typography: .headerSSemibold, color: Colors.textSecondary)
76
- content()
77
- }
81
+ },
82
+ params: [
83
+ .string("Message", $message),
84
+ .string("ButtonTitle", $buttonTitle),
85
+ .string("BoldMessage", $boldMessage),
86
+ .checkbox("Visible", $visible),
87
+ ]
88
+ )
78
89
  }
79
90
  }