├── .bundle └── config ├── .editorconfig ├── .eslintrc.js ├── .gitattributes ├── .gitignore ├── .npmrc ├── .prettierrc.js ├── .vscode ├── extensions.json └── settings.json ├── App.tsx ├── Gemfile ├── Gemfile.lock ├── README.md ├── android ├── app │ ├── build.gradle │ ├── debug.keystore │ ├── proguard-rules.pro │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── myuidemo │ │ │ ├── MainActivity.java │ │ │ ├── MainApplication.java │ │ │ └── MyUiPackage.java │ │ └── res │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── strings.xml │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── babel.config.js ├── demo ├── activity-indicator │ └── ActivityIndicatorScreen.tsx ├── assets │ ├── adaptive-icon.png │ ├── album-art-1.jpg │ ├── album-art-2.jpg │ ├── album-art-3.jpg │ ├── album-art-4.jpg │ ├── album-art-5.jpg │ ├── album-art-6.jpg │ ├── album-art-7.jpg │ ├── album-art-8.jpg │ ├── anabelle.jpg │ ├── arrow.png │ ├── arrowOther.png │ ├── avatar-1.png │ ├── avatar-2.png │ ├── book.jpg │ ├── candice.jpg │ ├── checkboxOff.png │ ├── checkboxOn.png │ ├── comment.png │ ├── cover.webp │ ├── egg.jpg │ ├── favicon.png │ ├── icon.png │ ├── indicator@2x.png │ ├── indicator@3x.png │ ├── like.png │ ├── mohamad.jpg │ ├── mubariz.jpg │ ├── retweet.pdf │ ├── retweet.png │ ├── retweet.svg │ ├── send.png │ ├── share.png │ ├── splash.png │ ├── tamara.jpg │ ├── trilo-3.json │ ├── trilo-4.json │ ├── trilo-5.json │ ├── window_closed@2x.png │ └── window_closed@3x.png ├── bottom-sheet │ ├── BottomModal.tsx │ ├── BottomSheetBackdropShadow │ │ └── index.tsx │ ├── BottomSheetFlashList │ │ └── index.tsx │ ├── BottomSheetPagerView │ │ └── index.tsx │ ├── BottomSheetWithoutScrollView │ │ ├── Button.tsx │ │ └── index.tsx │ ├── Home.tsx │ └── index.ts ├── components │ ├── CondeInput.tsx │ ├── FlatListPage.tsx │ ├── LoremIpsum.tsx │ ├── Messages │ │ ├── Avatar.tsx │ │ ├── ImageMessage.tsx │ │ ├── MessageItem.tsx │ │ ├── Messages.tsx │ │ ├── MessagesFlatList.tsx │ │ ├── TextBubble.tsx │ │ ├── TextInputBar.tsx │ │ ├── data │ │ │ └── messages.ts │ │ ├── index.ts │ │ ├── models │ │ │ ├── Message.ts │ │ │ └── MessageType.ts │ │ └── userName.tsx │ ├── Modal.tsx │ ├── ModalButton.tsx │ ├── ModalToolbar.tsx │ ├── PrimaryButton.tsx │ ├── ScrollViewPage.tsx │ ├── TabBar │ │ ├── ScrollBar.tsx │ │ ├── TabBar.tsx │ │ ├── TabBarIndicator.tsx │ │ ├── TabBarItem.tsx │ │ └── index.tsx │ ├── WebViewPage │ │ ├── index.tsx │ │ └── loading.json │ ├── contacts │ │ ├── ContactCell.tsx │ │ ├── ContactDivider.tsx │ │ ├── ContactHeader.tsx │ │ ├── ContactSectionHeader.tsx │ │ ├── Contacts.tsx │ │ ├── ContactsSectionList.tsx │ │ ├── data │ │ │ └── contacts.ts │ │ └── models │ │ │ └── Contact.ts │ ├── tabview │ │ ├── Shared │ │ │ ├── Albums.tsx │ │ │ ├── Article.tsx │ │ │ ├── Chat.tsx │ │ │ ├── Contacts.tsx │ │ │ └── Profile.tsx │ │ └── index.tsx │ ├── twitter │ │ ├── CustomCellRendererComponent.tsx │ │ ├── TweetCell.tsx │ │ ├── TweetContent.tsx │ │ ├── Twitter.tsx │ │ ├── TwitterFlatList.tsx │ │ ├── data │ │ │ └── tweets.ts │ │ ├── index.ts │ │ └── models │ │ │ ├── Author.ts │ │ │ └── Tweet.ts │ └── usePagerView.tsx ├── image-crop │ ├── ImageCropDemo.tsx │ ├── ImageCropPage.tsx │ ├── ImageCropResultPage.tsx │ └── index.ts ├── keyboard-insets │ ├── Home.tsx │ ├── KeyboardAdvoiding │ │ └── index.tsx │ ├── KeyboardChat │ │ ├── Message │ │ │ ├── data.ts │ │ │ ├── index.tsx │ │ │ ├── styles.ts │ │ │ └── types.ts │ │ ├── driver │ │ │ ├── Driver.ts │ │ │ ├── KeyboardDriver.ts │ │ │ └── ViewDriver.ts │ │ ├── icon │ │ │ ├── emoji@2x.png │ │ │ ├── emoji@3x.png │ │ │ ├── keyboard@2x.png │ │ │ ├── keyboard@3x.png │ │ │ ├── plus@2x.png │ │ │ └── plus@3x.png │ │ ├── index.tsx │ │ └── styles.ts │ ├── KeyboardChatReanimated │ │ ├── Message │ │ │ ├── data.ts │ │ │ ├── index.tsx │ │ │ ├── styles.ts │ │ │ └── types.ts │ │ ├── RekeyboardInsetsView.tsx │ │ ├── icon │ │ │ ├── emoji@2x.png │ │ │ ├── emoji@3x.png │ │ │ ├── keyboard@2x.png │ │ │ ├── keyboard@3x.png │ │ │ ├── plus@2x.png │ │ │ └── plus@3x.png │ │ ├── index.tsx │ │ ├── styles.ts │ │ └── useRekeyboard.ts │ ├── ModalTextInput │ │ └── index.tsx │ └── index.ts ├── nested-scroll │ ├── Home.tsx │ ├── NestedScrollFlatList │ │ └── index.tsx │ ├── NestedScrollPagerViewStickyHeader │ │ └── index.tsx │ ├── NestedScrollParallaxHeader │ │ ├── AnimatedNavbar.tsx │ │ ├── ParallaxHeader.tsx │ │ ├── components │ │ │ ├── HeaderComponent.tsx │ │ │ ├── HeaderNavBar.tsx │ │ │ ├── RoundButton.tsx │ │ │ └── TopNavBar.tsx │ │ ├── hooks │ │ │ ├── useAnimatedNavbar.ts │ │ │ └── useAnimatedScrollView.ts │ │ ├── icons │ │ │ ├── ArrowLeft.tsx │ │ │ ├── ArrowRight.tsx │ │ │ └── Share.tsx │ │ └── index.tsx │ ├── NestedScrollTabView │ │ └── index.tsx │ └── index.ts ├── overlay │ ├── Alert │ │ ├── Button.tsx │ │ ├── Message.tsx │ │ ├── Title.tsx │ │ └── index.tsx │ ├── AlertScreen.tsx │ ├── Home.tsx │ ├── Hoverball │ │ ├── Ball.ios.tsx │ │ ├── Ball.tsx │ │ ├── Menu.tsx │ │ ├── index.tsx │ │ └── types.ts │ ├── HoverballScreen.tsx │ ├── Toast │ │ └── index.tsx │ ├── ToastScreen.tsx │ └── index.ts ├── pull-to-refresh │ ├── Home.tsx │ ├── PullRefreshFlatList │ │ └── index.tsx │ ├── PullRefreshFlatListNestedScroll │ │ └── index.tsx │ ├── PullRefreshNestedScrollPagerView │ │ └── index.tsx │ ├── PullRefreshPagerView │ │ └── index.tsx │ ├── PullRefreshPagerViewNestedScroll │ │ └── index.tsx │ ├── PullRefreshScrollView │ │ └── index.tsx │ ├── PullRefreshWebView │ │ └── index.tsx │ ├── PullRefreshWithoutScrollView │ │ ├── ExpandingDot.tsx │ │ ├── Page.tsx │ │ ├── index.tsx │ │ └── usePagerView.ts │ ├── PullToRefresh │ │ ├── LottiePullToRefreshFooter.tsx │ │ ├── LottiePullToRefreshHeader.tsx │ │ ├── SpinnerPullToRefreshHeader.tsx │ │ ├── car.json │ │ ├── google-loading.json │ │ ├── index.ts │ │ └── square-loading.json │ └── index.ts └── wheel-picker │ ├── CityPicker.tsx │ ├── TimePicker.tsx │ ├── WheelPickerDemo.tsx │ ├── index.ts │ └── pc-code.json ├── index.ts ├── ios ├── .xcode.env ├── MyUiDemo.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── MyUiDemo.xcscheme ├── MyUiDemo.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── MyUiDemo │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ └── LaunchScreen.storyboard │ ├── Info.plist │ ├── PrivacyInfo.xcprivacy │ └── main.m ├── Podfile └── Podfile.lock ├── jest.config.js ├── metro.config.js ├── package.json ├── packages ├── activity-indicator │ ├── LICENSE │ ├── README.md │ ├── android │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── com │ │ │ └── reactnative │ │ │ └── activityindicator │ │ │ ├── ActivityIndicator.java │ │ │ ├── ActivityIndicatorManager.java │ │ │ └── ActivityIndicatorPackage.java │ ├── docs │ │ └── assets │ │ │ └── activity.png │ ├── package.json │ ├── react-native.config.js │ ├── src │ │ ├── ActivityIndicatorAndroid.ts │ │ └── index.tsx │ └── tsconfig.json ├── bottom-sheet │ ├── LICENSE │ ├── README.md │ ├── RNBottomSheet.podspec │ ├── android │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── com │ │ │ └── reactnative │ │ │ └── bottomsheet │ │ │ ├── BottomSheet.java │ │ │ ├── BottomSheetManager.java │ │ │ ├── BottomSheetPackage.java │ │ │ ├── BottomSheetState.java │ │ │ ├── OffsetChangedEvent.java │ │ │ └── StateChangedEvent.java │ ├── docs │ │ └── assets │ │ │ ├── pagerview.gif │ │ │ ├── scrollview.gif │ │ │ └── struct.png │ ├── ios │ │ ├── BottomSheet.xcodeproj │ │ │ └── project.pbxproj │ │ └── BottomSheet │ │ │ ├── RNBottomSheet.h │ │ │ ├── RNBottomSheet.m │ │ │ ├── RNBottomSheetManager.h │ │ │ ├── RNBottomSheetManager.m │ │ │ ├── RNBottomSheetOffsetChangedEvent.h │ │ │ ├── RNBottomSheetOffsetChangedEvent.m │ │ │ ├── RNBottomSheetState.h │ │ │ ├── RNBottomSheetState.m │ │ │ ├── RNBottomSheetStateChangedEvent.h │ │ │ └── RNBottomSheetStateChangedEvent.m │ ├── package.json │ ├── react-native.config.js │ ├── src │ │ ├── index.tsx │ │ └── splitLayoutProps.ts │ └── tsconfig.json ├── image-crop │ ├── LICENSE │ ├── README.md │ ├── RNImageCrop.podspec │ ├── android │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── reactnative │ │ │ │ └── imagecrop │ │ │ │ ├── ImageCropPackage.java │ │ │ │ ├── ObjectRect.java │ │ │ │ ├── RNImageCropView.java │ │ │ │ └── RNImageCropViewManager.java │ │ │ └── res │ │ │ └── layout │ │ │ └── rn_crop_view.xml │ ├── ios │ │ ├── ImageCrop.xcodeproj │ │ │ └── project.pbxproj │ │ └── ImageCrop │ │ │ ├── RNImageCrop.h │ │ │ ├── RNImageCrop.m │ │ │ ├── RNImageCropManager.h │ │ │ └── RNImageCropManager.m │ ├── package.json │ ├── react-native.config.js │ ├── src │ │ ├── ImageCropView.tsx │ │ ├── ImageCropViewRef.ts │ │ ├── index.ts │ │ └── typings.ts │ └── tsconfig.json ├── keyboard-insets │ ├── LICENSE │ ├── README.md │ ├── RNKeyboardInsets.podspec │ ├── android │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── com │ │ │ └── reactnative │ │ │ └── keyboardinsets │ │ │ ├── EdgeInsets.java │ │ │ ├── KeyboardAutoHandler.java │ │ │ ├── KeyboardInsetsCallback.java │ │ │ ├── KeyboardInsetsModule.java │ │ │ ├── KeyboardInsetsPackage.java │ │ │ ├── KeyboardInsetsView.java │ │ │ ├── KeyboardInsetsViewManager.java │ │ │ ├── KeyboardManualHandler.java │ │ │ ├── KeyboardPositionChangedEvent.java │ │ │ ├── KeyboardStatusChangedEvent.java │ │ │ └── SystemUI.java │ ├── docs │ │ └── assets │ │ │ ├── avoiding.gif │ │ │ └── chat.gif │ ├── ios │ │ ├── KeyboardInsets.xcodeproj │ │ │ └── project.pbxproj │ │ └── KeyboardInsets │ │ │ ├── RNKeyboardAutoHandler.h │ │ │ ├── RNKeyboardAutoHandler.m │ │ │ ├── RNKeyboardInsetsModule.h │ │ │ ├── RNKeyboardInsetsModule.m │ │ │ ├── RNKeyboardInsetsView.h │ │ │ ├── RNKeyboardInsetsView.m │ │ │ ├── RNKeyboardInsetsViewManager.h │ │ │ ├── RNKeyboardInsetsViewManager.m │ │ │ ├── RNKeyboardManualHandler.h │ │ │ ├── RNKeyboardManualHandler.m │ │ │ ├── RNKeyboardPositionChangedEvent.h │ │ │ ├── RNKeyboardPositionChangedEvent.m │ │ │ ├── RNKeyboardStatusChangedEvent.h │ │ │ └── RNKeyboardStatusChangedEvent.m │ ├── package.json │ ├── react-native.config.js │ ├── src │ │ ├── KeyboardInsetsView.tsx │ │ ├── hook.ts │ │ ├── index.ts │ │ └── native.ts │ └── tsconfig.json ├── modal-edge-to-edge │ ├── LICENSE │ ├── README.md │ ├── android │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── com │ │ │ └── reactnative │ │ │ └── modalx │ │ │ ├── EdgeToEdgeModule.java │ │ │ ├── EdgeToEdgePackage.java │ │ │ ├── ModalHostManager.java │ │ │ ├── ModalHostView.java │ │ │ ├── SystemUI.java │ │ │ └── SystemUI30.java │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── nested-scroll-webview │ ├── LICENSE │ ├── README.md │ ├── android │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── com │ │ │ ├── reactnative │ │ │ └── nestedscrollwebview │ │ │ │ └── NestedScrollWebViewPackage.java │ │ │ └── reactnativecommunity │ │ │ └── webview │ │ │ ├── RNCNestedScrollWebView.java │ │ │ └── RNCNestedScrollWebViewManager.java │ ├── package.json │ ├── react-native.config.js │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── nested-scroll │ ├── LICENSE │ ├── README.md │ ├── RNNestedScrollView.podspec │ ├── android │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── com │ │ │ └── reactnative │ │ │ └── nestedscroll │ │ │ ├── NestedScrollFlingHelper.java │ │ │ ├── NestedScrollView.java │ │ │ ├── NestedScrollViewHeader.java │ │ │ ├── NestedScrollViewHeaderManager.java │ │ │ ├── NestedScrollViewLocalData.java │ │ │ ├── NestedScrollViewManager.java │ │ │ ├── NestedScrollViewPackage.java │ │ │ ├── NestedScrollViewShadowNode.java │ │ │ └── NestedViewHeaderScrollEvent.java │ ├── docs │ │ └── assets │ │ │ ├── parallax.gif │ │ │ ├── sticky.gif │ │ │ └── struct.png │ ├── ios │ │ ├── NestedScrollView.xcodeproj │ │ │ └── project.pbxproj │ │ └── NestedScrollView │ │ │ ├── RNNestedScrollEvent.h │ │ │ ├── RNNestedScrollEvent.m │ │ │ ├── RNNestedScrollShadowView.h │ │ │ ├── RNNestedScrollShadowView.m │ │ │ ├── RNNestedScrollView.h │ │ │ ├── RNNestedScrollView.m │ │ │ ├── RNNestedScrollViewHeader.h │ │ │ ├── RNNestedScrollViewHeader.m │ │ │ ├── RNNestedScrollViewHeaderManager.h │ │ │ ├── RNNestedScrollViewHeaderManager.m │ │ │ ├── RNNestedScrollViewLocalData.h │ │ │ ├── RNNestedScrollViewLocalData.m │ │ │ ├── RNNestedScrollViewManager.h │ │ │ └── RNNestedScrollViewManager.m │ ├── package.json │ ├── react-native.config.js │ ├── src │ │ ├── NestedScrollViewHeader │ │ │ └── index.tsx │ │ └── index.tsx │ └── tsconfig.json ├── overlay │ ├── LICENSE │ ├── README.md │ ├── RNOverlay.podspec │ ├── android │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── com │ │ │ └── reactnative │ │ │ └── overlay │ │ │ ├── Overlay.java │ │ │ ├── OverlayModule.java │ │ │ ├── OverlayPackage.java │ │ │ └── OverlayRootView.java │ ├── ios │ │ ├── Overlay.xcodeproj │ │ │ └── project.pbxproj │ │ └── Overlay │ │ │ ├── RNOverlay.h │ │ │ ├── RNOverlay.m │ │ │ ├── RNOverlayModule.h │ │ │ └── RNOverlayModule.m │ ├── package.json │ ├── react-native.config.js │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── pull-to-refresh │ ├── LICENSE │ ├── README.md │ ├── RNPullToRefresh.podspec │ ├── android │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── com │ │ │ └── reactnative │ │ │ └── pulltorefresh │ │ │ ├── OnRefreshChangeListener.java │ │ │ ├── PullToRefresh.java │ │ │ ├── PullToRefreshFooter.java │ │ │ ├── PullToRefreshFooterLocalData.java │ │ │ ├── PullToRefreshFooterManager.java │ │ │ ├── PullToRefreshFooterShadowNode.java │ │ │ ├── PullToRefreshHeader.java │ │ │ ├── PullToRefreshHeaderLocalData.java │ │ │ ├── PullToRefreshHeaderManager.java │ │ │ ├── PullToRefreshHeaderShadowNode.java │ │ │ ├── PullToRefreshManager.java │ │ │ ├── PullToRefreshPackage.java │ │ │ ├── PullToRefreshState.java │ │ │ └── event │ │ │ ├── OffsetChangedEvent.java │ │ │ ├── RefreshEvent.java │ │ │ └── StateChangedEvent.java │ ├── docs │ │ └── assets │ │ │ ├── separated.gif │ │ │ └── shared.gif │ ├── ios │ │ ├── PullToRefresh.xcodeproj │ │ │ └── project.pbxproj │ │ └── PullToRefresh │ │ │ ├── Event │ │ │ ├── RNRefreshOffsetChangedEvent.h │ │ │ ├── RNRefreshOffsetChangedEvent.m │ │ │ ├── RNRefreshStateChangedEvent.h │ │ │ ├── RNRefreshStateChangedEvent.m │ │ │ ├── RNRefreshingEvent.h │ │ │ └── RNRefreshingEvent.m │ │ │ ├── Footer │ │ │ ├── RNRefreshFooter.h │ │ │ ├── RNRefreshFooter.m │ │ │ ├── RNRefreshFooterLocalData.h │ │ │ ├── RNRefreshFooterLocalData.m │ │ │ ├── RNRefreshFooterManager.h │ │ │ ├── RNRefreshFooterManager.m │ │ │ ├── RNRefreshFooterShadowView.h │ │ │ └── RNRefreshFooterShadowView.m │ │ │ ├── Header │ │ │ ├── RNRefreshHeader.h │ │ │ ├── RNRefreshHeader.m │ │ │ ├── RNRefreshHeaderLocalData.h │ │ │ ├── RNRefreshHeaderLocalData.m │ │ │ ├── RNRefreshHeaderManager.h │ │ │ ├── RNRefreshHeaderManager.m │ │ │ ├── RNRefreshHeaderShadowView.h │ │ │ └── RNRefreshHeaderShadowView.m │ │ │ ├── RNPullToRefresh.h │ │ │ ├── RNPullToRefresh.m │ │ │ ├── RNPullToRefreshManager.h │ │ │ ├── RNPullToRefreshManager.m │ │ │ ├── RNRefreshState.h │ │ │ └── RNRefreshState.m │ ├── package.json │ ├── react-native.config.js │ ├── src │ │ ├── Footer │ │ │ ├── DefaultPullToRefreshFooter.tsx │ │ │ ├── index.ts │ │ │ └── native.tsx │ │ ├── Header │ │ │ ├── DefaultPullToRefreshHeader.tsx │ │ │ ├── index.ts │ │ │ └── native.tsx │ │ ├── PullToRefresh │ │ │ ├── index.tsx │ │ │ └── native.tsx │ │ ├── RefreshControl.tsx │ │ ├── index.ts │ │ └── types.ts │ └── tsconfig.json └── wheel-picker │ ├── LICENSE │ ├── README.md │ ├── RNWheelPicker.podspec │ ├── android │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── reactnative │ │ └── wheelpicker │ │ ├── PickerView.java │ │ ├── PickerViewManager.java │ │ ├── WheelPickerPackage.java │ │ └── wheel │ │ ├── IPickerViewData.java │ │ ├── InertiaTimerTask.java │ │ ├── LoopViewGestureListener.java │ │ ├── MessageHandler.java │ │ ├── OnItemSelectedListener.java │ │ ├── SmoothScrollTimerTask.java │ │ ├── WheelAdapter.java │ │ └── WheelView.java │ ├── docs │ └── assets │ │ └── wheelpicker.png │ ├── ios │ ├── WheelPicker.xcodeproj │ │ └── project.pbxproj │ └── WheelPicker │ │ ├── RNWheelPicker.h │ │ ├── RNWheelPicker.m │ │ ├── RNWheelPickerManager.h │ │ └── RNWheelPickerManager.m │ ├── package.json │ ├── react-native.config.js │ ├── src │ ├── WheelPicker.tsx │ ├── index.tsx │ └── typing.ts │ └── tsconfig.json ├── patches └── react-native-pager-view+6.7.1.patch ├── tsconfig.json └── yarn.lock /.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = tab 6 | indent_size = 4 7 | max_line_length = 100 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.yml] 13 | indent_style = space 14 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native', 4 | }; 5 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/.npmrc -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "esbenp.prettier-vscode", 4 | "dbaeumer.vscode-eslint", 5 | "eamodio.gitlens", 6 | "editorconfig.editorconfig" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"], 3 | "editor.defaultFormatter": "esbenp.prettier-vscode", 4 | "editor.formatOnSave": true, 5 | "editor.codeActionsOnSave": { 6 | "source.fixAll.eslint": "explicit" 7 | }, 8 | "typescript.tsdk": "./node_modules/typescript/lib", 9 | "typescript.preferences.includePackageJsonAutoImports": "off" 10 | } 11 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby ">= 2.6.10" 5 | 6 | # Exclude problematic versions of cocoapods and activesupport that causes build failures. 7 | gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1' 8 | gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0' 9 | gem 'xcodeproj', '< 1.26.0' 10 | gem 'concurrent-ruby', '< 1.3.4' 11 | 12 | # Ruby 3.4.0 has removed some libraries from the standard library. 13 | gem 'bigdecimal' 14 | gem 'logger' 15 | gem 'benchmark' 16 | gem 'mutex_m' 17 | -------------------------------------------------------------------------------- /android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/android/app/debug.keystore -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/example/myuidemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.myuidemo; 2 | 3 | import com.reactnative.hybridnavigation.ReactAppCompatActivity; 4 | 5 | public class MainActivity extends ReactAppCompatActivity { 6 | 7 | } -------------------------------------------------------------------------------- /android/app/src/main/java/com/example/myuidemo/MyUiPackage.java: -------------------------------------------------------------------------------- 1 | package com.example.myuidemo; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import com.facebook.react.ReactPackage; 6 | import com.facebook.react.bridge.NativeModule; 7 | import com.facebook.react.bridge.ReactApplicationContext; 8 | import com.facebook.react.uimanager.ViewManager; 9 | import com.reactnativecommunity.webview.RNCNestedScrollWebViewManager; 10 | 11 | import java.util.Arrays; 12 | import java.util.Collections; 13 | import java.util.List; 14 | 15 | public class MyUiPackage implements ReactPackage { 16 | @NonNull 17 | @Override 18 | public List createNativeModules(@NonNull ReactApplicationContext reactContext) { 19 | return Collections.emptyList(); 20 | } 21 | 22 | @NonNull 23 | @Override 24 | public List createViewManagers(@NonNull ReactApplicationContext reactContext) { 25 | return Arrays.asList( 26 | new RNCNestedScrollWebViewManager() 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | MyUiDemo 3 | 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext { 3 | buildToolsVersion = "35.0.0" 4 | minSdkVersion = 24 5 | compileSdkVersion = 35 6 | targetSdkVersion = 35 7 | ndkVersion = "27.1.12297006" 8 | kotlinVersion = "2.0.21" 9 | } 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle") 16 | classpath("com.facebook.react:react-native-gradle-plugin") 17 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin") 18 | } 19 | } 20 | 21 | apply plugin: "com.facebook.react.rootproject" 22 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } 2 | plugins { id("com.facebook.react.settings") } 3 | extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } 4 | rootProject.name = 'MyUiDemo' 5 | include ':app' 6 | includeBuild('../node_modules/@react-native/gradle-plugin') 7 | 8 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:@react-native/babel-preset'], 3 | plugins: [ 4 | 'react-native-reanimated/plugin', 5 | [ 6 | 'module-resolver', 7 | { 8 | root: './demo', 9 | cwd: 'babelrc', 10 | extensions: ['.ts', '.tsx', '.js', '.jsx'], 11 | alias: { 12 | assets: './demo/assets', 13 | }, 14 | }, 15 | ], 16 | ], 17 | }; 18 | -------------------------------------------------------------------------------- /demo/activity-indicator/ActivityIndicatorScreen.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {View, StyleSheet} from 'react-native'; 3 | 4 | import ActivityIndicator from '@sdcx/activity-indicator'; 5 | import {withNavigationItem} from 'hybrid-navigation'; 6 | 7 | function ActivityIndicatorScreen() { 8 | return ( 9 | 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | } 17 | 18 | export default withNavigationItem({ 19 | titleItem: { 20 | title: '菊花 Loading', 21 | }, 22 | })(ActivityIndicatorScreen); 23 | 24 | const styles = StyleSheet.create({ 25 | container: { 26 | flex: 1, 27 | flexDirection: 'row', 28 | justifyContent: 'space-around', 29 | alignItems: 'center', 30 | paddingHorizontal: 80, 31 | }, 32 | }); 33 | -------------------------------------------------------------------------------- /demo/assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/adaptive-icon.png -------------------------------------------------------------------------------- /demo/assets/album-art-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/album-art-1.jpg -------------------------------------------------------------------------------- /demo/assets/album-art-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/album-art-2.jpg -------------------------------------------------------------------------------- /demo/assets/album-art-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/album-art-3.jpg -------------------------------------------------------------------------------- /demo/assets/album-art-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/album-art-4.jpg -------------------------------------------------------------------------------- /demo/assets/album-art-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/album-art-5.jpg -------------------------------------------------------------------------------- /demo/assets/album-art-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/album-art-6.jpg -------------------------------------------------------------------------------- /demo/assets/album-art-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/album-art-7.jpg -------------------------------------------------------------------------------- /demo/assets/album-art-8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/album-art-8.jpg -------------------------------------------------------------------------------- /demo/assets/anabelle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/anabelle.jpg -------------------------------------------------------------------------------- /demo/assets/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/arrow.png -------------------------------------------------------------------------------- /demo/assets/arrowOther.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/arrowOther.png -------------------------------------------------------------------------------- /demo/assets/avatar-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/avatar-1.png -------------------------------------------------------------------------------- /demo/assets/avatar-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/avatar-2.png -------------------------------------------------------------------------------- /demo/assets/book.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/book.jpg -------------------------------------------------------------------------------- /demo/assets/candice.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/candice.jpg -------------------------------------------------------------------------------- /demo/assets/checkboxOff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/checkboxOff.png -------------------------------------------------------------------------------- /demo/assets/checkboxOn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/checkboxOn.png -------------------------------------------------------------------------------- /demo/assets/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/comment.png -------------------------------------------------------------------------------- /demo/assets/cover.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/cover.webp -------------------------------------------------------------------------------- /demo/assets/egg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/egg.jpg -------------------------------------------------------------------------------- /demo/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/favicon.png -------------------------------------------------------------------------------- /demo/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/icon.png -------------------------------------------------------------------------------- /demo/assets/indicator@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/indicator@2x.png -------------------------------------------------------------------------------- /demo/assets/indicator@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/indicator@3x.png -------------------------------------------------------------------------------- /demo/assets/like.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/like.png -------------------------------------------------------------------------------- /demo/assets/mohamad.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/mohamad.jpg -------------------------------------------------------------------------------- /demo/assets/mubariz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/mubariz.jpg -------------------------------------------------------------------------------- /demo/assets/retweet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/retweet.png -------------------------------------------------------------------------------- /demo/assets/retweet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /demo/assets/send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/send.png -------------------------------------------------------------------------------- /demo/assets/share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/share.png -------------------------------------------------------------------------------- /demo/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/splash.png -------------------------------------------------------------------------------- /demo/assets/tamara.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/tamara.jpg -------------------------------------------------------------------------------- /demo/assets/window_closed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/window_closed@2x.png -------------------------------------------------------------------------------- /demo/assets/window_closed@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/assets/window_closed@3x.png -------------------------------------------------------------------------------- /demo/bottom-sheet/BottomSheetWithoutScrollView/Button.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, Text, TouchableOpacity} from 'react-native'; 3 | 4 | interface ButtonProps { 5 | onPress?: () => void; 6 | text: string; 7 | } 8 | 9 | export default function Button({onPress, text}: ButtonProps) { 10 | return ( 11 | 12 | {text} 13 | 14 | ); 15 | } 16 | 17 | const styles = StyleSheet.create({ 18 | button: { 19 | marginRight: 16, 20 | justifyContent: 'center', 21 | }, 22 | text: { 23 | fontSize: 16, 24 | color: '#FFFFFF', 25 | }, 26 | }); 27 | -------------------------------------------------------------------------------- /demo/bottom-sheet/index.ts: -------------------------------------------------------------------------------- 1 | import Navigation from 'hybrid-navigation'; 2 | 3 | import Home from './Home'; 4 | import BottomSheetWithoutScrollView from './BottomSheetWithoutScrollView'; 5 | import BottomSheetFlashList from './BottomSheetFlashList'; 6 | import BottomSheetPagerView from './BottomSheetPagerView'; 7 | import BottomSheetBackdropShadow from './BottomSheetBackdropShadow'; 8 | 9 | export function registerBottomSheetComponent() { 10 | Navigation.registerComponent('BottomSheet', () => Home); 11 | Navigation.registerComponent('BottomSheetWithoutScrollView', () => BottomSheetWithoutScrollView); 12 | Navigation.registerComponent('BottomSheetFlashList', () => BottomSheetFlashList); 13 | Navigation.registerComponent('BottomSheetPagerView', () => BottomSheetPagerView); 14 | Navigation.registerComponent('BottomSheetBackdropShadow', () => BottomSheetBackdropShadow); 15 | } 16 | -------------------------------------------------------------------------------- /demo/components/Messages/Avatar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet} from 'react-native'; 3 | import FastImage from 'react-native-fast-image'; 4 | 5 | interface AvatarProps { 6 | avatar?: string; 7 | } 8 | 9 | const Avatar = ({avatar}: AvatarProps) => { 10 | if (avatar === undefined) { 11 | return null; 12 | } 13 | return ; 14 | }; 15 | 16 | export default Avatar; 17 | 18 | const styles = StyleSheet.create({ 19 | avatar: { 20 | height: 30, 21 | width: 30, 22 | borderRadius: 15, 23 | margin: 8, 24 | marginRight: 0, 25 | marginTop: 0, 26 | flexShrink: 0, 27 | }, 28 | }); 29 | -------------------------------------------------------------------------------- /demo/components/Messages/ImageMessage.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {View, StyleSheet, Image} from 'react-native'; 3 | 4 | interface ImageMessageProps { 5 | image: string; 6 | mine: boolean; 7 | } 8 | 9 | const ImageMessage = ({image, mine}: ImageMessageProps) => { 10 | return ( 11 | 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default ImageMessage; 18 | 19 | const styles = StyleSheet.create({ 20 | otherImageWrapper: { 21 | margin: 8, 22 | }, 23 | mineImageWrapper: { 24 | margin: 8, 25 | display: 'flex', 26 | flexDirection: 'row', 27 | justifyContent: 'flex-end', 28 | }, 29 | image: { 30 | width: '80%', 31 | height: 200, 32 | borderRadius: 8, 33 | marginTop: 8, 34 | }, 35 | }); 36 | -------------------------------------------------------------------------------- /demo/components/Messages/MessageItem.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import Message from './models/Message'; 4 | import ImageMessage from './ImageMessage'; 5 | import TextBubble from './TextBubble'; 6 | import userName from './userName'; 7 | import MessageType from './models/MessageType'; 8 | 9 | const MessageItem = ({item}: {item: Message}) => { 10 | const mine = item.sender === userName; 11 | switch (item.type) { 12 | case MessageType.Text: 13 | return ; 14 | case MessageType.Image: 15 | return ; 16 | } 17 | }; 18 | 19 | export default MessageItem; 20 | -------------------------------------------------------------------------------- /demo/components/Messages/index.ts: -------------------------------------------------------------------------------- 1 | export {default as Messages} from './Messages'; 2 | export {default as MessagesFlatList} from './MessagesFlatList'; 3 | -------------------------------------------------------------------------------- /demo/components/Messages/models/Message.ts: -------------------------------------------------------------------------------- 1 | import MessageType from './MessageType'; 2 | 3 | export interface TextMessage { 4 | id: string; 5 | text: string; 6 | avatar?: string; 7 | sender: string; 8 | type: MessageType.Text; 9 | } 10 | 11 | export interface ImageMessage { 12 | id: string; 13 | avatar?: string; 14 | type: MessageType.Image; 15 | sender: string; 16 | image: string; 17 | } 18 | 19 | type Message = ImageMessage | TextMessage; 20 | 21 | export default Message; 22 | -------------------------------------------------------------------------------- /demo/components/Messages/models/MessageType.ts: -------------------------------------------------------------------------------- 1 | enum MessageType { 2 | Text, 3 | Image, 4 | } 5 | export default MessageType; 6 | -------------------------------------------------------------------------------- /demo/components/Messages/userName.tsx: -------------------------------------------------------------------------------- 1 | const userName = 'John'; 2 | export default userName; 3 | -------------------------------------------------------------------------------- /demo/components/Modal.tsx: -------------------------------------------------------------------------------- 1 | import React, {PropsWithChildren} from 'react'; 2 | import {useNavigator} from 'hybrid-navigation'; 3 | import {Pressable, StyleProp, StyleSheet, View, ViewStyle} from 'react-native'; 4 | 5 | interface ModalProps { 6 | cancelable?: boolean; 7 | style?: StyleProp; 8 | } 9 | 10 | export function Modal(props: PropsWithChildren) { 11 | const {cancelable = true, style, children} = props; 12 | 13 | const navigator = useNavigator(); 14 | 15 | const onPress = () => { 16 | if (cancelable) { 17 | navigator.hideModal(); 18 | } 19 | }; 20 | 21 | return ( 22 | 23 | 24 | {children} 25 | 26 | ); 27 | } 28 | 29 | const styles = StyleSheet.create({ 30 | container: { 31 | flex: 1, 32 | justifyContent: 'center', 33 | }, 34 | overlay: { 35 | position: 'absolute', 36 | left: 0, 37 | right: 0, 38 | top: 0, 39 | bottom: 0, 40 | }, 41 | box: { 42 | backgroundColor: '#FFFFFF', 43 | borderRadius: 12, 44 | marginHorizontal: 48, 45 | minHeight: 160, 46 | overflow: 'hidden', 47 | }, 48 | }); 49 | -------------------------------------------------------------------------------- /demo/components/ModalButton.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Pressable, StyleProp, StyleSheet, Text, TextStyle, ViewStyle} from 'react-native'; 3 | 4 | interface ModalButtonProps { 5 | text: string; 6 | onPress?: () => void; 7 | buttonStyle?: StyleProp; 8 | textStyle?: StyleProp; 9 | } 10 | 11 | export default function ModalButton(props: ModalButtonProps) { 12 | const {text, onPress, buttonStyle, textStyle} = props; 13 | return ( 14 | 15 | {text} 16 | 17 | ); 18 | } 19 | 20 | const styles = StyleSheet.create({ 21 | button: { 22 | flex: 1, 23 | alignItems: 'center', 24 | justifyContent: 'center', 25 | }, 26 | 27 | text: { 28 | fontSize: 18, 29 | }, 30 | }); 31 | -------------------------------------------------------------------------------- /demo/components/ModalToolbar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, View} from 'react-native'; 3 | import ModalButton from './ModalButton'; 4 | 5 | interface ModalToolbarProps { 6 | onCancel?: () => void; 7 | onConfirm?: () => void; 8 | } 9 | 10 | export function ModalToolbar(props: ModalToolbarProps) { 11 | const {onCancel, onConfirm} = props; 12 | return ( 13 | 14 | 15 | 22 | 23 | ); 24 | } 25 | 26 | const styles = StyleSheet.create({ 27 | divider: { 28 | borderLeftColor: '#DFE3E579', 29 | borderLeftWidth: 1, 30 | }, 31 | textCancel: { 32 | color: '#292F33', 33 | }, 34 | textConfirm: { 35 | color: '#1A9EFF', 36 | }, 37 | buttons: { 38 | borderTopColor: '#DFE3E579', 39 | borderTopWidth: 1, 40 | flexDirection: 'row', 41 | height: 48, 42 | }, 43 | }); 44 | -------------------------------------------------------------------------------- /demo/components/TabBar/TabBarIndicator.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Animated, StyleProp, StyleSheet, ViewStyle} from 'react-native'; 3 | 4 | interface TabBarIndicatorProps { 5 | style?: StyleProp; 6 | scrollX: Animated.AnimatedInterpolation; 7 | } 8 | 9 | export default function TabBarIndicator({style, scrollX}: TabBarIndicatorProps) { 10 | return ( 11 | 15 | ); 16 | } 17 | 18 | const styles = StyleSheet.create({ 19 | indicator: { 20 | position: 'absolute', 21 | left: 0, 22 | bottom: 0, 23 | width: 24, 24 | height: 4, 25 | backgroundColor: '#448AFF', 26 | borderRadius: 2, 27 | }, 28 | }); 29 | -------------------------------------------------------------------------------- /demo/components/TabBar/TabBarItem.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Animated, 4 | Pressable, 5 | StyleProp, 6 | StyleSheet, 7 | TextStyle, 8 | ViewProps, 9 | ViewStyle, 10 | } from 'react-native'; 11 | 12 | interface TabBarItemProps { 13 | title: string; 14 | onPress?: () => void; 15 | onLayout: ViewProps['onLayout']; 16 | style?: StyleProp; 17 | labelStyle?: 18 | | Animated.WithAnimatedObject 19 | | Animated.WithAnimatedArray>; 20 | } 21 | 22 | export default function TabBarItem({title, style, labelStyle, onPress, onLayout}: TabBarItemProps) { 23 | return ( 24 | 25 | {title} 26 | 27 | ); 28 | } 29 | 30 | const styles = StyleSheet.create({ 31 | tab: { 32 | height: '100%', 33 | minWidth: 24, 34 | justifyContent: 'center', 35 | alignItems: 'center', 36 | }, 37 | label: { 38 | color: '#333333', 39 | fontSize: 16, 40 | }, 41 | }); 42 | -------------------------------------------------------------------------------- /demo/components/TabBar/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet} from 'react-native'; 3 | import ScrollBar from './ScrollBar'; 4 | import TabBar, {TabBarProps} from './TabBar'; 5 | 6 | export default function (props: TabBarProps) { 7 | return ( 8 | 9 | 10 | 11 | ); 12 | } 13 | 14 | const styles = StyleSheet.create({ 15 | scrollbar: { 16 | height: 48, 17 | flexGrow: 0, 18 | }, 19 | tabbar: { 20 | height: '100%', 21 | borderBottomColor: '#eee', 22 | borderBottomWidth: 1, 23 | flex: 1, 24 | justifyContent: 'space-evenly', 25 | }, 26 | tab: { 27 | paddingHorizontal: 16, 28 | }, 29 | }); 30 | -------------------------------------------------------------------------------- /demo/components/contacts/ContactCell.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, View, Text} from 'react-native'; 3 | 4 | import Contact from './models/Contact'; 5 | 6 | interface ContactCellProps { 7 | contact: Contact; 8 | } 9 | 10 | const ContactCell = ({contact}: ContactCellProps) => { 11 | return ( 12 | 13 | 14 | {contact.firstName} 15 | {contact.lastName} 16 | 17 | 18 | ); 19 | }; 20 | 21 | export default ContactCell; 22 | 23 | const styles = StyleSheet.create({ 24 | rowContainer: { 25 | backgroundColor: 'white', 26 | padding: 10, 27 | }, 28 | firstName: { 29 | fontSize: 18, 30 | }, 31 | lastName: { 32 | fontSize: 18, 33 | fontWeight: 'bold', 34 | }, 35 | }); 36 | -------------------------------------------------------------------------------- /demo/components/contacts/ContactDivider.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, View} from 'react-native'; 3 | 4 | import Contact from './models/Contact'; 5 | 6 | interface ContactDividerProps { 7 | leadingItem: Contact | string; 8 | trailingItem: Contact | string; 9 | } 10 | 11 | const ContactDivider = ({leadingItem, trailingItem}: ContactDividerProps) => { 12 | if (typeof leadingItem === 'string' || typeof trailingItem === 'string') { 13 | return null; 14 | } 15 | return ( 16 | 17 | 18 | 19 | ); 20 | }; 21 | 22 | export default ContactDivider; 23 | 24 | const styles = StyleSheet.create({ 25 | divider: { 26 | marginHorizontal: 10, 27 | height: StyleSheet.hairlineWidth, 28 | backgroundColor: '#DDD', 29 | }, 30 | dividerContainer: { 31 | height: StyleSheet.hairlineWidth, 32 | backgroundColor: 'white', 33 | }, 34 | }); 35 | -------------------------------------------------------------------------------- /demo/components/contacts/ContactHeader.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Text, StyleSheet} from 'react-native'; 3 | 4 | const ContactHeader = () => { 5 | return My contacts; 6 | }; 7 | 8 | export default ContactHeader; 9 | 10 | const styles = StyleSheet.create({ 11 | headerTitle: { 12 | backgroundColor: 'white', 13 | paddingHorizontal: 10, 14 | paddingVertical: 20, 15 | fontSize: 17, 16 | fontWeight: 'bold', 17 | }, 18 | }); 19 | -------------------------------------------------------------------------------- /demo/components/contacts/ContactSectionHeader.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, View, Text} from 'react-native'; 3 | 4 | interface ContactSectionHeaderProps { 5 | title: string; 6 | } 7 | 8 | const ContactSectionHeader = ({title}: ContactSectionHeaderProps) => { 9 | return ( 10 | 11 | {title} 12 | 13 | ); 14 | }; 15 | 16 | export default ContactSectionHeader; 17 | 18 | const styles = StyleSheet.create({ 19 | headerTitle: { 20 | paddingLeft: 10, 21 | paddingVertical: 4, 22 | }, 23 | header: { 24 | backgroundColor: '#FAFAFA', 25 | }, 26 | }); 27 | -------------------------------------------------------------------------------- /demo/components/contacts/models/Contact.ts: -------------------------------------------------------------------------------- 1 | export default interface Contact { 2 | firstName: string; 3 | lastName: string; 4 | } 5 | -------------------------------------------------------------------------------- /demo/components/tabview/Shared/Albums.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import {Image, Dimensions, ScrollView, StyleSheet} from 'react-native'; 3 | 4 | const COVERS = [ 5 | require('assets/album-art-1.jpg'), 6 | require('assets/album-art-2.jpg'), 7 | require('assets/album-art-3.jpg'), 8 | require('assets/album-art-4.jpg'), 9 | require('assets/album-art-5.jpg'), 10 | require('assets/album-art-6.jpg'), 11 | require('assets/album-art-7.jpg'), 12 | require('assets/album-art-8.jpg'), 13 | ]; 14 | 15 | const Albums = () => { 16 | return ( 17 | 18 | {COVERS.map((source, i) => ( 19 | 20 | ))} 21 | 22 | ); 23 | }; 24 | 25 | export default Albums; 26 | 27 | const styles = StyleSheet.create({ 28 | container: { 29 | backgroundColor: '#343C46', 30 | }, 31 | content: { 32 | flexDirection: 'row', 33 | flexWrap: 'wrap', 34 | }, 35 | cover: { 36 | width: '50%', 37 | height: Dimensions.get('window').width / 2, 38 | }, 39 | }); 40 | -------------------------------------------------------------------------------- /demo/components/twitter/TweetCell.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Pressable} from 'react-native'; 3 | 4 | import Tweet from './models/Tweet'; 5 | import TweetContent from './TweetContent'; 6 | 7 | export interface TweetCellProps { 8 | tweet: Tweet; 9 | } 10 | 11 | const TweetCell = ({tweet}: TweetCellProps) => { 12 | return ( 13 | {}}> 14 | 15 | 16 | ); 17 | }; 18 | 19 | export default TweetCell; 20 | -------------------------------------------------------------------------------- /demo/components/twitter/index.ts: -------------------------------------------------------------------------------- 1 | export {default as Twitter} from './Twitter'; 2 | export {default as TwitterFlatList} from './TwitterFlatList'; 3 | -------------------------------------------------------------------------------- /demo/components/twitter/models/Author.ts: -------------------------------------------------------------------------------- 1 | export default interface Author { 2 | name: string; 3 | avatar: string; 4 | screenName: string; 5 | } 6 | -------------------------------------------------------------------------------- /demo/components/twitter/models/Tweet.ts: -------------------------------------------------------------------------------- 1 | import Author from './Author'; 2 | 3 | export default interface Tweet { 4 | id: string; 5 | author: Author; 6 | fullText: string; 7 | retweetCount: number; 8 | replyCount: number; 9 | favoriteCount: number; 10 | } 11 | -------------------------------------------------------------------------------- /demo/image-crop/ImageCropResultPage.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {NavigationProps, withNavigationItem} from 'hybrid-navigation'; 3 | import {StyleSheet, View} from 'react-native'; 4 | import FastImage from 'react-native-fast-image'; 5 | 6 | interface Props extends NavigationProps { 7 | fileUri: string; 8 | } 9 | 10 | function ImageCropResultPage({fileUri}: Props) { 11 | return ( 12 | 13 | 21 | 22 | ); 23 | } 24 | 25 | export default withNavigationItem({titleItem: {title: 'CropResultPage'}})(ImageCropResultPage); 26 | 27 | const styles = StyleSheet.create({ 28 | container: { 29 | flex: 1, 30 | justifyContent: 'flex-start', 31 | alignItems: 'stretch', 32 | backgroundColor: '#eef', 33 | }, 34 | image: { 35 | flex: 1, 36 | }, 37 | }); 38 | -------------------------------------------------------------------------------- /demo/image-crop/index.ts: -------------------------------------------------------------------------------- 1 | import Navigation from 'hybrid-navigation'; 2 | 3 | import ImageCropDemo from './ImageCropDemo'; 4 | import ImageCropPage from './ImageCropPage'; 5 | import ImageCropResultPage from './ImageCropResultPage'; 6 | 7 | export function registerImageCropComponent() { 8 | Navigation.registerComponent('ImageCropDemo', () => ImageCropDemo); 9 | Navigation.registerComponent('ImageCropPage', () => ImageCropPage); 10 | Navigation.registerComponent('ImageCropResultPage', () => ImageCropResultPage); 11 | } 12 | -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChat/Message/data.ts: -------------------------------------------------------------------------------- 1 | import type {MessageProps} from './types'; 2 | 3 | export const history: MessageProps[] = [ 4 | {text: 'Hmmmm🤔'}, 5 | {text: 'It looks like it still will be laggy...'}, 6 | {text: "But I don't know what should I try next"}, 7 | {text: 'Reanimated?', sender: true}, 8 | {text: 'A little bit disappointed 😔'}, 9 | {text: '🤯'}, 10 | {text: 'Try to check it. I hope it helps you...', sender: true}, 11 | {text: 'It really pushes you to think twice on how to design it first'}, 12 | { 13 | text: 'Looks promising!😎 I was always looking for a solution that would allow us to run animations on native thread and provide at least stable 60 FPS', 14 | }, 15 | {text: 'You have to check it!!!', sender: true}, 16 | {text: "Ha-ha! I'm definitely going to check it!"}, 17 | {text: 'Hello! How are you?'}, 18 | {text: "Hi! I'm good. How are you?", sender: true}, 19 | { 20 | text: "I'm fine, thank you! Have you seen new keyboard animation library?", 21 | }, 22 | {text: 'No! Let me check.', sender: true}, 23 | { 24 | text: "Wow! I've been looking for it for a while. It's awesome!", 25 | sender: true, 26 | }, 27 | ]; 28 | -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChat/Message/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Text, View} from 'react-native'; 3 | import styles from './styles'; 4 | 5 | import type {MessageProps} from './types'; 6 | 7 | export default function Message({text, sender}: MessageProps) { 8 | return ( 9 | 10 | {text} 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChat/Message/styles.ts: -------------------------------------------------------------------------------- 1 | import {StyleSheet} from 'react-native'; 2 | 3 | const container = { 4 | borderRadius: 10, 5 | padding: 10, 6 | margin: 10, 7 | marginVertical: 5, 8 | }; 9 | export default StyleSheet.create({ 10 | senderContainer: { 11 | alignSelf: 'flex-end', 12 | backgroundColor: '#e0e0e0', 13 | ...container, 14 | }, 15 | recipientContainer: { 16 | alignSelf: 'flex-start', 17 | backgroundColor: '#50FF00', 18 | ...container, 19 | }, 20 | message: { 21 | color: '#000000', 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChat/Message/types.ts: -------------------------------------------------------------------------------- 1 | export type MessageProps = { 2 | text: string; 3 | sender?: boolean; 4 | }; 5 | -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChat/driver/Driver.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Animated} from 'react-native'; 3 | 4 | export interface DriverState { 5 | // sender bottom 6 | bottom: number; 7 | driver: Driver | undefined; 8 | setDriver: React.Dispatch>; 9 | setTranslateY: React.Dispatch>; 10 | } 11 | 12 | export interface Driver { 13 | show: (state: DriverState) => void; 14 | hide: (state: DriverState) => void; 15 | toggle: (state: DriverState) => void; 16 | shown: boolean; 17 | height: number; 18 | name: string; 19 | } 20 | -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChat/icon/emoji@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/keyboard-insets/KeyboardChat/icon/emoji@2x.png -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChat/icon/emoji@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/keyboard-insets/KeyboardChat/icon/emoji@3x.png -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChat/icon/keyboard@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/keyboard-insets/KeyboardChat/icon/keyboard@2x.png -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChat/icon/keyboard@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/keyboard-insets/KeyboardChat/icon/keyboard@3x.png -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChat/icon/plus@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/keyboard-insets/KeyboardChat/icon/plus@2x.png -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChat/icon/plus@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/keyboard-insets/KeyboardChat/icon/plus@3x.png -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChatReanimated/Message/data.ts: -------------------------------------------------------------------------------- 1 | import type {MessageProps} from './types'; 2 | 3 | export const history: MessageProps[] = [ 4 | {text: 'Hmmmm🤔'}, 5 | {text: 'It looks like it still will be laggy...'}, 6 | {text: "But I don't know what should I try next"}, 7 | {text: 'Reanimated?', sender: true}, 8 | {text: 'A little bit disappointed 😔'}, 9 | {text: '🤯'}, 10 | {text: 'Try to check it. I hope it helps you...', sender: true}, 11 | {text: 'It really pushes you to think twice on how to design it first'}, 12 | { 13 | text: 'Looks promising!😎 I was always looking for a solution that would allow us to run animations on native thread and provide at least stable 60 FPS', 14 | }, 15 | {text: 'You have to check it!!!', sender: true}, 16 | {text: "Ha-ha! I'm definitely going to check it!"}, 17 | {text: 'Hello! How are you?'}, 18 | {text: "Hi! I'm good. How are you?", sender: true}, 19 | { 20 | text: "I'm fine, thank you! Have you seen new keyboard animation library?", 21 | }, 22 | {text: 'No! Let me check.', sender: true}, 23 | { 24 | text: "Wow! I've been looking for it for a while. It's awesome!", 25 | sender: true, 26 | }, 27 | ]; 28 | -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChatReanimated/Message/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Text, View} from 'react-native'; 3 | import styles from './styles'; 4 | 5 | import type {MessageProps} from './types'; 6 | 7 | export default function Message({text, sender}: MessageProps) { 8 | return ( 9 | 10 | {text} 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChatReanimated/Message/styles.ts: -------------------------------------------------------------------------------- 1 | import {StyleSheet} from 'react-native'; 2 | 3 | const container = { 4 | borderRadius: 10, 5 | padding: 10, 6 | margin: 10, 7 | marginVertical: 5, 8 | }; 9 | export default StyleSheet.create({ 10 | senderContainer: { 11 | alignSelf: 'flex-end', 12 | backgroundColor: '#e0e0e0', 13 | ...container, 14 | }, 15 | recipientContainer: { 16 | alignSelf: 'flex-start', 17 | backgroundColor: '#50FF00', 18 | ...container, 19 | }, 20 | message: { 21 | color: '#000000', 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChatReanimated/Message/types.ts: -------------------------------------------------------------------------------- 1 | export type MessageProps = { 2 | text: string; 3 | sender?: boolean; 4 | }; 5 | -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChatReanimated/icon/emoji@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/keyboard-insets/KeyboardChatReanimated/icon/emoji@2x.png -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChatReanimated/icon/emoji@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/keyboard-insets/KeyboardChatReanimated/icon/emoji@3x.png -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChatReanimated/icon/keyboard@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/keyboard-insets/KeyboardChatReanimated/icon/keyboard@2x.png -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChatReanimated/icon/keyboard@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/keyboard-insets/KeyboardChatReanimated/icon/keyboard@3x.png -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChatReanimated/icon/plus@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/keyboard-insets/KeyboardChatReanimated/icon/plus@2x.png -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChatReanimated/icon/plus@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcxtech/react-native-troika/d4c478eee06564bece181f5cfbc97fc2f12b930e/demo/keyboard-insets/KeyboardChatReanimated/icon/plus@3x.png -------------------------------------------------------------------------------- /demo/keyboard-insets/KeyboardChatReanimated/useRekeyboard.ts: -------------------------------------------------------------------------------- 1 | import {useCallback} from 'react'; 2 | import {useSharedValue} from 'react-native-reanimated'; 3 | import { 4 | KeyboardPositionChangedEventData, 5 | KeyboardStatusChangedEventData, 6 | } from '@sdcx/keyboard-insets'; 7 | 8 | export function useRekeyboard() { 9 | const position = useSharedValue(0); 10 | const height = useSharedValue(0); 11 | const shown = useSharedValue(false); 12 | const transitioning = useSharedValue(false); 13 | 14 | const onStatusChanged = useCallback( 15 | (e: KeyboardStatusChangedEventData) => { 16 | 'worklet'; 17 | shown.value = e.shown; 18 | transitioning.value = e.transitioning; 19 | height.value = e.height; 20 | }, 21 | [shown, transitioning, height], 22 | ); 23 | 24 | const onPositionChanged = useCallback( 25 | (e: KeyboardPositionChangedEventData) => { 26 | 'worklet'; 27 | position.value = e.position; 28 | }, 29 | [position], 30 | ); 31 | 32 | const keyboard = { 33 | position, 34 | height, 35 | shown, 36 | transitioning, 37 | }; 38 | 39 | return {keyboard, onStatusChanged, onPositionChanged}; 40 | } 41 | -------------------------------------------------------------------------------- /demo/keyboard-insets/index.ts: -------------------------------------------------------------------------------- 1 | import Navigation from 'hybrid-navigation'; 2 | 3 | import Home from './Home'; 4 | import KeyboardAdvoiding from './KeyboardAdvoiding'; 5 | import KeyboardChat from './KeyboardChat'; 6 | import KeyboardChatReanimated from './KeyboardChatReanimated'; 7 | import ModalTextInput from './ModalTextInput'; 8 | 9 | export function registerKeyboardComponent() { 10 | Navigation.registerComponent('Keyboard', () => Home); 11 | Navigation.registerComponent('KeyboardAdvoiding', () => KeyboardAdvoiding); 12 | Navigation.registerComponent('KeyboardChat', () => KeyboardChat); 13 | Navigation.registerComponent('KeyboardChatReanimated', () => KeyboardChatReanimated); 14 | Navigation.registerComponent('ModalTextInput', () => ModalTextInput); 15 | } 16 | -------------------------------------------------------------------------------- /demo/nested-scroll/NestedScrollParallaxHeader/components/HeaderComponent.tsx: -------------------------------------------------------------------------------- 1 | import {StyleSheet, Text, View} from 'react-native'; 2 | import React from 'react'; 3 | 4 | export const HeaderComponent = () => ( 5 | 6 | 7 | Foreground component 8 | 9 | 10 | ); 11 | 12 | const styles = StyleSheet.create({ 13 | container: { 14 | flex: 1, 15 | backgroundColor: 'transparent', 16 | alignItems: 'center', 17 | justifyContent: 'center', 18 | }, 19 | titleContainer: { 20 | backgroundColor: 'red', 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /demo/nested-scroll/NestedScrollParallaxHeader/components/HeaderNavBar.tsx: -------------------------------------------------------------------------------- 1 | import {RoundButton} from './RoundButton'; 2 | import {StyleSheet, View} from 'react-native'; 3 | import * as React from 'react'; 4 | import ArrowLeft from '../icons/ArrowLeft'; 5 | import ArrowRight from '../icons/ArrowRight'; 6 | import {Share} from '../icons/Share'; 7 | import {useNavigator} from 'hybrid-navigation'; 8 | 9 | export const HeaderNavBar = () => { 10 | const navigator = useNavigator(); 11 | return ( 12 | 13 | } onPress={navigator.pop} /> 14 | 15 | 16 | } onPress={() => null} /> 17 | 18 | } onPress={() => null} /> 19 | 20 | 21 | ); 22 | }; 23 | 24 | const styles = StyleSheet.create({ 25 | container: { 26 | width: '100%', 27 | paddingHorizontal: 8, 28 | flexDirection: 'row', 29 | justifyContent: 'space-between', 30 | }, 31 | btnRightContainer: { 32 | flexDirection: 'row', 33 | alignItems: 'center', 34 | }, 35 | btnRight: { 36 | marginRight: 8, 37 | }, 38 | }); 39 | -------------------------------------------------------------------------------- /demo/nested-scroll/NestedScrollParallaxHeader/components/RoundButton.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import {StyleSheet, TouchableOpacity} from 'react-native'; 3 | 4 | type Props = { 5 | icon: JSX.Element; 6 | onPress: () => void; 7 | }; 8 | export const RoundButton = ({icon, onPress}: Props) => { 9 | return ( 10 | 11 | {icon} 12 | 13 | ); 14 | }; 15 | const styles = StyleSheet.create({ 16 | container: { 17 | backgroundColor: 'white', 18 | width: 30, 19 | height: 30, 20 | borderRadius: 15, 21 | alignItems: 'center', 22 | justifyContent: 'center', 23 | }, 24 | }); 25 | -------------------------------------------------------------------------------- /demo/nested-scroll/NestedScrollParallaxHeader/hooks/useAnimatedNavbar.ts: -------------------------------------------------------------------------------- 1 | // fork:https://github.com/kanelloc/react-native-animated-header-scroll-view/blob/main/src/hooks/useAnimateNavbar.ts 2 | 3 | import type {Animated} from 'react-native'; 4 | 5 | export const useAnimatedNavbar = ( 6 | scroll: Animated.Value, 7 | imageHeight: number, 8 | headerHeight: number, 9 | ) => { 10 | const HEADER_HEIGHT_DIFFERENCE = imageHeight - headerHeight; 11 | const headerOpacity = scroll.interpolate({ 12 | inputRange: [0, HEADER_HEIGHT_DIFFERENCE * 0.75, HEADER_HEIGHT_DIFFERENCE], 13 | outputRange: [0, 0, 1], 14 | extrapolate: 'clamp', 15 | }); 16 | const overflowHeaderOpacity = scroll.interpolate({ 17 | inputRange: [0, HEADER_HEIGHT_DIFFERENCE * 0.75, HEADER_HEIGHT_DIFFERENCE], 18 | outputRange: [1, 1, 0], 19 | extrapolate: 'clamp', 20 | }); 21 | 22 | return [headerOpacity, overflowHeaderOpacity]; 23 | }; 24 | -------------------------------------------------------------------------------- /demo/nested-scroll/NestedScrollParallaxHeader/icons/ArrowLeft.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import Svg, {Path} from 'react-native-svg'; 3 | import {StyleSheet} from 'react-native'; 4 | 5 | const ArrowLeft = (props: any) => ( 6 | 12 | 20 | 21 | ); 22 | 23 | export default ArrowLeft; 24 | -------------------------------------------------------------------------------- /demo/nested-scroll/NestedScrollParallaxHeader/icons/ArrowRight.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import {StyleSheet} from 'react-native'; 3 | import type {SvgProps} from 'react-native-svg'; 4 | import Svg, {Path} from 'react-native-svg'; 5 | 6 | const ArrowRight = ({color = '#000000', style, ...props}: SvgProps) => ( 7 | 14 | 18 | 19 | ); 20 | 21 | export default ArrowRight; 22 | -------------------------------------------------------------------------------- /demo/nested-scroll/NestedScrollParallaxHeader/icons/Share.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import type {SvgProps} from 'react-native-svg'; 3 | import Svg, {Path} from 'react-native-svg'; 4 | 5 | export const Share = (props: SvgProps) => ( 6 | 7 | 14 | 15 | ); 16 | -------------------------------------------------------------------------------- /demo/nested-scroll/index.ts: -------------------------------------------------------------------------------- 1 | import Navigation from 'hybrid-navigation'; 2 | 3 | import Home from './Home'; 4 | import NestedScrollFlatList from './NestedScrollFlatList'; 5 | import NestedScrollParallaxHeader from './NestedScrollParallaxHeader'; 6 | import NestedScrollTabView from './NestedScrollTabView'; 7 | import NestedScrollPagerViewStickyHeader from './NestedScrollPagerViewStickyHeader'; 8 | 9 | export function registerNestedScrollComponent() { 10 | Navigation.registerComponent('NestedScroll', () => Home); 11 | Navigation.registerComponent('NestedScrollFlatList', () => NestedScrollFlatList); 12 | Navigation.registerComponent('NestedScrollParallaxHeader', () => NestedScrollParallaxHeader); 13 | Navigation.registerComponent('NestedScrollTabView', () => NestedScrollTabView); 14 | Navigation.registerComponent( 15 | 'NestedScrollPagerViewStickyHeader', 16 | () => NestedScrollPagerViewStickyHeader, 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /demo/overlay/Alert/Button.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, Text, ViewProps, TextStyle, StyleProp, Pressable} from 'react-native'; 3 | 4 | interface Props extends ViewProps { 5 | onPress: () => void; 6 | text: string; 7 | textStyle?: StyleProp; 8 | } 9 | 10 | export default function Button({style, text, onPress, textStyle}: Props) { 11 | return ( 12 | 13 | {text} 14 | 15 | ); 16 | } 17 | 18 | const styles = StyleSheet.create({ 19 | button: { 20 | height: 44, 21 | flex: 1, 22 | borderRadius: 4, 23 | alignItems: 'center', 24 | justifyContent: 'center', 25 | backgroundColor: '#F2F6FC', 26 | }, 27 | text: { 28 | fontSize: 16, 29 | color: '#606972', 30 | fontWeight: 'bold', 31 | }, 32 | }); 33 | -------------------------------------------------------------------------------- /demo/overlay/Alert/Message.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, Text, View} from 'react-native'; 3 | 4 | interface MessageProps { 5 | message: string; 6 | } 7 | 8 | export default function Message({message}: MessageProps) { 9 | return ( 10 | 11 | {message} 12 | 13 | ); 14 | } 15 | 16 | const styles = StyleSheet.create({ 17 | box: { 18 | paddingHorizontal: 12, 19 | }, 20 | message: { 21 | color: '#1D2023', 22 | fontSize: 15, 23 | lineHeight: 25, 24 | marginVertical: 6, 25 | }, 26 | }); 27 | -------------------------------------------------------------------------------- /demo/overlay/Alert/Title.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, Text} from 'react-native'; 3 | 4 | interface TitleProps { 5 | title: string; 6 | } 7 | 8 | export default function Title({title}: TitleProps) { 9 | return {title}; 10 | } 11 | 12 | const styles = StyleSheet.create({ 13 | title: { 14 | color: '#1D2023', 15 | fontSize: 17, 16 | fontWeight: 'bold', 17 | lineHeight: 26, 18 | alignSelf: 'center', 19 | marginVertical: 6, 20 | }, 21 | }); 22 | -------------------------------------------------------------------------------- /demo/overlay/Hoverball/types.ts: -------------------------------------------------------------------------------- 1 | export interface Anchor { 2 | x: number; 3 | y: number; 4 | size: number; 5 | } 6 | 7 | export interface BallProps { 8 | anchor: Anchor; 9 | onOffsetChanged?: (x: number, y: number) => void; 10 | } 11 | -------------------------------------------------------------------------------- /demo/overlay/HoverballScreen.tsx: -------------------------------------------------------------------------------- 1 | import React, {useEffect} from 'react'; 2 | import {View, Text, StyleSheet, Switch} from 'react-native'; 3 | import {withNavigationItem} from 'hybrid-navigation'; 4 | import Hoverball from './Hoverball'; 5 | 6 | function FloatingBall() { 7 | const [enabled, setEnabled] = React.useState(false); 8 | 9 | useEffect(() => { 10 | enabled ? Hoverball.show() : Hoverball.hide(); 11 | }, [enabled]); 12 | 13 | return ( 14 | 15 | 开启或关闭悬浮球 16 | 17 | 18 | 19 | ); 20 | } 21 | 22 | export default withNavigationItem({ 23 | titleItem: { 24 | title: '悬浮球', 25 | }, 26 | })(FloatingBall); 27 | 28 | const styles = StyleSheet.create({ 29 | container: { 30 | flex: 1, 31 | justifyContent: 'flex-start', 32 | alignItems: 'stretch', 33 | paddingTop: 16, 34 | paddingLeft: 32, 35 | paddingRight: 32, 36 | }, 37 | text: { 38 | backgroundColor: 'transparent', 39 | fontSize: 17, 40 | alignSelf: 'center', 41 | }, 42 | }); 43 | -------------------------------------------------------------------------------- /demo/overlay/ToastScreen.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {View, StyleSheet, Button} from 'react-native'; 3 | import {withNavigationItem} from 'hybrid-navigation'; 4 | import Toast from './Toast'; 5 | 6 | function ToastScreen() { 7 | return ( 8 | 9 |