@momo-kits/native-kits 0.162.2-debug → 0.162.2-sp.1-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/settings.local.json +55 -0
- package/compose/build.gradle.kts +1 -1
- package/compose/compose.podspec +1 -1
- package/gradle.properties +1 -1
- package/ios/Application/Components.swift +34 -43
- package/ios/Application/FloatingButton.swift +10 -8
- package/ios/Application/Navigation/BottomTab/BottomTab.swift +102 -0
- package/ios/Application/Navigation/BottomTab/BottomTabBar.swift +215 -0
- package/ios/Application/Navigation/BottomTab/CurvedContainer.swift +65 -0
- package/ios/Application/Navigation/HeaderBackProps.swift +66 -0
- package/ios/Application/Navigation/HeaderTitle.swift +57 -0
- package/ios/Application/Navigation/HeaderUser.swift +209 -0
- package/ios/Application/Navigation/NavigationContainer.swift +151 -0
- package/ios/Application/Navigation/NavigationOptions.swift +109 -0
- package/ios/Application/Navigation/Navigator.swift +360 -0
- package/ios/Application/Navigation/Overplay/BottomSheet.swift +176 -0
- package/ios/Application/Navigation/Overplay/ModalScreen.swift +68 -0
- package/ios/Application/Navigation/Overplay/SnackBar.swift +144 -0
- package/ios/Application/Navigation/component/Header.swift +178 -0
- package/ios/Application/Navigation/component/HeaderBackground.swift +83 -0
- package/ios/Application/Navigation/component/HeaderColor.swift +65 -0
- package/ios/Application/StackScreen.swift +449 -0
- package/ios/Avatar/Avatar.swift +193 -0
- package/ios/Badge/Badge.swift +11 -13
- package/ios/Badge/BadgeRibbon.swift +12 -19
- package/ios/BaselineView/BaselineView.swift +163 -0
- package/ios/Button/Button.swift +62 -23
- package/ios/Carousel/Carousel.swift +181 -0
- package/ios/Checkbox/Checkbox.swift +14 -12
- package/ios/Chip/Chip.swift +23 -9
- package/ios/Collapse/Collapse.swift +182 -0
- package/ios/Colors+Radius+Spacing/Colors.swift +1 -1
- package/ios/Colors+Radius+Spacing/Theme.swift +295 -0
- package/ios/DateTimePicker/DateTimePicker.swift +210 -0
- package/ios/DateTimePicker/DateTimePickerTypes.swift +55 -0
- package/ios/DateTimePicker/DateTimePickerUtils.swift +167 -0
- package/ios/DateTimePicker/WheelPicker.swift +161 -0
- package/ios/Divider/Divider.swift +16 -0
- package/ios/Icon/Icon.swift +6 -1
- package/ios/IconButton/IconButton.swift +112 -0
- package/ios/Information/Information.swift +151 -0
- package/ios/Input/Input.swift +42 -25
- package/ios/Input/InputPhoneNumber.swift +21 -19
- package/ios/Input/InputSearch.swift +101 -45
- package/ios/Input/InputTextArea.swift +67 -40
- package/ios/InputDropDown/InputDropDown.swift +198 -0
- package/ios/InputMoney/InputMoney.swift +335 -0
- package/ios/InputOTP/InputOTP.swift +210 -0
- package/ios/Loader/Loader.swift +113 -0
- package/ios/MoMoUIKits.podspec +5 -0
- package/ios/OTPKeyboard/KeyboardButton.swift +1 -1
- package/ios/Pagination/PaginationDot.swift +61 -0
- package/ios/Pagination/PaginationNumber.swift +35 -0
- package/ios/Pagination/PaginationScroll.swift +101 -0
- package/ios/Pagination/PaginationWhiteDot.swift +37 -0
- package/ios/Popup/PopupDisplay.swift +10 -12
- package/ios/Popup/PopupInput.swift +2 -6
- package/ios/Popup/PopupNotify.swift +219 -0
- package/ios/ProgressInfo/ProgressInfo.swift +294 -0
- package/ios/Radio/Radio.swift +70 -0
- package/ios/Rating/Rating.swift +82 -0
- package/ios/Skeleton/Skeleton.swift +99 -0
- package/ios/Slider/Slider.swift +237 -0
- package/ios/Stepper/Stepper.swift +220 -0
- package/ios/Steps/Steps.swift +451 -0
- package/ios/SuggestAction/SuggestAction.swift +97 -0
- package/ios/Swipeable/SwipeCell.swift +185 -0
- package/ios/Swipeable/SwipeCellModel.swift +21 -0
- package/ios/TabView/TabView.swift +530 -0
- package/ios/Tag/Tag.swift +98 -0
- package/ios/Template/TrustBanner/TrustBanner.swift +2 -0
- package/ios/Title/Title.swift +269 -0
- package/ios/Tooltip/Tooltip.swift +482 -0
- package/ios/Typography/Text.swift +77 -5
- package/ios/Typography/Typography.swift +9 -0
- package/ios/Uploader/Uploader.swift +183 -0
- package/ios/native-kits.podspec +58 -8
- package/ios-demo/MoMoUIKitsDemo.podspec +18 -0
- package/ios-demo/README.md +120 -0
- package/ios-demo/Resources/dot_loading.json +558 -0
- package/ios-demo/Resources/icon.json +4052 -0
- package/ios-demo/Resources/lottie_circle_loader.json +1 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/DemoScaffold.swift +48 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsBadgeDemoView.swift +25 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsButtonDemoView.swift +26 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsCheckboxDemoView.swift +19 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsChipDemoView.swift +33 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsInputDemoView.swift +48 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsPopupDemoView.swift +21 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsRadioDemoView.swift +17 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsTypographyDemoView.swift +28 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoContext.swift +31 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoFactory.swift +72 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AnimatedHeaderDemo.swift +110 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AvatarDemo.swift +93 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BadgeDemo.swift +269 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BaselineView.swift +117 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BottomTabDemo.swift +89 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ButtonDemo.swift +100 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CarouselDemo.swift +126 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CheckboxDemo.swift +63 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ChipDemo.swift +20 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CollapseDemo.swift +93 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +107 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DateTimePickerDemo.swift +124 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DividerDemo.swift +14 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/HeaderUserDemo.swift +49 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +261 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconButtonDemo.swift +58 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ImageDemo.swift +78 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InformationDemo.swift +138 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDemo.swift +111 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDropDownDemo.swift +136 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputMoneyDemo.swift +107 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputOTPDemo.swift +73 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputPhoneNumberDemo.swift +100 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputSearchDemo.swift +32 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputTextAreaDemo.swift +57 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LoaderDemo.swift +70 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +227 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PaginationDemo.swift +72 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +175 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +121 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +76 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ProgressInfoDemo.swift +89 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RadioDemo.swift +32 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RatingDemo.swift +56 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SkeletonDemo.swift +32 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SliderDemo.swift +150 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SnackBarDemo.swift +138 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepperDemo.swift +103 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepsDemo.swift +94 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SuggestActionDemo.swift +79 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwipeDemo.swift +152 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwitchDemo.swift +33 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TabViewDemo.swift +190 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TagDemo.swift +34 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ThemeDemo.swift +182 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TitleDemo.swift +109 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TooltipDemo.swift +187 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TypographyDemo.swift +87 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/UploaderDemo.swift +131 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SwiftUIDemoBrowserView.swift +50 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoModels.swift +15 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoRegistry.swift +73 -0
- package/local.properties +8 -0
- package/package.json +1 -1
- package/publish.sh +50 -0
- package/scripts/gen-ios-color.mjs +136 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ProgressInfoDemo.swift
|
|
3
|
+
// Example
|
|
4
|
+
//
|
|
5
|
+
|
|
6
|
+
import SwiftUI
|
|
7
|
+
import MoMoUIKits
|
|
8
|
+
|
|
9
|
+
// MARK: - ProgressInfoDemo
|
|
10
|
+
|
|
11
|
+
struct ProgressInfoDemo: View {
|
|
12
|
+
private let sampleSteps = [
|
|
13
|
+
ProgressInfoItem(title: "Bước 1", description: "Mô tả bước đầu tiên"),
|
|
14
|
+
ProgressInfoItem(title: "Bước 2", description: "Mô tả bước thứ hai"),
|
|
15
|
+
ProgressInfoItem(title: "Bước 3", description: "Mô tả bước thứ ba"),
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
private let sampleStepsNoDesc = [
|
|
19
|
+
ProgressInfoItem(title: "Đăng ký"),
|
|
20
|
+
ProgressInfoItem(title: "Xác minh"),
|
|
21
|
+
ProgressInfoItem(title: "Hoàn tất"),
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
var body: some View {
|
|
25
|
+
ScrollView {
|
|
26
|
+
VStack(alignment: .leading, spacing: 24) {
|
|
27
|
+
section("Vertical (default)") {
|
|
28
|
+
ProgressInfo(steps: sampleSteps)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
section("Vertical – no description") {
|
|
32
|
+
ProgressInfo(steps: sampleStepsNoDesc, showDescription: false)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
section("Vertical – useNumber") {
|
|
36
|
+
ProgressInfo(steps: sampleSteps, useNumber: true)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
section("Vertical – Small size") {
|
|
40
|
+
ProgressInfo(steps: sampleSteps, size: .small)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
section("Horizontal – Center (default)") {
|
|
44
|
+
ProgressInfo(steps: sampleSteps, horizontal: true)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
section("Horizontal – Left") {
|
|
48
|
+
ProgressInfo(steps: sampleSteps, horizontal: true, align: .left)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
section("Horizontal – Right") {
|
|
52
|
+
ProgressInfo(steps: sampleSteps, horizontal: true, align: .right)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
section("Horizontal – Stretch") {
|
|
56
|
+
ProgressInfo(steps: sampleSteps, horizontal: true, align: .stretch)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
section("Horizontal – useNumber") {
|
|
60
|
+
ProgressInfo(steps: sampleSteps, horizontal: true, useNumber: true)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
section("Horizontal – Small size") {
|
|
64
|
+
ProgressInfo(
|
|
65
|
+
steps: sampleStepsNoDesc,
|
|
66
|
+
horizontal: true,
|
|
67
|
+
size: .small,
|
|
68
|
+
showDescription: false
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
.padding(16)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@ViewBuilder
|
|
77
|
+
private func section<Content: View>(
|
|
78
|
+
_ title: String,
|
|
79
|
+
@ViewBuilder content: () -> Content
|
|
80
|
+
) -> some View {
|
|
81
|
+
VStack(alignment: .leading, spacing: 8) {
|
|
82
|
+
Text(title)
|
|
83
|
+
.font(.system(size: 14, weight: .semibold))
|
|
84
|
+
.foregroundColor(.secondary)
|
|
85
|
+
content()
|
|
86
|
+
}
|
|
87
|
+
.frame(maxWidth: .infinity, alignment: .leading)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import SwiftUI
|
|
2
|
+
import MoMoUIKits
|
|
3
|
+
|
|
4
|
+
struct RadioDemo: View {
|
|
5
|
+
@State private var group: AnyHashable = 1
|
|
6
|
+
|
|
7
|
+
var body: some View {
|
|
8
|
+
VStack(alignment: .leading, spacing: 24) {
|
|
9
|
+
// Value
|
|
10
|
+
VStack(alignment: .leading, spacing: 12) {
|
|
11
|
+
Text("Value").font(.description1)
|
|
12
|
+
Radio(value: 1, groupValue: $group)
|
|
13
|
+
Radio(value: 2, groupValue: $group)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Disabled
|
|
17
|
+
VStack(alignment: .leading, spacing: 12) {
|
|
18
|
+
Text("Disabled").font(.description1)
|
|
19
|
+
Radio(value: 1, groupValue: .constant(1), disabled: true)
|
|
20
|
+
Radio(value: 2, groupValue: .constant(1), disabled: false)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Label
|
|
24
|
+
VStack(alignment: .leading, spacing: 12) {
|
|
25
|
+
Text("Label").font(.description1)
|
|
26
|
+
Radio(value: 1, groupValue: .constant(1), label: "Label")
|
|
27
|
+
Radio(value: 2, groupValue: .constant(1), label: "Label")
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
.padding()
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import SwiftUI
|
|
2
|
+
import MoMoUIKits
|
|
3
|
+
|
|
4
|
+
struct RatingDemo: View {
|
|
5
|
+
@State private var interactiveRating: Float = 3
|
|
6
|
+
|
|
7
|
+
var body: some View {
|
|
8
|
+
ScrollView {
|
|
9
|
+
VStack(alignment: .leading, spacing: 24) {
|
|
10
|
+
section("Size") {
|
|
11
|
+
Rating(numOfStars: 5, rating: 3, size: .small)
|
|
12
|
+
Rating(numOfStars: 5, rating: 3, size: .medium)
|
|
13
|
+
Rating(numOfStars: 5, rating: 3, size: .large)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
section("Half star") {
|
|
17
|
+
Rating(numOfStars: 5, rating: 3.5)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
section("Full") {
|
|
21
|
+
Rating(numOfStars: 5, rating: 5)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
section("Empty") {
|
|
25
|
+
Rating(numOfStars: 5, rating: 0)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
section("Read-only (no callback)") {
|
|
29
|
+
Rating(numOfStars: 5, rating: 4)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
section("Interactive") {
|
|
33
|
+
Rating(
|
|
34
|
+
numOfStars: 5,
|
|
35
|
+
rating: interactiveRating,
|
|
36
|
+
onRatingChange: { newRating in
|
|
37
|
+
interactiveRating = Float(newRating)
|
|
38
|
+
}
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
.padding()
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@ViewBuilder
|
|
47
|
+
private func section<Content: View>(
|
|
48
|
+
_ title: String,
|
|
49
|
+
@ViewBuilder content: () -> Content
|
|
50
|
+
) -> some View {
|
|
51
|
+
VStack(alignment: .leading, spacing: 8) {
|
|
52
|
+
Text(title)
|
|
53
|
+
content()
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//
|
|
2
|
+
// SkeletonDemo.swift
|
|
3
|
+
// Example
|
|
4
|
+
//
|
|
5
|
+
|
|
6
|
+
import SwiftUI
|
|
7
|
+
import MoMoUIKits
|
|
8
|
+
|
|
9
|
+
public struct SkeletonDemo: View {
|
|
10
|
+
public init() {}
|
|
11
|
+
|
|
12
|
+
public var body: some View {
|
|
13
|
+
VStack(alignment: .leading, spacing: 12) {
|
|
14
|
+
Spacer().frame(height: 12)
|
|
15
|
+
|
|
16
|
+
// Square skeleton (Compose: fillMaxWidth().aspectRatio(1f)).
|
|
17
|
+
Skeleton()
|
|
18
|
+
.aspectRatio(1, contentMode: .fit)
|
|
19
|
+
.frame(maxWidth: .infinity)
|
|
20
|
+
|
|
21
|
+
// Fixed-height skeleton (Compose: fillMaxWidth().height(32.dp)).
|
|
22
|
+
Skeleton()
|
|
23
|
+
.frame(maxWidth: .infinity)
|
|
24
|
+
.frame(height: 32)
|
|
25
|
+
}
|
|
26
|
+
.padding()
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
#Preview {
|
|
31
|
+
SkeletonDemo()
|
|
32
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
//
|
|
2
|
+
// SliderDemo.swift
|
|
3
|
+
// Example
|
|
4
|
+
//
|
|
5
|
+
|
|
6
|
+
import Foundation
|
|
7
|
+
import MoMoUIKits
|
|
8
|
+
import SwiftUI
|
|
9
|
+
|
|
10
|
+
// MARK: - SliderDemo
|
|
11
|
+
|
|
12
|
+
struct SliderDemo: View {
|
|
13
|
+
// Playground state
|
|
14
|
+
@State private var pgLow: CGFloat = 20
|
|
15
|
+
@State private var pgHigh: CGFloat = 80
|
|
16
|
+
@State private var pgDisableRange = false
|
|
17
|
+
@State private var pgFloatingLabel = false
|
|
18
|
+
@State private var pgDisabled = false
|
|
19
|
+
@State private var pgMinRange = false
|
|
20
|
+
@State private var pgStepBig = false
|
|
21
|
+
|
|
22
|
+
var body: some View {
|
|
23
|
+
ScrollView {
|
|
24
|
+
VStack(alignment: .leading, spacing: 24) {
|
|
25
|
+
preview
|
|
26
|
+
Divider()
|
|
27
|
+
playground
|
|
28
|
+
}
|
|
29
|
+
.padding(.vertical, 16)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// MARK: - Preview
|
|
34
|
+
|
|
35
|
+
private var preview: some View {
|
|
36
|
+
VStack(alignment: .leading, spacing: 24) {
|
|
37
|
+
section("Range Slider (default)") {
|
|
38
|
+
MomoSlider(min: 0, max: 100, step: 1)
|
|
39
|
+
.padding(.horizontal, 8)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
section("Range Slider with initial values") {
|
|
43
|
+
MomoSlider(min: 0, max: 100, step: 1, low: 20, high: 80)
|
|
44
|
+
.padding(.horizontal, 8)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
section("Single-thumb Slider (disableRange)") {
|
|
48
|
+
MomoSlider(min: 0, max: 100, step: 1, low: 40, disableRange: true)
|
|
49
|
+
.padding(.horizontal, 8)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
section("Slider with step = 10") {
|
|
53
|
+
MomoSlider(min: 0, max: 100, step: 10, low: 20, high: 70)
|
|
54
|
+
.padding(.horizontal, 8)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
section("Slider with minRange = 20") {
|
|
58
|
+
MomoSlider(min: 0, max: 100, step: 1, low: 10, high: 90, minRange: 20)
|
|
59
|
+
.padding(.horizontal, 8)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
section("Floating Label") {
|
|
63
|
+
MomoSlider(min: 0, max: 100, step: 1, low: 30, high: 70, floatingLabel: true)
|
|
64
|
+
.padding(.horizontal, 8)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
section("Disabled") {
|
|
68
|
+
MomoSlider(min: 0, max: 100, step: 1, low: 30, high: 70, disabled: true)
|
|
69
|
+
.padding(.horizontal, 8)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
section("Disabled single-thumb") {
|
|
73
|
+
MomoSlider(min: 0, max: 100, step: 1, low: 50, disableRange: true, disabled: true)
|
|
74
|
+
.padding(.horizontal, 8)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// MARK: - Playground
|
|
80
|
+
|
|
81
|
+
private var playground: some View {
|
|
82
|
+
section("Playground") {
|
|
83
|
+
toggle("Disable Range (single thumb)", $pgDisableRange)
|
|
84
|
+
toggle("Floating Label", $pgFloatingLabel)
|
|
85
|
+
toggle("Disabled", $pgDisabled)
|
|
86
|
+
toggle("Min Range = 20", $pgMinRange)
|
|
87
|
+
toggle("Step = 10 (instead of 1)", $pgStepBig)
|
|
88
|
+
|
|
89
|
+
MomoSlider(
|
|
90
|
+
min: 0,
|
|
91
|
+
max: 100,
|
|
92
|
+
step: pgStepBig ? 10 : 1,
|
|
93
|
+
low: pgLow,
|
|
94
|
+
high: pgHigh,
|
|
95
|
+
minRange: pgMinRange ? 20 : 0,
|
|
96
|
+
disableRange: pgDisableRange,
|
|
97
|
+
floatingLabel: pgFloatingLabel,
|
|
98
|
+
disabled: pgDisabled,
|
|
99
|
+
onValueChanged: { low, high, _ in
|
|
100
|
+
pgLow = low
|
|
101
|
+
pgHigh = high
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
.padding(.horizontal, 8)
|
|
105
|
+
// Re-create slider when structural params change so initial values apply.
|
|
106
|
+
.id("\(pgDisableRange)-\(pgMinRange)-\(pgStepBig)")
|
|
107
|
+
|
|
108
|
+
if pgDisableRange {
|
|
109
|
+
Text("Value: \(Int(pgLow))")
|
|
110
|
+
.font(.subheadline)
|
|
111
|
+
.padding(.top, 8)
|
|
112
|
+
} else {
|
|
113
|
+
Text("Low: \(Int(pgLow)) · High: \(Int(pgHigh))")
|
|
114
|
+
.font(.subheadline)
|
|
115
|
+
.padding(.top, 8)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// MARK: - Helpers
|
|
121
|
+
|
|
122
|
+
@ViewBuilder
|
|
123
|
+
private func section<Content: View>(
|
|
124
|
+
_ title: String,
|
|
125
|
+
@ViewBuilder content: () -> Content
|
|
126
|
+
) -> some View {
|
|
127
|
+
VStack(alignment: .leading, spacing: 12) {
|
|
128
|
+
Text(title)
|
|
129
|
+
.font(.headline)
|
|
130
|
+
content()
|
|
131
|
+
}
|
|
132
|
+
.padding(.horizontal, 16)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@ViewBuilder
|
|
136
|
+
private func toggle(_ title: String, _ binding: Binding<Bool>) -> some View {
|
|
137
|
+
Toggle(isOn: binding) {
|
|
138
|
+
Text(title)
|
|
139
|
+
.font(.subheadline)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
#if DEBUG
|
|
145
|
+
struct SliderDemo_Previews: PreviewProvider {
|
|
146
|
+
static var previews: some View {
|
|
147
|
+
SliderDemo()
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
#endif
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import MoMoUIKits
|
|
2
|
+
import SwiftUI
|
|
3
|
+
|
|
4
|
+
struct SnackBarDemo: View {
|
|
5
|
+
var body: some View {
|
|
6
|
+
if #available(iOS 16.0, *) {
|
|
7
|
+
SnackBarDemoContent()
|
|
8
|
+
} else {
|
|
9
|
+
MomoText("SnackBar demo requires iOS 16+")
|
|
10
|
+
.padding()
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@available(iOS 16.0, *)
|
|
16
|
+
private struct SnackBarDemoContent: View {
|
|
17
|
+
@EnvironmentObject private var navigator: Navigator
|
|
18
|
+
|
|
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
|
|
29
|
+
}
|
|
30
|
+
return milliseconds / 1000
|
|
31
|
+
}
|
|
32
|
+
|
|
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
|
+
)
|
|
58
|
+
|
|
59
|
+
HStack(spacing: Spacing.M) {
|
|
60
|
+
MoMoUIKits.Switch($showFooter)
|
|
61
|
+
MomoText("Footer")
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
MoMoUIKits.Button(
|
|
65
|
+
title: "Show snack bar",
|
|
66
|
+
action: showSnackBar,
|
|
67
|
+
size: .large
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
MoMoUIKits.Button(
|
|
71
|
+
title: "Show toast",
|
|
72
|
+
action: { navigator.showSnackBar(.toast(duration: snackBarDuration)) },
|
|
73
|
+
type: .secondary,
|
|
74
|
+
size: .large
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
MoMoUIKits.Button(
|
|
78
|
+
title: "Hide snack bar",
|
|
79
|
+
action: { navigator.hideSnackBar() },
|
|
80
|
+
type: .text,
|
|
81
|
+
size: .large
|
|
82
|
+
)
|
|
83
|
+
}
|
|
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
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
|
|
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)
|
|
127
|
+
}
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
#if DEBUG
|
|
133
|
+
struct SnackBarDemo_Previews: PreviewProvider {
|
|
134
|
+
static var previews: some View {
|
|
135
|
+
SnackBarDemo()
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
#endif
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
//
|
|
2
|
+
// StepperDemo.swift
|
|
3
|
+
// Example
|
|
4
|
+
//
|
|
5
|
+
|
|
6
|
+
import Foundation
|
|
7
|
+
import MoMoUIKits
|
|
8
|
+
import SwiftUI
|
|
9
|
+
|
|
10
|
+
// MARK: - StepperDemo
|
|
11
|
+
|
|
12
|
+
struct StepperDemo: View {
|
|
13
|
+
@State private var sizeLarge = 5
|
|
14
|
+
@State private var sizeSmall = 5
|
|
15
|
+
|
|
16
|
+
@State private var def0 = 0
|
|
17
|
+
@State private var def50 = 50
|
|
18
|
+
@State private var def100 = 100
|
|
19
|
+
|
|
20
|
+
@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
|
+
|
|
29
|
+
@State private var disabledMinus = 5
|
|
30
|
+
@State private var disabledPlus = 5
|
|
31
|
+
|
|
32
|
+
@State private var boundLow = 0
|
|
33
|
+
@State private var boundHigh = 10
|
|
34
|
+
|
|
35
|
+
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)
|
|
78
|
+
}
|
|
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()
|
|
92
|
+
}
|
|
93
|
+
.padding(.horizontal, 16)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
#if DEBUG
|
|
98
|
+
struct StepperDemo_Previews: PreviewProvider {
|
|
99
|
+
static var previews: some View {
|
|
100
|
+
StepperDemo()
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
#endif
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
//
|
|
2
|
+
// StepsDemo.swift
|
|
3
|
+
// Example
|
|
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.
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
import MoMoUIKits
|
|
11
|
+
import SwiftUI
|
|
12
|
+
|
|
13
|
+
private let sampleSteps: [StepItem] = [
|
|
14
|
+
StepItem(title: "Order placed", description: "Your order has been received", time: "09:00"),
|
|
15
|
+
StepItem(title: "Processing", description: "We are preparing your order", time: "09:15"),
|
|
16
|
+
StepItem(title: "Shipped", description: "Your order is on the way", time: "10:30"),
|
|
17
|
+
StepItem(title: "Delivered", description: "Package delivered successfully", time: "14:00"),
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
private let shortSteps: [StepItem] = [
|
|
21
|
+
StepItem(title: "Step 1"),
|
|
22
|
+
StepItem(title: "Step 2"),
|
|
23
|
+
StepItem(title: "Step 3"),
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
private let stepsWithError: [StepItem] = [
|
|
27
|
+
StepItem(title: "Verified"),
|
|
28
|
+
StepItem(title: "Payment", error: true),
|
|
29
|
+
StepItem(title: "Complete"),
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
struct StepsDemo: View {
|
|
33
|
+
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)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
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
|
+
MomoText(title, typography: .headerSSemibold, color: Colors.text)
|
|
90
|
+
content()
|
|
91
|
+
}
|
|
92
|
+
.frame(maxWidth: .infinity, alignment: .leading)
|
|
93
|
+
}
|
|
94
|
+
}
|