@momo-kits/native-kits 0.162.30 → 0.162.31
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/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,33 +1,15 @@
|
|
|
1
1
|
import SwiftUI
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
let maxDeviceScale: CGFloat = 5
|
|
10
|
-
|
|
11
|
-
let deviceWidth = UIScreen.main.bounds.width
|
|
12
|
-
let deviceScale = deviceWidth / defaultScreenSize
|
|
13
|
-
|
|
14
|
-
let defaultFont = UIFont.systemFont(ofSize: UIFont.labelFontSize)
|
|
15
|
-
let scaledFont = UIFontMetrics.default.scaledFont(for: defaultFont)
|
|
16
|
-
let fontScale = scaledFont.pointSize / defaultFont.pointSize
|
|
17
|
-
|
|
18
|
-
var fontSizeDeviceScale = size
|
|
19
|
-
var fontSizeOSScale = size
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if deviceScale > 1 {
|
|
23
|
-
fontSizeDeviceScale = min(fontSizeDeviceScale * deviceScale, fontSizeDeviceScale + maxDeviceScale)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if fontScale > 1 {
|
|
27
|
-
fontSizeOSScale = min(fontSizeOSScale * fontScale, fontSizeOSScale * maxFontScale)
|
|
28
|
-
}
|
|
3
|
+
/// Non-reactive entry point, for call sites that cannot read the environment (UIKit bridges,
|
|
4
|
+
/// free functions). Inside a SwiftUI view prefer `@Environment(\.momoFontScale)` so the view
|
|
5
|
+
/// re-renders when Dynamic Type or the host preference changes.
|
|
6
|
+
public func scaleSize(_ size: CGFloat) -> CGFloat {
|
|
7
|
+
FontScaleStore.shared.snapshot(size)
|
|
8
|
+
}
|
|
29
9
|
|
|
30
|
-
|
|
10
|
+
@available(*, deprecated, message: "Max font scale is fixed at 1.5; this override is no longer applied. Drop the second argument.")
|
|
11
|
+
public func scaleSize(_ size: CGFloat, _ scaleRate: CGFloat?) -> CGFloat {
|
|
12
|
+
scaleSize(size)
|
|
31
13
|
}
|
|
32
14
|
|
|
33
15
|
public enum TypographyStyle {
|
|
@@ -119,6 +101,7 @@ public extension TypographyStyle {
|
|
|
119
101
|
|
|
120
102
|
public struct MomoText: View {
|
|
121
103
|
@Environment(\.appTheme) private var theme
|
|
104
|
+
@Environment(\.momoFontScale) private var fontScale
|
|
122
105
|
private let content: String
|
|
123
106
|
private let typography: TypographyStyle
|
|
124
107
|
private let color: Color?
|
|
@@ -176,7 +159,7 @@ public struct MomoText: View {
|
|
|
176
159
|
let isStrikethrough = strikethrough || typography.isStrikethrough
|
|
177
160
|
|
|
178
161
|
var text = SwiftUI.Text(content)
|
|
179
|
-
.font(.
|
|
162
|
+
.font(fontScale.font(size: typography.fontSize, weight: typography.fontWeight))
|
|
180
163
|
.foregroundColor(textColor)
|
|
181
164
|
.strikethrough(isStrikethrough, color: textColor)
|
|
182
165
|
.underline(underline, color: textColor)
|
|
@@ -187,7 +170,7 @@ public struct MomoText: View {
|
|
|
187
170
|
|
|
188
171
|
return text
|
|
189
172
|
.multilineTextAlignment(textAlign)
|
|
190
|
-
.lineSpacing(
|
|
173
|
+
.lineSpacing(fontScale(typography.lineHeight) - fontScale(typography.fontSize))
|
|
191
174
|
.modifier(LineLimitModifier(range: lineLimitRange))
|
|
192
175
|
.truncationMode(truncationMode)
|
|
193
176
|
.fixedSize(horizontal: !softWrap, vertical: false)
|
|
@@ -10,98 +10,78 @@ public extension View {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
public extension Font {
|
|
13
|
+
/// Non-reactive: resolves against the current `FontScaleStore` snapshot at each access. The
|
|
14
|
+
/// styles below are computed properties for that reason — as stored `static let`s they would
|
|
15
|
+
/// freeze the scale at first access and never pick up a Dynamic Type change.
|
|
16
|
+
/// Inside a view, `@Environment(\.momoFontScale)` + `fontScale.font(size:weight:)` also re-renders.
|
|
13
17
|
static func appFont(size: CGFloat) -> Font {
|
|
14
|
-
|
|
15
|
-
return Font.system(size: size * FontScaleStore.shared.userScaleRate)
|
|
16
|
-
}
|
|
17
|
-
let defaultScreenSize: CGFloat = 375
|
|
18
|
-
let maxFontScale: CGFloat = 1.5
|
|
19
|
-
let maxDeviceScale: CGFloat = 5
|
|
20
|
-
|
|
21
|
-
let deviceWidth = UIScreen.main.bounds.width
|
|
22
|
-
let deviceScale = deviceWidth / defaultScreenSize
|
|
23
|
-
|
|
24
|
-
let defaultFont = UIFont.systemFont(ofSize: UIFont.labelFontSize)
|
|
25
|
-
let scaledFont = UIFontMetrics.default.scaledFont(for: defaultFont)
|
|
26
|
-
let fontScale = scaledFont.pointSize / defaultFont.pointSize
|
|
27
|
-
|
|
28
|
-
var fontSize = size
|
|
29
|
-
|
|
30
|
-
if deviceScale > 1 {
|
|
31
|
-
fontSize = min(fontSize * deviceScale, fontSize + maxDeviceScale)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if fontScale > 1 {
|
|
35
|
-
fontSize = min(fontSize * fontScale, fontSize * maxFontScale)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return Font.system(size: fontSize)
|
|
18
|
+
FontScaleStore.shared.snapshot.font(size: size)
|
|
39
19
|
}
|
|
40
20
|
|
|
41
21
|
// New supported typography styles
|
|
42
|
-
static
|
|
43
|
-
static
|
|
44
|
-
static
|
|
45
|
-
static
|
|
46
|
-
static
|
|
47
|
-
static
|
|
48
|
-
static
|
|
49
|
-
static
|
|
50
|
-
static
|
|
51
|
-
static
|
|
52
|
-
static
|
|
53
|
-
static
|
|
54
|
-
static
|
|
55
|
-
static
|
|
56
|
-
static
|
|
57
|
-
static
|
|
22
|
+
static var headline_default_bold: Font { appFont(size: 24).weight(.bold) }
|
|
23
|
+
static var header_m_bold: Font { appFont(size: 18).weight(.bold) }
|
|
24
|
+
static var header_default_bold: Font { appFont(size: 16).weight(.bold) }
|
|
25
|
+
static var header_default_semibold: Font { appFont(size: 16).weight(.semibold) }
|
|
26
|
+
static var header_s_semibold: Font { appFont(size: 14).weight(.semibold) }
|
|
27
|
+
static var header_xs_semibold: Font { appFont(size: 12).weight(.semibold) }
|
|
28
|
+
static var body_default_regular: Font { appFont(size: 14).weight(.regular) }
|
|
29
|
+
static var description_default_regular: Font { appFont(size: 12).weight(.regular) }
|
|
30
|
+
static var description_xs_regular: Font { appFont(size: 10).weight(.regular) }
|
|
31
|
+
static var label_default_medium: Font { appFont(size: 14).weight(.medium) }
|
|
32
|
+
static var label_s_medium: Font { appFont(size: 12).weight(.medium) }
|
|
33
|
+
static var label_xs_medium: Font { appFont(size: 10).weight(.medium) }
|
|
34
|
+
static var action_default_bold: Font { appFont(size: 16).weight(.bold) }
|
|
35
|
+
static var action_s_bold: Font { appFont(size: 14).weight(.bold) }
|
|
36
|
+
static var action_xs_bold: Font { appFont(size: 12).weight(.bold) }
|
|
37
|
+
static var action_xxs_bold: Font { appFont(size: 10).weight(.bold) }
|
|
58
38
|
|
|
59
39
|
// Legacy styles
|
|
60
|
-
static
|
|
61
|
-
static
|
|
62
|
-
static
|
|
63
|
-
static
|
|
64
|
-
static
|
|
65
|
-
static
|
|
66
|
-
static
|
|
67
|
-
static
|
|
68
|
-
static
|
|
69
|
-
static
|
|
70
|
-
static
|
|
71
|
-
static
|
|
72
|
-
static
|
|
73
|
-
static
|
|
74
|
-
static
|
|
75
|
-
static
|
|
76
|
-
static
|
|
77
|
-
static
|
|
78
|
-
static
|
|
79
|
-
static
|
|
80
|
-
static
|
|
81
|
-
static
|
|
82
|
-
static
|
|
40
|
+
static var headline_default: Font { appFont(size: 28).weight(.semibold) }
|
|
41
|
+
static var headline_s: Font { appFont(size: 24).weight(.semibold) }
|
|
42
|
+
static var headline_l: Font { appFont(size: 32).weight(.semibold) }
|
|
43
|
+
static var headline_xl: Font { appFont(size: 36).weight(.semibold) }
|
|
44
|
+
static var title_default: Font { appFont(size: 20).weight(.bold) }
|
|
45
|
+
static var title_xs: Font { appFont(size: 16).weight(.bold) }
|
|
46
|
+
static var title_s: Font { appFont(size: 18).weight(.bold) }
|
|
47
|
+
static var header_default: Font { appFont(size: 15).weight(.semibold) }
|
|
48
|
+
static var header_xs: Font { appFont(size: 12).weight(.semibold) }
|
|
49
|
+
static var header_s: Font { appFont(size: 14).weight(.semibold) }
|
|
50
|
+
static var paragraph_default: Font { appFont(size: 15).weight(.regular) }
|
|
51
|
+
static var paragraph_bold: Font { appFont(size: 15).weight(.bold) }
|
|
52
|
+
static var description_default: Font { appFont(size: 14).weight(.regular) }
|
|
53
|
+
static var description_xs: Font { appFont(size: 10).weight(.regular) }
|
|
54
|
+
static var description_s: Font { appFont(size: 12).weight(.regular) }
|
|
55
|
+
static var label_default: Font { appFont(size: 14).weight(.medium) }
|
|
56
|
+
static var label_xxs: Font { appFont(size: 8).weight(.medium) }
|
|
57
|
+
static var label_xs: Font { appFont(size: 10).weight(.medium) }
|
|
58
|
+
static var label_s: Font { appFont(size: 12).weight(.medium) }
|
|
59
|
+
static var action_default: Font { appFont(size: 16).weight(.bold) }
|
|
60
|
+
static var action_xxs: Font { appFont(size: 10).weight(.bold) }
|
|
61
|
+
static var action_xs: Font { appFont(size: 12).weight(.bold) }
|
|
62
|
+
static var action_s: Font { appFont(size: 15).weight(.bold) }
|
|
83
63
|
|
|
84
64
|
// deprecated
|
|
85
|
-
static
|
|
86
|
-
static
|
|
87
|
-
static
|
|
88
|
-
static
|
|
89
|
-
static
|
|
90
|
-
static
|
|
91
|
-
static
|
|
92
|
-
static
|
|
93
|
-
static
|
|
94
|
-
static
|
|
95
|
-
static
|
|
96
|
-
static
|
|
97
|
-
static
|
|
98
|
-
static
|
|
99
|
-
static
|
|
100
|
-
static
|
|
101
|
-
static
|
|
102
|
-
static
|
|
103
|
-
static
|
|
104
|
-
static
|
|
105
|
-
static
|
|
106
|
-
static
|
|
65
|
+
static var h1: Font { appFont(size: 36).weight(.semibold) } //headline_xl
|
|
66
|
+
static var h2: Font { appFont(size: 32).weight(.semibold) }
|
|
67
|
+
static var h3: Font { appFont(size: 28).weight(.semibold) }
|
|
68
|
+
static var h4: Font { appFont(size: 24).weight(.semibold) }
|
|
69
|
+
static var title1: Font { appFont(size: 20).weight(.bold) }
|
|
70
|
+
static var title2: Font { appFont(size: 18).weight(.bold) }
|
|
71
|
+
static var title3: Font { appFont(size: 16).weight(.bold) }
|
|
72
|
+
static var headerText1: Font { appFont(size: 15).weight(.semibold) } //header_default
|
|
73
|
+
static var headerText2: Font { appFont(size: 14).weight(.semibold) }
|
|
74
|
+
static var headerText3: Font { appFont(size: 12).weight(.semibold) }
|
|
75
|
+
static var paragraph: Font { appFont(size: 15).weight(.regular) } //paragraph_default
|
|
76
|
+
static var description1: Font { appFont(size: 14).weight(.regular) }
|
|
77
|
+
static var description2: Font { appFont(size: 12).weight(.regular) }
|
|
78
|
+
static var description3: Font { appFont(size: 10).weight(.regular) }
|
|
79
|
+
static var label1: Font { appFont(size: 14).weight(.medium) }
|
|
80
|
+
static var label2: Font { appFont(size: 12).weight(.medium) }
|
|
81
|
+
static var label3: Font { appFont(size: 10).weight(.medium) }
|
|
82
|
+
static var label4: Font { appFont(size: 8).weight(.medium) }
|
|
83
|
+
static var action1: Font { appFont(size: 16).weight(.bold) }
|
|
84
|
+
static var action2: Font { appFont(size: 15).weight(.bold) }
|
|
85
|
+
static var action3: Font { appFont(size: 12).weight(.bold) }
|
|
86
|
+
static var action4: Font { appFont(size: 10).weight(.bold) }
|
|
107
87
|
}
|
package/ios/native-kits.podspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Pod::Spec.new do |s|
|
|
2
2
|
s.name = 'MoMoUIKits'
|
|
3
|
-
s.version = '0.163.1-
|
|
3
|
+
s.version = '0.163.1-sp.10'
|
|
4
4
|
s.summary = 'MoMoUIKits for iOS'
|
|
5
5
|
s.homepage = 'https://momo.vn'
|
|
6
6
|
s.license = { :type => 'MIT' }
|
|
@@ -34,6 +34,7 @@ Pod::Spec.new do |s|
|
|
|
34
34
|
"InputDropDown/**/*.{swift,m,h}",
|
|
35
35
|
"InputMoney/**/*.{swift,m,h}",
|
|
36
36
|
"InputOTP/**/*.{swift,m,h}",
|
|
37
|
+
"Layout/**/*.{swift,m,h}",
|
|
37
38
|
"Loader/**/*.{swift,m,h}",
|
|
38
39
|
"Lottie/**/*.{swift,m,h}",
|
|
39
40
|
"OTPKeyboard/**/*.{swift,m,h}",
|
|
@@ -2,92 +2,106 @@
|
|
|
2
2
|
// AvatarDemo.swift
|
|
3
3
|
// Example
|
|
4
4
|
//
|
|
5
|
+
// Preview + Playground demo (DemoScreen pattern).
|
|
6
|
+
//
|
|
5
7
|
|
|
6
|
-
import SwiftUI
|
|
7
8
|
import MoMoUIKits
|
|
9
|
+
import SwiftUI
|
|
8
10
|
|
|
9
11
|
struct AvatarDemo: View {
|
|
10
12
|
var body: some View {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
Avatar(size: .size48)
|
|
19
|
-
Avatar(size: .size56)
|
|
20
|
-
Avatar(size: .size72)
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
section("Rounded vs Square") {
|
|
25
|
-
HStack(spacing: 8) {
|
|
26
|
-
Avatar(size: .size40, rounded: true)
|
|
27
|
-
Avatar(size: .size40, rounded: false)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
section("Name (initials)") {
|
|
32
|
-
HStack(spacing: 8) {
|
|
33
|
-
Avatar(size: .size40, name: "Nguyen Van A")
|
|
34
|
-
Avatar(size: .size40, name: "John Doe")
|
|
35
|
-
Avatar(size: .size40, name: "MoMo")
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
section("Image") {
|
|
40
|
-
HStack(spacing: 8) {
|
|
41
|
-
Avatar(size: .size40, image: "https://i.pravatar.cc/150?img=1")
|
|
42
|
-
Avatar(size: .size56, image: "https://i.pravatar.cc/150?img=2")
|
|
43
|
-
Avatar(size: .size72, image: "https://i.pravatar.cc/150?img=3")
|
|
44
|
-
}
|
|
45
|
-
}
|
|
13
|
+
if #available(iOS 16.0, *) {
|
|
14
|
+
DemoScreen(preview: { AvatarPreview() }, playground: { AvatarPlayground() })
|
|
15
|
+
} else {
|
|
16
|
+
Text("Requires iOS 16+").padding()
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
46
20
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
21
|
+
private let avatarSizeList: [PlaygroundOption] = [
|
|
22
|
+
.init("size24", AvatarSize.size24),
|
|
23
|
+
.init("size32", AvatarSize.size32),
|
|
24
|
+
.init("size40", AvatarSize.size40),
|
|
25
|
+
.init("size48", AvatarSize.size48),
|
|
26
|
+
.init("size56", AvatarSize.size56),
|
|
27
|
+
.init("size72", AvatarSize.size72),
|
|
28
|
+
]
|
|
54
29
|
|
|
55
|
-
|
|
56
|
-
HStack(spacing: 8) {
|
|
57
|
-
Avatar(size: .size40, showIconSupport: true)
|
|
58
|
-
Avatar(size: .size48, name: "CS", showIconSupport: true)
|
|
59
|
-
Avatar(size: .size56, image: "https://i.pravatar.cc/150?img=5", showIconSupport: true)
|
|
60
|
-
}
|
|
61
|
-
}
|
|
30
|
+
// MARK: - Preview
|
|
62
31
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
32
|
+
private struct AvatarPreview: View {
|
|
33
|
+
var body: some View {
|
|
34
|
+
BasicColumnBox("Size", alignment: .leading) {
|
|
35
|
+
HStack(alignment: .center, spacing: Spacing.S) {
|
|
36
|
+
Avatar(size: .size24)
|
|
37
|
+
Avatar(size: .size32)
|
|
38
|
+
Avatar(size: .size40)
|
|
39
|
+
Avatar(size: .size48)
|
|
40
|
+
Avatar(size: .size56)
|
|
41
|
+
Avatar(size: .size72)
|
|
69
42
|
}
|
|
70
|
-
.padding()
|
|
71
43
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
44
|
+
BasicColumnBox("Rounded vs Square", alignment: .leading) {
|
|
45
|
+
HStack(spacing: Spacing.S) {
|
|
46
|
+
Avatar(size: .size40, rounded: true)
|
|
47
|
+
Avatar(size: .size40, rounded: false)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
BasicColumnBox("Name (initials)", alignment: .leading) {
|
|
51
|
+
HStack(spacing: Spacing.S) {
|
|
52
|
+
Avatar(size: .size40, name: "Nguyen Van A")
|
|
53
|
+
Avatar(size: .size40, name: "John Doe")
|
|
54
|
+
Avatar(size: .size40, name: "MoMo")
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
BasicColumnBox("Image", alignment: .leading) {
|
|
58
|
+
HStack(spacing: Spacing.S) {
|
|
59
|
+
Avatar(size: .size40, image: "https://i.pravatar.cc/150?img=1")
|
|
60
|
+
Avatar(size: .size56, image: "https://i.pravatar.cc/150?img=2")
|
|
61
|
+
Avatar(size: .size72, image: "https://i.pravatar.cc/150?img=3")
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
BasicColumnBox("Icon badges", alignment: .leading) {
|
|
65
|
+
HStack(spacing: Spacing.S) {
|
|
66
|
+
Avatar(size: .size48, showIconMomo: true)
|
|
67
|
+
Avatar(size: .size48, showIconSupport: true)
|
|
68
|
+
Avatar(size: .size56, showIconMomo: true, showIconSupport: true)
|
|
69
|
+
}
|
|
83
70
|
}
|
|
84
71
|
}
|
|
85
72
|
}
|
|
86
73
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
74
|
+
// MARK: - Playground
|
|
75
|
+
|
|
76
|
+
@available(iOS 16.0, *)
|
|
77
|
+
private struct AvatarPlayground: View {
|
|
78
|
+
@State private var size: PlaygroundOption? = avatarSizeList.first { $0.key == "size48" }
|
|
79
|
+
@State private var rounded = true
|
|
80
|
+
@State private var name = ""
|
|
81
|
+
@State private var image = ""
|
|
82
|
+
@State private var showIconMomo = false
|
|
83
|
+
@State private var showIconSupport = false
|
|
84
|
+
|
|
85
|
+
var body: some View {
|
|
86
|
+
PlaygroundTab(
|
|
87
|
+
component: {
|
|
88
|
+
Avatar(
|
|
89
|
+
size: (size?.value as? AvatarSize) ?? .size48,
|
|
90
|
+
rounded: rounded,
|
|
91
|
+
name: name.isEmpty ? nil : name,
|
|
92
|
+
image: image.isEmpty ? nil : image,
|
|
93
|
+
showIconMomo: showIconMomo,
|
|
94
|
+
showIconSupport: showIconSupport
|
|
95
|
+
)
|
|
96
|
+
},
|
|
97
|
+
params: [
|
|
98
|
+
.radio("Size", avatarSizeList, $size),
|
|
99
|
+
.checkbox("Rounded", $rounded),
|
|
100
|
+
.string("Name", $name),
|
|
101
|
+
.string("Image", $image),
|
|
102
|
+
.checkbox("ShowIconMomo", $showIconMomo),
|
|
103
|
+
.checkbox("ShowIconSupport", $showIconSupport),
|
|
104
|
+
]
|
|
105
|
+
)
|
|
91
106
|
}
|
|
92
107
|
}
|
|
93
|
-
#endif
|