@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.
- package/CLAUDE.md +19 -0
- package/compose/build.gradle.kts +1 -1
- package/compose/compose.podspec +1 -1
- package/gradle.properties +1 -1
- package/ios/Application/ApplicationEnvironment.swift +14 -6
- package/ios/Application/LanguageSource.swift +93 -0
- package/ios/Application/Localize.swift +73 -4
- package/ios/Application/LocalizeModifier.swift +30 -0
- package/ios/Application/Navigation/NavigationContainer.swift +28 -18
- package/ios/Application/Navigation/Navigator.swift +121 -53
- package/ios/Application/Navigation/NavigatorManager.swift +49 -0
- package/ios/Application/Navigation/component/NavigationFooter.swift +90 -0
- package/ios/Application/StackScreen.swift +19 -28
- package/ios/Badge/Badge.swift +2 -1
- package/ios/Badge/BadgeRibbon.swift +6 -2
- package/ios/Button/Button.swift +41 -61
- package/ios/Chip/Chip.swift +6 -5
- package/ios/Icon/Icon.swift +13 -4
- package/ios/Input/ErrorView.swift +2 -1
- package/ios/Input/Input.swift +9 -2
- package/ios/Input/InputPhoneNumber.swift +2 -1
- package/ios/Input/InputSearch.swift +3 -2
- package/ios/Input/InputTextArea.swift +6 -1
- package/ios/InputMoney/InputMoney.swift +5 -2
- package/ios/InputOTP/InputOTP.swift +2 -1
- package/ios/Layout/GridContext.swift +30 -0
- package/ios/Layout/Item.swift +42 -0
- package/ios/Layout/Section.swift +134 -0
- package/ios/Popup/PopupNotify.swift +2 -1
- package/ios/ProgressInfo/ProgressInfo.swift +4 -3
- package/ios/Rating/Rating.swift +2 -1
- package/ios/Stepper/Stepper.swift +2 -1
- package/ios/SuggestAction/SuggestAction.swift +3 -2
- package/ios/Tag/Tag.swift +2 -1
- package/ios/Template/TrustBanner/TrustBanner.swift +4 -2
- package/ios/Title/Title.swift +3 -2
- package/ios/Tooltip/Tooltip.swift +2 -1
- package/ios/Typography/FontScale.swift +103 -0
- package/ios/Typography/FontScaleStore.swift +52 -13
- package/ios/Typography/Text.swift +12 -29
- package/ios/Typography/Typography.swift +66 -86
- package/ios/native-kits.podspec +2 -1
- package/ios-demo/MoMoUIKitsDemo.podspec +1 -1
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AvatarDemo.swift +87 -73
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BadgeDemo.swift +55 -249
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ButtonDemo.swift +90 -82
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CarouselDemo.swift +74 -104
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CheckboxDemo.swift +47 -50
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ChipDemo.swift +63 -7
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CollapseDemo.swift +90 -81
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DateTimePickerDemo.swift +73 -97
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DemoScreen.swift +420 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DividerDemo.swift +46 -4
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +54 -57
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconButtonDemo.swift +80 -45
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconDemo.swift +81 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ImageDemo.swift +49 -62
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InformationDemo.swift +66 -116
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDemo.swift +104 -98
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDropDownDemo.swift +76 -118
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputMoneyDemo.swift +73 -86
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputOTPDemo.swift +69 -54
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputPhoneNumberDemo.swift +74 -54
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputSearchDemo.swift +73 -20
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputTextAreaDemo.swift +68 -38
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LoaderDemo.swift +55 -52
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LocalizeDemo.swift +51 -4
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +14 -2
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PaginationDemo.swift +47 -51
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PlaygroundData.swift +76 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +67 -93
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +34 -43
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ProgressInfoDemo.swift +83 -71
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RadioDemo.swift +55 -23
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RatingDemo.swift +58 -46
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SectionDemo.swift +83 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SkeletonDemo.swift +41 -12
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SliderDemo.swift +67 -127
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SnackBarDemo.swift +54 -110
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepperDemo.swift +69 -79
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepsDemo.swift +78 -58
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SuggestActionDemo.swift +76 -65
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwipeDemo.swift +82 -127
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwitchDemo.swift +44 -19
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TabViewDemo.swift +92 -168
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TagDemo.swift +79 -27
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ThemeDemo.swift +0 -1
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TitleDemo.swift +87 -92
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TooltipDemo.swift +94 -163
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TypographyDemo.swift +70 -70
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/UploaderDemo.swift +68 -114
- package/ios-demo/Sources/MoMoUIKitsDemo/SwiftUIDemoBrowserView.swift +3 -1
- package/package.json +2 -2
|
@@ -1,58 +1,93 @@
|
|
|
1
|
+
//
|
|
2
|
+
// IconButtonDemo.swift
|
|
3
|
+
// Example
|
|
4
|
+
//
|
|
5
|
+
// Preview + Playground demo (DemoScreen pattern).
|
|
6
|
+
//
|
|
7
|
+
|
|
1
8
|
import MoMoUIKits
|
|
2
9
|
import SwiftUI
|
|
3
10
|
|
|
4
|
-
|
|
11
|
+
private let iconButtonSizeList: [PlaygroundOption] = [
|
|
12
|
+
.init("large", IconSize.large),
|
|
13
|
+
.init("medium", IconSize.medium),
|
|
14
|
+
.init("small", IconSize.small),
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
private let iconShapeList: [PlaygroundOption] = [
|
|
18
|
+
.init("circle", IconShape.circle),
|
|
19
|
+
.init("square", IconShape.square),
|
|
20
|
+
]
|
|
5
21
|
|
|
6
22
|
struct IconButtonDemo: View {
|
|
7
23
|
var body: some View {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.font(.headline)
|
|
13
|
-
HStack(spacing: 12) {
|
|
14
|
-
IconButton(icon: url, onClick: onPress, type: .primary)
|
|
15
|
-
IconButton(icon: url2, onClick: onPress, type: .primary)
|
|
16
|
-
IconButton(icon: url3, onClick: onPress, type: .primary)
|
|
17
|
-
IconButton(icon: url4, onClick: onPress, type: .primary)
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
Group {
|
|
22
|
-
Text("Type")
|
|
23
|
-
.font(.headline)
|
|
24
|
-
HStack(spacing: 12) {
|
|
25
|
-
IconButton(icon: url, onClick: onPress, type: .primary)
|
|
26
|
-
IconButton(icon: url, onClick: onPress, type: .secondary)
|
|
27
|
-
IconButton(icon: url, onClick: onPress, type: .tonal)
|
|
28
|
-
IconButton(icon: url, onClick: onPress, type: .outline)
|
|
29
|
-
IconButton(icon: url, onClick: onPress, type: .disabled)
|
|
30
|
-
IconButton(icon: url, onClick: onPress, type: .danger)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
Group {
|
|
35
|
-
Text("Size")
|
|
36
|
-
.font(.headline)
|
|
37
|
-
HStack(spacing: 12) {
|
|
38
|
-
IconButton(icon: url, onClick: onPress, type: .primary, size: .large)
|
|
39
|
-
IconButton(icon: url, onClick: onPress, type: .primary, size: .small)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
.padding(16)
|
|
24
|
+
if #available(iOS 16.0, *) {
|
|
25
|
+
DemoScreen(preview: { IconButtonPreview() }, playground: { IconButtonPlayground() })
|
|
26
|
+
} else {
|
|
27
|
+
Text("Requires iOS 16+").padding()
|
|
44
28
|
}
|
|
45
|
-
.padding(.top)
|
|
46
29
|
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// MARK: - Preview
|
|
47
33
|
|
|
48
|
-
|
|
49
|
-
|
|
34
|
+
private struct IconButtonPreview: View {
|
|
35
|
+
private let icon = "travel_plane"
|
|
36
|
+
|
|
37
|
+
var body: some View {
|
|
38
|
+
BasicColumnBox("Source", alignment: .leading) {
|
|
39
|
+
HStack(spacing: Spacing.M) {
|
|
40
|
+
IconButton(icon: "travel_plane", onClick: {})
|
|
41
|
+
IconButton(icon: "shopping_coupon", onClick: {})
|
|
42
|
+
IconButton(icon: "shopping_store", onClick: {})
|
|
43
|
+
IconButton(icon: "time_alarm_check", onClick: {})
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
BasicColumnBox("Type", alignment: .leading) {
|
|
47
|
+
HStack(spacing: Spacing.M) {
|
|
48
|
+
IconButton(icon: icon, onClick: {}, type: .primary)
|
|
49
|
+
IconButton(icon: icon, onClick: {}, type: .secondary)
|
|
50
|
+
IconButton(icon: icon, onClick: {}, type: .tonal)
|
|
51
|
+
IconButton(icon: icon, onClick: {}, type: .outline)
|
|
52
|
+
IconButton(icon: icon, onClick: {}, type: .disabled)
|
|
53
|
+
IconButton(icon: icon, onClick: {}, type: .danger)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
BasicColumnBox("Size", alignment: .leading) {
|
|
57
|
+
HStack(spacing: Spacing.M) {
|
|
58
|
+
IconButton(icon: icon, onClick: {}, type: .primary, size: .large)
|
|
59
|
+
IconButton(icon: icon, onClick: {}, type: .primary, size: .small)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
50
62
|
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// MARK: - Playground
|
|
51
66
|
|
|
52
|
-
|
|
67
|
+
@available(iOS 16.0, *)
|
|
68
|
+
private struct IconButtonPlayground: View {
|
|
69
|
+
@State private var icon: PlaygroundOption? = playgroundIcons.first { $0.key == "basic_home" }
|
|
70
|
+
@State private var type: PlaygroundOption? = buttonTypeList.first { $0.key == "primary" }
|
|
71
|
+
@State private var size: PlaygroundOption? = iconButtonSizeList.first { $0.key == "small" }
|
|
72
|
+
@State private var shape: PlaygroundOption? = iconShapeList.first { $0.key == "circle" }
|
|
53
73
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
74
|
+
var body: some View {
|
|
75
|
+
PlaygroundTab(
|
|
76
|
+
component: {
|
|
77
|
+
IconButton(
|
|
78
|
+
icon: (icon?.value as? String) ?? "basic_home",
|
|
79
|
+
onClick: {},
|
|
80
|
+
type: (type?.value as? ButtonType) ?? .primary,
|
|
81
|
+
size: (size?.value as? IconSize) ?? .small,
|
|
82
|
+
shape: (shape?.value as? IconShape) ?? .circle
|
|
83
|
+
)
|
|
84
|
+
},
|
|
85
|
+
params: [
|
|
86
|
+
.option("Icon", playgroundIcons, $icon),
|
|
87
|
+
.radio("Type", buttonTypeList, $type),
|
|
88
|
+
.radio("Size", iconButtonSizeList, $size),
|
|
89
|
+
.radio("Shape", iconShapeList, $shape),
|
|
90
|
+
]
|
|
91
|
+
)
|
|
92
|
+
}
|
|
58
93
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
//
|
|
2
|
+
// IconDemo.swift
|
|
3
|
+
// Example
|
|
4
|
+
//
|
|
5
|
+
// Preview + Playground demo, mirroring Compose's IconUsage.kt.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import MoMoUIKits
|
|
9
|
+
import SwiftUI
|
|
10
|
+
|
|
11
|
+
struct IconDemo: View {
|
|
12
|
+
var body: some View {
|
|
13
|
+
if #available(iOS 16.0, *) {
|
|
14
|
+
DemoScreen(preview: { IconPreview() }, playground: { IconPlayground() })
|
|
15
|
+
} else {
|
|
16
|
+
Text("Requires iOS 16+").padding()
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// MARK: - Preview
|
|
22
|
+
|
|
23
|
+
private struct IconPreview: View {
|
|
24
|
+
var body: some View {
|
|
25
|
+
BasicColumnBox("Source", alignment: .leading) {
|
|
26
|
+
HStack(spacing: Spacing.M) {
|
|
27
|
+
Icon(source: "basic_home", size: 24)
|
|
28
|
+
Icon(source: "basic_flag", size: 24)
|
|
29
|
+
Icon(source: "basic_filter", size: 24)
|
|
30
|
+
Icon(source: "basic_delete", size: 24)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
BasicColumnBox("Size", alignment: .leading) {
|
|
34
|
+
HStack(alignment: .center, spacing: Spacing.M) {
|
|
35
|
+
Icon(source: "basic_home", size: 16)
|
|
36
|
+
Icon(source: "basic_flag", size: 20)
|
|
37
|
+
Icon(source: "basic_filter", size: 24)
|
|
38
|
+
Icon(source: "basic_delete", size: 28)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
BasicColumnBox("Color", alignment: .leading) {
|
|
42
|
+
HStack(spacing: Spacing.M) {
|
|
43
|
+
Icon(source: "basic_home", size: 24, color: Colors.red03)
|
|
44
|
+
Icon(source: "basic_flag", size: 24, color: Colors.green04)
|
|
45
|
+
Icon(source: "basic_filter", size: 24, color: Colors.pink06)
|
|
46
|
+
Icon(source: "basic_delete", size: 24, color: Colors.yellow02)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
BasicColumnBox("No theme icon", alignment: .leading) {
|
|
50
|
+
HStack(spacing: Spacing.M) {
|
|
51
|
+
Icon(source: "ic_round_momo_tiny", size: 24)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// MARK: - Playground
|
|
58
|
+
|
|
59
|
+
@available(iOS 16.0, *)
|
|
60
|
+
private struct IconPlayground: View {
|
|
61
|
+
@State private var source: PlaygroundOption? = playgroundIcons.first { $0.key == "basic_home" }
|
|
62
|
+
@State private var color: PlaygroundOption? = playgroundColors.first { $0.key == "black17" }
|
|
63
|
+
@State private var size = "24"
|
|
64
|
+
|
|
65
|
+
var body: some View {
|
|
66
|
+
PlaygroundTab(
|
|
67
|
+
component: {
|
|
68
|
+
Icon(
|
|
69
|
+
source: (source?.value as? String) ?? "basic_home",
|
|
70
|
+
size: CGFloat(Int(size) ?? 24),
|
|
71
|
+
color: color?.value as? Color
|
|
72
|
+
)
|
|
73
|
+
},
|
|
74
|
+
params: [
|
|
75
|
+
.option("Source", playgroundIcons, $source),
|
|
76
|
+
.color("Color", playgroundColors, $color),
|
|
77
|
+
.number("Size (dp)", $size),
|
|
78
|
+
]
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -2,77 +2,64 @@
|
|
|
2
2
|
// ImageDemo.swift
|
|
3
3
|
// Example
|
|
4
4
|
//
|
|
5
|
-
//
|
|
5
|
+
// Preview + Playground demo for ImageView.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import SwiftUI
|
|
9
8
|
import MoMoUIKits
|
|
9
|
+
import SwiftUI
|
|
10
10
|
|
|
11
11
|
struct ImageDemo: View {
|
|
12
|
-
// MARK: - Properties
|
|
13
|
-
@State private var time = 1000
|
|
14
|
-
|
|
15
|
-
// MARK: - Body
|
|
16
12
|
var body: some View {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
ImageView("https://source.unsplash.com/random/\(time)")
|
|
22
|
-
.frame(width: 100, height: 100)
|
|
23
|
-
|
|
24
|
-
Spacer()
|
|
25
|
-
|
|
26
|
-
ImageView("https://abc.com")
|
|
27
|
-
.frame(width: 100, height: 100)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
ImageView("https://source.unsplash.com/random/\(time)")
|
|
31
|
-
.frame(maxWidth: .infinity)
|
|
32
|
-
.frame(height: 100)
|
|
33
|
-
.aspectRatio(contentMode: .fill)
|
|
34
|
-
.clipped()
|
|
35
|
-
|
|
36
|
-
ImageView("https://images.unsplash.com/photo-1509395062183-67c5ad6faff9")
|
|
37
|
-
.frame(maxWidth: .infinity)
|
|
38
|
-
.frame(height: 100)
|
|
39
|
-
.aspectRatio(contentMode: .fill)
|
|
40
|
-
.clipped()
|
|
41
|
-
|
|
42
|
-
ImageView("https://source.unsplash.com/random/\(time)")
|
|
43
|
-
.frame(maxWidth: .infinity)
|
|
44
|
-
.frame(height: 100)
|
|
45
|
-
.aspectRatio(contentMode: .fill)
|
|
46
|
-
.clipped()
|
|
47
|
-
|
|
48
|
-
ImageView("https://source.unsplash.com/random/\(time)")
|
|
49
|
-
.frame(maxWidth: .infinity)
|
|
50
|
-
.frame(height: 100)
|
|
51
|
-
.aspectRatio(contentMode: .fit)
|
|
52
|
-
|
|
53
|
-
ImageView("https://source.unsplash.com/random/\(time)")
|
|
54
|
-
.frame(maxWidth: .infinity)
|
|
55
|
-
.frame(height: 100)
|
|
56
|
-
.aspectRatio(contentMode: .fit)
|
|
57
|
-
|
|
58
|
-
ImageView("https://source.unsplash.com/random/\(time)")
|
|
59
|
-
.frame(maxWidth: .infinity)
|
|
60
|
-
.frame(height: 100)
|
|
61
|
-
.aspectRatio(contentMode: .fit)
|
|
62
|
-
}
|
|
63
|
-
.padding()
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
.onAppear {
|
|
67
|
-
startTimer()
|
|
13
|
+
if #available(iOS 16.0, *) {
|
|
14
|
+
DemoScreen(preview: { ImagePreview() }, playground: { ImagePlayground() })
|
|
15
|
+
} else {
|
|
16
|
+
Text("Requires iOS 16+").padding()
|
|
68
17
|
}
|
|
69
18
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// MARK: - Preview
|
|
22
|
+
|
|
23
|
+
private struct ImagePreview: View {
|
|
24
|
+
private let sample = "https://images.unsplash.com/photo-1509395062183-67c5ad6faff9"
|
|
25
|
+
|
|
26
|
+
var body: some View {
|
|
27
|
+
BasicColumnBox("Fixed size", alignment: .leading) {
|
|
28
|
+
ImageView(sample).frame(width: 100, height: 100)
|
|
29
|
+
}
|
|
30
|
+
BasicColumnBox("Fill width", alignment: .leading) {
|
|
31
|
+
ImageView(sample)
|
|
32
|
+
.frame(maxWidth: .infinity)
|
|
33
|
+
.frame(height: 120)
|
|
34
|
+
.aspectRatio(contentMode: .fill)
|
|
35
|
+
.clipped()
|
|
36
|
+
}
|
|
37
|
+
BasicColumnBox("Invalid URL (fallback)", alignment: .leading) {
|
|
38
|
+
ImageView("https://abc.com").frame(width: 100, height: 100)
|
|
75
39
|
}
|
|
76
40
|
}
|
|
77
41
|
}
|
|
78
42
|
|
|
43
|
+
// MARK: - Playground
|
|
44
|
+
|
|
45
|
+
@available(iOS 16.0, *)
|
|
46
|
+
private struct ImagePlayground: View {
|
|
47
|
+
@State private var url = "https://images.unsplash.com/photo-1509395062183-67c5ad6faff9"
|
|
48
|
+
@State private var height: Double = 120
|
|
49
|
+
|
|
50
|
+
var body: some View {
|
|
51
|
+
PlaygroundTab(
|
|
52
|
+
component: {
|
|
53
|
+
ImageView(url)
|
|
54
|
+
.frame(maxWidth: .infinity)
|
|
55
|
+
.frame(height: CGFloat(height))
|
|
56
|
+
.aspectRatio(contentMode: .fill)
|
|
57
|
+
.clipped()
|
|
58
|
+
},
|
|
59
|
+
params: [
|
|
60
|
+
.string("URL", $url),
|
|
61
|
+
.slider("Height", $height, min: 60, max: 240, step: 10),
|
|
62
|
+
]
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -2,137 +2,87 @@
|
|
|
2
2
|
// InformationDemo.swift
|
|
3
3
|
// Example
|
|
4
4
|
//
|
|
5
|
-
//
|
|
5
|
+
// Preview + Playground demo (DemoScreen pattern).
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import Foundation
|
|
9
8
|
import MoMoUIKits
|
|
10
9
|
import SwiftUI
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
private let informationStateList: [PlaygroundOption] = [
|
|
12
|
+
.init("default", InformationState.default),
|
|
13
|
+
.init("warning", InformationState.warning),
|
|
14
|
+
.init("error", InformationState.error),
|
|
15
|
+
]
|
|
13
16
|
|
|
14
17
|
struct InformationDemo: View {
|
|
15
|
-
@State private var showDismissible = true
|
|
16
|
-
|
|
17
18
|
var body: some View {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
section("States") {
|
|
23
|
-
Information(
|
|
24
|
-
title: "Default",
|
|
25
|
-
description: "This is a default information message.",
|
|
26
|
-
showIconClose: true,
|
|
27
|
-
onPressClose: {}
|
|
28
|
-
)
|
|
29
|
-
Information(
|
|
30
|
-
title: "Warning",
|
|
31
|
-
description: "This is a warning information message.",
|
|
32
|
-
state: .warning
|
|
33
|
-
)
|
|
34
|
-
Information(
|
|
35
|
-
title: "Error",
|
|
36
|
-
description: "This is an error information message.",
|
|
37
|
-
state: .error
|
|
38
|
-
)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// MARK: - Without title
|
|
42
|
-
|
|
43
|
-
section("Description only") {
|
|
44
|
-
Information(
|
|
45
|
-
description: "Information without a title, only a description."
|
|
46
|
-
)
|
|
47
|
-
Information(
|
|
48
|
-
description: "Warning without a title.",
|
|
49
|
-
state: .warning
|
|
50
|
-
)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// MARK: - With action
|
|
54
|
-
|
|
55
|
-
section("With action") {
|
|
56
|
-
Information(
|
|
57
|
-
title: "Update available",
|
|
58
|
-
description: "A new version is ready to install.",
|
|
59
|
-
onPressAction: { print("Action pressed") },
|
|
60
|
-
action: "Update now"
|
|
61
|
-
)
|
|
62
|
-
Information(
|
|
63
|
-
title: "Payment failed",
|
|
64
|
-
description: "We couldn't process your payment.",
|
|
65
|
-
state: .error,
|
|
66
|
-
onPressAction: { print("Retry pressed") },
|
|
67
|
-
action: "Retry"
|
|
68
|
-
)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// MARK: - With close button
|
|
72
|
-
|
|
73
|
-
section("Dismissible") {
|
|
74
|
-
if showDismissible {
|
|
75
|
-
Information(
|
|
76
|
-
title: "Dismissible",
|
|
77
|
-
description: "Tap the close icon to dismiss this banner.",
|
|
78
|
-
onPressClose: { showDismissible = false }
|
|
79
|
-
)
|
|
80
|
-
} else {
|
|
81
|
-
Information(
|
|
82
|
-
description: "Banner dismissed. Toggle to show again.",
|
|
83
|
-
state: .warning,
|
|
84
|
-
onPressAction: { showDismissible = true }, showIcon: true,
|
|
85
|
-
action: "Show again"
|
|
86
|
-
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// MARK: - With image
|
|
92
|
-
|
|
93
|
-
section("With image") {
|
|
94
|
-
Information(
|
|
95
|
-
title: "Custom image",
|
|
96
|
-
description: "Uses a remote image instead of the state icon.",
|
|
97
|
-
image: "https://images.unsplash.com/photo-1509395062183-67c5ad6faff9",
|
|
98
|
-
onPressClose: { print("Close pressed") }
|
|
99
|
-
)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// MARK: - Without icon
|
|
103
|
-
|
|
104
|
-
section("Without icon") {
|
|
105
|
-
Information(
|
|
106
|
-
title: "No icon",
|
|
107
|
-
description: "showIcon is set to false.",
|
|
108
|
-
showIcon: false
|
|
109
|
-
)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
.padding(.vertical, 16)
|
|
19
|
+
if #available(iOS 16.0, *) {
|
|
20
|
+
DemoScreen(preview: { InformationPreview() }, playground: { InformationPlayground() })
|
|
21
|
+
} else {
|
|
22
|
+
Text("Requires iOS 16+").padding()
|
|
113
23
|
}
|
|
114
24
|
}
|
|
25
|
+
}
|
|
115
26
|
|
|
116
|
-
|
|
27
|
+
// MARK: - Preview
|
|
117
28
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
29
|
+
private struct InformationPreview: View {
|
|
30
|
+
var body: some View {
|
|
31
|
+
BasicColumnBox("States", alignment: .leading) {
|
|
32
|
+
Information(title: "Default", description: "This is a default information message.",
|
|
33
|
+
showIconClose: true, onPressClose: {})
|
|
34
|
+
Information(title: "Warning", description: "This is a warning information message.", state: .warning)
|
|
35
|
+
Information(title: "Error", description: "This is an error information message.", state: .error)
|
|
36
|
+
}
|
|
37
|
+
BasicColumnBox("Description only", alignment: .leading) {
|
|
38
|
+
Information(description: "Information without a title, only a description.")
|
|
39
|
+
Information(description: "Warning without a title.", state: .warning)
|
|
40
|
+
}
|
|
41
|
+
BasicColumnBox("With action", alignment: .leading) {
|
|
42
|
+
Information(title: "Update available", description: "A new version is ready to install.",
|
|
43
|
+
onPressAction: {}, action: "Update now")
|
|
44
|
+
Information(title: "Payment failed", description: "We couldn't process your payment.",
|
|
45
|
+
state: .error, onPressAction: {}, action: "Retry")
|
|
46
|
+
}
|
|
47
|
+
BasicColumnBox("Without icon", alignment: .leading) {
|
|
48
|
+
Information(title: "No icon", description: "showIcon is set to false.", showIcon: false)
|
|
127
49
|
}
|
|
128
|
-
.padding(.horizontal, 16)
|
|
129
50
|
}
|
|
130
51
|
}
|
|
131
52
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
53
|
+
// MARK: - Playground
|
|
54
|
+
|
|
55
|
+
@available(iOS 16.0, *)
|
|
56
|
+
private struct InformationPlayground: View {
|
|
57
|
+
@State private var title = "Title"
|
|
58
|
+
@State private var description = "Information description."
|
|
59
|
+
@State private var state: PlaygroundOption? = informationStateList.first { $0.key == "default" }
|
|
60
|
+
@State private var showIcon = true
|
|
61
|
+
@State private var showIconClose = false
|
|
62
|
+
@State private var action = ""
|
|
63
|
+
|
|
64
|
+
var body: some View {
|
|
65
|
+
PlaygroundTab(
|
|
66
|
+
component: {
|
|
67
|
+
Information(
|
|
68
|
+
title: title.isEmpty ? nil : title,
|
|
69
|
+
description: description,
|
|
70
|
+
state: (state?.value as? InformationState) ?? .default,
|
|
71
|
+
onPressAction: {},
|
|
72
|
+
showIcon: showIcon,
|
|
73
|
+
action: action.isEmpty ? nil : action,
|
|
74
|
+
showIconClose: showIconClose,
|
|
75
|
+
onPressClose: {}
|
|
76
|
+
)
|
|
77
|
+
},
|
|
78
|
+
params: [
|
|
79
|
+
.string("Title", $title),
|
|
80
|
+
.string("Description", $description),
|
|
81
|
+
.radio("State", informationStateList, $state),
|
|
82
|
+
.checkbox("ShowIcon", $showIcon),
|
|
83
|
+
.checkbox("ShowIconClose", $showIconClose),
|
|
84
|
+
.string("Action", $action),
|
|
85
|
+
]
|
|
86
|
+
)
|
|
136
87
|
}
|
|
137
88
|
}
|
|
138
|
-
#endif
|