@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
@@ -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
  }
@@ -1,152 +1,107 @@
1
+ //
2
+ // SwipeDemo.swift
3
+ // Example
4
+ //
5
+ // Preview + Playground demo, mirroring Compose's SwipeUsage.kt.
6
+ //
7
+
1
8
  import MoMoUIKits
2
9
  import SwiftUI
3
10
 
11
+ private func swipeContent(_ text: String) -> some View {
12
+ HStack {
13
+ MomoText(text, typography: .bodyDefaultRegular, color: Colors.text)
14
+ Spacer(minLength: 0)
15
+ }
16
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
17
+ .padding(.horizontal, Spacing.M)
18
+ .background(Colors.card)
19
+ }
20
+
4
21
  struct SwipeDemo: View {
5
- @State private var showLeftActions = true
6
- @State private var showRightActions = true
7
- @State private var heightValue: Double = 56
8
- @State private var radiusValue: Double = 0
9
- @State private var lastAction = "No action yet"
22
+ var body: some View {
23
+ if #available(iOS 16.0, *) {
24
+ DemoScreen(preview: { SwipePreview() }, playground: { SwipePlayground() })
25
+ } else {
26
+ Text("Requires iOS 16+").padding()
27
+ }
28
+ }
29
+ }
30
+
31
+ // MARK: - Preview
10
32
 
33
+ private struct SwipePreview: View {
11
34
  private var editAction: SwipeAction {
12
- SwipeAction(
13
- label: "Edit",
14
- icon: "24_basic_copy",
15
- backgroundColor: Colors.blue03,
16
- onPress: { lastAction = "Edit pressed" }
17
- )
35
+ SwipeAction(label: "Edit", icon: "24_basic_copy", backgroundColor: Colors.blue03, onPress: {})
18
36
  }
19
-
20
37
  private var deleteAction: SwipeAction {
21
- SwipeAction(
22
- label: "Delete",
23
- icon: "24_basic_delete",
24
- backgroundColor: Colors.red03,
25
- onPress: { lastAction = "Delete pressed" }
26
- )
38
+ SwipeAction(label: "Delete", icon: "24_basic_delete", backgroundColor: Colors.red03, onPress: {})
27
39
  }
28
-
29
40
  private var archiveAction: SwipeAction {
30
- SwipeAction(
31
- label: "Archive",
32
- icon: "24_basic_flag",
33
- backgroundColor: Colors.orange03,
34
- onPress: { lastAction = "Archive pressed" }
35
- )
41
+ SwipeAction(label: "Archive", icon: "24_basic_flag", backgroundColor: Colors.orange03, onPress: {})
36
42
  }
37
43
 
38
44
  var body: some View {
39
- ScrollView {
40
- VStack(alignment: .leading, spacing: Spacing.XL) {
41
- preview
42
- Divider()
43
- playground
44
- }
45
- .padding(.vertical, Spacing.L)
45
+ BasicColumnBox("Right actions only", alignment: .leading) {
46
+ Swipe(rightActions: [deleteAction]) { swipeContent("Swipe left to delete") }
46
47
  }
47
- .background(Colors.background)
48
- }
49
-
50
- private var preview: some View {
51
- VStack(alignment: .leading, spacing: Spacing.XL) {
52
- section("Right actions only") {
53
- Swipe(rightActions: [deleteAction]) {
54
- swipeContent("Swipe left to delete")
55
- }
56
- }
57
-
58
- section("Left actions only") {
59
- Swipe(leftActions: [editAction, archiveAction]) {
60
- swipeContent("Swipe right for actions")
61
- }
62
- }
63
-
64
- section("Both sides") {
65
- Swipe(leftActions: [editAction], rightActions: [deleteAction]) {
66
- swipeContent("Swipe both directions")
67
- }
68
- }
69
-
70
- section("Multiple right actions") {
71
- Swipe(rightActions: [editAction, archiveAction, deleteAction]) {
72
- swipeContent("3 right actions")
73
- }
74
- }
75
-
76
- section("With itemRadius") {
77
- Swipe(rightActions: [deleteAction], itemRadius: Radius.S) {
78
- swipeContent("Rounded corners")
79
- }
80
- }
81
-
82
- section("Custom height") {
83
- Swipe(rightActions: [deleteAction], height: 80) {
84
- swipeContent("Taller row (80dp)")
85
- }
86
- }
48
+ BasicColumnBox("Left actions only", alignment: .leading) {
49
+ Swipe(leftActions: [editAction, archiveAction]) { swipeContent("Swipe right for actions") }
50
+ }
51
+ BasicColumnBox("Both sides", alignment: .leading) {
52
+ Swipe(leftActions: [editAction], rightActions: [deleteAction]) { swipeContent("Swipe both directions") }
53
+ }
54
+ BasicColumnBox("Multiple right actions", alignment: .leading) {
55
+ Swipe(rightActions: [editAction, archiveAction, deleteAction]) { swipeContent("3 right actions") }
56
+ }
57
+ BasicColumnBox("With itemRadius", alignment: .leading) {
58
+ Swipe(rightActions: [deleteAction], itemRadius: Radius.S) { swipeContent("Rounded corners") }
59
+ }
60
+ BasicColumnBox("Custom height", alignment: .leading) {
61
+ Swipe(rightActions: [deleteAction], height: 80) { swipeContent("Taller row (80dp)") }
87
62
  }
88
63
  }
64
+ }
89
65
 
90
- private var playground: some View {
91
- section("Playground") {
92
- Toggle(isOn: $showLeftActions) {
93
- MomoText("Show Left Actions", typography: .labelSMedium, color: Colors.text)
94
- }
95
-
96
- Toggle(isOn: $showRightActions) {
97
- MomoText("Show Right Actions", typography: .labelSMedium, color: Colors.text)
98
- }
99
-
100
- VStack(alignment: .leading, spacing: Spacing.XS) {
101
- MomoText("Height: \(Int(heightValue))", typography: .labelSMedium, color: Colors.textSecondary)
102
- Slider(value: $heightValue, in: 40...100, step: 1)
103
- }
104
-
105
- VStack(alignment: .leading, spacing: Spacing.XS) {
106
- MomoText("Item Radius: \(Int(radiusValue))", typography: .labelSMedium, color: Colors.textSecondary)
107
- Slider(value: $radiusValue, in: 0...24, step: 1)
108
- }
66
+ // MARK: - Playground
109
67
 
110
- Swipe(
111
- leftActions: showLeftActions ? [editAction, archiveAction] : [],
112
- rightActions: showRightActions ? [deleteAction] : [],
113
- height: CGFloat(heightValue),
114
- itemRadius: CGFloat(radiusValue)
115
- ) {
116
- swipeContent("Swipe me!")
117
- }
68
+ @available(iOS 16.0, *)
69
+ private struct SwipePlayground: View {
70
+ @State private var showLeftActions = true
71
+ @State private var showRightActions = true
72
+ @State private var heightValue: Double = 56
73
+ @State private var radiusValue: Double = 0
74
+ @State private var lastAction = "No action yet"
118
75
 
119
- MomoText(lastAction, typography: .descriptionDefaultRegular, color: Colors.textSecondary)
120
- }
76
+ private var editAction: SwipeAction {
77
+ SwipeAction(label: "Edit", icon: "24_basic_copy", backgroundColor: Colors.blue03, onPress: { lastAction = "Edit pressed" })
121
78
  }
122
-
123
- @ViewBuilder
124
- private func section<Content: View>(
125
- _ title: String,
126
- @ViewBuilder content: () -> Content
127
- ) -> some View {
128
- VStack(alignment: .leading, spacing: Spacing.M) {
129
- MomoText(title, typography: .headerSSemibold, color: Colors.text)
130
- content()
131
- }
132
- .padding(.horizontal, Spacing.M)
79
+ private var deleteAction: SwipeAction {
80
+ SwipeAction(label: "Delete", icon: "24_basic_delete", backgroundColor: Colors.red03, onPress: { lastAction = "Delete pressed" })
133
81
  }
134
-
135
- private func swipeContent(_ text: String) -> some View {
136
- HStack {
137
- MomoText(text, typography: .bodyDefaultRegular, color: Colors.text)
138
- Spacer(minLength: 0)
139
- }
140
- .frame(maxWidth: .infinity, maxHeight: .infinity)
141
- .padding(.horizontal, Spacing.M)
142
- .background(Colors.card)
82
+ private var archiveAction: SwipeAction {
83
+ SwipeAction(label: "Archive", icon: "24_basic_flag", backgroundColor: Colors.orange03, onPress: { lastAction = "Archive pressed" })
143
84
  }
144
- }
145
85
 
146
- #if DEBUG
147
- struct SwipeDemo_Previews: PreviewProvider {
148
- static var previews: some View {
149
- SwipeDemo()
86
+ var body: some View {
87
+ PlaygroundTab(
88
+ component: {
89
+ VStack(alignment: .leading, spacing: Spacing.S) {
90
+ Swipe(
91
+ leftActions: showLeftActions ? [editAction, archiveAction] : [],
92
+ rightActions: showRightActions ? [deleteAction] : [],
93
+ height: CGFloat(heightValue),
94
+ itemRadius: CGFloat(radiusValue)
95
+ ) { swipeContent("Swipe me!") }
96
+ MomoText(lastAction, typography: .descriptionDefaultRegular, color: Colors.textSecondary)
97
+ }
98
+ },
99
+ params: [
100
+ .checkbox("ShowLeftActions", $showLeftActions),
101
+ .checkbox("ShowRightActions", $showRightActions),
102
+ .slider("Height", $heightValue, min: 40, max: 100, step: 1),
103
+ .slider("ItemRadius", $radiusValue, min: 0, max: 24, step: 1),
104
+ ]
105
+ )
150
106
  }
151
107
  }
152
- #endif
@@ -2,32 +2,57 @@
2
2
  // SwitchDemo.swift
3
3
  // Example
4
4
  //
5
- // Created by dung.pham2 on 3/12/24.
5
+ // Preview + Playground demo for Switch.
6
6
  //
7
7
 
8
- import SwiftUI
9
8
  import MoMoUIKits
9
+ import SwiftUI
10
10
 
11
11
  struct SwitchDemo: View {
12
+ var body: some View {
13
+ if #available(iOS 16.0, *) {
14
+ DemoScreen(preview: { SwitchPreview() }, playground: { SwitchPlayground() })
15
+ } else {
16
+ Text("Requires iOS 16+").padding()
17
+ }
18
+ }
19
+ }
20
+
21
+ // MARK: - Preview
22
+
23
+ private struct SwitchPreview: View {
12
24
  @State private var checked = false
13
-
25
+
14
26
  var body: some View {
15
- VStack(alignment: .leading, spacing: 8) {
16
- Text("Value")
17
- Switch($checked, onChange: { newValue in
18
- checked = newValue
19
- })
20
-
21
-
22
- Text("Disabled")
23
- Switch( .constant(true), disabled: true, onChange: { _ in
24
- checked = !checked
25
- })
26
-
27
- Switch( .constant(false), disabled: true, onChange: { _ in
28
- checked = !checked
29
- })
27
+ BasicColumnBox("Value", alignment: .leading) {
28
+ Switch($checked, onChange: { checked = $0 })
30
29
  }
31
- .padding()
30
+ BasicColumnBox("Disabled (on)", alignment: .leading) {
31
+ Switch(.constant(true), disabled: true)
32
+ }
33
+ BasicColumnBox("Disabled (off)", alignment: .leading) {
34
+ Switch(.constant(false), disabled: true)
35
+ }
36
+ }
37
+ }
38
+
39
+ // MARK: - Playground
40
+
41
+ @available(iOS 16.0, *)
42
+ private struct SwitchPlayground: View {
43
+ @State private var value = false
44
+ @State private var title = ""
45
+ @State private var disabled = false
46
+
47
+ var body: some View {
48
+ PlaygroundTab(
49
+ component: {
50
+ Switch($value, disabled: disabled, onChange: { value = $0 }, title: title)
51
+ },
52
+ params: [
53
+ .string("Title", $title),
54
+ .checkbox("Disabled", $disabled),
55
+ ]
56
+ )
32
57
  }
33
58
  }