@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
|
@@ -2,12 +2,13 @@ import SwiftUI
|
|
|
2
2
|
import SDWebImageSwiftUI
|
|
3
3
|
|
|
4
4
|
public struct PopupPromotion: View {
|
|
5
|
-
@Environment(\.
|
|
5
|
+
@Environment(\.screenLayout) private var layout
|
|
6
6
|
|
|
7
7
|
var imageUrl: String
|
|
8
8
|
var onIconClose: (() -> Void)?
|
|
9
9
|
var onAction: (() -> Void)?
|
|
10
10
|
|
|
11
|
+
@State private var imageFailed = false
|
|
11
12
|
|
|
12
13
|
public init(
|
|
13
14
|
imageUrl: String,
|
|
@@ -19,56 +20,39 @@ public struct PopupPromotion: View {
|
|
|
19
20
|
self.onAction = onAction
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
WebImage(url: URL(string: imageUrl)!)
|
|
29
|
-
.resizable()
|
|
30
|
-
.placeholder {
|
|
31
|
-
Color.gray
|
|
32
|
-
.aspectRatio(0.72, contentMode: .fit)
|
|
33
|
-
.frame(maxWidth: UIScreen.main.bounds.width - Spacing.XL * 2)
|
|
34
|
-
.clipped()
|
|
35
|
-
}
|
|
36
|
-
.aspectRatio(0.72, contentMode: .fit)
|
|
37
|
-
.frame(maxWidth: UIScreen.main.bounds.width - Spacing.XL * 2, alignment: .center)
|
|
38
|
-
.clipped()
|
|
39
|
-
.onTapGesture {
|
|
40
|
-
onAction?()
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
buildCloseIcon()
|
|
44
|
-
.accessibility(identifier: "ic_popup_close")
|
|
45
|
-
}
|
|
46
|
-
.accessibilityElement(children: .ignore)
|
|
47
|
-
.accessibility(identifier: "popup_promotion")
|
|
48
|
-
}
|
|
23
|
+
private static let aspectRatio: CGFloat = 0.72
|
|
24
|
+
private static let closeTapSize: CGFloat = 40
|
|
25
|
+
// close button row under the image: top padding + 40pt tap target
|
|
26
|
+
private static let closeRowHeight: CGFloat = Spacing.S + closeTapSize
|
|
49
27
|
|
|
50
|
-
|
|
51
|
-
private
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
ZStack {
|
|
57
|
-
Circle()
|
|
58
|
-
.strokeBorder(theme.colors.background.surface, lineWidth: 2)
|
|
59
|
-
.background(Circle().fill(theme.colors.text.default))
|
|
60
|
-
.frame(width: 22, height: 22)
|
|
28
|
+
// fit the portrait image by height when iPhone Duo leaves too little room
|
|
29
|
+
private var imageWidth: CGFloat {
|
|
30
|
+
let width = min(layout.width - Spacing.M * 2, layout.popupMaxWidth)
|
|
31
|
+
guard let maxHeight = layout.popupMaxHeight else { return width }
|
|
32
|
+
return min(width, (maxHeight - Self.closeRowHeight) * Self.aspectRatio)
|
|
33
|
+
}
|
|
61
34
|
|
|
62
|
-
|
|
35
|
+
public var body: some View {
|
|
36
|
+
VStack(spacing: 0) {
|
|
37
|
+
// stretched like Compose's ContentScale.FillBounds; an empty url shows the error state, as in Compose
|
|
38
|
+
WebImage(url: URL(string: imageUrl))
|
|
39
|
+
.onSuccess { _, _, _ in imageFailed = false }
|
|
40
|
+
.onFailure { _ in imageFailed = true }
|
|
41
|
+
.resizable()
|
|
42
|
+
.placeholder { PopupImagePlaceholder(failed: imageFailed || URL(string: imageUrl) == nil) }
|
|
43
|
+
.aspectRatio(Self.aspectRatio, contentMode: .fit)
|
|
44
|
+
.frame(maxWidth: imageWidth)
|
|
45
|
+
.contentShape(Rectangle())
|
|
46
|
+
.onTapGesture {
|
|
47
|
+
onAction?()
|
|
63
48
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
49
|
+
|
|
50
|
+
PopupCloseButton(tapSize: Self.closeTapSize) {
|
|
51
|
+
onIconClose?()
|
|
67
52
|
}
|
|
53
|
+
.padding(.top, Spacing.S)
|
|
68
54
|
}
|
|
55
|
+
.accessibilityElement(children: .contain)
|
|
56
|
+
.accessibilityIdentifier("popup_promotion")
|
|
69
57
|
}
|
|
70
|
-
|
|
71
58
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
@@ -51,12 +51,9 @@ public struct FullscreenPopup<Item: Equatable, PopupContent: View>: ViewModifier
|
|
|
51
51
|
@State private var opacity = 0.0
|
|
52
52
|
|
|
53
53
|
// MARK: - Autohide
|
|
54
|
-
///
|
|
55
|
-
|
|
56
|
-
private var
|
|
57
|
-
|
|
58
|
-
/// holder for autohiding dispatch work (to be able to cancel it when needed)
|
|
59
|
-
private var dispatchWorkHolder = DispatchWorkHolder()
|
|
54
|
+
/// holder for autohiding dispatch work (to be able to cancel it when needed);
|
|
55
|
+
/// state so it outlives re-renders, which would otherwise orphan the pending work
|
|
56
|
+
@State private var dispatchWorkHolder = DispatchWorkHolder()
|
|
60
57
|
|
|
61
58
|
// MARK: - Internal
|
|
62
59
|
/// Set dismiss souce to pass to dismiss callback
|
|
@@ -85,9 +82,6 @@ public struct FullscreenPopup<Item: Equatable, PopupContent: View>: ViewModifier
|
|
|
85
82
|
self.backgroundColor = backgroundColor
|
|
86
83
|
self.dismissCallback = dismissCallback
|
|
87
84
|
self.view = view
|
|
88
|
-
|
|
89
|
-
self.isPresentedRef = ClassReference(self.$isPresented)
|
|
90
|
-
self.itemRef = ClassReference(self.$item)
|
|
91
85
|
}
|
|
92
86
|
|
|
93
87
|
init(item: Binding<Item?>,
|
|
@@ -113,9 +107,6 @@ public struct FullscreenPopup<Item: Equatable, PopupContent: View>: ViewModifier
|
|
|
113
107
|
self.backgroundColor = backgroundColor
|
|
114
108
|
self.dismissCallback = dismissCallback
|
|
115
109
|
self.view = view
|
|
116
|
-
|
|
117
|
-
self.isPresentedRef = ClassReference(self.$isPresented)
|
|
118
|
-
self.itemRef = ClassReference(self.$item)
|
|
119
110
|
}
|
|
120
111
|
|
|
121
112
|
public func body(content: Content) -> some View {
|
|
@@ -214,7 +205,8 @@ public struct FullscreenPopup<Item: Equatable, PopupContent: View>: ViewModifier
|
|
|
214
205
|
}
|
|
215
206
|
|
|
216
207
|
func onAnimationCompleted() -> () {
|
|
217
|
-
|
|
208
|
+
// only proceed on hiding, once: both the offset animation and the fallback timer land here
|
|
209
|
+
if shouldShowContent || !showContent {
|
|
218
210
|
return
|
|
219
211
|
}
|
|
220
212
|
showContent = false // unload popup body after hiding animation is done
|
|
@@ -229,12 +221,14 @@ public struct FullscreenPopup<Item: Equatable, PopupContent: View>: ViewModifier
|
|
|
229
221
|
if let autohideIn = autohideIn {
|
|
230
222
|
dispatchWorkHolder.work?.cancel()
|
|
231
223
|
|
|
232
|
-
//
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
dismissSource = .autohide
|
|
224
|
+
// bindings only: capturing the struct would retain the work holder in a cycle
|
|
225
|
+
let isPresented = $isPresented
|
|
226
|
+
let item = $item
|
|
227
|
+
let dismissSource = $dismissSource
|
|
228
|
+
dispatchWorkHolder.work = DispatchWorkItem(block: {
|
|
229
|
+
dismissSource.wrappedValue = .autohide
|
|
230
|
+
isPresented.wrappedValue = false
|
|
231
|
+
item.wrappedValue = nil
|
|
238
232
|
})
|
|
239
233
|
if sheetPresented, let work = dispatchWorkHolder.work {
|
|
240
234
|
DispatchQueue.main.asyncAfter(deadline: .now() + autohideIn, execute: work)
|
|
@@ -239,7 +239,7 @@ public struct Popup<Item: Equatable, PopupContent: View>: ViewModifier {
|
|
|
239
239
|
.onAnimationCompleted(for: currentOffset) {
|
|
240
240
|
animationCompletedCallback()
|
|
241
241
|
}
|
|
242
|
-
.animation(animation)
|
|
242
|
+
.animation(animation, value: currentOffset)
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
#if !os(tvOS)
|
|
@@ -112,7 +112,9 @@ private struct ProgressInfoHorizontal: View {
|
|
|
112
112
|
|
|
113
113
|
var body: some View {
|
|
114
114
|
HStack(alignment: .top, spacing: 0) {
|
|
115
|
-
|
|
115
|
+
// Keyed by position: `ProgressInfoItem.id` is a fresh UUID per init, so it churns
|
|
116
|
+
// identity whenever the caller rebuilds `steps`.
|
|
117
|
+
ForEach(Array(steps.enumerated()), id: \.offset) { index, item in
|
|
116
118
|
let isFirst = index == 0
|
|
117
119
|
let isLast = index == steps.count - 1
|
|
118
120
|
|
|
@@ -207,7 +209,7 @@ private struct ProgressInfoVertical: View {
|
|
|
207
209
|
|
|
208
210
|
var body: some View {
|
|
209
211
|
VStack(alignment: .leading, spacing: 0) {
|
|
210
|
-
ForEach(Array(steps.enumerated()), id: \.
|
|
212
|
+
ForEach(Array(steps.enumerated()), id: \.offset) { index, item in
|
|
211
213
|
let isLast = index == steps.count - 1
|
|
212
214
|
|
|
213
215
|
HStack(alignment: .top, spacing: 0) {
|
package/ios/Radio/Radio.swift
CHANGED
|
@@ -36,8 +36,9 @@ public struct Radio: View {
|
|
|
36
36
|
public var body: some View {
|
|
37
37
|
SwiftUI.Button(action: onTap) {
|
|
38
38
|
HStack(spacing: 0) {
|
|
39
|
+
// strokeBorder keeps the ring inside 20pt, like Compose `border`.
|
|
39
40
|
RoundedRectangle(cornerRadius: Radius.M)
|
|
40
|
-
.
|
|
41
|
+
.strokeBorder(borderColor, lineWidth: borderWidth)
|
|
41
42
|
.frame(width: 20, height: 20)
|
|
42
43
|
.padding(.trailing, label.isEmpty ? 0 : Spacing.XS)
|
|
43
44
|
|
package/ios/Rating/Rating.swift
CHANGED
|
@@ -35,7 +35,7 @@ public struct Rating: View {
|
|
|
35
35
|
|
|
36
36
|
public var body: some View {
|
|
37
37
|
HStack(spacing: 2) {
|
|
38
|
-
ForEach(0..<numOfStars, id: \.self) { index in
|
|
38
|
+
ForEach(0..<max(numOfStars, 0), id: \.self) { index in
|
|
39
39
|
star(at: index)
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -59,7 +59,14 @@ public struct Rating: View {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
// Kotlin's toInt() maps NaN to 0 and saturates; Swift's Int(_:) traps on both.
|
|
63
|
+
private var safeRating: Float {
|
|
64
|
+
guard rating.isFinite else { return 0 }
|
|
65
|
+
return min(max(rating, -Float(Int32.max)), Float(Int32.max))
|
|
66
|
+
}
|
|
67
|
+
|
|
62
68
|
private func starIcon(at index: Int) -> String {
|
|
69
|
+
let rating = safeRating
|
|
63
70
|
let intRating = Int(rating)
|
|
64
71
|
if index < intRating {
|
|
65
72
|
return "reaction_star_full"
|
|
@@ -71,6 +78,7 @@ public struct Rating: View {
|
|
|
71
78
|
}
|
|
72
79
|
|
|
73
80
|
private func starColor(at index: Int) -> Color {
|
|
81
|
+
let rating = safeRating
|
|
74
82
|
let intRating = Int(rating)
|
|
75
83
|
if index < intRating {
|
|
76
84
|
return Colors.yellow03
|