@momo-kits/native-kits 0.300.3-debug → 0.300.4-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 +51 -7
- package/README.md +2 -2
- package/compose/build.gradle.kts +10 -2
- package/compose/build.gradle.kts.backup +8 -0
- package/compose/compose.podspec +1 -3
- package/compose/src/androidMain/kotlin/vn/momo/kits/const/HostFont.android.kt +4 -3
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +2 -0
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/ReservedRegions.android.kt +6 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +0 -14
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/DesignSystemKits.kt +62 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +351 -111
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +20 -21
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +2 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +4 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +9 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +11 -12
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +4 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +2 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +10 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +6 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +55 -22
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +12 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +7 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +13 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +13 -5
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +3 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +14 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +19 -21
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +2 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +5 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +3 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +7 -15
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/HostFont.kt +2 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +20 -15
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +1 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/ScreenLayout.kt +306 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +43 -4
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +8 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +10 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +6 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +6 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +197 -60
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +132 -83
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +54 -62
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoBarCompression.kt +97 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoTabBar.kt +377 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +122 -24
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +34 -14
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderJourney.kt +3 -3
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderLocation.kt +1 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +113 -26
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +2 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +1 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HelpCenterRequest.kt +37 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SideBar.kt +192 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +2 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/ToolkitRequests.kt +8 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +3 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ReservedRegions.kt +20 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +13 -0
- package/compose/src/commonTest/kotlin/vn/momo/kits/navigation/component/HelpCenterRequestTest.kt +44 -0
- package/compose/src/commonTest/kotlin/vn/momo/kits/navigation/component/ToolkitRequestsTest.kt +15 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/const/HostFont.ios.kt +3 -1
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +4 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/ReservedRegions.ios.kt +138 -0
- package/gradle/libs.versions.toml +3 -14
- package/gradle/wrapper/gradle-wrapper.properties +0 -2
- package/gradle.properties +3 -5
- package/ios/Application/ApplicationEnvironment.swift +24 -6
- package/ios/Application/DesignSystemKits.swift +100 -0
- package/ios/Application/DesignSystemKitsPayload.swift +68 -0
- package/ios/Application/MaxApi.swift +30 -3
- package/ios/Avatar/Avatar.swift +4 -3
- package/ios/Badge/Badge.swift +6 -4
- package/ios/Badge/BadgeDot.swift +1 -1
- package/ios/Badge/BadgeRibbon.swift +8 -2
- package/ios/Button/Button.swift +15 -12
- package/ios/CalculatorKeyboard/CalculatorKeyboard.swift +64 -18
- package/ios/Carousel/Carousel.swift +29 -12
- package/ios/Checkbox/Checkbox.swift +7 -3
- package/ios/Chip/Chip.swift +5 -4
- package/ios/Collapse/Collapse.swift +70 -19
- package/ios/Colors+Radius+Spacing/Colors.swift +10 -1
- package/ios/Colors+Radius+Spacing/Radius.swift +6 -0
- package/ios/DateTimePicker/DateTimePicker.swift +54 -20
- package/ios/DateTimePicker/WheelPicker.swift +103 -105
- package/ios/Divider/Divider.swift +37 -4
- package/ios/Extensions/Color++.swift +38 -9
- package/ios/Extensions/OptionalEnvironmentObject.swift +12 -0
- package/ios/Extensions/SkeletonUICompat.swift +11 -0
- package/ios/Icon/Icon.swift +21 -23
- package/ios/Icon/Icons.swift +1329 -0
- package/ios/IconButton/IconButton.swift +15 -7
- package/ios/Image/Image.swift +7 -23
- package/ios/Information/Information.swift +27 -9
- package/ios/Input/ErrorView.swift +2 -2
- package/ios/Input/Input.swift +171 -148
- package/ios/Input/InputPhoneNumber.swift +10 -9
- package/ios/Input/InputSearch.swift +107 -78
- package/ios/Input/InputTextArea.swift +133 -148
- package/ios/InputDropDown/InputDropDown.swift +10 -7
- package/ios/InputMoney/InputMoney.swift +32 -11
- package/ios/InputOTP/InputOTP.swift +22 -12
- package/ios/Layout/Card.swift +50 -0
- package/ios/Layout/GridContext.swift +187 -3
- package/ios/Layout/Item.swift +5 -4
- package/ios/Layout/ScreenLayout.swift +415 -0
- package/ios/Layout/Section.swift +4 -100
- package/ios/Loader/Loader.swift +5 -9
- package/ios/Lottie/LottieView.swift +14 -2
- package/ios/{Application/Navigation/Overplay → Navigation}/BottomSheet.swift +169 -29
- package/ios/Navigation/BottomTab/BottomTab.swift +332 -0
- package/ios/{Application/Navigation → Navigation}/BottomTab/BottomTabBar.swift +18 -7
- package/ios/Navigation/BottomTab/DuoBarCompression.swift +104 -0
- package/ios/Navigation/BottomTab/DuoTabBar.swift +329 -0
- package/ios/{Application → Navigation/Component}/FloatingButton.swift +43 -54
- package/ios/Navigation/Component/Header.swift +545 -0
- package/ios/Navigation/Component/HeaderBackground.swift +154 -0
- package/ios/Navigation/Component/HeaderJourney.swift +73 -0
- package/ios/Navigation/Component/HeaderLocation.swift +48 -0
- package/ios/Navigation/Component/HeaderRight.swift +425 -0
- package/ios/Navigation/Component/HeaderTitle.swift +36 -0
- package/ios/{Application/Navigation → Navigation/Component}/HeaderUser.swift +21 -24
- package/ios/Navigation/Component/SideBar.swift +183 -0
- package/ios/{Application/Navigation/Overplay → Navigation/Component}/SnackBar.swift +8 -8
- package/ios/Navigation/HostBackGestureBridge.swift +78 -0
- package/ios/{Application/Navigation/Overplay → Navigation}/ModalScreen.swift +9 -2
- package/ios/Navigation/Navigation.swift +204 -0
- package/ios/Navigation/NavigationContainer.swift +195 -0
- package/ios/{Application/Navigation → Navigation}/Navigator.swift +207 -107
- package/ios/Navigation/StackScreen.swift +930 -0
- package/ios/Navigation/StackTransition.swift +400 -0
- package/ios/Navigation/SwipeBackHaptic.swift +33 -0
- package/ios/{Application/Navigation → Navigation}/Tracking/ScreenTracker.swift +12 -5
- package/ios/OTPKeyboard/OTPKeyboard.swift +8 -11
- package/ios/Pagination/PaginationScroll.swift +2 -2
- package/ios/Popup/PopupDisplay.swift +72 -135
- package/ios/Popup/PopupInput.swift +10 -13
- package/ios/Popup/PopupLayout.swift +138 -0
- package/ios/Popup/PopupNotify.swift +59 -69
- package/ios/Popup/PopupPromotion.swift +31 -47
- package/ios/PopupView/FullscreenPopup.swift +13 -19
- package/ios/PopupView/PopupView.swift +1 -1
- package/ios/PopupView/Utils++.swift +0 -8
- package/ios/ProgressInfo/ProgressInfo.swift +4 -2
- package/ios/Radio/Radio.swift +2 -1
- package/ios/Rating/Rating.swift +9 -1
- package/ios/Resources/dot_loading.json +558 -0
- package/ios/Resources/lottie_circle_loader.json +1 -0
- package/ios/ScrollIndicator/ScrollIndicator.swift +11 -10
- package/ios/Skeleton/Skeleton.swift +22 -27
- package/ios/Slider/Slider.swift +16 -18
- package/ios/Stepper/Stepper.swift +7 -3
- package/ios/Steps/Steps.swift +8 -6
- package/ios/SuggestAction/SuggestAction.swift +5 -0
- package/ios/Swipeable/SwipeCell.swift +10 -6
- package/ios/Switch/Switch.swift +22 -20
- package/ios/TabView/TabView.swift +102 -21
- package/ios/Tag/Tag.swift +15 -4
- package/ios/Template/Logo/Logo.swift +2 -1
- package/ios/Template/TrustBanner/TrustBanner.swift +109 -55
- package/ios/Title/Title.swift +6 -17
- package/ios/Tooltip/Tooltip.swift +29 -14
- package/ios/Typography/FontScale.swift +17 -14
- package/ios/Typography/Text.swift +156 -20
- package/ios/Typography/Typography.swift +2 -2
- package/ios/Uploader/Uploader.swift +3 -1
- package/ios/native-kits.podspec +2 -3
- package/ios-demo/MoMoUIKitsDemo.podspec +1 -3
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +1 -1
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DuoTabDemo.swift +80 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +2 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IPhoneDuoDemo.swift +173 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +77 -1
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +1 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +2 -2
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +2 -0
- package/package.json +1 -1
- package/publish.sh +19 -2
- package/scripts/gen-ios-icons.mjs +36 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +0 -52
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +0 -183
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +0 -207
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +0 -39
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +0 -86
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +0 -76
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +0 -76
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +0 -293
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +0 -33
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +0 -110
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +0 -378
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +0 -69
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitDesignSystem.kt +0 -18
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitFontScale.kt +0 -22
- package/ios/Application/Components.swift +0 -270
- package/ios/Application/ComposeApi.swift +0 -22
- package/ios/Application/HeaderRight.swift +0 -306
- package/ios/Application/Navigation/BottomTab/BottomTab.swift +0 -104
- package/ios/Application/Navigation/HeaderBackProps.swift +0 -66
- package/ios/Application/Navigation/HeaderTitle.swift +0 -57
- package/ios/Application/Navigation/NavigationContainer.swift +0 -213
- package/ios/Application/Navigation/NavigationOptions.swift +0 -109
- package/ios/Application/Navigation/NavigatorManager.swift +0 -22
- package/ios/Application/Navigation/component/Header.swift +0 -178
- package/ios/Application/Navigation/component/HeaderBackground.swift +0 -83
- package/ios/Application/Navigation/component/HeaderColor.swift +0 -65
- package/ios/Application/Navigation/component/HeaderRightWidthKey.swift +0 -11
- package/ios/Application/Navigation/component/NavigationFooter.swift +0 -90
- package/ios/Application/Navigation/component/NavigationHeaderRight.swift +0 -196
- package/ios/Application/Screen.swift +0 -250
- package/ios/Application/StackScreen.swift +0 -492
- package/ios/Typography/FontScaleStore.swift +0 -58
- package/ios/Typography/KitDesignSystem.swift +0 -17
- /package/ios/{Application/Navigation → Navigation}/BottomTab/CurvedContainer.swift +0 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import SDWebImageSwiftUI
|
|
2
1
|
import SwiftUI
|
|
3
2
|
|
|
4
3
|
// MARK: - PopupButtonDirection
|
|
@@ -16,45 +15,13 @@ public enum PopupButtonType {
|
|
|
16
15
|
case button
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
extension View {
|
|
20
|
-
func measureLineHeights(font: Font,
|
|
21
|
-
oneLine: Binding<CGFloat>,
|
|
22
|
-
twoLines: Binding<CGFloat>) -> some View {
|
|
23
|
-
overlay(
|
|
24
|
-
VStack(spacing: 0) {
|
|
25
|
-
Text("A")
|
|
26
|
-
.font(font)
|
|
27
|
-
.ignoreBoldTextSetting()
|
|
28
|
-
.lineLimit(1)
|
|
29
|
-
.fixedSize()
|
|
30
|
-
.background(
|
|
31
|
-
GeometryReader { g in
|
|
32
|
-
Color.clear.onAppear { oneLine.wrappedValue = g.size.height }
|
|
33
|
-
}
|
|
34
|
-
)
|
|
35
|
-
.hidden()
|
|
36
|
-
|
|
37
|
-
Text("A\nA")
|
|
38
|
-
.font(font)
|
|
39
|
-
.ignoreBoldTextSetting()
|
|
40
|
-
.lineLimit(2)
|
|
41
|
-
.fixedSize(horizontal: false, vertical: true)
|
|
42
|
-
.background(
|
|
43
|
-
GeometryReader { g in
|
|
44
|
-
Color.clear.onAppear { twoLines.wrappedValue = g.size.height }
|
|
45
|
-
}
|
|
46
|
-
)
|
|
47
|
-
.hidden()
|
|
48
|
-
}
|
|
49
|
-
.frame(width: 0, height: 0)
|
|
50
|
-
)
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
18
|
// MARK: - PopupDisplay
|
|
55
19
|
|
|
56
20
|
public struct PopupDisplay: View {
|
|
21
|
+
@Environment(\.appTheme) private var theme
|
|
57
22
|
@Environment(\.localize) private var localize
|
|
23
|
+
@Environment(\.momoFontScale) private var fontScale
|
|
24
|
+
@Environment(\.screenLayout) private var layout
|
|
58
25
|
|
|
59
26
|
// MARK: Lifecycle
|
|
60
27
|
|
|
@@ -75,109 +42,53 @@ public struct PopupDisplay: View {
|
|
|
75
42
|
}
|
|
76
43
|
|
|
77
44
|
// MARK: Public
|
|
78
|
-
|
|
45
|
+
|
|
79
46
|
@State private var oneLineH: CGFloat = 0
|
|
80
47
|
@State private var twoLineH: CGFloat = 0
|
|
48
|
+
@State private var textHeight: CGFloat = .zero
|
|
49
|
+
@State private var actionsHeight: CGFloat = 0
|
|
81
50
|
|
|
82
|
-
|
|
83
|
-
private var
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
guard oneLineH > 0 && twoLineH > 0 else { return ceil(fallbackLH * lines) }
|
|
87
|
-
return ceil(oneLineH + max(0, lines - 1) * (twoLineH - oneLineH))
|
|
51
|
+
// ~8.5 lines as laid out; nominal line height until measured
|
|
52
|
+
private var maxHeight8_5: CGFloat {
|
|
53
|
+
popupLinesHeight(8.5, oneLine: oneLineH, twoLines: twoLineH)
|
|
54
|
+
?? fontScale(TypographyStyle.bodyDefaultRegular.lineHeight) * 8.5
|
|
88
55
|
}
|
|
89
|
-
private var maxHeight8_5: CGFloat { heightForLines(lines: 8.5) }
|
|
90
56
|
|
|
57
|
+
private var shouldUseColumn: Bool {
|
|
58
|
+
// UTF-16 length, as PopupNotify counts it
|
|
59
|
+
buttonDirection == .column || (buttonDirection == .auto && (closeButtonTitle.utf16.count > 12 || actionButtonTitle.utf16.count > 12))
|
|
60
|
+
}
|
|
91
61
|
|
|
92
|
-
@State private var textHeight: CGFloat = .zero
|
|
93
|
-
@State private var isScrollable = false
|
|
94
|
-
|
|
95
62
|
public var body: some View {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
SwiftUI.Button(action: onClose) {
|
|
104
|
-
Image(systemName: "xmark.circle.fill")
|
|
105
|
-
.resizable()
|
|
106
|
-
.frame(width: 22, height: 22)
|
|
107
|
-
.overlay(RoundedRectangle(cornerRadius: Radius.L).stroke(Colors.black01, lineWidth: 2))
|
|
108
|
-
}.foregroundColor(Colors.black20)
|
|
109
|
-
.background(Colors.black01.cornerRadius(15))
|
|
110
|
-
.padding(.trailing, -11)
|
|
111
|
-
.padding(.top, -11)
|
|
112
|
-
.zIndex(1)
|
|
113
|
-
.accessibility(identifier: "ic_popup_close")
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
VStack(spacing: 0) {
|
|
117
|
-
if(!url.isEmpty) {
|
|
118
|
-
WebImage(url: URL(string: url), isAnimating: .constant(true))
|
|
119
|
-
.resizable()
|
|
120
|
-
.placeholder {
|
|
121
|
-
Rectangle()
|
|
122
|
-
.fill(Color.gray.opacity(0.3))
|
|
123
|
-
.aspectRatio(1.777, contentMode: .fit)
|
|
124
|
-
.frame(maxWidth: .infinity, maxHeight: 184)
|
|
125
|
-
}
|
|
126
|
-
.aspectRatio(1.777, contentMode: .fit)
|
|
127
|
-
.frame(maxWidth: .infinity, alignment: .center)
|
|
128
|
-
.clipShape(RoundedCorner(radius: 15, corners: [.topLeft, .topRight]))
|
|
129
|
-
.clipped()
|
|
130
|
-
}
|
|
131
|
-
VStack(alignment: .leading, spacing: 0) {
|
|
132
|
-
MomoText(title, typography: .headerDefaultBold)
|
|
133
|
-
.padding(.top, 24)
|
|
134
|
-
.padding(.bottom, 8)
|
|
135
|
-
.lineLimit(2)
|
|
136
|
-
.accessibility(identifier: "title_popup_permission")
|
|
137
|
-
|
|
138
|
-
Group {
|
|
139
|
-
if isScrollable {
|
|
140
|
-
ScrollView(showsIndicators: false) {
|
|
141
|
-
MomoText(description, typography: .bodyDefaultRegular)
|
|
142
|
-
.multilineTextAlignment(.leading)
|
|
143
|
-
.background(GeometryReader { geo in
|
|
144
|
-
Color.clear.onAppear { textHeight = geo.size.height }
|
|
145
|
-
})
|
|
146
|
-
.measureLineHeights(font: .body_default_regular,
|
|
147
|
-
oneLine: $oneLineH,
|
|
148
|
-
twoLines: $twoLineH)
|
|
149
|
-
.accessibility(identifier: "description_popup_permission")
|
|
150
|
-
}
|
|
151
|
-
// Cap the visible height to ~8.5 lines
|
|
152
|
-
.frame(height: min(maxHeight8_5, textHeight))
|
|
153
|
-
} else {
|
|
154
|
-
MomoText(description, typography: .bodyDefaultRegular)
|
|
155
|
-
.multilineTextAlignment(.leading)
|
|
156
|
-
.background(GeometryReader { geo in
|
|
157
|
-
Color.clear.onAppear {
|
|
158
|
-
textHeight = geo.size.height
|
|
159
|
-
// Trigger scroll at ~8.5 lines
|
|
160
|
-
isScrollable = textHeight > maxHeight8_5
|
|
161
|
-
}
|
|
162
|
-
})
|
|
163
|
-
.measureLineHeights(font: .body_default_regular,
|
|
164
|
-
oneLine: $oneLineH,
|
|
165
|
-
twoLines: $twoLineH)
|
|
166
|
-
.accessibility(identifier: "description_popup_permission")
|
|
167
|
-
}
|
|
63
|
+
ZStack(alignment: .topTrailing) {
|
|
64
|
+
VStack(spacing: 0) {
|
|
65
|
+
// scrolls when iPhone Duo landscape is too short; actions stay visible
|
|
66
|
+
PopupScrollBody(maxHeight: layout.popupMaxHeight.map { $0 - actionsHeight }) {
|
|
67
|
+
VStack(spacing: 0) {
|
|
68
|
+
if !url.isEmpty {
|
|
69
|
+
PopupHeaderImage(url: url)
|
|
168
70
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
MomoText(localize.translate("errorCode") + errorCode, typography: .descriptionXsRegular, color: Colors.black12)
|
|
173
|
-
.lineLimit(1)
|
|
71
|
+
VStack(alignment: .leading, spacing: 0) {
|
|
72
|
+
MomoText(title, typography: .headerDefaultBold, maxLines: 2, accessibilityId: "title_popup_permission")
|
|
73
|
+
.padding(.top, 24)
|
|
174
74
|
.padding(.bottom, 8)
|
|
75
|
+
|
|
76
|
+
descriptionContent
|
|
77
|
+
.padding(.bottom, 8)
|
|
78
|
+
|
|
79
|
+
if !errorCode.isEmpty {
|
|
80
|
+
MomoText(localize.translate("errorCode") + errorCode, typography: .descriptionXsRegular, color: theme.colors.text.hint, maxLines: 1)
|
|
81
|
+
.padding(.bottom, 8)
|
|
82
|
+
}
|
|
175
83
|
}
|
|
84
|
+
.frame(maxWidth: .infinity, alignment: .leading)
|
|
85
|
+
.padding(.horizontal, 24)
|
|
86
|
+
.padding(.bottom, 16)
|
|
87
|
+
.measureLineHeights(typography: .bodyDefaultRegular, oneLine: $oneLineH, twoLines: $twoLineH)
|
|
176
88
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
Group {
|
|
181
92
|
if shouldUseColumn {
|
|
182
93
|
if buttonType == .text {
|
|
183
94
|
ColumnTextButtons
|
|
@@ -192,13 +103,39 @@ public struct PopupDisplay: View {
|
|
|
192
103
|
}
|
|
193
104
|
}
|
|
194
105
|
}
|
|
195
|
-
.
|
|
106
|
+
.popupReadHeight($actionsHeight)
|
|
107
|
+
}
|
|
108
|
+
.fixedSize(horizontal: false, vertical: true)
|
|
109
|
+
.background(theme.colors.background.surface)
|
|
110
|
+
.clipShape(RoundedRectangle(cornerRadius: Radius.L))
|
|
111
|
+
|
|
112
|
+
if isShowCloseIcon {
|
|
113
|
+
PopupCloseButton(action: onClose)
|
|
114
|
+
.offset(x: 11, y: -11)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
.frame(maxWidth: layout.popupMaxWidth)
|
|
118
|
+
.padding(.horizontal, 12)
|
|
119
|
+
.accessibilityElement(children: .contain)
|
|
120
|
+
.accessibilityIdentifier("popup_notify")
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@ViewBuilder
|
|
124
|
+
private var descriptionContent: some View {
|
|
125
|
+
if textHeight > maxHeight8_5 {
|
|
126
|
+
ScrollView(showsIndicators: false) {
|
|
127
|
+
descriptionText
|
|
196
128
|
}
|
|
129
|
+
.frame(height: maxHeight8_5)
|
|
130
|
+
} else {
|
|
131
|
+
descriptionText
|
|
197
132
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private var descriptionText: some View {
|
|
136
|
+
MomoText(description, typography: .bodyDefaultRegular, accessibilityId: "description_popup_permission")
|
|
137
|
+
.frame(maxWidth: .infinity, alignment: .leading)
|
|
138
|
+
.popupReadHeight($textHeight)
|
|
202
139
|
}
|
|
203
140
|
|
|
204
141
|
// MARK: Internal
|
|
@@ -248,7 +185,7 @@ public struct PopupDisplay: View {
|
|
|
248
185
|
}
|
|
249
186
|
|
|
250
187
|
var RowButtons: some View {
|
|
251
|
-
HStack {
|
|
188
|
+
HStack(spacing: Spacing.S) {
|
|
252
189
|
if(!closeButtonTitle.isEmpty) {
|
|
253
190
|
Button(title: closeButtonTitle, action: onPressCloseButton, type: .text, size: .medium).accessibility(identifier: "btn_popup_cancel")
|
|
254
191
|
}
|
|
@@ -261,7 +198,7 @@ public struct PopupDisplay: View {
|
|
|
261
198
|
}
|
|
262
199
|
|
|
263
200
|
var ColumnButtons: some View {
|
|
264
|
-
VStack(alignment: .trailing) {
|
|
201
|
+
VStack(alignment: .trailing, spacing: Spacing.S) {
|
|
265
202
|
Button(
|
|
266
203
|
title: actionButtonTitle,
|
|
267
204
|
action: onPressAction,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import SDWebImageSwiftUI
|
|
2
1
|
import SwiftUI
|
|
3
2
|
|
|
4
3
|
public struct PopupInput: View {
|
|
4
|
+
@Environment(\.appTheme) private var theme
|
|
5
|
+
@Environment(\.screenLayout) private var layout
|
|
6
|
+
|
|
5
7
|
// MARK: Lifecycle
|
|
6
8
|
|
|
7
9
|
public init(isPresented: Binding<Bool>, title: String = "", description: String = "", numberOfButtons: Int = 1, actionButtonTitle: String = "", closeButtonTitle: String = "", onPressAction: @escaping () -> Void = {}, onPressCloseButton: @escaping () -> Void = {}, onClose: @escaping () -> Void = {}, inputPlaceholder: String = "", inputValue: Binding<String> = Binding.constant(""), onTextChange: ((String) -> Void)? = nil) {
|
|
@@ -24,22 +26,13 @@ public struct PopupInput: View {
|
|
|
24
26
|
public var body: some View {
|
|
25
27
|
VStack(spacing: 12) {
|
|
26
28
|
ZStack(alignment: .topTrailing) {
|
|
27
|
-
SwiftUI.Button(action: onPressClose) {
|
|
28
|
-
Image(systemName: "xmark.circle.fill")
|
|
29
|
-
.resizable()
|
|
30
|
-
.frame(width: 16, height: 16)
|
|
31
|
-
}.foregroundColor(Colors.black20)
|
|
32
|
-
.background(Colors.black01.cornerRadius(8))
|
|
33
|
-
.offset(x: 6, y: -6)
|
|
34
|
-
.zIndex(1)
|
|
35
|
-
|
|
36
29
|
VStack {
|
|
37
30
|
VStack(alignment: .leading) {
|
|
38
|
-
MomoText(title, typography: .headerDefaultBold
|
|
31
|
+
MomoText(title, typography: .headerDefaultBold)
|
|
39
32
|
.padding(.top, 12)
|
|
40
33
|
.padding(.bottom, 24)
|
|
41
34
|
|
|
42
|
-
MomoText(description, typography: .bodyDefaultRegular
|
|
35
|
+
MomoText(description, typography: .bodyDefaultRegular)
|
|
43
36
|
.opacity(0.6)
|
|
44
37
|
.multilineTextAlignment(.leading)
|
|
45
38
|
.padding(.bottom, 20)
|
|
@@ -61,11 +54,15 @@ public struct PopupInput: View {
|
|
|
61
54
|
}
|
|
62
55
|
|
|
63
56
|
}.clipped()
|
|
57
|
+
|
|
58
|
+
PopupCloseButton(action: onPressClose)
|
|
59
|
+
.offset(x: 11, y: -11)
|
|
64
60
|
}
|
|
65
61
|
}
|
|
66
|
-
.background(
|
|
62
|
+
.background(theme.colors.background.surface.cornerRadius(8))
|
|
67
63
|
.shadow(color: .black.opacity(0.08), radius: 2, x: 0, y: 0)
|
|
68
64
|
.shadow(color: .black.opacity(0.16), radius: 24, x: 0, y: 0)
|
|
65
|
+
.frame(maxWidth: layout.popupMaxWidth)
|
|
69
66
|
.padding(.horizontal, 40)
|
|
70
67
|
}
|
|
71
68
|
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import SDWebImageSwiftUI
|
|
2
|
+
import SwiftUI
|
|
3
|
+
|
|
4
|
+
// Width of a system alert on the iPhone Duo inner display, in both orientations (RN Popup/utils.ts).
|
|
5
|
+
private let duoPopupMaxWidth: CGFloat = 440
|
|
6
|
+
|
|
7
|
+
extension ScreenLayout {
|
|
8
|
+
/// Card width cap (Compose `popupMaxWidth`); unbounded off iPhone Duo, where the popup's own padding sets the width.
|
|
9
|
+
var popupMaxWidth: CGFloat {
|
|
10
|
+
isDuoDevice ? duoPopupMaxWidth : .infinity
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/// Room left for a popup on iPhone Duo, where landscape is too short for it; nil elsewhere.
|
|
14
|
+
var popupMaxHeight: CGFloat? {
|
|
15
|
+
guard isDuoDevice else { return nil }
|
|
16
|
+
return height - duoTopInset - insets.bottom - Spacing.XL * 2
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/// Scrolls `content` once it is taller than `maxHeight`; otherwise sizes to it.
|
|
21
|
+
struct PopupScrollBody<Content: View>: View {
|
|
22
|
+
let maxHeight: CGFloat?
|
|
23
|
+
@ViewBuilder let content: () -> Content
|
|
24
|
+
|
|
25
|
+
@State private var contentHeight: CGFloat = 0
|
|
26
|
+
|
|
27
|
+
var body: some View {
|
|
28
|
+
if let maxHeight {
|
|
29
|
+
ScrollView(.vertical, showsIndicators: false) {
|
|
30
|
+
content()
|
|
31
|
+
.background(
|
|
32
|
+
GeometryReader { proxy in
|
|
33
|
+
Color.clear
|
|
34
|
+
.onAppear { contentHeight = proxy.size.height }
|
|
35
|
+
.onChange(of: proxy.size.height) { contentHeight = $0 }
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
.frame(height: min(contentHeight, max(maxHeight, 0)))
|
|
40
|
+
} else {
|
|
41
|
+
content()
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/// Height of `lines` (may be fractional) lines measured by `measureLineHeights`; nil until measured.
|
|
47
|
+
func popupLinesHeight(_ lines: CGFloat, oneLine: CGFloat, twoLines: CGFloat) -> CGFloat? {
|
|
48
|
+
guard oneLine > 0, twoLines > oneLine else { return nil }
|
|
49
|
+
return oneLine + (lines - 1) * (twoLines - oneLine)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
extension View {
|
|
53
|
+
/// Measures one and two lines of `typography` as MomoText lays them out, its line spacing included.
|
|
54
|
+
func measureLineHeights(typography: TypographyStyle,
|
|
55
|
+
oneLine: Binding<CGFloat>,
|
|
56
|
+
twoLines: Binding<CGFloat>) -> some View {
|
|
57
|
+
overlay(
|
|
58
|
+
VStack(spacing: 0) {
|
|
59
|
+
MomoText("A", typography: typography)
|
|
60
|
+
.fixedSize()
|
|
61
|
+
.popupReadHeight(oneLine)
|
|
62
|
+
MomoText("A\nA", typography: typography)
|
|
63
|
+
.fixedSize()
|
|
64
|
+
.popupReadHeight(twoLines)
|
|
65
|
+
}
|
|
66
|
+
.frame(width: 0, height: 0)
|
|
67
|
+
.hidden()
|
|
68
|
+
.accessibilityHidden(true)
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
func popupReadHeight(_ height: Binding<CGFloat>) -> some View {
|
|
73
|
+
background(
|
|
74
|
+
GeometryReader { proxy in
|
|
75
|
+
Color.clear
|
|
76
|
+
.onAppear { height.wrappedValue = proxy.size.height }
|
|
77
|
+
.onChange(of: proxy.size.height) { height.wrappedValue = $0 }
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/// 22pt round close button shared by the popups (Compose `PopupNotify` / `PopupPromotion`).
|
|
84
|
+
struct PopupCloseButton: View {
|
|
85
|
+
@Environment(\.appTheme) private var theme
|
|
86
|
+
var tapSize: CGFloat = 22
|
|
87
|
+
let action: () -> Void
|
|
88
|
+
|
|
89
|
+
var body: some View {
|
|
90
|
+
SwiftUI.Button(action: action) {
|
|
91
|
+
Circle()
|
|
92
|
+
.fill(theme.colors.text.default)
|
|
93
|
+
.overlay(Circle().strokeBorder(theme.colors.background.surface, lineWidth: 2))
|
|
94
|
+
.overlay(Icon(source: "navigation_close", size: 16, color: theme.colors.background.surface))
|
|
95
|
+
.frame(width: 22, height: 22)
|
|
96
|
+
.frame(width: tapSize, height: tapSize)
|
|
97
|
+
.contentShape(Rectangle())
|
|
98
|
+
}
|
|
99
|
+
.accessibilityIdentifier("ic_popup_close")
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/// Compose `Image` states: skeleton while loading, `media_fail` once loading fails.
|
|
104
|
+
struct PopupImagePlaceholder: View {
|
|
105
|
+
@Environment(\.appTheme) private var theme
|
|
106
|
+
let failed: Bool
|
|
107
|
+
|
|
108
|
+
var body: some View {
|
|
109
|
+
if failed {
|
|
110
|
+
Icon(source: "media_fail", color: theme.colors.text.disable)
|
|
111
|
+
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
112
|
+
} else {
|
|
113
|
+
Skeleton()
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/// 16:9 header image, cropped like Compose `Image` (ContentScale.Crop).
|
|
119
|
+
struct PopupHeaderImage: View {
|
|
120
|
+
let url: String
|
|
121
|
+
|
|
122
|
+
@State private var failed = false
|
|
123
|
+
|
|
124
|
+
var body: some View {
|
|
125
|
+
Color.clear
|
|
126
|
+
.aspectRatio(1.777, contentMode: .fit)
|
|
127
|
+
.frame(maxWidth: .infinity)
|
|
128
|
+
.overlay(
|
|
129
|
+
WebImage(url: URL(string: url), isAnimating: .constant(true))
|
|
130
|
+
.onSuccess { _, _, _ in failed = false }
|
|
131
|
+
.onFailure { _ in failed = true }
|
|
132
|
+
.resizable()
|
|
133
|
+
.placeholder { PopupImagePlaceholder(failed: failed || URL(string: url) == nil) }
|
|
134
|
+
.scaledToFill()
|
|
135
|
+
)
|
|
136
|
+
.clipped()
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
import SDWebImageSwiftUI
|
|
2
1
|
import SwiftUI
|
|
3
2
|
|
|
4
3
|
public typealias PopupActionDirection = PopupButtonDirection
|
|
5
4
|
|
|
5
|
+
public struct PopupAction {
|
|
6
|
+
public let title: String
|
|
7
|
+
public let onPress: (() -> Void)?
|
|
8
|
+
|
|
9
|
+
public init(title: String, onPress: (() -> Void)? = nil) {
|
|
10
|
+
self.title = title
|
|
11
|
+
self.onPress = onPress
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
6
15
|
public struct PopupNotifyProps {
|
|
7
16
|
public var image: String
|
|
8
17
|
public var title: String
|
|
@@ -38,19 +47,26 @@ public struct PopupNotifyProps {
|
|
|
38
47
|
}
|
|
39
48
|
|
|
40
49
|
public struct PopupNotify: View {
|
|
50
|
+
@Environment(\.appTheme) private var theme
|
|
41
51
|
@Environment(\.localize) private var localize
|
|
42
52
|
@Environment(\.momoFontScale) private var fontScale
|
|
53
|
+
@Environment(\.screenLayout) private var layout
|
|
43
54
|
|
|
44
55
|
public let props: PopupNotifyProps
|
|
45
56
|
|
|
46
57
|
@State private var descriptionHeight: CGFloat = 0
|
|
58
|
+
@State private var actionsHeight: CGFloat = 0
|
|
59
|
+
@State private var oneLineHeight: CGFloat = 0
|
|
60
|
+
@State private var twoLinesHeight: CGFloat = 0
|
|
47
61
|
|
|
48
62
|
private var errorCodePrefix: String {
|
|
49
63
|
localize.translate("errorCode")
|
|
50
64
|
}
|
|
51
65
|
|
|
66
|
+
// ~8.5 lines as laid out (Compose measures the real lines); nominal line height until measured
|
|
52
67
|
private var maxDescriptionHeight: CGFloat {
|
|
53
|
-
|
|
68
|
+
popupLinesHeight(8.5, oneLine: oneLineHeight, twoLines: twoLinesHeight)
|
|
69
|
+
?? fontScale(TypographyStyle.bodyDefaultRegular.lineHeight) * 8.5
|
|
54
70
|
}
|
|
55
71
|
|
|
56
72
|
private var shouldUseColumnButtons: Bool {
|
|
@@ -60,7 +76,9 @@ public struct PopupNotify: View {
|
|
|
60
76
|
case .row:
|
|
61
77
|
return false
|
|
62
78
|
case .auto:
|
|
63
|
-
|
|
79
|
+
// UTF-16 length, as Kotlin and JS count it
|
|
80
|
+
guard let secondary = props.secondary else { return false }
|
|
81
|
+
return secondary.title.utf16.count > 12 || (props.primary?.title.utf16.count ?? 0) > 12
|
|
64
82
|
}
|
|
65
83
|
}
|
|
66
84
|
|
|
@@ -71,63 +89,60 @@ public struct PopupNotify: View {
|
|
|
71
89
|
public var body: some View {
|
|
72
90
|
ZStack(alignment: .topTrailing) {
|
|
73
91
|
VStack(spacing: 0) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
typography: .headerDefaultBold,
|
|
82
|
-
maxLines: 2,
|
|
83
|
-
accessibilityId: "title_popup_permission"
|
|
84
|
-
)
|
|
85
|
-
.padding(.bottom, Spacing.S)
|
|
86
|
-
|
|
87
|
-
descriptionContent
|
|
88
|
-
|
|
89
|
-
if !props.error.isEmpty {
|
|
90
|
-
MomoText(
|
|
91
|
-
errorCodePrefix + props.error,
|
|
92
|
-
typography: .descriptionXsRegular,
|
|
93
|
-
color: Colors.black12,
|
|
94
|
-
maxLines: 1
|
|
95
|
-
)
|
|
96
|
-
.padding(.top, Spacing.S)
|
|
92
|
+
// scrolls when iPhone Duo landscape is too short; actions stay visible
|
|
93
|
+
PopupScrollBody(maxHeight: layout.popupMaxHeight.map { $0 - actionsHeight }) {
|
|
94
|
+
VStack(spacing: 0) {
|
|
95
|
+
if !props.image.isEmpty {
|
|
96
|
+
PopupHeaderImage(url: props.image)
|
|
97
|
+
}
|
|
98
|
+
textContent
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
|
-
.frame(maxWidth: .infinity, alignment: .leading)
|
|
100
|
-
.padding(Spacing.XL)
|
|
101
101
|
|
|
102
102
|
actionButtons
|
|
103
103
|
.padding(.horizontal, Spacing.XL)
|
|
104
104
|
.padding(.bottom, Spacing.XL)
|
|
105
|
+
.popupReadHeight($actionsHeight)
|
|
105
106
|
}
|
|
106
|
-
.background(
|
|
107
|
+
.background(theme.colors.background.surface)
|
|
107
108
|
.clipShape(RoundedRectangle(cornerRadius: Radius.L))
|
|
108
109
|
|
|
109
110
|
if props.isShowCloseIcon {
|
|
110
|
-
|
|
111
|
-
.offset(x:
|
|
111
|
+
PopupCloseButton(action: props.onIconClose)
|
|
112
|
+
.offset(x: 11, y: -11)
|
|
112
113
|
}
|
|
113
114
|
}
|
|
115
|
+
.frame(maxWidth: layout.popupMaxWidth)
|
|
114
116
|
.padding(.horizontal, Spacing.M)
|
|
115
|
-
.accessibilityElement(children: .
|
|
117
|
+
.accessibilityElement(children: .contain)
|
|
116
118
|
.accessibilityIdentifier("popup_notify")
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
private var
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
121
|
+
private var textContent: some View {
|
|
122
|
+
VStack(alignment: .leading, spacing: 0) {
|
|
123
|
+
MomoText(
|
|
124
|
+
props.title,
|
|
125
|
+
typography: .headerDefaultBold,
|
|
126
|
+
maxLines: 2,
|
|
127
|
+
accessibilityId: "title_popup_permission"
|
|
128
|
+
)
|
|
129
|
+
.padding(.bottom, Spacing.S)
|
|
130
|
+
|
|
131
|
+
descriptionContent
|
|
132
|
+
|
|
133
|
+
if !props.error.isEmpty {
|
|
134
|
+
MomoText(
|
|
135
|
+
errorCodePrefix + props.error,
|
|
136
|
+
typography: .descriptionXsRegular,
|
|
137
|
+
color: theme.colors.text.hint,
|
|
138
|
+
maxLines: 1
|
|
139
|
+
)
|
|
140
|
+
.padding(.top, Spacing.S)
|
|
127
141
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
142
|
+
}
|
|
143
|
+
.frame(maxWidth: .infinity, alignment: .leading)
|
|
144
|
+
.padding(Spacing.XL)
|
|
145
|
+
.measureLineHeights(typography: .bodyDefaultRegular, oneLine: $oneLineHeight, twoLines: $twoLinesHeight)
|
|
131
146
|
}
|
|
132
147
|
|
|
133
148
|
@ViewBuilder
|
|
@@ -149,15 +164,7 @@ public struct PopupNotify: View {
|
|
|
149
164
|
accessibilityId: "description_popup_permission"
|
|
150
165
|
)
|
|
151
166
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
152
|
-
.
|
|
153
|
-
GeometryReader { proxy in
|
|
154
|
-
Color.clear
|
|
155
|
-
.onAppear { descriptionHeight = proxy.size.height }
|
|
156
|
-
.onChange(of: props.description) { _ in
|
|
157
|
-
descriptionHeight = proxy.size.height
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
)
|
|
167
|
+
.popupReadHeight($descriptionHeight)
|
|
161
168
|
}
|
|
162
169
|
|
|
163
170
|
@ViewBuilder
|
|
@@ -199,21 +206,4 @@ public struct PopupNotify: View {
|
|
|
199
206
|
)
|
|
200
207
|
.accessibilityIdentifier("btn_popup_cancel")
|
|
201
208
|
}
|
|
202
|
-
|
|
203
|
-
private var closeButton: some View {
|
|
204
|
-
SwiftUI.Button(action: props.onIconClose) {
|
|
205
|
-
ZStack {
|
|
206
|
-
Circle()
|
|
207
|
-
.fill(Colors.black17)
|
|
208
|
-
.overlay(
|
|
209
|
-
Circle()
|
|
210
|
-
.stroke(Colors.black01, lineWidth: 2)
|
|
211
|
-
)
|
|
212
|
-
.frame(width: 22, height: 22)
|
|
213
|
-
|
|
214
|
-
Icon(source: "navigation_close", size: 16, color: Colors.black01)
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
.accessibilityIdentifier("ic_popup_close")
|
|
218
|
-
}
|
|
219
209
|
}
|