@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
package/ios/Input/Input.swift
CHANGED
|
@@ -1,98 +1,482 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import SwiftUI
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
fileprivate struct FloatingComponent: View {
|
|
6
|
-
var floatingValue: String
|
|
7
|
-
|
|
8
|
-
public init (_ floatingValue: String = ""){
|
|
9
|
-
self.floatingValue = floatingValue
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
public var body: some View {
|
|
13
|
-
return HStack {
|
|
14
|
-
Text(floatingValue)
|
|
15
|
-
.foregroundColor(Colors.black09)
|
|
16
|
-
.font(.system(size: 12))
|
|
17
|
-
.padding(.leading, 8)
|
|
18
|
-
Image(systemName: "info.circle")
|
|
19
|
-
.foregroundColor(Colors.black09)
|
|
20
|
-
.frame(width: 16, height: 16)
|
|
21
|
-
.padding(.leading, -4)
|
|
22
|
-
.padding(.trailing, 8)
|
|
23
|
-
}
|
|
24
|
-
.background(Colors.black01)
|
|
25
|
-
.offset(x: 16, y:-8)
|
|
26
|
-
.zIndex(10)
|
|
27
|
-
}
|
|
28
|
-
}
|
|
3
|
+
import Combine
|
|
29
4
|
|
|
30
5
|
public struct Input: View {
|
|
31
|
-
@
|
|
32
|
-
@
|
|
6
|
+
@Environment(\.appTheme) private var theme
|
|
7
|
+
@Environment(\.momoFontScale) private var fontScale
|
|
8
|
+
@Binding public var text: String
|
|
33
9
|
|
|
34
|
-
var
|
|
35
|
-
var
|
|
36
|
-
var
|
|
37
|
-
var
|
|
38
|
-
var
|
|
10
|
+
public var placeholder: String
|
|
11
|
+
public var floatingValue: String
|
|
12
|
+
public var floatingValueColor: Color?
|
|
13
|
+
public var floatingIcon: String
|
|
14
|
+
public var floatingIconColor: Color?
|
|
15
|
+
public var size: InputSize
|
|
16
|
+
public var hintText: String
|
|
17
|
+
public var error: String
|
|
18
|
+
public var errorSpacing: Bool
|
|
19
|
+
public var disabled: Bool
|
|
20
|
+
public var readOnly: Bool
|
|
21
|
+
public var secureTextEntry: Bool
|
|
22
|
+
public var rightIcon: String
|
|
23
|
+
public var rightIconColor: Color?
|
|
24
|
+
public var leadingIcon: String
|
|
25
|
+
public var leadingIconColor: Color?
|
|
26
|
+
public var loading: Bool
|
|
27
|
+
public var required: Bool
|
|
28
|
+
public var maxLength: Int?
|
|
29
|
+
public var fontWeight: InputFontWeight
|
|
30
|
+
public var keyboardType: UIKeyboardType
|
|
31
|
+
public var autofocus: Bool
|
|
32
|
+
public var onChangeText: ((String) -> Void)?
|
|
33
|
+
public var onFocus: (() -> Void)?
|
|
34
|
+
public var onBlur: (() -> Void)?
|
|
35
|
+
public var onRightIconPressed: (() -> Void)?
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
@State private var isFocused: Bool = false
|
|
38
|
+
@State private var isPasswordHidden: Bool = true
|
|
39
|
+
@FocusState private var isFieldFocused: Bool
|
|
40
|
+
@State private var floatingLabelHeight: CGFloat = 16
|
|
43
41
|
|
|
44
|
-
public init(
|
|
42
|
+
public init(
|
|
43
|
+
text: Binding<String>,
|
|
44
|
+
placeholder: String = "",
|
|
45
|
+
floatingValue: String = "",
|
|
46
|
+
floatingValueColor: Color? = nil,
|
|
47
|
+
floatingIcon: String = "",
|
|
48
|
+
floatingIconColor: Color? = nil,
|
|
49
|
+
size: InputSize = .small,
|
|
50
|
+
hintText: String = "",
|
|
51
|
+
error: String = "",
|
|
52
|
+
errorSpacing: Bool = false,
|
|
53
|
+
disabled: Bool = false,
|
|
54
|
+
readOnly: Bool = false,
|
|
55
|
+
secureTextEntry: Bool = false,
|
|
56
|
+
rightIcon: String = "",
|
|
57
|
+
rightIconColor: Color? = nil,
|
|
58
|
+
leadingIcon: String = "",
|
|
59
|
+
leadingIconColor: Color? = nil,
|
|
60
|
+
loading: Bool = false,
|
|
61
|
+
required: Bool = false,
|
|
62
|
+
maxLength: Int? = nil,
|
|
63
|
+
fontWeight: InputFontWeight = .regular,
|
|
64
|
+
keyboardType: UIKeyboardType = .default,
|
|
65
|
+
autofocus: Bool = false,
|
|
66
|
+
onChangeText: ((String) -> Void)? = nil,
|
|
67
|
+
onFocus: (() -> Void)? = nil,
|
|
68
|
+
onBlur: (() -> Void)? = nil,
|
|
69
|
+
onRightIconPressed: (() -> Void)? = nil
|
|
70
|
+
) {
|
|
71
|
+
self._text = text
|
|
45
72
|
self.placeholder = placeholder
|
|
46
73
|
self.floatingValue = floatingValue
|
|
47
|
-
self.
|
|
48
|
-
self.
|
|
49
|
-
self.
|
|
74
|
+
self.floatingValueColor = floatingValueColor
|
|
75
|
+
self.floatingIcon = floatingIcon
|
|
76
|
+
self.floatingIconColor = floatingIconColor
|
|
77
|
+
self.size = size
|
|
78
|
+
self.hintText = hintText
|
|
79
|
+
self.error = error
|
|
80
|
+
self.errorSpacing = errorSpacing
|
|
81
|
+
self.disabled = disabled
|
|
82
|
+
self.readOnly = readOnly
|
|
83
|
+
self.secureTextEntry = secureTextEntry
|
|
84
|
+
self.rightIcon = rightIcon
|
|
85
|
+
self.rightIconColor = rightIconColor
|
|
86
|
+
self.leadingIcon = leadingIcon
|
|
87
|
+
self.leadingIconColor = leadingIconColor
|
|
88
|
+
self.loading = loading
|
|
89
|
+
self.required = required
|
|
90
|
+
self.maxLength = maxLength
|
|
91
|
+
self.fontWeight = fontWeight
|
|
92
|
+
self.keyboardType = keyboardType
|
|
93
|
+
self.autofocus = autofocus
|
|
94
|
+
self.onChangeText = onChangeText
|
|
95
|
+
self.onFocus = onFocus
|
|
96
|
+
self.onBlur = onBlur
|
|
97
|
+
self.onRightIconPressed = onRightIconPressed
|
|
50
98
|
}
|
|
51
|
-
|
|
99
|
+
|
|
100
|
+
// MARK: - Body
|
|
52
101
|
public var body: some View {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
102
|
+
let textBinding = Binding<String>(
|
|
103
|
+
get: { self.text },
|
|
104
|
+
set: { newValue in
|
|
105
|
+
// Trim atomically before publishing, mirroring Kotlin's `onValueChange`
|
|
106
|
+
// (`newText.take(maxLength)` before the state ever updates) — avoids a
|
|
107
|
+
// render with the untrimmed value that a separate `.onChange` correction
|
|
108
|
+
// would otherwise briefly show.
|
|
109
|
+
let limited = limitText(newValue)
|
|
110
|
+
self.text = limited
|
|
111
|
+
self.onChangeText?(limited)
|
|
112
|
+
}
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
VStack(alignment: .leading, spacing: 4) {
|
|
116
|
+
ZStack(alignment: .topLeading) {
|
|
117
|
+
// Floating label
|
|
118
|
+
if !floatingValue.isEmpty || !floatingIcon.isEmpty {
|
|
119
|
+
HStack(spacing: Spacing.XS) {
|
|
120
|
+
MomoText(floatingValue, typography: .labelSMedium, color: getFloatingColor())
|
|
121
|
+
if required {
|
|
122
|
+
MomoText("*", typography: .labelSMedium, color: theme.colors.error.primary)
|
|
123
|
+
}
|
|
124
|
+
if !floatingIcon.isEmpty {
|
|
125
|
+
Icon(source: floatingIcon, size: 16, color: getFloatingIconColor())
|
|
126
|
+
}
|
|
64
127
|
}
|
|
128
|
+
.padding(.horizontal, Spacing.S)
|
|
129
|
+
.background(
|
|
130
|
+
GeometryReader { geo in
|
|
131
|
+
Color.clear.onAppear { floatingLabelHeight = geo.size.height }
|
|
132
|
+
}
|
|
133
|
+
)
|
|
134
|
+
.background(theme.colors.background.surface)
|
|
135
|
+
// Kotlin centers the label within the (box-height-tall) decorationBox
|
|
136
|
+
// by default, then applies `offsetY = -size.values.height / 2` — net
|
|
137
|
+
// effect: the label ends up centered exactly on the box's top border
|
|
138
|
+
// (spanning -labelHeight/2 ... +labelHeight/2 around y=0). Our ZStack
|
|
139
|
+
// anchors top-leading instead, so reproducing that requires offsetting
|
|
140
|
+
// by half the label's OWN measured height, not half the box height.
|
|
141
|
+
.offset(x: Spacing.S, y: -floatingLabelHeight / 2)
|
|
142
|
+
.zIndex(10)
|
|
65
143
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
.
|
|
71
|
-
|
|
144
|
+
|
|
145
|
+
// Input container
|
|
146
|
+
HStack(alignment: .center, spacing: 0) {
|
|
147
|
+
// Leading icon
|
|
148
|
+
if !leadingIcon.isEmpty {
|
|
149
|
+
Icon(source: leadingIcon, size: size == .small ? 24 : 32, color: getLeadingIconColor())
|
|
150
|
+
.padding(.trailing, Spacing.M)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Text input field
|
|
154
|
+
ZStack(alignment: .leading) {
|
|
155
|
+
if text.isEmpty {
|
|
156
|
+
MomoText(
|
|
157
|
+
placeholder + (required && floatingValue.isEmpty ? " *" : ""),
|
|
158
|
+
typography: fontWeight == .bold ? .actionSBold : .bodyDefaultRegular,
|
|
159
|
+
color: getPlaceholderColor()
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if secureTextEntry && isPasswordHidden {
|
|
164
|
+
SecureInputField(
|
|
165
|
+
text: $text,
|
|
166
|
+
keyboardType: keyboardType,
|
|
167
|
+
fontSize: fontScale(14),
|
|
168
|
+
fontWeight: fontWeight == .bold ? .bold : .regular,
|
|
169
|
+
textColor: UIColor(getTextColor()),
|
|
170
|
+
cursorColor: UIColor(theme.colors.primary),
|
|
171
|
+
isDisabled: disabled || readOnly,
|
|
172
|
+
maxLength: maxLength,
|
|
173
|
+
autofocus: autofocus,
|
|
174
|
+
onFocusChange: { focused in
|
|
175
|
+
handleFocusChange(focused)
|
|
176
|
+
},
|
|
177
|
+
onChangeText: onChangeText
|
|
178
|
+
)
|
|
179
|
+
} else {
|
|
180
|
+
TextField("", text: textBinding, onEditingChanged: { focused in
|
|
181
|
+
handleFocusChange(focused)
|
|
182
|
+
})
|
|
183
|
+
.keyboardType(keyboardType)
|
|
184
|
+
.font(fontWeight == .bold ? .action_s_bold : .body_default_regular)
|
|
185
|
+
.ignoreBoldTextSetting()
|
|
186
|
+
.foregroundColor(getTextColor())
|
|
187
|
+
.disabled(disabled || readOnly)
|
|
188
|
+
.applyCursorColor(theme.colors.primary)
|
|
189
|
+
.focused($isFieldFocused)
|
|
190
|
+
.onAppear {
|
|
191
|
+
if autofocus { isFieldFocused = true }
|
|
192
|
+
}
|
|
193
|
+
// SwiftUI reads a TextField's UIKit input traits only when it
|
|
194
|
+
// builds the backing UITextField, so a later `keyboardType`
|
|
195
|
+
// change is silently dropped. The secure path can call
|
|
196
|
+
// `reloadInputViews()` in `updateUIView`; here the only lever
|
|
197
|
+
// is to force a rebuild.
|
|
198
|
+
.id(keyboardType.rawValue)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
72
201
|
|
|
202
|
+
// Clear button (only show when focused and has text)
|
|
203
|
+
if isFocused && !text.isEmpty {
|
|
204
|
+
SwiftUI.Button(action: {
|
|
205
|
+
text = ""
|
|
206
|
+
onChangeText?("")
|
|
207
|
+
}) {
|
|
208
|
+
Icon(source: "24_navigation_close_circle_full", size: 16, color: theme.colors.text.hint)
|
|
209
|
+
.padding(.leading, Spacing.S).accessibility(identifier: "ic_clear")
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Loading indicator
|
|
214
|
+
if loading {
|
|
215
|
+
ActivityIndicator(isAnimating: .constant(true), style: .medium)
|
|
216
|
+
.frame(width: 16, height: 16)
|
|
217
|
+
.padding(.leading, Spacing.S)
|
|
218
|
+
}
|
|
73
219
|
|
|
220
|
+
// Right icon (password toggle or custom icon)
|
|
221
|
+
if secureTextEntry {
|
|
222
|
+
if !text.isEmpty {
|
|
223
|
+
SwiftUI.Button(action: togglePasswordVisibility) {
|
|
224
|
+
Icon(
|
|
225
|
+
source: isPasswordHidden ? "24_security_eye_off" : "24_security_eye_open",
|
|
226
|
+
size: 24,
|
|
227
|
+
color: getRightIconColor()
|
|
228
|
+
)
|
|
229
|
+
.padding(.leading, Spacing.S).accessibility(identifier: "ic_show_hide")
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
} else if !rightIcon.isEmpty {
|
|
233
|
+
SwiftUI.Button(action: { onRightIconPressed?() }) {
|
|
234
|
+
Icon(source: rightIcon, size: 24, color: getRightIconColor())
|
|
235
|
+
.padding(.leading, Spacing.S)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
74
238
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
239
|
+
.padding(.horizontal, Spacing.M)
|
|
240
|
+
.frame(height: fontScale(size == .small ? 48 : 56))
|
|
241
|
+
.background(
|
|
242
|
+
RoundedRectangle(cornerRadius: Radius.S)
|
|
243
|
+
.fill(theme.colors.background.surface)
|
|
244
|
+
)
|
|
245
|
+
.overlay(
|
|
246
|
+
RoundedRectangle(cornerRadius: Radius.S)
|
|
247
|
+
.stroke(borderColor(), lineWidth: 1)
|
|
248
|
+
)
|
|
82
249
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
250
|
+
|
|
251
|
+
// Error or hint
|
|
252
|
+
ErrorView(
|
|
253
|
+
errorMessage: error,
|
|
254
|
+
errorSpacing: errorSpacing,
|
|
255
|
+
hintText: hintText
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
.onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)) { _ in
|
|
259
|
+
if isFocused && !secureTextEntry {
|
|
260
|
+
DispatchQueue.main.async {
|
|
261
|
+
handleFocusChange(false)
|
|
262
|
+
}
|
|
93
263
|
}
|
|
94
|
-
|
|
95
|
-
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// MARK: - Helpers
|
|
268
|
+
|
|
269
|
+
private func handleFocusChange(_ focused: Bool) {
|
|
270
|
+
isFocused = focused
|
|
271
|
+
if focused {
|
|
272
|
+
onFocus?()
|
|
273
|
+
} else {
|
|
274
|
+
onBlur?()
|
|
275
|
+
}
|
|
96
276
|
}
|
|
97
277
|
|
|
278
|
+
private func togglePasswordVisibility() {
|
|
279
|
+
isPasswordHidden.toggle()
|
|
280
|
+
onRightIconPressed?()
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
private func limitText(_ value: String) -> String {
|
|
284
|
+
guard let maxLength = maxLength else {
|
|
285
|
+
return value
|
|
286
|
+
}
|
|
287
|
+
return String(value.prefix(maxLength))
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
private func borderColor() -> Color {
|
|
291
|
+
if disabled {
|
|
292
|
+
return theme.colors.border.disable
|
|
293
|
+
}
|
|
294
|
+
if !error.isEmpty {
|
|
295
|
+
return theme.colors.error.primary
|
|
296
|
+
}
|
|
297
|
+
if isFocused {
|
|
298
|
+
return theme.colors.primary
|
|
299
|
+
}
|
|
300
|
+
return theme.colors.border.default
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
private func getTextColor() -> Color {
|
|
304
|
+
return disabled ? theme.colors.text.disable : theme.colors.text.default
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
private func getPlaceholderColor() -> Color {
|
|
308
|
+
return disabled ? theme.colors.text.disable : theme.colors.text.hint
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
private func getFloatingColor() -> Color {
|
|
312
|
+
return disabled ? theme.colors.text.disable : (floatingValueColor ?? theme.colors.text.hint)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
private func getFloatingIconColor() -> Color {
|
|
316
|
+
return disabled ? theme.colors.text.disable : (floatingIconColor ?? theme.colors.text.default)
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
private func getLeadingIconColor() -> Color {
|
|
320
|
+
return disabled ? theme.colors.text.disable : (leadingIconColor ?? theme.colors.text.hint)
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
private func getRightIconColor() -> Color {
|
|
324
|
+
return disabled ? theme.colors.text.disable : (rightIconColor ?? theme.colors.text.default)
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
// MARK: - Secure Input Field (UIViewRepresentable)
|
|
330
|
+
private struct SecureInputField: UIViewRepresentable {
|
|
331
|
+
@Binding var text: String
|
|
332
|
+
var keyboardType: UIKeyboardType
|
|
333
|
+
var fontSize: CGFloat
|
|
334
|
+
var fontWeight: UIFont.Weight
|
|
335
|
+
var textColor: UIColor
|
|
336
|
+
var cursorColor: UIColor
|
|
337
|
+
var isDisabled: Bool
|
|
338
|
+
var maxLength: Int?
|
|
339
|
+
var autofocus: Bool = false
|
|
340
|
+
var onFocusChange: (Bool) -> Void
|
|
341
|
+
var onChangeText: ((String) -> Void)?
|
|
342
|
+
|
|
343
|
+
func makeCoordinator() -> Coordinator {
|
|
344
|
+
Coordinator(self)
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
func makeUIView(context: Context) -> UITextField {
|
|
348
|
+
let textField = UITextField()
|
|
349
|
+
textField.isSecureTextEntry = true
|
|
350
|
+
textField.delegate = context.coordinator
|
|
351
|
+
textField.keyboardType = keyboardType
|
|
352
|
+
textField.font = UIFont.systemFont(ofSize: fontSize, weight: fontWeight)
|
|
353
|
+
textField.textColor = textColor
|
|
354
|
+
textField.isEnabled = !isDisabled
|
|
355
|
+
textField.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
|
356
|
+
textField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
|
357
|
+
textField.text = text
|
|
358
|
+
textField.tintColor = cursorColor
|
|
359
|
+
textField.addTarget(
|
|
360
|
+
context.coordinator,
|
|
361
|
+
action: #selector(Coordinator.textFieldDidChange(_:)),
|
|
362
|
+
for: .editingChanged
|
|
363
|
+
)
|
|
364
|
+
if autofocus {
|
|
365
|
+
DispatchQueue.main.async {
|
|
366
|
+
textField.becomeFirstResponder()
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return textField
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
func updateUIView(_ textField: UITextField, context: Context) {
|
|
373
|
+
context.coordinator.parent = self
|
|
374
|
+
if textField.text != text {
|
|
375
|
+
textField.text = text
|
|
376
|
+
}
|
|
377
|
+
textField.isEnabled = !isDisabled
|
|
378
|
+
textField.textColor = textColor
|
|
379
|
+
textField.tintColor = cursorColor
|
|
380
|
+
if textField.keyboardType != keyboardType {
|
|
381
|
+
textField.keyboardType = keyboardType
|
|
382
|
+
textField.reloadInputViews()
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
class Coordinator: NSObject, UITextFieldDelegate {
|
|
387
|
+
var parent: SecureInputField
|
|
388
|
+
private var isResettingText = false
|
|
389
|
+
|
|
390
|
+
init(_ parent: SecureInputField) {
|
|
391
|
+
self.parent = parent
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
func textFieldDidBeginEditing(_ textField: UITextField) {
|
|
395
|
+
let existingText = textField.text ?? ""
|
|
396
|
+
if !existingText.isEmpty {
|
|
397
|
+
// When a secure text field regains focus, iOS marks the
|
|
398
|
+
// existing text as "committed". The next keystroke would
|
|
399
|
+
// replace ALL committed text with the new character.
|
|
400
|
+
// Prevent this by clearing and re-inserting via insertText(),
|
|
401
|
+
// which puts the text into an "active editing" state.
|
|
402
|
+
isResettingText = true
|
|
403
|
+
textField.text = ""
|
|
404
|
+
textField.insertText(existingText)
|
|
405
|
+
isResettingText = false
|
|
406
|
+
}
|
|
407
|
+
parent.onFocusChange(true)
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
func textFieldDidEndEditing(_ textField: UITextField) {
|
|
411
|
+
parent.text = limitText(textField.text ?? "")
|
|
412
|
+
parent.onFocusChange(false)
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
func textField(
|
|
416
|
+
_ textField: UITextField,
|
|
417
|
+
shouldChangeCharactersIn range: NSRange,
|
|
418
|
+
replacementString string: String
|
|
419
|
+
) -> Bool {
|
|
420
|
+
if isResettingText { return true }
|
|
421
|
+
return true
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
@objc func textFieldDidChange(_ textField: UITextField) {
|
|
425
|
+
if isResettingText { return }
|
|
426
|
+
let newText = limitText(textField.text ?? "")
|
|
427
|
+
if textField.text != newText {
|
|
428
|
+
textField.text = newText
|
|
429
|
+
}
|
|
430
|
+
parent.text = newText
|
|
431
|
+
parent.onChangeText?(newText)
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
|
435
|
+
textField.resignFirstResponder()
|
|
436
|
+
return true
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
private func limitText(_ value: String) -> String {
|
|
440
|
+
guard let maxLength = parent.maxLength else {
|
|
441
|
+
return value
|
|
442
|
+
}
|
|
443
|
+
return String(value.prefix(maxLength))
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// MARK: - Helper Extension
|
|
449
|
+
private extension View {
|
|
450
|
+
func applyCursorColor(_ color: Color) -> some View {
|
|
451
|
+
if #available(iOS 15.0, *) {
|
|
452
|
+
return self.tint(color)
|
|
453
|
+
} else {
|
|
454
|
+
return self
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// MARK: - Activity Indicator
|
|
460
|
+
struct ActivityIndicator: UIViewRepresentable {
|
|
461
|
+
@Binding var isAnimating: Bool
|
|
462
|
+
let style: UIActivityIndicatorView.Style
|
|
463
|
+
|
|
464
|
+
func makeUIView(context: UIViewRepresentableContext<ActivityIndicator>) -> UIActivityIndicatorView {
|
|
465
|
+
return UIActivityIndicatorView(style: style)
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext<ActivityIndicator>) {
|
|
469
|
+
isAnimating ? uiView.startAnimating() : uiView.stopAnimating()
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// MARK: - Enums
|
|
474
|
+
public enum InputSize {
|
|
475
|
+
case small
|
|
476
|
+
case large
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
public enum InputFontWeight {
|
|
480
|
+
case regular
|
|
481
|
+
case bold
|
|
98
482
|
}
|