@momo-kits/native-kits 0.0.1-beta.4 → 0.0.2-alpha.1
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 +99 -0
- package/PUBLISH_GUIDE.md +675 -0
- package/README.md +184 -5
- package/ios/Application/ApplicationEnvironment.swift +71 -0
- package/ios/Application/Components.swift +270 -0
- package/ios/Application/ComposeApi.swift +22 -0
- package/ios/Application/FloatingButton.swift +174 -0
- package/ios/Application/HeaderRight.swift +306 -0
- package/ios/Application/LanguageSource.swift +93 -0
- package/ios/Application/Localize.swift +378 -0
- package/ios/Application/LocalizeModifier.swift +30 -0
- package/ios/Application/MaxApi.swift +18 -0
- package/ios/Application/Navigation/BottomTab/BottomTab.swift +104 -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 +213 -0
- package/ios/Application/Navigation/NavigationOptions.swift +109 -0
- package/ios/Application/Navigation/Navigator.swift +453 -0
- package/ios/Application/Navigation/NavigatorManager.swift +22 -0
- package/ios/Application/Navigation/Overplay/BottomSheet.swift +256 -0
- package/ios/Application/Navigation/Overplay/ModalScreen.swift +74 -0
- package/ios/Application/Navigation/Overplay/SnackBar.swift +144 -0
- package/ios/Application/Navigation/Tracking/ScreenTracker.swift +117 -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/Navigation/component/HeaderRightWidthKey.swift +11 -0
- package/ios/Application/Navigation/component/NavigationFooter.swift +90 -0
- package/ios/Application/Navigation/component/NavigationHeaderRight.swift +196 -0
- package/ios/Application/Screen.swift +250 -0
- package/ios/Application/StackScreen.swift +492 -0
- package/ios/Avatar/Avatar.swift +193 -0
- package/ios/Badge/Badge.swift +84 -0
- package/ios/Badge/BadgeDot.swift +31 -0
- package/ios/Badge/BadgeRibbon.swift +319 -0
- package/ios/BaselineView/BaselineView.swift +163 -0
- package/ios/Button/Button.swift +232 -84
- package/ios/CalculatorKeyboard/CalculatorKeyboard.swift +126 -0
- package/ios/Carousel/Carousel.swift +196 -0
- package/ios/Checkbox/Checkbox.swift +77 -0
- package/ios/Chip/Chip.swift +120 -0
- package/ios/Collapse/Collapse.swift +192 -0
- package/ios/{Colors+Spacing → Colors+Radius+Spacing}/Colors.swift +42 -37
- package/ios/Colors+Radius+Spacing/Radius.swift +22 -0
- package/ios/{Colors+Spacing → Colors+Radius+Spacing}/Spacing.swift +3 -1
- package/ios/Colors+Radius+Spacing/Theme.swift +295 -0
- package/ios/DateTimePicker/DateTimePicker.swift +212 -0
- package/ios/DateTimePicker/DateTimePickerTypes.swift +55 -0
- package/ios/DateTimePicker/DateTimePickerUtils.swift +167 -0
- package/ios/DateTimePicker/WheelPicker.swift +165 -0
- package/ios/Divider/Divider.swift +16 -0
- package/ios/Extensions/ActiveOpacityButtonStyle.swift +14 -0
- package/ios/Extensions/Color++.swift +32 -0
- package/ios/Icon/Icon.swift +69 -0
- package/ios/IconButton/IconButton.swift +140 -0
- package/ios/Image/Image.swift +87 -0
- package/ios/Information/Information.swift +156 -0
- package/ios/Input/ErrorView.swift +58 -0
- package/ios/Input/Input.swift +461 -77
- package/ios/Input/InputPhoneNumber.swift +192 -0
- package/ios/Input/InputSearch.swift +301 -0
- package/ios/Input/InputTextArea.swift +318 -0
- package/ios/InputDropDown/InputDropDown.swift +201 -0
- package/ios/InputMoney/InputMoney.swift +405 -0
- package/ios/InputOTP/InputOTP.swift +211 -0
- package/ios/Layout/GridContext.swift +30 -0
- package/ios/Layout/Item.swift +42 -0
- package/ios/Layout/Section.swift +134 -0
- package/ios/Loader/Loader.swift +113 -0
- package/ios/Lottie/LottieView.swift +86 -0
- package/ios/MoMoUIKits.podspec +5 -0
- package/ios/OTPKeyboard/KeyboardButton.swift +13 -5
- package/ios/OTPKeyboard/OTPKeyboard.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 +279 -0
- package/ios/Popup/PopupInput.swift +92 -0
- package/ios/Popup/PopupNotify.swift +219 -0
- package/ios/Popup/PopupPromotion.swift +74 -0
- package/ios/PopupView/FullscreenPopup.swift +251 -0
- package/ios/{Popup → PopupView}/Modifiers.swift +6 -20
- package/ios/{Popup → PopupView}/PopupView.swift +38 -146
- package/ios/PopupView/Utils++.swift +281 -0
- package/ios/ProgressInfo/ProgressInfo.swift +297 -0
- package/ios/Radio/Radio.swift +69 -0
- package/ios/Rating/Rating.swift +83 -0
- package/{example/ios/Example/Preview Content/Preview Assets.xcassets/Contents.json → ios/Resources/MoMoUIKitsColors.xcassets/AccentColor.colorset/Contents.json} +5 -0
- package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Text.colorset/Contents.json +3 -3
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/Contents.json +9 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-default.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-disable.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-pressed.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-selected.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-surface.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-tonal.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-default.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-disable.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/gradient.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/primary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/secondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-container.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-primary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-secondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-default.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-disable.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-hint.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-secondary.colorset/Contents.json +38 -0
- package/ios/ScrollIndicator/ScrollIndicator.swift +110 -0
- package/ios/Skeleton/Skeleton.swift +99 -0
- package/ios/Slider/Slider.swift +237 -0
- package/ios/StatusBarTap/StatusBarTap.h +13 -0
- package/ios/StatusBarTap/StatusBarTap.m +75 -0
- package/ios/Stepper/Stepper.swift +221 -0
- package/ios/Steps/Steps.swift +467 -0
- package/ios/SuggestAction/SuggestAction.swift +100 -0
- package/ios/Swipeable/SwipeCell.swift +226 -31
- package/ios/Swipeable/SwipeCellModel.swift +21 -0
- package/ios/Switch/Switch.swift +69 -0
- package/ios/TabView/TabView.swift +534 -0
- package/ios/Tag/Tag.swift +99 -0
- package/ios/Template/Logo/Logo.swift +75 -0
- package/ios/Template/TrustBanner/TrustBanner.swift +123 -0
- package/ios/Title/Title.swift +270 -0
- package/ios/Tooltip/Tooltip.swift +486 -0
- package/ios/Typography/FontScale.swift +103 -0
- package/ios/Typography/FontScaleStore.swift +58 -0
- package/ios/Typography/KitDesignSystem.swift +17 -0
- package/ios/Typography/Text.swift +262 -0
- package/ios/Typography/Typography.swift +80 -23
- package/ios/Uploader/Uploader.swift +174 -0
- package/ios/native-kits.podspec +73 -13
- package/ios-demo/MoMoUIKitsDemo.podspec +20 -0
- package/ios-demo/Resources/dot_loading.json +558 -0
- package/ios-demo/Resources/icon.json +4052 -0
- package/ios-demo/Resources/lottie_circle_loader.json +1 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/DemoScaffold.swift +48 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsBadgeDemoView.swift +25 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsButtonDemoView.swift +26 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsCheckboxDemoView.swift +19 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsChipDemoView.swift +33 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsInputDemoView.swift +48 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsPopupDemoView.swift +21 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsRadioDemoView.swift +17 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsTypographyDemoView.swift +28 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoContext.swift +31 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoFactory.swift +24 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AnimatedHeaderDemo.swift +110 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AvatarDemo.swift +107 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BadgeDemo.swift +75 -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 +108 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CarouselDemo.swift +96 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CheckboxDemo.swift +60 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ChipDemo.swift +76 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CollapseDemo.swift +102 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +107 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DateTimePickerDemo.swift +100 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DemoScreen.swift +420 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DividerDemo.swift +56 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/HeaderUserDemo.swift +49 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +276 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconButtonDemo.swift +93 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconDemo.swift +81 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ImageDemo.swift +65 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InformationDemo.swift +96 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDemo.swift +117 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDropDownDemo.swift +94 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputMoneyDemo.swift +94 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputOTPDemo.swift +88 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputPhoneNumberDemo.swift +120 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputSearchDemo.swift +85 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputTextAreaDemo.swift +87 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LoaderDemo.swift +73 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LocalizeDemo.swift +235 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +241 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PaginationDemo.swift +68 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PlaygroundData.swift +76 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +175 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +95 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +67 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ProgressInfoDemo.swift +101 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RadioDemo.swift +64 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RatingDemo.swift +68 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SectionDemo.swift +83 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SkeletonDemo.swift +61 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SliderDemo.swift +90 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SnackBarDemo.swift +82 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepperDemo.swift +93 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepsDemo.swift +114 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SuggestActionDemo.swift +90 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwipeDemo.swift +107 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwitchDemo.swift +58 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TabViewDemo.swift +114 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TagDemo.swift +86 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ThemeDemo.swift +181 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TitleDemo.swift +104 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TooltipDemo.swift +118 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TypographyDemo.swift +87 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/UploaderDemo.swift +85 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SwiftUIDemoBrowserView.swift +53 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoModels.swift +15 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoRegistry.swift +73 -0
- package/package.json +6 -6
- package/publish.sh +554 -20
- package/scripts/gen-ios-color.mjs +136 -0
- package/CODE_OF_CONDUCT.md +0 -133
- package/CONTRIBUTING.md +0 -114
- package/LICENSE +0 -20
- package/android/build.gradle +0 -82
- package/android/gradle.properties +0 -5
- package/android/src/main/AndroidManifest.xml +0 -4
- package/android/src/main/java/com/momoplatform/nativekits/NativeKitsPackage.kt +0 -17
- package/android/src/main/java/com/momoplatform/nativekits/NativeKitsViewManager.kt +0 -20
- package/example/ios/Example/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -63
- package/example/ios/Example/ComponentDetail.swift +0 -35
- package/example/ios/Example/ComponentItem.swift +0 -24
- package/example/ios/Example/ComponentModel.swift +0 -33
- package/example/ios/Example/ContentView.swift +0 -53
- package/example/ios/Example/Example.entitlements +0 -10
- package/example/ios/Example/Foundation/ButtonDemo.swift +0 -80
- package/example/ios/Example/Foundation/Popup/ActionSheets.swift +0 -136
- package/example/ios/Example/Foundation/Popup/Floats.swift +0 -127
- package/example/ios/Example/Foundation/Popup/Popups.swift +0 -101
- package/example/ios/Example/Foundation/PopupDemo.swift +0 -366
- package/example/ios/Example/Foundation/TextInputDemo.swift +0 -31
- package/example/ios/Example/Foundation/TypographyDemo.swift +0 -53
- package/example/ios/Example/Foundation.swift +0 -26
- package/example/ios/Example/Info.plist +0 -18
- package/example/ios/Example/Library/SwipeableDemo.swift +0 -105
- package/example/ios/Example/Library.swift +0 -26
- package/example/ios/Example/Main.swift +0 -11
- package/example/ios/Example/Overview.swift +0 -20
- package/example/ios/Example/Resource/SFProText-Black.ttf +0 -0
- package/example/ios/Example/Resource/SFProText-Bold.ttf +0 -0
- package/example/ios/Example/Resource/SFProText-Heavy.ttf +0 -0
- package/example/ios/Example/Resource/SFProText-Light.ttf +0 -0
- package/example/ios/Example/Resource/SFProText-Medium.ttf +0 -0
- package/example/ios/Example/Resource/SFProText-Regular.ttf +0 -0
- package/example/ios/Example/Resource/SFProText-Semibold.ttf +0 -0
- package/example/ios/Example/Resource/SFProText-Thin.ttf +0 -0
- package/example/ios/Example/Resource/SFProText-Ultralight.ttf +0 -0
- package/example/ios/Example/Resource/foundation.json +0 -33
- package/example/ios/Example/Resource/library.json +0 -8
- package/example/ios/Example/Utils.swift +0 -30
- package/example/ios/Example/ViewModifier/DarkViewModifier.swift +0 -22
- package/example/ios/Example.xcodeproj/project.pbxproj +0 -570
- package/example/ios/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/example/ios/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- package/example/ios/Example.xcodeproj/project.xcworkspace/xcuserdata/wem.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/example/ios/Example.xcodeproj/xcuserdata/wem.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
- package/example/ios/Example.xcworkspace/contents.xcworkspacedata +0 -10
- package/example/ios/Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- package/example/ios/Example.xcworkspace/xcuserdata/wem.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/example/ios/Example.xcworkspace/xcuserdata/wem.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +0 -6
- package/example/ios/Podfile +0 -6
- package/example/ios/Podfile.lock +0 -16
- package/example/ios/Pods/Local Podspecs/MoMoUIKits.podspec.json +0 -29
- package/example/ios/Pods/Manifest.lock +0 -16
- package/example/ios/Pods/Pods.xcodeproj/project.pbxproj +0 -661
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/wem.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/wem.xcuserdatad/xcschemes/Pods-Example.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/wem.xcuserdatad/xcschemes/xcschememanagement.plist +0 -25
- package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits-dummy.m +0 -5
- package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits-prefix.pch +0 -12
- package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits-umbrella.h +0 -16
- package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits.debug.xcconfig +0 -12
- package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits.modulemap +0 -6
- package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits.release.xcconfig +0 -12
- package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example-acknowledgements.markdown +0 -3
- package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example-acknowledgements.plist +0 -29
- package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example-dummy.m +0 -5
- package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example-umbrella.h +0 -16
- package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example.debug.xcconfig +0 -14
- package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example.modulemap +0 -6
- package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example.release.xcconfig +0 -14
- package/ios/Colors+Spacing/Radius.swift +0 -11
- package/ios/Popup/Utils++.swift +0 -163
- package/ios/Theme.md +0 -18
- /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Background.colorset/Contents.json +0 -0
- /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Border.colorset/Contents.json +0 -0
- /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Card.colorset/Contents.json +0 -0
- /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Contents.json +0 -0
- /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Error.colorset/Contents.json +0 -0
- /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Primary.colorset/Contents.json +0 -0
- /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/PrimaryDark.colorset/Contents.json +0 -0
- /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/PrimaryLight.colorset/Contents.json +0 -0
- /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Secondary.colorset/Contents.json +0 -0
- /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Success.colorset/Contents.json +0 -0
- /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/TextSecondary.colorset/Contents.json +0 -0
- /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Warning.colorset/Contents.json +0 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import SwiftUI
|
|
2
|
+
import Foundation
|
|
3
|
+
|
|
4
|
+
public struct SuggestAction: View {
|
|
5
|
+
@Environment(\.appTheme) private var theme
|
|
6
|
+
@Environment(\.momoFontScale) private var fontScale
|
|
7
|
+
|
|
8
|
+
private let message: String
|
|
9
|
+
private let buttonTitle: String
|
|
10
|
+
private let boldMessage: String
|
|
11
|
+
private let image: String
|
|
12
|
+
private let visible: Bool
|
|
13
|
+
private let onClose: () -> Void
|
|
14
|
+
private let onPressButton: () -> Void
|
|
15
|
+
|
|
16
|
+
public init(
|
|
17
|
+
message: String,
|
|
18
|
+
buttonTitle: String,
|
|
19
|
+
boldMessage: String = "",
|
|
20
|
+
image: String = "",
|
|
21
|
+
visible: Bool = false,
|
|
22
|
+
onClose: @escaping () -> Void = {},
|
|
23
|
+
onPressButton: @escaping () -> Void = {}
|
|
24
|
+
) {
|
|
25
|
+
self.message = message
|
|
26
|
+
self.buttonTitle = buttonTitle
|
|
27
|
+
self.boldMessage = boldMessage
|
|
28
|
+
self.image = image
|
|
29
|
+
self.visible = visible
|
|
30
|
+
self.onClose = onClose
|
|
31
|
+
self.onPressButton = onPressButton
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Builds an attributed string with `boldMessage` (case-insensitive) emphasized.
|
|
35
|
+
private var annotatedMessage: AttributedString {
|
|
36
|
+
let baseFont = Font.system(size: fontScale(TypographyStyle.bodyDefaultRegular.fontSize), weight: .regular)
|
|
37
|
+
var attributed = AttributedString(message)
|
|
38
|
+
attributed.font = baseFont
|
|
39
|
+
|
|
40
|
+
guard !boldMessage.isEmpty,
|
|
41
|
+
let range = message.range(of: boldMessage, options: .caseInsensitive)
|
|
42
|
+
else {
|
|
43
|
+
return attributed
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if let boldRange = Range(range, in: attributed) {
|
|
47
|
+
attributed[boldRange].font = Font.system(
|
|
48
|
+
size: fontScale(TypographyStyle.bodyDefaultRegular.fontSize),
|
|
49
|
+
weight: .bold
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
return attributed
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public var body: some View {
|
|
56
|
+
Group {
|
|
57
|
+
if visible {
|
|
58
|
+
HStack(spacing: 0) {
|
|
59
|
+
if !image.isEmpty {
|
|
60
|
+
ImageView(image)
|
|
61
|
+
.frame(width: 32, height: 32)
|
|
62
|
+
.clipShape(RoundedRectangle(cornerRadius: Radius.XS, style: .continuous))
|
|
63
|
+
Spacer().frame(width: Spacing.S)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
Text(annotatedMessage)
|
|
67
|
+
.foregroundColor(theme.colors.text.default)
|
|
68
|
+
.frame(maxWidth: .infinity, alignment: .leading)
|
|
69
|
+
.padding(.trailing, Spacing.M)
|
|
70
|
+
|
|
71
|
+
Button(
|
|
72
|
+
title: buttonTitle,
|
|
73
|
+
action: { onPressButton() },
|
|
74
|
+
type: .tonal,
|
|
75
|
+
size: .small,
|
|
76
|
+
isFull: false
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
Spacer().frame(width: Spacing.S)
|
|
80
|
+
|
|
81
|
+
SwiftUI.Button(action: onClose) {
|
|
82
|
+
Icon(source: "navigation_close", size: 24, color: theme.colors.text.default)
|
|
83
|
+
.contentShape(Rectangle())
|
|
84
|
+
}
|
|
85
|
+
.buttonStyle(ActiveOpacityButtonStyle())
|
|
86
|
+
}
|
|
87
|
+
.padding(Spacing.M)
|
|
88
|
+
.frame(maxWidth: .infinity)
|
|
89
|
+
.background(
|
|
90
|
+
RoundedRectangle(cornerRadius: Radius.S, style: .continuous)
|
|
91
|
+
.fill(theme.colors.background.surface)
|
|
92
|
+
)
|
|
93
|
+
.clipShape(RoundedRectangle(cornerRadius: Radius.S, style: .continuous))
|
|
94
|
+
.shadow(color: theme.colors.text.default.opacity(0.12), radius: 8, x: 0, y: 4)
|
|
95
|
+
.transition(.opacity)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
.animation(.easeInOut, value: visible)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -1,6 +1,193 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import SwiftUI
|
|
3
3
|
|
|
4
|
+
private let swipeActionWidth: CGFloat = 56
|
|
5
|
+
|
|
6
|
+
// MARK: - Swipe
|
|
7
|
+
|
|
8
|
+
public struct Swipe<Content: View>: View {
|
|
9
|
+
@Environment(\.appTheme) private var theme
|
|
10
|
+
|
|
11
|
+
private let leftActions: [SwipeAction]
|
|
12
|
+
private let rightActions: [SwipeAction]
|
|
13
|
+
private let height: CGFloat
|
|
14
|
+
private let itemRadius: CGFloat
|
|
15
|
+
private let onSwipeableOpen: () -> Void
|
|
16
|
+
private let onSwipeableClose: () -> Void
|
|
17
|
+
private let onSwipeableLeftOpen: () -> Void
|
|
18
|
+
private let onSwipeableRightOpen: () -> Void
|
|
19
|
+
private let content: () -> Content
|
|
20
|
+
|
|
21
|
+
@State private var offsetX: CGFloat = 0
|
|
22
|
+
@State private var dragStartOffsetX: CGFloat?
|
|
23
|
+
|
|
24
|
+
public init(
|
|
25
|
+
leftActions: [SwipeAction] = [],
|
|
26
|
+
rightActions: [SwipeAction] = [],
|
|
27
|
+
height: CGFloat = 56,
|
|
28
|
+
itemRadius: CGFloat = 0,
|
|
29
|
+
onSwipeableOpen: @escaping () -> Void = {},
|
|
30
|
+
onSwipeableClose: @escaping () -> Void = {},
|
|
31
|
+
onSwipeableLeftOpen: @escaping () -> Void = {},
|
|
32
|
+
onSwipeableRightOpen: @escaping () -> Void = {},
|
|
33
|
+
@ViewBuilder content: @escaping () -> Content
|
|
34
|
+
) {
|
|
35
|
+
self.leftActions = Array(leftActions.prefix(3))
|
|
36
|
+
self.rightActions = Array(rightActions.prefix(3))
|
|
37
|
+
self.height = height
|
|
38
|
+
self.itemRadius = itemRadius
|
|
39
|
+
self.onSwipeableOpen = onSwipeableOpen
|
|
40
|
+
self.onSwipeableClose = onSwipeableClose
|
|
41
|
+
self.onSwipeableLeftOpen = onSwipeableLeftOpen
|
|
42
|
+
self.onSwipeableRightOpen = onSwipeableRightOpen
|
|
43
|
+
self.content = content
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public var body: some View {
|
|
47
|
+
let leftWidth = swipeActionWidth * CGFloat(leftActions.count)
|
|
48
|
+
let rightWidth = swipeActionWidth * CGFloat(rightActions.count)
|
|
49
|
+
let shape = RoundedRectangle(cornerRadius: itemRadius)
|
|
50
|
+
|
|
51
|
+
ZStack {
|
|
52
|
+
if !leftActions.isEmpty {
|
|
53
|
+
HStack(spacing: 0) {
|
|
54
|
+
ForEach(Array(leftActions.enumerated()), id: \.offset) { _, action in
|
|
55
|
+
SwipeActionButton(
|
|
56
|
+
action: action,
|
|
57
|
+
height: height,
|
|
58
|
+
itemRadius: itemRadius,
|
|
59
|
+
defaultBackgroundColor: theme.colors.primary
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
Spacer(minLength: 0)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if !rightActions.isEmpty {
|
|
67
|
+
HStack(spacing: 0) {
|
|
68
|
+
Spacer(minLength: 0)
|
|
69
|
+
ForEach(Array(rightActions.enumerated()), id: \.offset) { _, action in
|
|
70
|
+
SwipeActionButton(
|
|
71
|
+
action: action,
|
|
72
|
+
height: height,
|
|
73
|
+
itemRadius: itemRadius,
|
|
74
|
+
defaultBackgroundColor: theme.colors.error.primary
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
ZStack {
|
|
81
|
+
theme.colors.background.surface
|
|
82
|
+
content()
|
|
83
|
+
}
|
|
84
|
+
.frame(maxWidth: .infinity)
|
|
85
|
+
.frame(height: height)
|
|
86
|
+
.clipShape(shape)
|
|
87
|
+
.offset(x: offsetX)
|
|
88
|
+
.gesture(
|
|
89
|
+
DragGesture(minimumDistance: 8, coordinateSpace: .local)
|
|
90
|
+
.onChanged { value in
|
|
91
|
+
dragOnChanged(value: value, leftWidth: leftWidth, rightWidth: rightWidth)
|
|
92
|
+
}
|
|
93
|
+
.onEnded { _ in
|
|
94
|
+
dragStartOffsetX = nil
|
|
95
|
+
snapToClosest(leftWidth: leftWidth, rightWidth: rightWidth)
|
|
96
|
+
}
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
.frame(maxWidth: .infinity)
|
|
100
|
+
.frame(height: height)
|
|
101
|
+
.clipped()
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private func dragOnChanged(value: DragGesture.Value, leftWidth: CGFloat, rightWidth: CGFloat) {
|
|
105
|
+
if dragStartOffsetX == nil {
|
|
106
|
+
dragStartOffsetX = offsetX
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
let proposedOffset = (dragStartOffsetX ?? 0) + value.translation.width
|
|
110
|
+
offsetX = min(max(proposedOffset, -rightWidth), leftWidth)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private func snapToClosest(leftWidth: CGFloat, rightWidth: CGFloat) {
|
|
114
|
+
let target: CGFloat
|
|
115
|
+
|
|
116
|
+
if offsetX > leftWidth * 0.5, !leftActions.isEmpty {
|
|
117
|
+
onSwipeableLeftOpen()
|
|
118
|
+
onSwipeableOpen()
|
|
119
|
+
target = leftWidth
|
|
120
|
+
} else if offsetX < -rightWidth * 0.5, !rightActions.isEmpty {
|
|
121
|
+
onSwipeableRightOpen()
|
|
122
|
+
onSwipeableOpen()
|
|
123
|
+
target = -rightWidth
|
|
124
|
+
} else {
|
|
125
|
+
onSwipeableClose()
|
|
126
|
+
target = 0
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
withAnimation(.easeOut(duration: 0.2)) {
|
|
130
|
+
offsetX = target
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
public extension Swipe where Content == EmptyView {
|
|
136
|
+
init(
|
|
137
|
+
leftActions: [SwipeAction] = [],
|
|
138
|
+
rightActions: [SwipeAction] = [],
|
|
139
|
+
height: CGFloat = 56,
|
|
140
|
+
itemRadius: CGFloat = 0,
|
|
141
|
+
onSwipeableOpen: @escaping () -> Void = {},
|
|
142
|
+
onSwipeableClose: @escaping () -> Void = {},
|
|
143
|
+
onSwipeableLeftOpen: @escaping () -> Void = {},
|
|
144
|
+
onSwipeableRightOpen: @escaping () -> Void = {}
|
|
145
|
+
) {
|
|
146
|
+
self.init(
|
|
147
|
+
leftActions: leftActions,
|
|
148
|
+
rightActions: rightActions,
|
|
149
|
+
height: height,
|
|
150
|
+
itemRadius: itemRadius,
|
|
151
|
+
onSwipeableOpen: onSwipeableOpen,
|
|
152
|
+
onSwipeableClose: onSwipeableClose,
|
|
153
|
+
onSwipeableLeftOpen: onSwipeableLeftOpen,
|
|
154
|
+
onSwipeableRightOpen: onSwipeableRightOpen
|
|
155
|
+
) {
|
|
156
|
+
EmptyView()
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private struct SwipeActionButton: View {
|
|
162
|
+
let action: SwipeAction
|
|
163
|
+
let height: CGFloat
|
|
164
|
+
let itemRadius: CGFloat
|
|
165
|
+
let defaultBackgroundColor: Color
|
|
166
|
+
|
|
167
|
+
var body: some View {
|
|
168
|
+
SwiftUI.Button(action: action.onPress) {
|
|
169
|
+
VStack(spacing: Spacing.XXS) {
|
|
170
|
+
if !action.icon.isEmpty {
|
|
171
|
+
Icon(source: action.icon, size: 20, color: Colors.black01)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if !action.label.isEmpty {
|
|
175
|
+
MomoText(
|
|
176
|
+
action.label,
|
|
177
|
+
typography: .labelSMedium,
|
|
178
|
+
color: Colors.black01,
|
|
179
|
+
maxLines: 1
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
.frame(width: swipeActionWidth, height: height)
|
|
184
|
+
.background(action.backgroundColor ?? defaultBackgroundColor)
|
|
185
|
+
.clipShape(RoundedRectangle(cornerRadius: itemRadius))
|
|
186
|
+
}
|
|
187
|
+
.buttonStyle(.plain)
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
4
191
|
// MARK: - SwipeCellModifier
|
|
5
192
|
|
|
6
193
|
public struct SwipeCellModifier: ViewModifier {
|
|
@@ -10,9 +197,9 @@ public struct SwipeCellModifier: ViewModifier {
|
|
|
10
197
|
var trailingSideGroup: [SwipeCellActionItem] = []
|
|
11
198
|
@Binding var currentUserInteractionCellID: String?
|
|
12
199
|
var settings: SwipeCellSettings = .init()
|
|
13
|
-
|
|
200
|
+
|
|
14
201
|
@State private var offsetX: CGFloat = 0
|
|
15
|
-
|
|
202
|
+
|
|
16
203
|
let generator = UINotificationFeedbackGenerator()
|
|
17
204
|
@State private var hapticFeedbackOccurred: Bool = false
|
|
18
205
|
@State private var openSideLock: SwipeGroupSide?
|
|
@@ -22,15 +209,23 @@ public struct SwipeCellModifier: ViewModifier {
|
|
|
22
209
|
if self.leadingSideGroup.isEmpty == false && self.offsetX != 0 {
|
|
23
210
|
self.swipeToRevealArea(swipeItemGroup: self.leadingSideGroup, side: .leading)
|
|
24
211
|
}
|
|
25
|
-
|
|
212
|
+
|
|
26
213
|
if self.trailingSideGroup.isEmpty == false && self.offsetX != 0 {
|
|
27
214
|
self.swipeToRevealArea(swipeItemGroup: self.trailingSideGroup, side: .trailing)
|
|
28
215
|
}
|
|
29
|
-
|
|
216
|
+
|
|
30
217
|
content
|
|
31
218
|
.offset(x: self.offsetX)
|
|
32
|
-
.
|
|
33
|
-
|
|
219
|
+
.simultaneousGesture(
|
|
220
|
+
DragGesture(minimumDistance: 30, coordinateSpace: .local)
|
|
221
|
+
.onChanged { value in
|
|
222
|
+
self.dragOnChanged(value: value)
|
|
223
|
+
}
|
|
224
|
+
.onEnded { value in
|
|
225
|
+
self.dragOnEnded(value: value)
|
|
226
|
+
}
|
|
227
|
+
)
|
|
228
|
+
|
|
34
229
|
}.frame(width: cellWidth)
|
|
35
230
|
.edgesIgnoringSafeArea(.horizontal)
|
|
36
231
|
.clipped()
|
|
@@ -43,7 +238,7 @@ public struct SwipeCellModifier: ViewModifier {
|
|
|
43
238
|
}
|
|
44
239
|
}
|
|
45
240
|
}
|
|
46
|
-
|
|
241
|
+
|
|
47
242
|
internal func swipeToRevealArea(swipeItemGroup: [SwipeCellActionItem], side: SwipeGroupSide)->some View {
|
|
48
243
|
HStack {
|
|
49
244
|
if side == .trailing {
|
|
@@ -63,17 +258,17 @@ public struct SwipeCellModifier: ViewModifier {
|
|
|
63
258
|
}
|
|
64
259
|
}
|
|
65
260
|
}.opacity(self.swipeRevealAreaOpacity(side: side))
|
|
66
|
-
|
|
261
|
+
|
|
67
262
|
if side == .leading {
|
|
68
263
|
Spacer()
|
|
69
264
|
}
|
|
70
265
|
}
|
|
71
266
|
}
|
|
72
|
-
|
|
267
|
+
|
|
73
268
|
internal func buttonContentView(item: SwipeCellActionItem, group: [SwipeCellActionItem], side: SwipeGroupSide)->some View {
|
|
74
269
|
ZStack {
|
|
75
270
|
item.backgroundColor
|
|
76
|
-
|
|
271
|
+
|
|
77
272
|
HStack {
|
|
78
273
|
if self.warnSwipeOutCondition(side: side, hasSwipeOut: item.swipeOutAction) && item.swipeOutButtonView != nil {
|
|
79
274
|
item.swipeOutButtonView!()
|
|
@@ -81,28 +276,28 @@ public struct SwipeCellModifier: ViewModifier {
|
|
|
81
276
|
item.buttonView()
|
|
82
277
|
}
|
|
83
278
|
}
|
|
84
|
-
|
|
279
|
+
|
|
85
280
|
}.frame(width: self.itemButtonWidth(item: item, itemGroup: group, side: side))
|
|
86
281
|
}
|
|
87
|
-
|
|
282
|
+
|
|
88
283
|
internal func menuWidth(side: SwipeGroupSide)->CGFloat {
|
|
89
284
|
switch side {
|
|
90
285
|
case .leading:
|
|
91
286
|
return self.leadingSideGroup.map { $0.buttonWidth }.reduce(0, +)
|
|
92
|
-
|
|
287
|
+
|
|
93
288
|
case .trailing:
|
|
94
289
|
return self.trailingSideGroup.map { $0.buttonWidth }.reduce(0, +)
|
|
95
290
|
}
|
|
96
291
|
}
|
|
97
|
-
|
|
292
|
+
|
|
98
293
|
// MARK: drag gesture
|
|
99
|
-
|
|
294
|
+
|
|
100
295
|
internal func dragOnChanged(value: DragGesture.Value) {
|
|
101
296
|
let horizontalTranslation = value.translation.width
|
|
102
297
|
if self.nonDraggableCondition(horizontalTranslation: horizontalTranslation) {
|
|
103
298
|
return
|
|
104
299
|
}
|
|
105
|
-
|
|
300
|
+
|
|
106
301
|
if self.openSideLock != nil {
|
|
107
302
|
// if one side is open, we need to add the menu width!
|
|
108
303
|
let menuWidth = self.openSideLock == .leading ? self.menuWidth(side: .leading) : self.menuWidth(side: .trailing)
|
|
@@ -110,9 +305,9 @@ public struct SwipeCellModifier: ViewModifier {
|
|
|
110
305
|
self.triggerHapticFeedbackIfNeeded(horizontalTranslation: horizontalTranslation)
|
|
111
306
|
return
|
|
112
307
|
}
|
|
113
|
-
|
|
308
|
+
|
|
114
309
|
self.triggerHapticFeedbackIfNeeded(horizontalTranslation: horizontalTranslation)
|
|
115
|
-
|
|
310
|
+
|
|
116
311
|
if horizontalTranslation > 8 || horizontalTranslation < -8 { // makes sure the swipe cell doesn't open too easily
|
|
117
312
|
self.currentUserInteractionCellID = self.id
|
|
118
313
|
self.offsetX = horizontalTranslation
|
|
@@ -120,11 +315,11 @@ public struct SwipeCellModifier: ViewModifier {
|
|
|
120
315
|
self.offsetX = 0
|
|
121
316
|
}
|
|
122
317
|
}
|
|
123
|
-
|
|
318
|
+
|
|
124
319
|
internal func nonDraggableCondition(horizontalTranslation: CGFloat)->Bool {
|
|
125
320
|
return self.offsetX == 0 && (self.leadingSideGroup.isEmpty && horizontalTranslation > 0 || self.trailingSideGroup.isEmpty && horizontalTranslation < 0)
|
|
126
321
|
}
|
|
127
|
-
|
|
322
|
+
|
|
128
323
|
internal func dragOnEnded(value: DragGesture.Value) {
|
|
129
324
|
let swipeOutTriggerValue = self.cellWidth * self.settings.swipeOutTriggerRatio
|
|
130
325
|
|
|
@@ -139,7 +334,7 @@ public struct SwipeCellModifier: ViewModifier {
|
|
|
139
334
|
} else {
|
|
140
335
|
self.lockSideMenu(side: .leading)
|
|
141
336
|
}
|
|
142
|
-
|
|
337
|
+
|
|
143
338
|
} else {
|
|
144
339
|
// leading group emtpy
|
|
145
340
|
self.setOffsetX(value: 0)
|
|
@@ -160,7 +355,7 @@ public struct SwipeCellModifier: ViewModifier {
|
|
|
160
355
|
}
|
|
161
356
|
}
|
|
162
357
|
}
|
|
163
|
-
|
|
358
|
+
|
|
164
359
|
internal func triggerHapticFeedbackIfNeeded(horizontalTranslation: CGFloat) {
|
|
165
360
|
let side: SwipeGroupSide = horizontalTranslation > 0 ? .leading : .trailing
|
|
166
361
|
let group = side == .leading ? self.leadingSideGroup : self.trailingSideGroup
|
|
@@ -170,7 +365,7 @@ public struct SwipeCellModifier: ViewModifier {
|
|
|
170
365
|
self.hapticFeedbackOccurred = true
|
|
171
366
|
}
|
|
172
367
|
}
|
|
173
|
-
|
|
368
|
+
|
|
174
369
|
internal func swipeOutItemWithHapticFeedback(group: [SwipeCellActionItem])->SwipeCellActionItem? {
|
|
175
370
|
if let item = group.filter({ $0.swipeOutAction == true }).first {
|
|
176
371
|
if item.swipeOutHapticFeedbackType != nil {
|
|
@@ -179,7 +374,7 @@ public struct SwipeCellModifier: ViewModifier {
|
|
|
179
374
|
}
|
|
180
375
|
return nil
|
|
181
376
|
}
|
|
182
|
-
|
|
377
|
+
|
|
183
378
|
internal func swipeOutAction(item: SwipeCellActionItem, sideFactor: CGFloat) {
|
|
184
379
|
if item.swipeOutIsDestructive {
|
|
185
380
|
let swipeOutWidth = cellWidth + 10
|
|
@@ -188,12 +383,12 @@ public struct SwipeCellModifier: ViewModifier {
|
|
|
188
383
|
} else {
|
|
189
384
|
self.setOffsetX(value: 0) // open side lock set in function!
|
|
190
385
|
}
|
|
191
|
-
|
|
386
|
+
|
|
192
387
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
|
193
388
|
item.actionCallback()
|
|
194
389
|
}
|
|
195
390
|
}
|
|
196
|
-
|
|
391
|
+
|
|
197
392
|
internal func lockSideMenu(side: SwipeGroupSide) {
|
|
198
393
|
self.setOffsetX(value: side.sideFactor * self.menuWidth(side: side))
|
|
199
394
|
self.openSideLock = side
|
|
@@ -214,7 +409,7 @@ public struct SwipeCellModifier: ViewModifier {
|
|
|
214
409
|
let dynamicButtonWidth = self.dynamicButtonWidth(item: item, itemCount: itemGroup.count, side: side)
|
|
215
410
|
let triggerValue = self.cellWidth * settings.swipeOutTriggerRatio
|
|
216
411
|
let swipeOutActionCondition = side == .leading ? self.offsetX > triggerValue : self.offsetX < -triggerValue
|
|
217
|
-
|
|
412
|
+
|
|
218
413
|
if item.swipeOutAction && swipeOutActionCondition {
|
|
219
414
|
return self.offsetX.magnitude + settings.addWidthMargin
|
|
220
415
|
} else if swipeOutActionCondition && item.swipeOutAction == false && itemGroup.contains(where: { $0.swipeOutAction == true }) {
|
|
@@ -223,12 +418,12 @@ public struct SwipeCellModifier: ViewModifier {
|
|
|
223
418
|
return dynamicButtonWidth
|
|
224
419
|
}
|
|
225
420
|
}
|
|
226
|
-
|
|
421
|
+
|
|
227
422
|
internal func dynamicButtonWidth(item: SwipeCellActionItem, itemCount: Int, side: SwipeGroupSide)->CGFloat {
|
|
228
423
|
let menuWidth = self.menuWidth(side: side)
|
|
229
424
|
return (self.offsetX.magnitude + settings.addWidthMargin) * (item.buttonWidth / menuWidth)
|
|
230
425
|
}
|
|
231
|
-
|
|
426
|
+
|
|
232
427
|
internal func warnSwipeOutCondition(side: SwipeGroupSide, hasSwipeOut: Bool)->Bool {
|
|
233
428
|
if hasSwipeOut == false {
|
|
234
429
|
return false
|
|
@@ -236,11 +431,11 @@ public struct SwipeCellModifier: ViewModifier {
|
|
|
236
431
|
let triggerValue = self.cellWidth * settings.swipeOutTriggerRatio
|
|
237
432
|
return (side == .trailing && self.offsetX < -triggerValue) || (side == .leading && self.offsetX > triggerValue)
|
|
238
433
|
}
|
|
239
|
-
|
|
434
|
+
|
|
240
435
|
internal func swipeRevealAreaOpacity(side: SwipeGroupSide)->Double {
|
|
241
436
|
switch side {
|
|
242
437
|
case .leading:
|
|
243
|
-
|
|
438
|
+
|
|
244
439
|
return self.offsetX > 5 ? 1 : 0
|
|
245
440
|
case .trailing:
|
|
246
441
|
return self.offsetX < -5 ? 1 : 0
|
|
@@ -3,6 +3,27 @@
|
|
|
3
3
|
import Foundation
|
|
4
4
|
import SwiftUI
|
|
5
5
|
|
|
6
|
+
// MARK: - SwipeAction
|
|
7
|
+
|
|
8
|
+
public struct SwipeAction {
|
|
9
|
+
public init(
|
|
10
|
+
label: String = "",
|
|
11
|
+
icon: String = "",
|
|
12
|
+
backgroundColor: Color? = nil,
|
|
13
|
+
onPress: @escaping () -> Void = {}
|
|
14
|
+
) {
|
|
15
|
+
self.label = label
|
|
16
|
+
self.icon = icon
|
|
17
|
+
self.backgroundColor = backgroundColor
|
|
18
|
+
self.onPress = onPress
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public var label: String
|
|
22
|
+
public var icon: String
|
|
23
|
+
public var backgroundColor: Color?
|
|
24
|
+
public var onPress: () -> Void
|
|
25
|
+
}
|
|
26
|
+
|
|
6
27
|
// MARK: - SwipeGroupSide
|
|
7
28
|
|
|
8
29
|
public enum SwipeGroupSide {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import SwiftUI
|
|
3
|
+
|
|
4
|
+
public struct Switch: View {
|
|
5
|
+
@Binding var value: Bool
|
|
6
|
+
var disabled: Bool
|
|
7
|
+
var onChange: ((Bool) -> Void)?
|
|
8
|
+
var title: String?
|
|
9
|
+
var accessibilityId: String?
|
|
10
|
+
|
|
11
|
+
public init(
|
|
12
|
+
_ value: Binding<Bool>,
|
|
13
|
+
disabled: Bool = false,
|
|
14
|
+
onChange: ((Bool) -> Void)? = nil,
|
|
15
|
+
title: String? = "",
|
|
16
|
+
accessibilityId: String? = ""
|
|
17
|
+
) {
|
|
18
|
+
self._value = value
|
|
19
|
+
self.disabled = disabled
|
|
20
|
+
self.onChange = onChange
|
|
21
|
+
self.title = title
|
|
22
|
+
self.accessibilityId = accessibilityId
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Mirrors Kotlin's `backgroundColor`: shared by the track AND the inner dot.
|
|
26
|
+
private var backgroundColor: Color {
|
|
27
|
+
switch (disabled, value) {
|
|
28
|
+
case (true, true): return Colors.green09
|
|
29
|
+
case (true, false): return Colors.black05
|
|
30
|
+
case (false, true): return Colors.green03
|
|
31
|
+
case (false, false): return Colors.black07
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Mirrors Kotlin's `circleBackgroundColor` (the outer 14pt thumb circle).
|
|
36
|
+
private var circleColor: Color {
|
|
37
|
+
value ? Colors.black01 : Colors.black03
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private var automationId: String {
|
|
41
|
+
accessibilityId?.isEmpty == false ? accessibilityId! : "toggle_\(title?.isEmpty == false ? title! : "unknown")_\(value)"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public var body: some View {
|
|
45
|
+
SwiftUI.Button(action: {
|
|
46
|
+
withAnimation {
|
|
47
|
+
value.toggle()
|
|
48
|
+
onChange?(value)
|
|
49
|
+
}
|
|
50
|
+
}) {
|
|
51
|
+
HStack {
|
|
52
|
+
HStack {}
|
|
53
|
+
.frame(width: 6, height: 6)
|
|
54
|
+
.background(backgroundColor)
|
|
55
|
+
.clipShape(Circle())
|
|
56
|
+
}
|
|
57
|
+
.frame(width: 14, height: 14)
|
|
58
|
+
.background(circleColor)
|
|
59
|
+
.clipShape(Circle())
|
|
60
|
+
.padding(.leading, Spacing.XS)
|
|
61
|
+
.padding(.trailing, Spacing.XS)
|
|
62
|
+
}
|
|
63
|
+
.disabled(disabled)
|
|
64
|
+
.frame(width: 38, height: 20, alignment: value ? .trailing : .leading)
|
|
65
|
+
.background(backgroundColor)
|
|
66
|
+
.clipShape(Capsule())
|
|
67
|
+
.accessibilityIdentifier(automationId)
|
|
68
|
+
}
|
|
69
|
+
}
|