@momo-kits/native-kits 0.163.1-beta.3-debug → 0.163.1-beta.5-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 +1 -1
- package/compose/build.gradle.kts +2 -1
- package/compose/build.gradle.kts.backup +1 -0
- package/compose/compose.podspec +1 -1
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/OsFontScale.android.kt +7 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +8 -10
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +3 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +56 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +11 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +40 -55
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +69 -26
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +3 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +21 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +3 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitFontScale.kt +22 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +28 -21
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +4 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +112 -115
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +11 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +3 -4
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +3 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +2 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/OsFontScale.kt +9 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/OsFontScale.ios.kt +66 -0
- package/gradle/libs.versions.toml +2 -0
- package/gradle.properties +1 -1
- package/ios/Application/ApplicationEnvironment.swift +11 -1
- package/ios/Application/Components.swift +34 -44
- package/ios/Application/FloatingButton.swift +10 -9
- package/ios/Application/HeaderRight.swift +79 -45
- package/ios/Application/Navigation/BottomTab/BottomTab.swift +103 -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 +176 -0
- package/ios/Application/Navigation/NavigationOptions.swift +109 -0
- package/ios/Application/Navigation/Navigator.swift +364 -0
- package/ios/Application/Navigation/Overplay/BottomSheet.swift +188 -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/Screen.swift +2 -1
- package/ios/Application/StackScreen.swift +453 -0
- package/ios/Avatar/Avatar.swift +193 -0
- package/ios/Badge/Badge.swift +11 -14
- package/ios/Badge/BadgeRibbon.swift +12 -21
- package/ios/BaselineView/BaselineView.swift +163 -0
- package/ios/Button/Button.swift +61 -22
- package/ios/Carousel/Carousel.swift +181 -0
- package/ios/Checkbox/Checkbox.swift +14 -13
- package/ios/Chip/Chip.swift +23 -9
- package/ios/Collapse/Collapse.swift +182 -0
- package/ios/Colors+Radius+Spacing/Colors.swift +12 -12
- 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/Extensions/Color++.swift +32 -0
- package/ios/Icon/Icon.swift +6 -1
- package/ios/IconButton/IconButton.swift +112 -0
- package/ios/Input/Input.swift +41 -25
- package/ios/Input/InputPhoneNumber.swift +20 -19
- package/ios/Input/InputSearch.swift +100 -47
- package/ios/Input/InputTextArea.swift +66 -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/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 +8 -16
- package/ios/Popup/PopupInput.swift +2 -8
- 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/Resources/MoMoUIKitsColors.xcassets/AccentColor.colorset/Contents.json +11 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Background.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Border.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Card.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Contents.json +6 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Error.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Primary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryDark.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryLight.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Secondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Success.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Text.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/TextSecondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/Contents.json +9 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-default.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-disable.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-pressed.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-selected.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-surface.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-tonal.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-default.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-disable.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/gradient.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/primary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/secondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-container.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-primary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-secondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-default.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-disable.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-hint.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-secondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Warning.colorset/Contents.json +38 -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/Title/Title.swift +269 -0
- package/ios/Tooltip/Tooltip.swift +482 -0
- package/ios/Typography/FontScaleStore.swift +19 -0
- package/ios/Typography/Text.swift +86 -17
- package/ios/Typography/Typography.swift +12 -14
- package/ios/Uploader/Uploader.swift +183 -0
- package/ios/native-kits.podspec +61 -8
- package/ios-demo/MoMoUIKitsDemo.podspec +20 -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 +24 -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 +278 -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 +51 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoModels.swift +15 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoRegistry.swift +73 -0
- package/package.json +1 -1
- package/publish.sh +50 -0
- package/scripts/gen-ios-color.mjs +136 -0
- package/example/ios/Example.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
- package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -5
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/Pods-Example.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImage.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImageSwiftUI.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SkeletonUI.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -46
- package/ios/Application/FontScaleStore.swift +0 -59
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import SwiftUI
|
|
2
|
+
|
|
3
|
+
let LOGO_MOMO_URL =
|
|
4
|
+
"https://static.momocdn.net/app/img/kits/logo_momo_circle.png"
|
|
5
|
+
let ICON_SUPPORT_DEFAULT_URL =
|
|
6
|
+
"https://static.momocdn.net/app/img/kits/_indicator.png"
|
|
7
|
+
|
|
8
|
+
public enum AvatarSize {
|
|
9
|
+
case size24
|
|
10
|
+
case size32
|
|
11
|
+
case size40
|
|
12
|
+
case size48
|
|
13
|
+
case size56
|
|
14
|
+
case size72
|
|
15
|
+
|
|
16
|
+
var sizeDp: CGFloat {
|
|
17
|
+
switch self {
|
|
18
|
+
case .size24: return 24
|
|
19
|
+
case .size32: return 32
|
|
20
|
+
case .size40: return 40
|
|
21
|
+
case .size48: return 48
|
|
22
|
+
case .size56: return 56
|
|
23
|
+
case .size72: return 72
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var iconSizeDp: CGFloat {
|
|
28
|
+
switch self {
|
|
29
|
+
case .size24: return 16
|
|
30
|
+
case .size32: return 16
|
|
31
|
+
case .size40: return 24
|
|
32
|
+
case .size48: return 32
|
|
33
|
+
case .size56: return 32
|
|
34
|
+
case .size72: return 40
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public struct Avatar: View {
|
|
40
|
+
@Environment(\.appTheme) private var theme
|
|
41
|
+
|
|
42
|
+
// MARK: Lifecycle
|
|
43
|
+
|
|
44
|
+
public init(
|
|
45
|
+
size: AvatarSize = .size32,
|
|
46
|
+
rounded: Bool = true,
|
|
47
|
+
name: String? = nil,
|
|
48
|
+
image: String? = nil,
|
|
49
|
+
showIconMomo: Bool = false,
|
|
50
|
+
showIconSupport: Bool = false,
|
|
51
|
+
iconSupport: String = "https://static.momocdn.net/app/img/kits/_indicator.png",
|
|
52
|
+
accessibilityLabel: String? = nil
|
|
53
|
+
) {
|
|
54
|
+
self.size = size
|
|
55
|
+
self.rounded = rounded
|
|
56
|
+
self.name = name
|
|
57
|
+
self.image = image
|
|
58
|
+
self.showIconMomo = showIconMomo
|
|
59
|
+
self.showIconSupport = showIconSupport
|
|
60
|
+
self.iconSupport = iconSupport
|
|
61
|
+
self.accessibilityLabel = accessibilityLabel
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// MARK: Public
|
|
65
|
+
|
|
66
|
+
public var body: some View {
|
|
67
|
+
ZStack {
|
|
68
|
+
// Inner content clipped by shape with border
|
|
69
|
+
ZStack {
|
|
70
|
+
content
|
|
71
|
+
}
|
|
72
|
+
.frame(width: size.sizeDp, height: size.sizeDp)
|
|
73
|
+
.background(Colors.pink09)
|
|
74
|
+
.clipShape(RoundedRectangle(cornerRadius: cornerRadius))
|
|
75
|
+
.overlay(
|
|
76
|
+
RoundedRectangle(cornerRadius: cornerRadius)
|
|
77
|
+
.stroke(theme.colors.border.default, lineWidth: 1)
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
// Badge icons — outside clip so they are not cut by border
|
|
81
|
+
if shouldShowIconTop {
|
|
82
|
+
ImageView(LOGO_MOMO_URL)
|
|
83
|
+
.frame(width: badgeSizeDp, height: badgeSizeDp)
|
|
84
|
+
.clipShape(RoundedRectangle(cornerRadius: badgeCornerRadius))
|
|
85
|
+
.offset(x: 1, y: -1)
|
|
86
|
+
.frame(
|
|
87
|
+
width: size.sizeDp,
|
|
88
|
+
height: size.sizeDp,
|
|
89
|
+
alignment: .topTrailing
|
|
90
|
+
)
|
|
91
|
+
.zIndex(1)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if shouldShowIconBottom {
|
|
95
|
+
ImageView(iconSupport)
|
|
96
|
+
.frame(width: badgeSizeDp, height: badgeSizeDp)
|
|
97
|
+
.clipShape(RoundedRectangle(cornerRadius: badgeCornerRadius))
|
|
98
|
+
.offset(x: 1, y: 1)
|
|
99
|
+
.frame(
|
|
100
|
+
width: size.sizeDp,
|
|
101
|
+
height: size.sizeDp,
|
|
102
|
+
alignment: .bottomTrailing
|
|
103
|
+
)
|
|
104
|
+
.zIndex(1)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
.frame(width: size.sizeDp, height: size.sizeDp)
|
|
108
|
+
.accessibilityElement(children: .ignore)
|
|
109
|
+
.accessibilityLabel(automationId)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// MARK: Internal
|
|
113
|
+
|
|
114
|
+
let size: AvatarSize
|
|
115
|
+
let rounded: Bool
|
|
116
|
+
let name: String?
|
|
117
|
+
let image: String?
|
|
118
|
+
let showIconMomo: Bool
|
|
119
|
+
let showIconSupport: Bool
|
|
120
|
+
let iconSupport: String
|
|
121
|
+
let accessibilityLabel: String?
|
|
122
|
+
|
|
123
|
+
@ViewBuilder
|
|
124
|
+
private var content: some View {
|
|
125
|
+
if let image {
|
|
126
|
+
ImageView(image, contentMode: .fill)
|
|
127
|
+
.frame(width: size.sizeDp, height: size.sizeDp)
|
|
128
|
+
.clipShape(RoundedRectangle(cornerRadius: cornerRadius))
|
|
129
|
+
} else if let name {
|
|
130
|
+
MomoText(
|
|
131
|
+
Self.avatarInitials(name),
|
|
132
|
+
typography: .descriptionXsRegular,
|
|
133
|
+
color: Colors.pink03
|
|
134
|
+
)
|
|
135
|
+
} else {
|
|
136
|
+
Icon(
|
|
137
|
+
source: "basic_person",
|
|
138
|
+
size: size.iconSizeDp,
|
|
139
|
+
color: Colors.pink03
|
|
140
|
+
)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private var cornerRadius: CGFloat {
|
|
145
|
+
rounded ? size.sizeDp / 2 : Spacing.XS
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private var badgeSizeDp: CGFloat {
|
|
149
|
+
size.iconSizeDp / 2
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private var badgeCornerRadius: CGFloat {
|
|
153
|
+
size.iconSizeDp / 4
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
private var shouldShowIconTop: Bool {
|
|
157
|
+
showIconMomo && rounded
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private var shouldShowIconBottom: Bool {
|
|
161
|
+
showIconSupport && rounded
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private var automationId: String {
|
|
165
|
+
accessibilityLabel ?? "Avatar\(name != nil ? "/\(name!)" : "")"
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
private static func avatarInitials(_ name: String) -> String {
|
|
169
|
+
let words = name.trimmingCharacters(in: .whitespaces)
|
|
170
|
+
.split(separator: " ")
|
|
171
|
+
.filter { !$0.isEmpty }
|
|
172
|
+
return words.suffix(2)
|
|
173
|
+
.compactMap { $0.first?.uppercased() }
|
|
174
|
+
.joined()
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// MARK: - Preview
|
|
179
|
+
#if DEBUG
|
|
180
|
+
struct Avatar_Previews: PreviewProvider {
|
|
181
|
+
static var previews: some View {
|
|
182
|
+
HStack(spacing: 12) {
|
|
183
|
+
Avatar(size: .size40)
|
|
184
|
+
Avatar(size: .size40, name: "Nguyen Van A")
|
|
185
|
+
Avatar(size: .size40, rounded: false, name: "John Doe")
|
|
186
|
+
Avatar(size: .size56, image: "https://i.pravatar.cc/150?img=1", showIconMomo: true)
|
|
187
|
+
Avatar(size: .size56, showIconSupport: true)
|
|
188
|
+
}
|
|
189
|
+
.padding()
|
|
190
|
+
.previewLayout(.sizeThatFits)
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
#endif
|
package/ios/Badge/Badge.swift
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import SwiftUI
|
|
2
2
|
|
|
3
3
|
public struct Badge: View {
|
|
4
|
+
@Environment(\.appTheme) private var theme
|
|
4
5
|
let label: String
|
|
5
6
|
let backgroundColor: Color?
|
|
6
7
|
|
|
@@ -38,24 +39,21 @@ public struct Badge: View {
|
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
private var badgeColor: Color {
|
|
41
|
-
//
|
|
42
|
-
|
|
42
|
+
// Default colors based on label type
|
|
43
|
+
let defaultColor: Color = isNumber(label)
|
|
44
|
+
? theme.colors.error.primary
|
|
45
|
+
: theme.colors.warning.primary
|
|
46
|
+
|
|
47
|
+
// Mirror Compose: only apply backgroundColor when it is one of the
|
|
48
|
+
// allowed primaryColors; otherwise fall back to the label-based default.
|
|
49
|
+
if let bgColor = backgroundColor, primaryColors.contains(bgColor) {
|
|
43
50
|
return bgColor
|
|
44
51
|
}
|
|
45
|
-
|
|
46
|
-
// Otherwise, use default colors based on label type
|
|
47
|
-
if isNumber(label) {
|
|
48
|
-
return Colors.red03 // error.primary
|
|
49
|
-
} else {
|
|
50
|
-
return Colors.orange03 // warning.primary
|
|
51
|
-
}
|
|
52
|
+
return defaultColor
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
public var body: some View {
|
|
55
|
-
|
|
56
|
-
.font(.system(size: scaleSize(10), weight: .bold))
|
|
57
|
-
.ignoreBoldTextSetting()
|
|
58
|
-
.foregroundColor(Colors.black01)
|
|
56
|
+
MomoText(formatTitle(label), typography: .actionXxsBold, color: Colors.black01)
|
|
59
57
|
.padding(.horizontal, Spacing.XS)
|
|
60
58
|
.frame(minWidth: scaleSize(16), minHeight: scaleSize(16))
|
|
61
59
|
.background(badgeColor)
|
|
@@ -83,4 +81,3 @@ struct Badge_Previews: PreviewProvider {
|
|
|
83
81
|
}
|
|
84
82
|
}
|
|
85
83
|
#endif
|
|
86
|
-
|
|
@@ -77,10 +77,11 @@ public enum RibbonPosition {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
public struct BadgeRibbon: View {
|
|
80
|
+
@Environment(\.appTheme) private var theme
|
|
80
81
|
let position: RibbonPosition
|
|
81
82
|
let label: String
|
|
82
83
|
let isRound: Bool
|
|
83
|
-
let backgroundColor: Color
|
|
84
|
+
let backgroundColor: Color?
|
|
84
85
|
|
|
85
86
|
public init(
|
|
86
87
|
position: RibbonPosition = .topRight,
|
|
@@ -91,7 +92,7 @@ public struct BadgeRibbon: View {
|
|
|
91
92
|
self.position = position
|
|
92
93
|
self.label = label
|
|
93
94
|
self.isRound = isRound
|
|
94
|
-
self.backgroundColor = backgroundColor
|
|
95
|
+
self.backgroundColor = backgroundColor
|
|
95
96
|
}
|
|
96
97
|
|
|
97
98
|
private var rotation: Angle {
|
|
@@ -117,6 +118,8 @@ public struct BadgeRibbon: View {
|
|
|
117
118
|
}
|
|
118
119
|
|
|
119
120
|
public var body: some View {
|
|
121
|
+
let bgColor = backgroundColor ?? theme.colors.warning.primary
|
|
122
|
+
|
|
120
123
|
HStack(alignment: verticalAlignment, spacing: 0) {
|
|
121
124
|
if useUpTail {
|
|
122
125
|
upTail
|
|
@@ -125,22 +128,18 @@ public struct BadgeRibbon: View {
|
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
if isRound {
|
|
128
|
-
roundContent
|
|
131
|
+
roundContent(backgroundColor: bgColor)
|
|
129
132
|
} else {
|
|
130
|
-
skewContent
|
|
133
|
+
skewContent(backgroundColor: bgColor)
|
|
131
134
|
}
|
|
132
135
|
}
|
|
133
136
|
.frame(height: RibbonConstants.ribbonHeight)
|
|
134
137
|
.rotationEffect(rotation)
|
|
135
138
|
}
|
|
136
139
|
|
|
137
|
-
private
|
|
140
|
+
private func roundContent(backgroundColor: Color) -> some View {
|
|
138
141
|
HStack(spacing: 0) {
|
|
139
|
-
|
|
140
|
-
.font(.system(size: scaleSize(12), weight: .medium))
|
|
141
|
-
.ignoreBoldTextSetting()
|
|
142
|
-
.foregroundColor(Colors.black01)
|
|
143
|
-
.lineLimit(1)
|
|
142
|
+
MomoText(label, typography: .labelXsMedium, color: Colors.black01, maxLines: 1)
|
|
144
143
|
.rotationEffect(rotation)
|
|
145
144
|
}
|
|
146
145
|
.frame(height: RibbonConstants.roundHeight)
|
|
@@ -156,13 +155,9 @@ public struct BadgeRibbon: View {
|
|
|
156
155
|
)
|
|
157
156
|
}
|
|
158
157
|
|
|
159
|
-
private
|
|
158
|
+
private func skewContent(backgroundColor: Color) -> some View {
|
|
160
159
|
HStack(spacing: 0) {
|
|
161
|
-
|
|
162
|
-
.font(.system(size: scaleSize(12), weight: .medium))
|
|
163
|
-
.ignoreBoldTextSetting()
|
|
164
|
-
.foregroundColor(Colors.black01)
|
|
165
|
-
.lineLimit(1)
|
|
160
|
+
MomoText(label, typography: .labelXsMedium, color: Colors.black01, maxLines: 1)
|
|
166
161
|
.rotationEffect(rotation)
|
|
167
162
|
.frame(height: RibbonConstants.skewBodyHeight)
|
|
168
163
|
.padding(.horizontal, 8)
|
|
@@ -179,7 +174,6 @@ public struct BadgeRibbon: View {
|
|
|
179
174
|
)
|
|
180
175
|
.frame(width: RibbonConstants.headTailWidth, height: RibbonConstants.headTailHeight)
|
|
181
176
|
.rotationEffect(.degrees(180))
|
|
182
|
-
.offset(x: 1)
|
|
183
177
|
.clipped()
|
|
184
178
|
}
|
|
185
179
|
|
|
@@ -189,7 +183,6 @@ public struct BadgeRibbon: View {
|
|
|
189
183
|
placeholder: AnyView(Color.clear)
|
|
190
184
|
)
|
|
191
185
|
.frame(width: RibbonConstants.headTailWidth, height: RibbonConstants.headTailHeight)
|
|
192
|
-
.offset(x: 1)
|
|
193
186
|
.clipped()
|
|
194
187
|
}
|
|
195
188
|
|
|
@@ -199,7 +192,6 @@ public struct BadgeRibbon: View {
|
|
|
199
192
|
placeholder: AnyView(Color.clear)
|
|
200
193
|
)
|
|
201
194
|
.frame(width: RibbonConstants.skewTailWidth, height: RibbonConstants.skewTailHeight)
|
|
202
|
-
.offset(x: -2)
|
|
203
195
|
.clipped()
|
|
204
196
|
}
|
|
205
197
|
}
|
|
@@ -209,7 +201,7 @@ private struct RibbonConstants {
|
|
|
209
201
|
static let ribbonHeight: CGFloat = 20
|
|
210
202
|
static let roundHeight: CGFloat = 16
|
|
211
203
|
static let skewBodyHeight: CGFloat = 16
|
|
212
|
-
static let roundRightRadius: CGFloat =
|
|
204
|
+
static let roundRightRadius: CGFloat = 12
|
|
213
205
|
static let roundPaddingEnd: CGFloat = 6
|
|
214
206
|
static let skewTailWidth: CGFloat = 8
|
|
215
207
|
static let skewTailHeight: CGFloat = 16
|
|
@@ -241,4 +233,3 @@ struct BadgeRibbon_Previews: PreviewProvider {
|
|
|
241
233
|
}
|
|
242
234
|
}
|
|
243
235
|
#endif
|
|
244
|
-
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import SwiftUI
|
|
2
|
+
|
|
3
|
+
public struct BaselineView: View {
|
|
4
|
+
private let enabled: Bool
|
|
5
|
+
|
|
6
|
+
public init(enabled: Bool = true) {
|
|
7
|
+
self.enabled = enabled
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
public var body: some View {
|
|
11
|
+
if enabled {
|
|
12
|
+
GeometryReader { geometry in
|
|
13
|
+
let topInset = geometry.safeAreaInsets.top
|
|
14
|
+
let bottomInset = min(geometry.safeAreaInsets.bottom, 21)
|
|
15
|
+
|
|
16
|
+
ZStack(alignment: .topLeading) {
|
|
17
|
+
dangerZones(topInset: topInset, bottomInset: bottomInset)
|
|
18
|
+
guideLines(
|
|
19
|
+
topInset: topInset,
|
|
20
|
+
bottomInset: bottomInset,
|
|
21
|
+
width: geometry.size.width
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
25
|
+
.ignoresSafeArea()
|
|
26
|
+
.allowsHitTesting(false)
|
|
27
|
+
.accessibilityHidden(true)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private func dangerZones(topInset: CGFloat, bottomInset: CGFloat) -> some View {
|
|
33
|
+
let safeBackground = Color.red.opacity(0.15)
|
|
34
|
+
|
|
35
|
+
return ZStack(alignment: .topLeading) {
|
|
36
|
+
safeBackground
|
|
37
|
+
.frame(maxWidth: .infinity)
|
|
38
|
+
.frame(height: topInset)
|
|
39
|
+
|
|
40
|
+
HStack(spacing: 0) {
|
|
41
|
+
safeBackground
|
|
42
|
+
.frame(width: 12)
|
|
43
|
+
Spacer(minLength: 0)
|
|
44
|
+
safeBackground
|
|
45
|
+
.frame(width: 12)
|
|
46
|
+
}
|
|
47
|
+
.padding(.top, topInset)
|
|
48
|
+
.padding(.bottom, bottomInset)
|
|
49
|
+
|
|
50
|
+
VStack(spacing: 0) {
|
|
51
|
+
Spacer(minLength: 0)
|
|
52
|
+
safeBackground
|
|
53
|
+
.frame(maxWidth: .infinity)
|
|
54
|
+
.frame(height: bottomInset)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private func guideLines(topInset: CGFloat, bottomInset: CGFloat, width: CGFloat) -> some View {
|
|
60
|
+
ZStack(alignment: .topLeading) {
|
|
61
|
+
baselineLine(isDotted: false, color: Color(hex: 0xE400FF))
|
|
62
|
+
.offset(y: topInset)
|
|
63
|
+
|
|
64
|
+
baselineLine(color: Color(hex: 0xE400FF))
|
|
65
|
+
.offset(y: topInset + 52)
|
|
66
|
+
|
|
67
|
+
baselineLine(color: Color(hex: 0xE400FF))
|
|
68
|
+
.offset(y: topInset + 104)
|
|
69
|
+
|
|
70
|
+
bottomLine(bottomInset: bottomInset + 64, color: Color(hex: 0xE400FF))
|
|
71
|
+
|
|
72
|
+
bottomLine(bottomInset: bottomInset, isDotted: false, color: Color(hex: 0xE400FF))
|
|
73
|
+
|
|
74
|
+
baselineLine(orientation: .vertical, isDotted: false, color: Color(hex: 0xE400FF))
|
|
75
|
+
.offset(x: 12)
|
|
76
|
+
|
|
77
|
+
baselineLine(orientation: .vertical, isDotted: false, color: Color(hex: 0xE400FF))
|
|
78
|
+
.offset(x: width - 12)
|
|
79
|
+
|
|
80
|
+
baselineLine(color: Color(hex: 0xFF7A00))
|
|
81
|
+
.offset(y: topInset + 26)
|
|
82
|
+
|
|
83
|
+
bottomLine(bottomInset: bottomInset + 56, color: Color(hex: 0xFFCC00))
|
|
84
|
+
|
|
85
|
+
bottomLine(bottomInset: bottomInset + 8, color: Color(hex: 0xFFCC00))
|
|
86
|
+
|
|
87
|
+
baselineLine(orientation: .vertical, color: Color(hex: 0x00C520))
|
|
88
|
+
.frame(height: 52)
|
|
89
|
+
.offset(x: 40, y: topInset)
|
|
90
|
+
|
|
91
|
+
baselineLine(orientation: .vertical, color: Color(hex: 0x00C520))
|
|
92
|
+
.frame(height: 52)
|
|
93
|
+
.offset(x: 48, y: topInset)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private func bottomLine(
|
|
98
|
+
bottomInset: CGFloat,
|
|
99
|
+
isDotted: Bool = true,
|
|
100
|
+
color: Color
|
|
101
|
+
) -> some View {
|
|
102
|
+
VStack(spacing: 0) {
|
|
103
|
+
Spacer(minLength: 0)
|
|
104
|
+
baselineLine(isDotted: isDotted, color: color)
|
|
105
|
+
.padding(.bottom, bottomInset)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private func baselineLine(
|
|
110
|
+
orientation: BaselineOrientation = .horizontal,
|
|
111
|
+
isDotted: Bool = true,
|
|
112
|
+
color: Color
|
|
113
|
+
) -> some View {
|
|
114
|
+
BaselineLineShape(orientation: orientation)
|
|
115
|
+
.stroke(
|
|
116
|
+
color,
|
|
117
|
+
style: StrokeStyle(
|
|
118
|
+
lineWidth: 1,
|
|
119
|
+
lineCap: .round,
|
|
120
|
+
dash: isDotted ? [8, 8] : []
|
|
121
|
+
)
|
|
122
|
+
)
|
|
123
|
+
.frame(
|
|
124
|
+
maxWidth: orientation == .horizontal ? .infinity : 1,
|
|
125
|
+
maxHeight: orientation == .vertical ? .infinity : 1
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public enum BaselineOrientation: Sendable {
|
|
131
|
+
case horizontal
|
|
132
|
+
case vertical
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private struct BaselineLineShape: Shape {
|
|
136
|
+
let orientation: BaselineOrientation
|
|
137
|
+
|
|
138
|
+
func path(in rect: CGRect) -> Path {
|
|
139
|
+
var path = Path()
|
|
140
|
+
|
|
141
|
+
switch orientation {
|
|
142
|
+
case .horizontal:
|
|
143
|
+
path.move(to: CGPoint(x: rect.minX, y: rect.midY))
|
|
144
|
+
path.addLine(to: CGPoint(x: rect.maxX, y: rect.midY))
|
|
145
|
+
case .vertical:
|
|
146
|
+
path.move(to: CGPoint(x: rect.midX, y: rect.minY))
|
|
147
|
+
path.addLine(to: CGPoint(x: rect.midX, y: rect.maxY))
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return path
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
#if DEBUG
|
|
155
|
+
struct BaselineView_Previews: PreviewProvider {
|
|
156
|
+
static var previews: some View {
|
|
157
|
+
ZStack {
|
|
158
|
+
Colors.black01
|
|
159
|
+
BaselineView()
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
#endif
|
package/ios/Button/Button.swift
CHANGED
|
@@ -31,33 +31,45 @@ public struct ButtonStyleData {
|
|
|
31
31
|
|
|
32
32
|
public extension ButtonType {
|
|
33
33
|
func backgroundColor(loading: Bool) -> Color {
|
|
34
|
+
backgroundColor(loading: loading, theme: defaultTheme)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
func backgroundColor(loading: Bool, theme: Theme) -> Color {
|
|
34
38
|
switch self {
|
|
35
|
-
case .disabled: return
|
|
36
|
-
case .primary: return
|
|
37
|
-
case .secondary: return
|
|
38
|
-
case .outline: return
|
|
39
|
-
case .tonal: return
|
|
40
|
-
case .danger: return
|
|
39
|
+
case .disabled: return theme.colors.background.disable.opacity(loading ? 0.75 : 1)
|
|
40
|
+
case .primary: return theme.colors.primary.opacity(loading ? 0.75 : 1)
|
|
41
|
+
case .secondary: return theme.colors.background.surface.opacity(loading ? 0.75 : 1)
|
|
42
|
+
case .outline: return theme.colors.background.surface.opacity(loading ? 0.75 : 1)
|
|
43
|
+
case .tonal: return theme.colors.background.tonal.opacity(loading ? 0.75 : 1)
|
|
44
|
+
case .danger: return theme.colors.error.primary.opacity(loading ? 0.75 : 1)
|
|
41
45
|
case .text: return .clear
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
func contentColor(loading: Bool) -> Color {
|
|
50
|
+
contentColor(loading: loading, theme: defaultTheme)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
func contentColor(loading: Bool, theme: Theme) -> Color {
|
|
46
54
|
switch self {
|
|
47
|
-
case .disabled: return
|
|
55
|
+
case .disabled: return theme.colors.text.disable.opacity(loading ? 0.75 : 1)
|
|
48
56
|
case .primary: return Colors.black01
|
|
49
|
-
case .secondary: return
|
|
50
|
-
case .outline: return
|
|
51
|
-
case .tonal: return
|
|
57
|
+
case .secondary: return theme.colors.text.default
|
|
58
|
+
case .outline: return theme.colors.primary
|
|
59
|
+
case .tonal: return theme.colors.primary
|
|
52
60
|
case .danger: return Colors.black01
|
|
53
|
-
case .text: return
|
|
61
|
+
case .text: return theme.colors.primary
|
|
54
62
|
}
|
|
55
63
|
}
|
|
56
64
|
|
|
57
65
|
var borderColor: Color? {
|
|
66
|
+
borderColor(theme: defaultTheme)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
func borderColor(theme: Theme) -> Color? {
|
|
58
70
|
switch self {
|
|
59
|
-
case .outline: return
|
|
60
|
-
case .secondary: return
|
|
71
|
+
case .outline: return theme.colors.primary
|
|
72
|
+
case .secondary: return theme.colors.border.default
|
|
61
73
|
default: return nil
|
|
62
74
|
}
|
|
63
75
|
}
|
|
@@ -117,6 +129,7 @@ extension ButtonSize {
|
|
|
117
129
|
}
|
|
118
130
|
|
|
119
131
|
public struct Button: View {
|
|
132
|
+
@Environment(\.appTheme) private var theme
|
|
120
133
|
var title: String
|
|
121
134
|
var action: () -> Void
|
|
122
135
|
var type: ButtonType
|
|
@@ -125,6 +138,7 @@ public struct Button: View {
|
|
|
125
138
|
var iconRight: AnyView?
|
|
126
139
|
var isFull: Bool
|
|
127
140
|
var loading: Bool
|
|
141
|
+
var useTintColor: Bool
|
|
128
142
|
|
|
129
143
|
public init(
|
|
130
144
|
title: String = "",
|
|
@@ -134,7 +148,8 @@ public struct Button: View {
|
|
|
134
148
|
iconLeft: AnyView? = nil,
|
|
135
149
|
iconRight: AnyView? = nil,
|
|
136
150
|
isFull: Bool = true,
|
|
137
|
-
loading: Bool = false
|
|
151
|
+
loading: Bool = false,
|
|
152
|
+
useTintColor: Bool = true
|
|
138
153
|
) {
|
|
139
154
|
self.title = title
|
|
140
155
|
self.action = action
|
|
@@ -144,6 +159,7 @@ public struct Button: View {
|
|
|
144
159
|
self.iconRight = iconRight
|
|
145
160
|
self.isFull = isFull
|
|
146
161
|
self.loading = loading
|
|
162
|
+
self.useTintColor = useTintColor
|
|
147
163
|
}
|
|
148
164
|
|
|
149
165
|
private func shouldLoadingOnLeft(_ left: AnyView?, _ right: AnyView?) -> Bool {
|
|
@@ -160,14 +176,15 @@ public struct Button: View {
|
|
|
160
176
|
|
|
161
177
|
public var body: some View {
|
|
162
178
|
let loadingOnLeft = shouldLoadingOnLeft(iconLeft, iconRight)
|
|
179
|
+
let isEnabled = type != .disabled && !loading
|
|
163
180
|
|
|
164
|
-
let bg = type.backgroundColor(loading: loading)
|
|
165
|
-
let fg = type.contentColor(loading: loading)
|
|
166
|
-
let border = type.borderColor
|
|
181
|
+
let bg = type.backgroundColor(loading: loading, theme: theme)
|
|
182
|
+
let fg = type.contentColor(loading: loading, theme: theme)
|
|
183
|
+
let border = type.borderColor(theme: theme)
|
|
167
184
|
let borderWidth = type.borderWidth
|
|
168
185
|
|
|
169
186
|
SwiftUI.Button(action: {
|
|
170
|
-
if
|
|
187
|
+
if isEnabled {
|
|
171
188
|
action()
|
|
172
189
|
}
|
|
173
190
|
}) {
|
|
@@ -178,7 +195,7 @@ public struct Button: View {
|
|
|
178
195
|
.colorMultiply(fg)
|
|
179
196
|
|
|
180
197
|
} else if let iconLeft = iconLeft {
|
|
181
|
-
iconLeft
|
|
198
|
+
tintedIcon(iconLeft, color: fg)
|
|
182
199
|
}
|
|
183
200
|
|
|
184
201
|
MomoText(title, typography: size.typographyStyle, color: fg)
|
|
@@ -191,7 +208,7 @@ public struct Button: View {
|
|
|
191
208
|
.colorMultiply(fg)
|
|
192
209
|
|
|
193
210
|
} else if let iconRight = iconRight {
|
|
194
|
-
iconRight
|
|
211
|
+
tintedIcon(iconRight, color: fg)
|
|
195
212
|
}
|
|
196
213
|
}
|
|
197
214
|
.frame(maxWidth: isFull ? .infinity : nil)
|
|
@@ -203,8 +220,30 @@ public struct Button: View {
|
|
|
203
220
|
.strokeBorder(border ?? .clear, lineWidth: border != nil ? borderWidth : 0)
|
|
204
221
|
)
|
|
205
222
|
.clipShape(RoundedRectangle(cornerRadius: size.radius))
|
|
206
|
-
.opacity(loading ? 0.75 : 1)
|
|
207
223
|
}
|
|
208
|
-
.
|
|
224
|
+
.buttonStyle(ButtonPressFeedbackStyle(isEnabled: isEnabled))
|
|
225
|
+
.disabled(!isEnabled)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
@ViewBuilder
|
|
229
|
+
private func tintedIcon(_ icon: AnyView, color: Color) -> some View {
|
|
230
|
+
if useTintColor {
|
|
231
|
+
icon
|
|
232
|
+
.frame(width: size.iconSize, height: size.iconSize)
|
|
233
|
+
.colorMultiply(color)
|
|
234
|
+
} else {
|
|
235
|
+
icon
|
|
236
|
+
.frame(width: size.iconSize, height: size.iconSize)
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
private struct ButtonPressFeedbackStyle: ButtonStyle {
|
|
242
|
+
let isEnabled: Bool
|
|
243
|
+
|
|
244
|
+
func makeBody(configuration: Configuration) -> some View {
|
|
245
|
+
configuration.label
|
|
246
|
+
.opacity(configuration.isPressed && isEnabled ? 0.5 : 1)
|
|
247
|
+
.animation(.easeInOut(duration: 0.1), value: configuration.isPressed)
|
|
209
248
|
}
|
|
210
249
|
}
|