@momo-kits/native-kits 0.162.2-beta.1 → 0.162.2-sp.1-debug
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +55 -0
- package/build.gradle.kts +11 -0
- package/compose/build.gradle.kts +186 -0
- package/compose/build.gradle.kts.backup +186 -0
- package/compose/compose.podspec +47 -0
- package/compose/src/androidMain/kotlin/vn/momo/kits/navigation/ScrollToTop.android.kt +6 -0
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +123 -0
- package/compose/src/commonMain/composeResources/font/momosignature.otf +0 -0
- package/compose/src/commonMain/composeResources/font/momotrustdisplay.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_black.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_black.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_bold.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_heavy.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_light.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_medium.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_regular.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_semibold.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_thin.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_thin.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.ttf +0 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +57 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +109 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +201 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +222 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +48 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +86 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +76 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +76 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +305 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +33 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +921 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +121 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +403 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +69 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Avatar.kt +157 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +85 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +32 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +340 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +198 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +357 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +123 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +94 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +136 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +224 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +543 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +23 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +76 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +148 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +188 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +116 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +452 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +172 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +255 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +235 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +233 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +259 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +241 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +364 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Loader.kt +108 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +56 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +41 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +92 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +40 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +352 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +103 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +338 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +70 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Rating.kt +87 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +17 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +96 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +348 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +256 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +494 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +131 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +215 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +96 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +531 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +92 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +135 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +214 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +590 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +177 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +192 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +205 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +29 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +239 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +191 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +306 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +12 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +16 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +188 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +285 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +2 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +35 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +2 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +57 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +68 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +11 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +14 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +50 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +51 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +253 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +133 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +104 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +145 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +345 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScrollToTop.kt +8 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +556 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +161 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +243 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +86 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +187 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +315 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +80 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +306 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +34 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +370 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +131 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +167 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +72 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +66 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +1329 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +70 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +15 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +105 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +33 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +186 -0
- package/gradle/libs.versions.toml +67 -0
- package/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/gradle/wrapper/gradle-wrapper.properties +8 -0
- package/gradle.properties +26 -0
- package/gradlew +252 -0
- package/gradlew.bat +94 -0
- package/ios/Application/Components.swift +34 -43
- package/ios/Application/FloatingButton.swift +10 -8
- package/ios/Application/Navigation/BottomTab/BottomTab.swift +102 -0
- package/ios/Application/Navigation/BottomTab/BottomTabBar.swift +215 -0
- package/ios/Application/Navigation/BottomTab/CurvedContainer.swift +65 -0
- package/ios/Application/Navigation/HeaderBackProps.swift +66 -0
- package/ios/Application/Navigation/HeaderTitle.swift +57 -0
- package/ios/Application/Navigation/HeaderUser.swift +209 -0
- package/ios/Application/Navigation/NavigationContainer.swift +151 -0
- package/ios/Application/Navigation/NavigationOptions.swift +109 -0
- package/ios/Application/Navigation/Navigator.swift +360 -0
- package/ios/Application/Navigation/Overplay/BottomSheet.swift +176 -0
- package/ios/Application/Navigation/Overplay/ModalScreen.swift +68 -0
- package/ios/Application/Navigation/Overplay/SnackBar.swift +144 -0
- package/ios/Application/Navigation/component/Header.swift +178 -0
- package/ios/Application/Navigation/component/HeaderBackground.swift +83 -0
- package/ios/Application/Navigation/component/HeaderColor.swift +65 -0
- package/ios/Application/StackScreen.swift +449 -0
- package/ios/Avatar/Avatar.swift +193 -0
- package/ios/Badge/Badge.swift +11 -13
- package/ios/Badge/BadgeRibbon.swift +12 -19
- package/ios/BaselineView/BaselineView.swift +163 -0
- package/ios/Button/Button.swift +62 -23
- package/ios/Carousel/Carousel.swift +181 -0
- package/ios/Checkbox/Checkbox.swift +14 -12
- package/ios/Chip/Chip.swift +23 -9
- package/ios/Collapse/Collapse.swift +182 -0
- package/ios/Colors+Radius+Spacing/Colors.swift +1 -1
- package/ios/Colors+Radius+Spacing/Theme.swift +295 -0
- package/ios/DateTimePicker/DateTimePicker.swift +210 -0
- package/ios/DateTimePicker/DateTimePickerTypes.swift +55 -0
- package/ios/DateTimePicker/DateTimePickerUtils.swift +167 -0
- package/ios/DateTimePicker/WheelPicker.swift +161 -0
- package/ios/Divider/Divider.swift +16 -0
- package/ios/Icon/Icon.swift +6 -1
- package/ios/IconButton/IconButton.swift +112 -0
- package/ios/Information/Information.swift +151 -0
- package/ios/Input/Input.swift +42 -25
- package/ios/Input/InputPhoneNumber.swift +21 -19
- package/ios/Input/InputSearch.swift +101 -45
- package/ios/Input/InputTextArea.swift +67 -40
- package/ios/InputDropDown/InputDropDown.swift +198 -0
- package/ios/InputMoney/InputMoney.swift +335 -0
- package/ios/InputOTP/InputOTP.swift +210 -0
- package/ios/Loader/Loader.swift +113 -0
- package/ios/MoMoUIKits.podspec +5 -0
- package/ios/OTPKeyboard/KeyboardButton.swift +1 -1
- package/ios/Pagination/PaginationDot.swift +61 -0
- package/ios/Pagination/PaginationNumber.swift +35 -0
- package/ios/Pagination/PaginationScroll.swift +101 -0
- package/ios/Pagination/PaginationWhiteDot.swift +37 -0
- package/ios/Popup/PopupDisplay.swift +10 -12
- package/ios/Popup/PopupInput.swift +2 -6
- package/ios/Popup/PopupNotify.swift +219 -0
- package/ios/ProgressInfo/ProgressInfo.swift +294 -0
- package/ios/Radio/Radio.swift +70 -0
- package/ios/Rating/Rating.swift +82 -0
- package/ios/Skeleton/Skeleton.swift +99 -0
- package/ios/Slider/Slider.swift +237 -0
- package/ios/Stepper/Stepper.swift +220 -0
- package/ios/Steps/Steps.swift +451 -0
- package/ios/SuggestAction/SuggestAction.swift +97 -0
- package/ios/Swipeable/SwipeCell.swift +185 -0
- package/ios/Swipeable/SwipeCellModel.swift +21 -0
- package/ios/TabView/TabView.swift +530 -0
- package/ios/Tag/Tag.swift +98 -0
- package/ios/Template/TrustBanner/TrustBanner.swift +2 -0
- package/ios/Title/Title.swift +269 -0
- package/ios/Tooltip/Tooltip.swift +482 -0
- package/ios/Typography/Text.swift +86 -24
- package/ios/Typography/Typography.swift +31 -6
- package/ios/Uploader/Uploader.swift +183 -0
- package/ios/native-kits.podspec +58 -8
- package/ios-demo/MoMoUIKitsDemo.podspec +18 -0
- package/ios-demo/README.md +120 -0
- package/ios-demo/Resources/dot_loading.json +558 -0
- package/ios-demo/Resources/icon.json +4052 -0
- package/ios-demo/Resources/lottie_circle_loader.json +1 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/DemoScaffold.swift +48 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsBadgeDemoView.swift +25 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsButtonDemoView.swift +26 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsCheckboxDemoView.swift +19 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsChipDemoView.swift +33 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsInputDemoView.swift +48 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsPopupDemoView.swift +21 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsRadioDemoView.swift +17 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsTypographyDemoView.swift +28 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoContext.swift +31 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoFactory.swift +72 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AnimatedHeaderDemo.swift +110 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AvatarDemo.swift +93 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BadgeDemo.swift +269 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BaselineView.swift +117 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BottomTabDemo.swift +89 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ButtonDemo.swift +100 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CarouselDemo.swift +126 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CheckboxDemo.swift +63 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ChipDemo.swift +20 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CollapseDemo.swift +93 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +107 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DateTimePickerDemo.swift +124 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DividerDemo.swift +14 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/HeaderUserDemo.swift +49 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +261 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconButtonDemo.swift +58 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ImageDemo.swift +78 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InformationDemo.swift +138 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDemo.swift +111 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDropDownDemo.swift +136 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputMoneyDemo.swift +107 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputOTPDemo.swift +73 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputPhoneNumberDemo.swift +100 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputSearchDemo.swift +32 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputTextAreaDemo.swift +57 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LoaderDemo.swift +70 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +227 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PaginationDemo.swift +72 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +175 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +121 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +76 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ProgressInfoDemo.swift +89 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RadioDemo.swift +32 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RatingDemo.swift +56 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SkeletonDemo.swift +32 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SliderDemo.swift +150 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SnackBarDemo.swift +138 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepperDemo.swift +103 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepsDemo.swift +94 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SuggestActionDemo.swift +79 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwipeDemo.swift +152 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwitchDemo.swift +33 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TabViewDemo.swift +190 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TagDemo.swift +34 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ThemeDemo.swift +182 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TitleDemo.swift +109 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TooltipDemo.swift +187 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TypographyDemo.swift +87 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/UploaderDemo.swift +131 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SwiftUIDemoBrowserView.swift +50 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoModels.swift +15 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoRegistry.swift +73 -0
- package/local.properties +8 -0
- package/package.json +1 -1
- package/publish.sh +50 -0
- package/scripts/gen-ios-color.mjs +136 -0
- package/settings.gradle.kts +64 -0
- package/example/ios/Example.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/Example.xcscheme +0 -32
- package/example/ios/Example.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
- package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/WorkspaceSettings.xcsettings +0 -16
- package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +0 -6
- package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +0 -5
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/Pods-Example.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SDWebImage.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SDWebImageSwiftUI.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SkeletonUI.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/lottie-ios-LottiePrivacyInfo.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/lottie-ios.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +0 -60
- package/ios/Typography/MomoFontScale.swift +0 -36
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import SwiftUI
|
|
3
|
+
|
|
4
|
+
// MARK: - OTPCaret
|
|
5
|
+
|
|
6
|
+
/// Blinking caret shown at the active OTP cell, mirroring Compose `OTPCaret`.
|
|
7
|
+
private struct OTPCaret: View {
|
|
8
|
+
@Environment(\.appTheme) private var theme
|
|
9
|
+
@State private var visible: Bool = true
|
|
10
|
+
|
|
11
|
+
var body: some View {
|
|
12
|
+
HStack(spacing: 0) {
|
|
13
|
+
Rectangle()
|
|
14
|
+
.fill(theme.colors.primary)
|
|
15
|
+
.frame(width: 1, height: scaleSize(12))
|
|
16
|
+
.opacity(visible ? 1 : 0)
|
|
17
|
+
.animation(
|
|
18
|
+
.linear(duration: 0.5).repeatForever(autoreverses: true),
|
|
19
|
+
value: visible
|
|
20
|
+
)
|
|
21
|
+
MomoText("-", typography: .descriptionDefaultRegular, color: theme.colors.text.hint)
|
|
22
|
+
}
|
|
23
|
+
.onAppear { visible = false }
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// MARK: - InputOTP
|
|
28
|
+
|
|
29
|
+
/// Native SwiftUI port of Compose `InputOTP`.
|
|
30
|
+
///
|
|
31
|
+
/// A row of OTP cells driven by a hidden `TextField`. When `length` is provided
|
|
32
|
+
/// it renders fixed-count slots (`-` placeholders + blinking caret); otherwise it
|
|
33
|
+
/// renders the typed characters followed by a trailing caret while focused.
|
|
34
|
+
public struct InputOTP: View {
|
|
35
|
+
@Environment(\.appTheme) private var theme
|
|
36
|
+
@Binding public var value: String
|
|
37
|
+
|
|
38
|
+
public var length: Int?
|
|
39
|
+
public var errorMessage: String
|
|
40
|
+
public var errorSpacing: Bool
|
|
41
|
+
public var floatingValue: String
|
|
42
|
+
public var placeholder: String
|
|
43
|
+
public var dataType: String
|
|
44
|
+
public var onChangeText: ((String) -> Void)?
|
|
45
|
+
public var onFocus: (() -> Void)?
|
|
46
|
+
public var onBlur: (() -> Void)?
|
|
47
|
+
|
|
48
|
+
@FocusState private var isFocused: Bool
|
|
49
|
+
@State private var hasBeenFocused: Bool = false
|
|
50
|
+
|
|
51
|
+
private var maxLength: Int { length ?? 10 }
|
|
52
|
+
|
|
53
|
+
public init(
|
|
54
|
+
value: Binding<String>,
|
|
55
|
+
length: Int? = nil,
|
|
56
|
+
errorMessage: String = "",
|
|
57
|
+
errorSpacing: Bool = false,
|
|
58
|
+
floatingValue: String = "Label",
|
|
59
|
+
placeholder: String = "",
|
|
60
|
+
dataType: String = "number",
|
|
61
|
+
onChangeText: ((String) -> Void)? = nil,
|
|
62
|
+
onFocus: (() -> Void)? = nil,
|
|
63
|
+
onBlur: (() -> Void)? = nil
|
|
64
|
+
) {
|
|
65
|
+
self._value = value
|
|
66
|
+
self.length = length
|
|
67
|
+
self.errorMessage = errorMessage
|
|
68
|
+
self.errorSpacing = errorSpacing
|
|
69
|
+
self.floatingValue = floatingValue
|
|
70
|
+
self.placeholder = placeholder
|
|
71
|
+
self.dataType = dataType
|
|
72
|
+
self.onChangeText = onChangeText
|
|
73
|
+
self.onFocus = onFocus
|
|
74
|
+
self.onBlur = onBlur
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public var body: some View {
|
|
78
|
+
VStack(alignment: .leading, spacing: 0) {
|
|
79
|
+
ZStack {
|
|
80
|
+
// Hidden text field that owns the keyboard / cursor.
|
|
81
|
+
hiddenField
|
|
82
|
+
|
|
83
|
+
// Floating label over the border.
|
|
84
|
+
if !floatingValue.isEmpty {
|
|
85
|
+
HStack {
|
|
86
|
+
MomoText(floatingValue, typography: .labelSMedium, color: theme.colors.text.hint)
|
|
87
|
+
}
|
|
88
|
+
.padding(.horizontal, Spacing.S)
|
|
89
|
+
.background(theme.colors.background.surface)
|
|
90
|
+
.offset(y: -28)
|
|
91
|
+
.zIndex(10)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Bordered container with cells.
|
|
95
|
+
cells
|
|
96
|
+
.frame(maxWidth: .infinity)
|
|
97
|
+
.frame(height: 56)
|
|
98
|
+
.overlay(
|
|
99
|
+
RoundedRectangle(cornerRadius: Radius.S)
|
|
100
|
+
.stroke(borderColor, lineWidth: 1)
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
// Trailing clear button.
|
|
104
|
+
HStack {
|
|
105
|
+
Spacer()
|
|
106
|
+
SwiftUI.Button(action: clearText) {
|
|
107
|
+
Icon(source: "24_navigation_close_circle_full", size: 12, color: theme.colors.text.hint)
|
|
108
|
+
.padding(.trailing, 12)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
.zIndex(10)
|
|
112
|
+
}
|
|
113
|
+
.frame(height: 56)
|
|
114
|
+
.contentShape(Rectangle())
|
|
115
|
+
.onTapGesture { isFocused = true }
|
|
116
|
+
|
|
117
|
+
ErrorView(errorMessage: errorMessage, errorSpacing: errorSpacing, hintText: "")
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// MARK: Subviews
|
|
122
|
+
|
|
123
|
+
private var hiddenField: some View {
|
|
124
|
+
TextField("", text: Binding(
|
|
125
|
+
get: { value },
|
|
126
|
+
set: { handleChangeText($0) }
|
|
127
|
+
))
|
|
128
|
+
.keyboardType(dataType == "number" ? .numberPad : .asciiCapable)
|
|
129
|
+
.focused($isFocused)
|
|
130
|
+
.foregroundColor(.clear)
|
|
131
|
+
.accentColor(.clear)
|
|
132
|
+
.frame(maxWidth: .infinity)
|
|
133
|
+
.frame(height: 56)
|
|
134
|
+
.opacity(0.01)
|
|
135
|
+
.onChange(of: isFocused) { focused in
|
|
136
|
+
if focused {
|
|
137
|
+
onFocus?()
|
|
138
|
+
hasBeenFocused = true
|
|
139
|
+
} else if hasBeenFocused {
|
|
140
|
+
onBlur?()
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@ViewBuilder
|
|
146
|
+
private var cells: some View {
|
|
147
|
+
if let length = length {
|
|
148
|
+
HStack(spacing: Spacing.L) {
|
|
149
|
+
ForEach(0 ..< length, id: \.self) { i in
|
|
150
|
+
cell(at: i)
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
.padding(.vertical, 8)
|
|
154
|
+
} else {
|
|
155
|
+
HStack(spacing: Spacing.L) {
|
|
156
|
+
if value.isEmpty && !isFocused && !placeholder.isEmpty {
|
|
157
|
+
MomoText(placeholder, typography: .descriptionDefaultRegular, color: theme.colors.text.hint)
|
|
158
|
+
} else {
|
|
159
|
+
ForEach(Array(value.enumerated()), id: \.offset) { _, ch in
|
|
160
|
+
MomoText(String(ch), typography: .headerDefaultBold, color: theme.colors.text.default)
|
|
161
|
+
}
|
|
162
|
+
if isFocused && value.count != maxLength {
|
|
163
|
+
OTPCaret()
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
.padding(.vertical, 8)
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
@ViewBuilder
|
|
172
|
+
private func cell(at index: Int) -> some View {
|
|
173
|
+
if isFocused && value.count == index {
|
|
174
|
+
OTPCaret()
|
|
175
|
+
} else {
|
|
176
|
+
let chars = Array(value)
|
|
177
|
+
let filled = index < chars.count
|
|
178
|
+
MomoText(
|
|
179
|
+
filled ? String(chars[index]) : "-",
|
|
180
|
+
typography: filled ? .headerDefaultBold : .descriptionDefaultRegular,
|
|
181
|
+
color: filled ? theme.colors.text.default : theme.colors.text.hint
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// MARK: Logic
|
|
187
|
+
|
|
188
|
+
private func handleChangeText(_ text: String) {
|
|
189
|
+
let validData = dataType != "number" || text.allSatisfy { $0.isNumber }
|
|
190
|
+
let changed = text.count != value.count
|
|
191
|
+
if text.count <= maxLength && validData && changed {
|
|
192
|
+
value = text
|
|
193
|
+
onChangeText?(text)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private func clearText() {
|
|
198
|
+
handleChangeText("")
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
private var borderColor: Color {
|
|
202
|
+
if !errorMessage.isEmpty {
|
|
203
|
+
return theme.colors.error.primary
|
|
204
|
+
}
|
|
205
|
+
if isFocused {
|
|
206
|
+
return theme.colors.primary
|
|
207
|
+
}
|
|
208
|
+
return theme.colors.border.default
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import SwiftUI
|
|
3
|
+
|
|
4
|
+
/// Loader variants, mirroring Compose `LoaderType`.
|
|
5
|
+
public enum LoaderType {
|
|
6
|
+
case dot
|
|
7
|
+
case spinner
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/// Native SwiftUI port of the Compose `Loader` component.
|
|
11
|
+
///
|
|
12
|
+
/// Mirrors Compose `Loader(type:, tintColor:, modifier:)` which delegates to
|
|
13
|
+
/// `DotLoader` / `SpinnerLoader`. Both variants render Lottie animations
|
|
14
|
+
/// (`files/dot_loading` and `files/lottie_circle_loader`) and optionally tint
|
|
15
|
+
/// the fill/stroke. The tint is reproduced here by masking a solid color rect
|
|
16
|
+
/// with the (monochrome) Lottie animation.
|
|
17
|
+
public struct Loader: View {
|
|
18
|
+
private let type: LoaderType
|
|
19
|
+
private let tintColor: Color?
|
|
20
|
+
|
|
21
|
+
public init(type: LoaderType = .dot, tintColor: Color? = nil) {
|
|
22
|
+
self.type = type
|
|
23
|
+
self.tintColor = tintColor
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public var body: some View {
|
|
27
|
+
switch type {
|
|
28
|
+
case .dot:
|
|
29
|
+
DotLoader(tintColor: tintColor)
|
|
30
|
+
case .spinner:
|
|
31
|
+
SpinnerLoader(tintColor: tintColor)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/// Looping dot animation. Compose size: 52 x 18.
|
|
37
|
+
public struct DotLoader: View {
|
|
38
|
+
private let tintColor: Color?
|
|
39
|
+
|
|
40
|
+
public init(tintColor: Color? = nil) {
|
|
41
|
+
self.tintColor = tintColor
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public var body: some View {
|
|
45
|
+
TintedLottie(name: "dot_loading", tintColor: tintColor)
|
|
46
|
+
.frame(width: 52, height: 18)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/// Looping circular spinner. Compose size: 24 x 24.
|
|
51
|
+
public struct SpinnerLoader: View {
|
|
52
|
+
private let tintColor: Color?
|
|
53
|
+
|
|
54
|
+
public init(tintColor: Color? = nil) {
|
|
55
|
+
self.tintColor = tintColor
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public var body: some View {
|
|
59
|
+
TintedLottie(name: "lottie_circle_loader", tintColor: tintColor)
|
|
60
|
+
.frame(width: 24, height: 24)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/// Horizontal determinate progress bar.
|
|
65
|
+
///
|
|
66
|
+
/// Mirrors Compose `ProgressBar(percent:, color:, modifier:)`:
|
|
67
|
+
/// - `percent` clamped to 0...100, animated with a 200ms ease.
|
|
68
|
+
/// - track = theme background default (`0xFFF2F2F6`), fill = `color` or primary (pink_03).
|
|
69
|
+
/// - height 4, corner radius `Radius.XXS`, fills max width.
|
|
70
|
+
public struct ProgressBar: View {
|
|
71
|
+
@Environment(\.appTheme) private var theme
|
|
72
|
+
|
|
73
|
+
private let percent: CGFloat
|
|
74
|
+
private let color: Color?
|
|
75
|
+
|
|
76
|
+
public init(percent: CGFloat = 0, color: Color? = nil) {
|
|
77
|
+
self.percent = percent
|
|
78
|
+
self.color = color
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private var clampedFraction: CGFloat {
|
|
82
|
+
min(max(percent, 0), 100) / 100
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public var body: some View {
|
|
86
|
+
GeometryReader { proxy in
|
|
87
|
+
ZStack(alignment: .leading) {
|
|
88
|
+
RoundedRectangle(cornerRadius: Radius.XXS)
|
|
89
|
+
.fill(theme.colors.background.default)
|
|
90
|
+
RoundedRectangle(cornerRadius: Radius.XXS)
|
|
91
|
+
.fill(color ?? theme.colors.primary)
|
|
92
|
+
.frame(width: proxy.size.width * clampedFraction)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
.frame(height: 4)
|
|
96
|
+
.animation(.easeInOut(duration: 0.2), value: clampedFraction)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/// Renders a looping Lottie animation, optionally recolored via a mask.
|
|
101
|
+
private struct TintedLottie: View {
|
|
102
|
+
let name: String
|
|
103
|
+
let tintColor: Color?
|
|
104
|
+
|
|
105
|
+
var body: some View {
|
|
106
|
+
if let tintColor = tintColor {
|
|
107
|
+
tintColor
|
|
108
|
+
.mask(LottieView(name: name, loopMode: .loop))
|
|
109
|
+
} else {
|
|
110
|
+
LottieView(name: name, loopMode: .loop)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -22,7 +22,7 @@ public struct KeyboardButton: View {
|
|
|
22
22
|
public var body: some View {
|
|
23
23
|
SwiftUI.Button(action: { self.action(key) }) {
|
|
24
24
|
HStack {
|
|
25
|
-
Text(key).font(.system(size: 24, weight: .bold))
|
|
25
|
+
Text(key).font(.system(size: 24, weight: .bold)).ignoreBoldTextSetting()
|
|
26
26
|
}.frame(maxWidth: CGFloat(width), minHeight: height)
|
|
27
27
|
.background(color)
|
|
28
28
|
.foregroundColor(textColor)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//
|
|
2
|
+
// PaginationDot.swift
|
|
3
|
+
// MoMoUIKits
|
|
4
|
+
//
|
|
5
|
+
// Native SwiftUI port of Compose's PaginationDot.
|
|
6
|
+
// An active dot is a 12x4 pill in `activeColor`; inactive dots are 4x4
|
|
7
|
+
// rounded squares in the pressed-background token.
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
import SwiftUI
|
|
11
|
+
|
|
12
|
+
// MARK: - Dot
|
|
13
|
+
|
|
14
|
+
/// A single pagination dot, mirroring Compose's `Dot` composable.
|
|
15
|
+
public struct PaginationDotItem: View {
|
|
16
|
+
@Environment(\.appTheme) private var theme
|
|
17
|
+
|
|
18
|
+
private let active: Bool
|
|
19
|
+
private let activeColor: Color
|
|
20
|
+
|
|
21
|
+
public init(active: Bool = false, activeColor: Color) {
|
|
22
|
+
self.active = active
|
|
23
|
+
self.activeColor = activeColor
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public var body: some View {
|
|
27
|
+
if active {
|
|
28
|
+
RoundedRectangle(cornerRadius: 4)
|
|
29
|
+
.fill(activeColor)
|
|
30
|
+
.frame(width: 12, height: 4)
|
|
31
|
+
} else {
|
|
32
|
+
RoundedRectangle(cornerRadius: 4)
|
|
33
|
+
.fill(theme.colors.background.pressed)
|
|
34
|
+
.frame(width: 4, height: 4)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// MARK: - PaginationDot
|
|
40
|
+
|
|
41
|
+
/// Mirrors Compose's `PaginationDot(activeIndex, dataLength)`.
|
|
42
|
+
public struct PaginationDot: View {
|
|
43
|
+
@Environment(\.appTheme) private var theme
|
|
44
|
+
|
|
45
|
+
private let activeIndex: Int
|
|
46
|
+
private let dataLength: Int
|
|
47
|
+
|
|
48
|
+
public init(activeIndex: Int = 0, dataLength: Int = 3) {
|
|
49
|
+
self.activeIndex = activeIndex
|
|
50
|
+
self.dataLength = dataLength
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public var body: some View {
|
|
54
|
+
HStack(spacing: 0) {
|
|
55
|
+
ForEach(0..<max(dataLength, 0), id: \.self) { i in
|
|
56
|
+
PaginationDotItem(active: i == activeIndex, activeColor: theme.colors.primary)
|
|
57
|
+
.padding(.trailing, i != dataLength - 1 ? Spacing.XS : 0)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//
|
|
2
|
+
// PaginationNumber.swift
|
|
3
|
+
// MoMoUIKits
|
|
4
|
+
//
|
|
5
|
+
// Native SwiftUI port of Compose's PaginationNumber.
|
|
6
|
+
// Renders "current/total" text on a translucent black rounded chip.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import SwiftUI
|
|
10
|
+
|
|
11
|
+
// MARK: - PaginationNumber
|
|
12
|
+
|
|
13
|
+
/// Mirrors Compose's `PaginationNumber(activeIndex, dataLength)`.
|
|
14
|
+
public struct PaginationNumber: View {
|
|
15
|
+
private let activeIndex: Int
|
|
16
|
+
private let dataLength: Int
|
|
17
|
+
|
|
18
|
+
public init(activeIndex: Int = 0, dataLength: Int = 2) {
|
|
19
|
+
self.activeIndex = activeIndex
|
|
20
|
+
self.dataLength = dataLength
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public var body: some View {
|
|
24
|
+
MomoText(
|
|
25
|
+
"\(1 + activeIndex)/\(dataLength)",
|
|
26
|
+
typography: .labelDefaultMedium,
|
|
27
|
+
color: Colors.black01
|
|
28
|
+
)
|
|
29
|
+
.padding(.horizontal, Spacing.S)
|
|
30
|
+
.background(
|
|
31
|
+
RoundedRectangle(cornerRadius: Radius.L)
|
|
32
|
+
.fill(Color.black.opacity(0.2)) // Color(0x33000000)
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
//
|
|
2
|
+
// PaginationScroll.swift
|
|
3
|
+
// MoMoUIKits
|
|
4
|
+
//
|
|
5
|
+
// Native SwiftUI port of Compose's PaginationScroll.
|
|
6
|
+
// Wraps arbitrary horizontally-scrollable content and renders a
|
|
7
|
+
// progress-bar style indicator whose position tracks the scroll offset.
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
import SwiftUI
|
|
11
|
+
|
|
12
|
+
// MARK: - Constants
|
|
13
|
+
|
|
14
|
+
private let INDICATOR_WIDTH: CGFloat = 24
|
|
15
|
+
private let PROGRESS_WIDTH: CGFloat = 72
|
|
16
|
+
|
|
17
|
+
/// Memoized offset calculation, mirroring Compose's `calculateOffset`.
|
|
18
|
+
private func calculateOffset(currentPosition: CGFloat, maxBound: CGFloat) -> CGFloat {
|
|
19
|
+
guard maxBound > 0 else { return 0 }
|
|
20
|
+
return (PROGRESS_WIDTH - INDICATOR_WIDTH) * (currentPosition / maxBound)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// MARK: - PaginationScroll
|
|
24
|
+
|
|
25
|
+
/// Mirrors Compose's `PaginationScroll(modifier, content)`.
|
|
26
|
+
///
|
|
27
|
+
/// The trailing-closure `content` is laid out in a horizontal scroll view and
|
|
28
|
+
/// the indicator below reflects the current scroll progress.
|
|
29
|
+
public struct PaginationScroll<Content: View>: View {
|
|
30
|
+
@Environment(\.appTheme) private var theme
|
|
31
|
+
|
|
32
|
+
private let content: Content
|
|
33
|
+
|
|
34
|
+
@State private var scrollOffset: CGFloat = 0
|
|
35
|
+
@State private var contentWidth: CGFloat = 0
|
|
36
|
+
@State private var viewportWidth: CGFloat = 0
|
|
37
|
+
|
|
38
|
+
public init(@ViewBuilder content: () -> Content) {
|
|
39
|
+
self.content = content()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private var maxBound: CGFloat {
|
|
43
|
+
max(contentWidth - viewportWidth, 0)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private var indicatorOffset: CGFloat {
|
|
47
|
+
calculateOffset(currentPosition: scrollOffset, maxBound: maxBound)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public var body: some View {
|
|
51
|
+
VStack(spacing: 0) {
|
|
52
|
+
ScrollView(.horizontal, showsIndicators: false) {
|
|
53
|
+
HStack(spacing: 0) {
|
|
54
|
+
content
|
|
55
|
+
}
|
|
56
|
+
.background(
|
|
57
|
+
GeometryReader { proxy in
|
|
58
|
+
Color.clear
|
|
59
|
+
.preference(
|
|
60
|
+
key: ScrollOffsetKey.self,
|
|
61
|
+
value: -proxy.frame(in: .named("paginationScroll")).minX
|
|
62
|
+
)
|
|
63
|
+
.onAppear { contentWidth = proxy.size.width }
|
|
64
|
+
.onChange(of: proxy.size.width) { contentWidth = $0 }
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
.coordinateSpace(name: "paginationScroll")
|
|
69
|
+
.background(
|
|
70
|
+
GeometryReader { viewport in
|
|
71
|
+
Color.clear
|
|
72
|
+
.onAppear { viewportWidth = viewport.size.width }
|
|
73
|
+
.onChange(of: viewport.size.width) { viewportWidth = $0 }
|
|
74
|
+
}
|
|
75
|
+
)
|
|
76
|
+
.onPreferenceChange(ScrollOffsetKey.self) { scrollOffset = max($0, 0) }
|
|
77
|
+
.padding(.bottom, Spacing.L)
|
|
78
|
+
|
|
79
|
+
// Progress indicator
|
|
80
|
+
ZStack(alignment: .leading) {
|
|
81
|
+
RoundedRectangle(cornerRadius: Spacing.XS)
|
|
82
|
+
.fill(theme.colors.background.pressed)
|
|
83
|
+
.frame(width: PROGRESS_WIDTH, height: 4)
|
|
84
|
+
|
|
85
|
+
RoundedRectangle(cornerRadius: Spacing.XS)
|
|
86
|
+
.fill(theme.colors.primary)
|
|
87
|
+
.frame(width: INDICATOR_WIDTH, height: 4)
|
|
88
|
+
.offset(x: indicatorOffset)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// MARK: - Preference key
|
|
95
|
+
|
|
96
|
+
private struct ScrollOffsetKey: PreferenceKey {
|
|
97
|
+
static var defaultValue: CGFloat = 0
|
|
98
|
+
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
|
|
99
|
+
value = nextValue()
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//
|
|
2
|
+
// PaginationWhiteDot.swift
|
|
3
|
+
// MoMoUIKits
|
|
4
|
+
//
|
|
5
|
+
// Native SwiftUI port of Compose's PaginationWhiteDot.
|
|
6
|
+
// Same dot layout as PaginationDot, but the active color is white
|
|
7
|
+
// (black_01) and the row sits on a translucent black rounded surface.
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
import SwiftUI
|
|
11
|
+
|
|
12
|
+
// MARK: - PaginationWhiteDot
|
|
13
|
+
|
|
14
|
+
/// Mirrors Compose's `PaginationWhiteDot(activeIndex, dataLength)`.
|
|
15
|
+
public struct PaginationWhiteDot: View {
|
|
16
|
+
private let activeIndex: Int
|
|
17
|
+
private let dataLength: Int
|
|
18
|
+
|
|
19
|
+
public init(activeIndex: Int = 0, dataLength: Int = 3) {
|
|
20
|
+
self.activeIndex = activeIndex
|
|
21
|
+
self.dataLength = dataLength
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public var body: some View {
|
|
25
|
+
HStack(spacing: 0) {
|
|
26
|
+
ForEach(0..<max(dataLength, 0), id: \.self) { i in
|
|
27
|
+
PaginationDotItem(active: i == activeIndex, activeColor: Colors.black01)
|
|
28
|
+
.padding(.trailing, i != dataLength - 1 ? Spacing.XS : 0)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
.padding(Spacing.XS)
|
|
32
|
+
.background(
|
|
33
|
+
RoundedRectangle(cornerRadius: Radius.S)
|
|
34
|
+
.fill(Color.black.opacity(0.2)) // Color(0x33000000)
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -24,6 +24,7 @@ extension View {
|
|
|
24
24
|
VStack(spacing: 0) {
|
|
25
25
|
Text("A")
|
|
26
26
|
.font(font)
|
|
27
|
+
.ignoreBoldTextSetting()
|
|
27
28
|
.lineLimit(1)
|
|
28
29
|
.fixedSize()
|
|
29
30
|
.background(
|
|
@@ -35,6 +36,7 @@ extension View {
|
|
|
35
36
|
|
|
36
37
|
Text("A\nA")
|
|
37
38
|
.font(font)
|
|
39
|
+
.ignoreBoldTextSetting()
|
|
38
40
|
.lineLimit(2)
|
|
39
41
|
.fixedSize(horizontal: false, vertical: true)
|
|
40
42
|
.background(
|
|
@@ -219,15 +221,13 @@ public struct PopupDisplay: View {
|
|
|
219
221
|
var RowTextButtons: some View {
|
|
220
222
|
HStack {
|
|
221
223
|
SwiftUI.Button(action: onPressCloseButton) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}.foregroundColor(Colors.black09)
|
|
224
|
+
MomoText(closeButtonTitle, typography: .actionSBold, color: Colors.black09)
|
|
225
|
+
}
|
|
225
226
|
.padding(.trailing, 12)
|
|
226
227
|
|
|
227
228
|
SwiftUI.Button(action: onPressAction) {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}.foregroundColor(Colors.primary)
|
|
229
|
+
MomoText(actionButtonTitle, typography: .actionSBold, color: Colors.primary)
|
|
230
|
+
}
|
|
231
231
|
}
|
|
232
232
|
.frame(maxWidth: .infinity, alignment: .trailing)
|
|
233
233
|
.padding(EdgeInsets(top: 0, leading: 0, bottom: 24, trailing: 24))
|
|
@@ -236,15 +236,13 @@ public struct PopupDisplay: View {
|
|
|
236
236
|
var ColumnTextButtons: some View {
|
|
237
237
|
VStack(alignment: .trailing) {
|
|
238
238
|
SwiftUI.Button(action: onPressAction) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
}.foregroundColor(Colors.primary)
|
|
239
|
+
MomoText(actionButtonTitle, typography: .actionSBold, color: Colors.primary)
|
|
240
|
+
}
|
|
242
241
|
.padding(.bottom, 6)
|
|
243
242
|
|
|
244
243
|
SwiftUI.Button(action: onPressCloseButton) {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}.foregroundColor(Colors.black09)
|
|
244
|
+
MomoText(closeButtonTitle, typography: .actionSBold, color: Colors.black09)
|
|
245
|
+
}
|
|
248
246
|
}
|
|
249
247
|
.frame(maxWidth: .infinity, alignment: .trailing)
|
|
250
248
|
.padding(EdgeInsets(top: 0, leading: 0, bottom: 24, trailing: 24))
|
|
@@ -35,15 +35,11 @@ public struct PopupInput: View {
|
|
|
35
35
|
|
|
36
36
|
VStack {
|
|
37
37
|
VStack(alignment: .leading) {
|
|
38
|
-
|
|
39
|
-
.foregroundColor(.black)
|
|
40
|
-
.font(.headerText1)
|
|
38
|
+
MomoText(title, typography: .headerDefaultBold, color: .black)
|
|
41
39
|
.padding(.top, 12)
|
|
42
40
|
.padding(.bottom, 24)
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
.foregroundColor(.black)
|
|
46
|
-
.font(.paragraph)
|
|
42
|
+
MomoText(description, typography: .bodyDefaultRegular, color: .black)
|
|
47
43
|
.opacity(0.6)
|
|
48
44
|
.multilineTextAlignment(.leading)
|
|
49
45
|
.padding(.bottom, 20)
|