├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── deprecated-react-native-ios-adsupport ├── AdSupportIOS.js ├── index.js ├── ios │ ├── RCTAdSupport.h │ ├── RCTAdSupport.m │ └── RCTDeprecatedAdSupport.xcodeproj │ │ └── project.pbxproj └── package.json ├── deprecated-react-native-ios-mapview ├── DeprecatedMapView.js ├── index.js ├── ios │ ├── RCTConvert+MapKit.h │ ├── RCTConvert+MapKit.m │ ├── RCTMap.h │ ├── RCTMap.m │ ├── RCTMapAnnotation.h │ ├── RCTMapAnnotation.m │ ├── RCTMapManager.h │ ├── RCTMapManager.m │ ├── RCTMapOverlay.h │ ├── RCTMapOverlay.m │ └── RNDeprecatedMapView.xcodeproj │ │ └── project.pbxproj └── package.json ├── deprecated-react-native-listview ├── CHANGELOG.md ├── InternalListViewType.js ├── ListViewDataSource.js ├── ListViewDataSource.js.flow ├── ScrollResponder.js ├── StaticRenderer.js ├── index.js ├── index.js.flow ├── isEmpty.js └── package.json ├── deprecated-react-native-prop-types ├── CHANGELOG.md ├── DeprecatedColorPropType.js ├── DeprecatedEdgeInsetsPropType.js ├── DeprecatedImagePropType.js ├── DeprecatedImageSourcePropType.js ├── DeprecatedImageStylePropTypes.js ├── DeprecatedLayoutPropTypes.js ├── DeprecatedPointPropType.js ├── DeprecatedShadowPropTypesIOS.js ├── DeprecatedStyleSheetPropType.js ├── DeprecatedTextInputPropTypes.js ├── DeprecatedTextPropTypes.js ├── DeprecatedTextStylePropTypes.js ├── DeprecatedTransformPropTypes.js ├── DeprecatedViewAccessibility.js ├── DeprecatedViewPropTypes.js ├── DeprecatedViewStylePropTypes.js ├── README.md ├── deprecatedCreateStrictShapeTypeChecker.js ├── index.js ├── package.json └── yarn.lock └── deprecated-react-native-swipeablelistview ├── SwipeableListViewDataSource.js ├── SwipeableRow.js ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | !**/*.xcodeproj 3 | !**/*.pbxproj 4 | !**/*.xcworkspacedata 5 | !**/*.xcsettings 6 | !**/*.xcscheme 7 | *.pbxuser 8 | !default.pbxuser 9 | *.mode1v3 10 | !default.mode1v3 11 | *.mode2v3 12 | !default.mode2v3 13 | *.perspectivev3 14 | !default.perspectivev3 15 | xcuserdata 16 | *.xccheckout 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | *.xcuserstate 22 | project.xcworkspace 23 | 24 | # Gradle 25 | /build/ 26 | 27 | # Android 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | /android/ 33 | 34 | # Node 35 | node_modules 36 | *.log 37 | .nvm 38 | 39 | # OS X 40 | .DS_Store -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to make participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies within all project spaces, and it also applies when 49 | an individual is representing the project or its community in public spaces. 50 | Examples of representing a project or community include using an official 51 | project e-mail address, posting via an official social media account, or acting 52 | as an appointed representative at an online or offline event. Representation of 53 | a project may be further defined and clarified by project maintainers. 54 | 55 | This Code of Conduct also applies outside the project spaces when there is a 56 | reasonable belief that an individual's behavior may have a negative impact on 57 | the project or its community. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported by contacting the project team at . All 63 | complaints will be reviewed and investigated and will result in a response that 64 | is deemed necessary and appropriate to the circumstances. The project team is 65 | obligated to maintain confidentiality with regard to the reporter of an incident. 66 | Further details of specific enforcement policies may be posted separately. 67 | 68 | Project maintainers who do not follow or enforce the Code of Conduct in good 69 | faith may face temporary or permanent repercussions as determined by other 70 | members of the project's leadership. 71 | 72 | ## Attribution 73 | 74 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 75 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 76 | 77 | [homepage]: https://www.contributor-covenant.org 78 | 79 | For answers to common questions about this code of conduct, see 80 | https://www.contributor-covenant.org/faq 81 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to react-native-deprecated-modules 2 | We want to make contributing to this project as easy and transparent as 3 | possible. 4 | 5 | ## Pull Requests 6 | We actively welcome your pull requests. 7 | 8 | 1. Fork the repo and create your branch from `main`. 9 | 2. If you've added code that should be tested, add tests. 10 | 3. If you've changed APIs, update the documentation. 11 | 4. Ensure the test suite passes. 12 | 5. Make sure your code lints. 13 | 6. If you haven't already, complete the Contributor License Agreement ("CLA"). 14 | 15 | ## Contributor License Agreement ("CLA") 16 | In order to accept your pull request, we need you to submit a CLA. You only need 17 | to do this once to work on any of Facebook's open source projects. 18 | 19 | Complete your CLA here: 20 | 21 | ## Issues 22 | We use GitHub issues to track public bugs. Please ensure your description is 23 | clear and has sufficient instructions to be able to reproduce the issue. 24 | 25 | Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe 26 | disclosure of security bugs. In those cases, please go through the process 27 | outlined on that page and do not file a public issue. 28 | 29 | ## License 30 | By contributing to react-native-deprecated-modules, you agree that your contributions will be licensed 31 | under the LICENSE file in the root directory of this source tree. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Meta Platforms, Inc. and affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Native - Deprecated Modules 2 | 3 | Packages in this repository contain modules that have been or are planned to be deprecated from [React Native](http://facebook.github.io/react-native/). 4 | 5 | You should typically avoid using these packages in your application. 6 | 7 | ## Contributing 8 | 9 | Since the packages in this repository are deprecated, major contributions to this repository will generally not be reviewed. However, if a package is deprecated but not yet completely removed from [React Native](http://facebook.github.io/react-native/), you are welcome to send a pull request. 10 | 11 | ## 📄 License 12 | 13 | React Native is MIT licensed, as found in the [LICENSE][l] file. 14 | 15 | [l]: https://github.com/facebook/react-native-deprecated-modules/blob/HEAD/LICENSE 16 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-adsupport/AdSupportIOS.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule AdSupportIOS 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | var AdSupport = require('react-native').NativeModules.AdSupport; 14 | 15 | /** 16 | * `AdSupport` provides access to the "advertising identifier". If you link this library 17 | * in your project, you may need to justify your use for this identifier when submitting 18 | * your application to the App Store. 19 | * 20 | * In order to use `AdSupport` in your project, you must link the `RCTAdSupport` library. 21 | * In Xcode, you can manually add the `RCTAdSupport.m` and `RCTAdSupport.h` files from 22 | * `node_modules/react-native/Libraries/AdSupport/` to the `Libraries/React/Base/` folder 23 | * of your current project. 24 | * 25 | * You can refer to [Linking](docs/linking-libraries-ios.html) for help. 26 | * 27 | */ 28 | 29 | module.exports = { 30 | getAdvertisingId: function(onSuccess: Function, onFailure: Function) { 31 | AdSupport.getAdvertisingId(onSuccess, onFailure); 32 | }, 33 | 34 | getAdvertisingTrackingEnabled: function(onSuccess: Function, onFailure: Function) { 35 | AdSupport.getAdvertisingTrackingEnabled(onSuccess, onFailure); 36 | }, 37 | }; 38 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-adsupport/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import AdSupportIOS from './AdSupportIOS'; 9 | 10 | export default AdSupportIOS; 11 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-adsupport/ios/RCTAdSupport.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | @interface RCTAdSupport : NSObject 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-adsupport/ios/RCTAdSupport.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "RCTAdSupport.h" 9 | 10 | #import 11 | 12 | #import 13 | 14 | @implementation RCTAdSupport 15 | 16 | RCT_EXPORT_MODULE() 17 | 18 | RCT_EXPORT_METHOD(getAdvertisingId:(RCTResponseSenderBlock)callback 19 | withErrorCallback:(RCTResponseErrorBlock)errorCallback) 20 | { 21 | NSUUID *advertisingIdentifier = [ASIdentifierManager sharedManager].advertisingIdentifier; 22 | if (advertisingIdentifier) { 23 | callback(@[advertisingIdentifier.UUIDString]); 24 | } else { 25 | errorCallback(RCTErrorWithMessage(@"Advertising identifier is unavailable.")); 26 | } 27 | } 28 | 29 | RCT_EXPORT_METHOD(getAdvertisingTrackingEnabled:(RCTResponseSenderBlock)callback 30 | withErrorCallback:(__unused RCTResponseSenderBlock)errorCallback) 31 | { 32 | callback(@[@([ASIdentifierManager sharedManager].advertisingTrackingEnabled)]); 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-adsupport/ios/RCTDeprecatedAdSupport.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 832C819C1AAF6E1A007FA2F7 /* RCTAdSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 832C819B1AAF6E1A007FA2F7 /* RCTAdSupport.m */; }; 11 | /* End PBXBuildFile section */ 12 | 13 | /* Begin PBXCopyFilesBuildPhase section */ 14 | 832C817E1AAF6DEF007FA2F7 /* CopyFiles */ = { 15 | isa = PBXCopyFilesBuildPhase; 16 | buildActionMask = 2147483647; 17 | dstPath = "include/$(PRODUCT_NAME)"; 18 | dstSubfolderSpec = 16; 19 | files = ( 20 | ); 21 | runOnlyForDeploymentPostprocessing = 0; 22 | }; 23 | /* End PBXCopyFilesBuildPhase section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 832C81801AAF6DEF007FA2F7 /* libRCTAdSupport.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTAdSupport.a; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | 832C819A1AAF6E1A007FA2F7 /* RCTAdSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTAdSupport.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 28 | 832C819B1AAF6E1A007FA2F7 /* RCTAdSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAdSupport.m; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | 832C817D1AAF6DEF007FA2F7 /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | 832C81771AAF6DEF007FA2F7 = { 43 | isa = PBXGroup; 44 | children = ( 45 | 832C819A1AAF6E1A007FA2F7 /* RCTAdSupport.h */, 46 | 832C819B1AAF6E1A007FA2F7 /* RCTAdSupport.m */, 47 | 832C81811AAF6DEF007FA2F7 /* Products */, 48 | ); 49 | indentWidth = 2; 50 | sourceTree = ""; 51 | tabWidth = 2; 52 | }; 53 | 832C81811AAF6DEF007FA2F7 /* Products */ = { 54 | isa = PBXGroup; 55 | children = ( 56 | 832C81801AAF6DEF007FA2F7 /* libRCTAdSupport.a */, 57 | ); 58 | name = Products; 59 | sourceTree = ""; 60 | }; 61 | /* End PBXGroup section */ 62 | 63 | /* Begin PBXNativeTarget section */ 64 | 832C817F1AAF6DEF007FA2F7 /* RCTAdSupport */ = { 65 | isa = PBXNativeTarget; 66 | buildConfigurationList = 832C81941AAF6DF0007FA2F7 /* Build configuration list for PBXNativeTarget "RCTAdSupport" */; 67 | buildPhases = ( 68 | 832C817C1AAF6DEF007FA2F7 /* Sources */, 69 | 832C817D1AAF6DEF007FA2F7 /* Frameworks */, 70 | 832C817E1AAF6DEF007FA2F7 /* CopyFiles */, 71 | ); 72 | buildRules = ( 73 | ); 74 | dependencies = ( 75 | ); 76 | name = RCTAdSupport; 77 | productName = RCTAdSupport; 78 | productReference = 832C81801AAF6DEF007FA2F7 /* libRCTAdSupport.a */; 79 | productType = "com.apple.product-type.library.static"; 80 | }; 81 | /* End PBXNativeTarget section */ 82 | 83 | /* Begin PBXProject section */ 84 | 832C81781AAF6DEF007FA2F7 /* Project object */ = { 85 | isa = PBXProject; 86 | attributes = { 87 | LastUpgradeCheck = 0620; 88 | ORGANIZATIONNAME = Facebook; 89 | TargetAttributes = { 90 | 832C817F1AAF6DEF007FA2F7 = { 91 | CreatedOnToolsVersion = 6.2; 92 | }; 93 | }; 94 | }; 95 | buildConfigurationList = 832C817B1AAF6DEF007FA2F7 /* Build configuration list for PBXProject "RCTAdSupport" */; 96 | compatibilityVersion = "Xcode 3.2"; 97 | developmentRegion = English; 98 | hasScannedForEncodings = 0; 99 | knownRegions = ( 100 | en, 101 | ); 102 | mainGroup = 832C81771AAF6DEF007FA2F7; 103 | productRefGroup = 832C81811AAF6DEF007FA2F7 /* Products */; 104 | projectDirPath = ""; 105 | projectRoot = ""; 106 | targets = ( 107 | 832C817F1AAF6DEF007FA2F7 /* RCTAdSupport */, 108 | ); 109 | }; 110 | /* End PBXProject section */ 111 | 112 | /* Begin PBXSourcesBuildPhase section */ 113 | 832C817C1AAF6DEF007FA2F7 /* Sources */ = { 114 | isa = PBXSourcesBuildPhase; 115 | buildActionMask = 2147483647; 116 | files = ( 117 | 832C819C1AAF6E1A007FA2F7 /* RCTAdSupport.m in Sources */, 118 | ); 119 | runOnlyForDeploymentPostprocessing = 0; 120 | }; 121 | /* End PBXSourcesBuildPhase section */ 122 | 123 | /* Begin XCBuildConfiguration section */ 124 | 832C81921AAF6DF0007FA2F7 /* Debug */ = { 125 | isa = XCBuildConfiguration; 126 | buildSettings = { 127 | ALWAYS_SEARCH_USER_PATHS = NO; 128 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 129 | CLANG_CXX_LIBRARY = "libc++"; 130 | CLANG_ENABLE_MODULES = YES; 131 | CLANG_ENABLE_OBJC_ARC = YES; 132 | CLANG_WARN_BOOL_CONVERSION = YES; 133 | CLANG_WARN_CONSTANT_CONVERSION = YES; 134 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 135 | CLANG_WARN_EMPTY_BODY = YES; 136 | CLANG_WARN_ENUM_CONVERSION = YES; 137 | CLANG_WARN_INT_CONVERSION = YES; 138 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 139 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 140 | CLANG_WARN_UNREACHABLE_CODE = YES; 141 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 142 | COPY_PHASE_STRIP = NO; 143 | ENABLE_STRICT_OBJC_MSGSEND = YES; 144 | GCC_C_LANGUAGE_STANDARD = gnu99; 145 | GCC_DYNAMIC_NO_PIC = NO; 146 | GCC_OPTIMIZATION_LEVEL = 0; 147 | GCC_PREPROCESSOR_DEFINITIONS = ( 148 | "DEBUG=1", 149 | "$(inherited)", 150 | ); 151 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 152 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 153 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 154 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; 155 | GCC_WARN_SHADOW = YES; 156 | GCC_WARN_UNDECLARED_SELECTOR = YES; 157 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 158 | GCC_WARN_UNUSED_FUNCTION = YES; 159 | GCC_WARN_UNUSED_VARIABLE = YES; 160 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 161 | MTL_ENABLE_DEBUG_INFO = YES; 162 | ONLY_ACTIVE_ARCH = YES; 163 | SDKROOT = iphoneos; 164 | SKIP_INSTALL = YES; 165 | WARNING_CFLAGS = ( 166 | "-Werror", 167 | "-Wall", 168 | ); 169 | }; 170 | name = Debug; 171 | }; 172 | 832C81931AAF6DF0007FA2F7 /* Release */ = { 173 | isa = XCBuildConfiguration; 174 | buildSettings = { 175 | ALWAYS_SEARCH_USER_PATHS = NO; 176 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 177 | CLANG_CXX_LIBRARY = "libc++"; 178 | CLANG_ENABLE_MODULES = YES; 179 | CLANG_ENABLE_OBJC_ARC = YES; 180 | CLANG_WARN_BOOL_CONVERSION = YES; 181 | CLANG_WARN_CONSTANT_CONVERSION = YES; 182 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 183 | CLANG_WARN_EMPTY_BODY = YES; 184 | CLANG_WARN_ENUM_CONVERSION = YES; 185 | CLANG_WARN_INT_CONVERSION = YES; 186 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 187 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 188 | CLANG_WARN_UNREACHABLE_CODE = YES; 189 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 190 | COPY_PHASE_STRIP = NO; 191 | ENABLE_NS_ASSERTIONS = NO; 192 | ENABLE_STRICT_OBJC_MSGSEND = YES; 193 | GCC_C_LANGUAGE_STANDARD = gnu99; 194 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 195 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 196 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; 197 | GCC_WARN_SHADOW = YES; 198 | GCC_WARN_UNDECLARED_SELECTOR = YES; 199 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 200 | GCC_WARN_UNUSED_FUNCTION = YES; 201 | GCC_WARN_UNUSED_VARIABLE = YES; 202 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 203 | MTL_ENABLE_DEBUG_INFO = NO; 204 | SDKROOT = iphoneos; 205 | SKIP_INSTALL = YES; 206 | VALIDATE_PRODUCT = YES; 207 | WARNING_CFLAGS = ( 208 | "-Werror", 209 | "-Wall", 210 | ); 211 | }; 212 | name = Release; 213 | }; 214 | 832C81951AAF6DF0007FA2F7 /* Debug */ = { 215 | isa = XCBuildConfiguration; 216 | buildSettings = { 217 | CLANG_STATIC_ANALYZER_MODE = deep; 218 | OTHER_LDFLAGS = "-ObjC"; 219 | PRODUCT_NAME = "$(TARGET_NAME)"; 220 | RUN_CLANG_STATIC_ANALYZER = YES; 221 | }; 222 | name = Debug; 223 | }; 224 | 832C81961AAF6DF0007FA2F7 /* Release */ = { 225 | isa = XCBuildConfiguration; 226 | buildSettings = { 227 | CLANG_STATIC_ANALYZER_MODE = deep; 228 | OTHER_LDFLAGS = "-ObjC"; 229 | PRODUCT_NAME = "$(TARGET_NAME)"; 230 | }; 231 | name = Release; 232 | }; 233 | /* End XCBuildConfiguration section */ 234 | 235 | /* Begin XCConfigurationList section */ 236 | 832C817B1AAF6DEF007FA2F7 /* Build configuration list for PBXProject "RCTAdSupport" */ = { 237 | isa = XCConfigurationList; 238 | buildConfigurations = ( 239 | 832C81921AAF6DF0007FA2F7 /* Debug */, 240 | 832C81931AAF6DF0007FA2F7 /* Release */, 241 | ); 242 | defaultConfigurationIsVisible = 0; 243 | defaultConfigurationName = Release; 244 | }; 245 | 832C81941AAF6DF0007FA2F7 /* Build configuration list for PBXNativeTarget "RCTAdSupport" */ = { 246 | isa = XCConfigurationList; 247 | buildConfigurations = ( 248 | 832C81951AAF6DF0007FA2F7 /* Debug */, 249 | 832C81961AAF6DF0007FA2F7 /* Release */, 250 | ); 251 | defaultConfigurationIsVisible = 0; 252 | defaultConfigurationName = Release; 253 | }; 254 | /* End XCConfigurationList section */ 255 | }; 256 | rootObject = 832C81781AAF6DEF007FA2F7 /* Project object */; 257 | } 258 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-adsupport/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "deprecated-react-native-ios-adsupport", 3 | "version": "0.48.0", 4 | "description": "", 5 | "license": "MIT", 6 | "repository": { 7 | "type": "git", 8 | "url": "git@github.com:facebook/react-native-deprecated-modules.git" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-mapview/DeprecatedMapView.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule DeprecatedMapView 8 | * @flow 9 | */ 10 | 'use strict'; 11 | 12 | // We cannot use Haste in 3rd-party modules: 13 | // 14 | // const ColorPropType = require('ColorPropType'); 15 | // const EdgeInsetsPropType = require('EdgeInsetsPropType'); 16 | // const Image = require('Image'); 17 | // const NativeMethodsMixin = require('react/lib/NativeMethodsMixin'); 18 | // const React = require('React'); 19 | // const StyleSheet = require('StyleSheet'); 20 | // const View = require('View'); 21 | 22 | // const deprecatedPropType = require('deprecatedPropType'); 23 | // const processColor = require('processColor'); 24 | // const resolveAssetSource = require('resolveAssetSource'); 25 | // const requireNativeComponent = require('requireNativeComponent'); 26 | 27 | 28 | // Haste imports above rewritten as CommonJS imports: 29 | 30 | import React from 'react'; 31 | 32 | // Hack to get RN internals 33 | import NativeMethodsMixin from 'react/lib/NativeMethodsMixin'; 34 | import deprecatedPropType from 'react-native/Libraries/Utilities/deprecatedPropType'; 35 | import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; 36 | 37 | import { 38 | ColorPropType, 39 | EdgeInsetsPropType, 40 | Image, 41 | StyleSheet, 42 | View, 43 | processColor, 44 | requireNativeComponent, 45 | } from 'react-native'; 46 | 47 | type Event = Object; 48 | 49 | /** 50 | * State an annotation on the map. 51 | */ 52 | export type AnnotationDragState = $Enum<{ 53 | /** 54 | * Annotation is not being touched. 55 | */ 56 | idle: string, 57 | /** 58 | * Annotation dragging has began. 59 | */ 60 | starting: string, 61 | /** 62 | * Annotation is being dragged. 63 | */ 64 | dragging: string, 65 | /** 66 | * Annotation dragging is being canceled. 67 | */ 68 | canceling: string, 69 | /** 70 | * Annotation dragging has ended. 71 | */ 72 | ending: string, 73 | }>; 74 | 75 | /** 76 | * **This component is only supported on iOS.** 77 | * 78 | * `DeprecatedMapView` is used to display embeddable maps and annotations using 79 | * `MKMapView`. 80 | * 81 | * For a cross-platform solution, check out 82 | * [react-native-maps](https://github.com/airbnb/react-native-maps) 83 | * by Airbnb. 84 | * 85 | * ``` 86 | * import React, { Component } from 'react'; 87 | * import { DeprecatedMapView } from 'derprecated-react-native-ios-mapview'; 88 | * 89 | * class MapMyRide extends Component { 90 | * render() { 91 | * return ( 92 | * 96 | * ); 97 | * } 98 | * } 99 | * ``` 100 | * 101 | */ 102 | 103 | const DeprecatedMapView = React.createClass({ 104 | 105 | mixins: [NativeMethodsMixin], 106 | 107 | propTypes: { 108 | ...View.propTypes, 109 | /** 110 | * Used to style and layout the `DeprecatedMapView`. 111 | */ 112 | style: View.propTypes.style, 113 | 114 | /** 115 | * If `true` the app will ask for the user's location and display it on 116 | * the map. Default value is `false`. 117 | * 118 | * **NOTE**: You'll need to add the `NSLocationWhenInUseUsageDescription` 119 | * key in Info.plist to enable geolocation, otherwise it will fail silently. 120 | */ 121 | showsUserLocation: React.PropTypes.bool, 122 | 123 | /** 124 | * If `true` the map will follow the user's location whenever it changes. 125 | * Note that this has no effect unless `showsUserLocation` is enabled. 126 | * Default value is `true`. 127 | */ 128 | followUserLocation: React.PropTypes.bool, 129 | 130 | /** 131 | * If `false` points of interest won't be displayed on the map. 132 | * Default value is `true`. 133 | */ 134 | showsPointsOfInterest: React.PropTypes.bool, 135 | 136 | /** 137 | * If `false`, compass won't be displayed on the map. 138 | * Default value is `true`. 139 | */ 140 | showsCompass: React.PropTypes.bool, 141 | 142 | /** 143 | * If `false` the user won't be able to pinch/zoom the map. 144 | * Default value is `true`. 145 | */ 146 | zoomEnabled: React.PropTypes.bool, 147 | 148 | /** 149 | * When this property is set to `true` and a valid camera is associated with 150 | * the map, the camera's heading angle is used to rotate the plane of the 151 | * map around its center point. 152 | * 153 | * When this property is set to `false`, the 154 | * camera's heading angle is ignored and the map is always oriented so 155 | * that true north is situated at the top of the map view 156 | */ 157 | rotateEnabled: React.PropTypes.bool, 158 | 159 | /** 160 | * When this property is set to `true` and a valid camera is associated 161 | * with the map, the camera's pitch angle is used to tilt the plane 162 | * of the map. 163 | * 164 | * When this property is set to `false`, the camera's pitch 165 | * angle is ignored and the map is always displayed as if the user 166 | * is looking straight down onto it. 167 | */ 168 | pitchEnabled: React.PropTypes.bool, 169 | 170 | /** 171 | * If `false` the user won't be able to change the map region being displayed. 172 | * Default value is `true`. 173 | */ 174 | scrollEnabled: React.PropTypes.bool, 175 | 176 | /** 177 | * The map type to be displayed. 178 | * 179 | * - `standard`: Standard road map (default). 180 | * - `satellite`: Satellite view. 181 | * - `hybrid`: Satellite view with roads and points of interest overlaid. 182 | */ 183 | mapType: React.PropTypes.oneOf([ 184 | 'standard', 185 | 'satellite', 186 | 'hybrid', 187 | ]), 188 | 189 | /** 190 | * The region to be displayed by the map. 191 | * 192 | * The region is defined by the center coordinates and the span of 193 | * coordinates to display. 194 | */ 195 | region: React.PropTypes.shape({ 196 | /** 197 | * Coordinates for the center of the map. 198 | */ 199 | latitude: React.PropTypes.number.isRequired, 200 | longitude: React.PropTypes.number.isRequired, 201 | 202 | /** 203 | * Distance between the minimum and the maximum latitude/longitude 204 | * to be displayed. 205 | */ 206 | latitudeDelta: React.PropTypes.number, 207 | longitudeDelta: React.PropTypes.number, 208 | }), 209 | 210 | /** 211 | * Map annotations with title and subtitle. 212 | */ 213 | annotations: React.PropTypes.arrayOf(React.PropTypes.shape({ 214 | /** 215 | * The location of the annotation. 216 | */ 217 | latitude: React.PropTypes.number.isRequired, 218 | longitude: React.PropTypes.number.isRequired, 219 | 220 | /** 221 | * Whether the pin drop should be animated or not 222 | */ 223 | animateDrop: React.PropTypes.bool, 224 | 225 | /** 226 | * Whether the pin should be draggable or not 227 | */ 228 | draggable: React.PropTypes.bool, 229 | 230 | /** 231 | * Event that fires when the annotation drag state changes. 232 | */ 233 | onDragStateChange: React.PropTypes.func, 234 | 235 | /** 236 | * Event that fires when the annotation gets was tapped by the user 237 | * and the callout view was displayed. 238 | */ 239 | onFocus: React.PropTypes.func, 240 | 241 | /** 242 | * Event that fires when another annotation or the mapview itself 243 | * was tapped and a previously shown annotation will be closed. 244 | */ 245 | onBlur: React.PropTypes.func, 246 | 247 | /** 248 | * Annotation title and subtile. 249 | */ 250 | title: React.PropTypes.string, 251 | subtitle: React.PropTypes.string, 252 | 253 | /** 254 | * Callout views. 255 | */ 256 | leftCalloutView: React.PropTypes.element, 257 | rightCalloutView: React.PropTypes.element, 258 | detailCalloutView: React.PropTypes.element, 259 | 260 | /** 261 | * The pin color. This can be any valid color string, or you can use one 262 | * of the predefined PinColors constants. Applies to both standard pins 263 | * and custom pin images. 264 | * 265 | * Note that on iOS 8 and earlier, only the standard PinColor constants 266 | * are supported for regular pins. For custom pin images, any tintColor 267 | * value is supported on all iOS versions. 268 | */ 269 | tintColor: ColorPropType, 270 | 271 | /** 272 | * Custom pin image. This must be a static image resource inside the app. 273 | */ 274 | image: Image.propTypes.source, 275 | 276 | /** 277 | * Custom pin view. If set, this replaces the pin or custom pin image. 278 | */ 279 | view: React.PropTypes.element, 280 | 281 | /** 282 | * annotation id 283 | */ 284 | id: React.PropTypes.string, 285 | 286 | /** 287 | * Deprecated. Use the left/right/detailsCalloutView props instead. 288 | */ 289 | hasLeftCallout: deprecatedPropType( 290 | React.PropTypes.bool, 291 | 'Use `leftCalloutView` instead.' 292 | ), 293 | hasRightCallout: deprecatedPropType( 294 | React.PropTypes.bool, 295 | 'Use `rightCalloutView` instead.' 296 | ), 297 | onLeftCalloutPress: deprecatedPropType( 298 | React.PropTypes.func, 299 | 'Use `leftCalloutView` instead.' 300 | ), 301 | onRightCalloutPress: deprecatedPropType( 302 | React.PropTypes.func, 303 | 'Use `rightCalloutView` instead.' 304 | ), 305 | })), 306 | 307 | /** 308 | * Map overlays 309 | */ 310 | overlays: React.PropTypes.arrayOf(React.PropTypes.shape({ 311 | /** 312 | * Polyline coordinates 313 | */ 314 | coordinates: React.PropTypes.arrayOf(React.PropTypes.shape({ 315 | latitude: React.PropTypes.number.isRequired, 316 | longitude: React.PropTypes.number.isRequired 317 | })), 318 | 319 | /** 320 | * Line attributes 321 | */ 322 | lineWidth: React.PropTypes.number, 323 | strokeColor: ColorPropType, 324 | fillColor: ColorPropType, 325 | 326 | /** 327 | * Overlay id 328 | */ 329 | id: React.PropTypes.string 330 | })), 331 | 332 | /** 333 | * Maximum size of the area that can be displayed. 334 | */ 335 | maxDelta: React.PropTypes.number, 336 | 337 | /** 338 | * Minimum size of the area that can be displayed. 339 | */ 340 | minDelta: React.PropTypes.number, 341 | 342 | /** 343 | * Insets for the map's legal label, originally at bottom left of the map. 344 | */ 345 | legalLabelInsets: EdgeInsetsPropType, 346 | 347 | /** 348 | * Callback that is called continuously when the user is dragging the map. 349 | */ 350 | onRegionChange: React.PropTypes.func, 351 | 352 | /** 353 | * Callback that is called once, when the user is done moving the map. 354 | */ 355 | onRegionChangeComplete: React.PropTypes.func, 356 | 357 | /** 358 | * Deprecated. Use annotation `onFocus` and `onBlur` instead. 359 | */ 360 | onAnnotationPress: React.PropTypes.func, 361 | 362 | /** 363 | * @platform android 364 | */ 365 | active: React.PropTypes.bool, 366 | }, 367 | 368 | statics: { 369 | /** 370 | * Standard iOS MapView pin color constants, to be used with the 371 | * `annotation.tintColor` property. On iOS 8 and earlier these are the 372 | * only supported values when using regular pins. On iOS 9 and later 373 | * you are not obliged to use these, but they are useful for matching 374 | * the standard iOS look and feel. 375 | */ 376 | PinColors: { 377 | RED: '#ff3b30', 378 | GREEN: '#4cd964', 379 | PURPLE: '#c969e0', 380 | }, 381 | }, 382 | 383 | render: function() { 384 | let children = [], {annotations, overlays, followUserLocation} = this.props; 385 | annotations = annotations && annotations.map((annotation: Object) => { 386 | let { 387 | id, 388 | image, 389 | tintColor, 390 | view, 391 | leftCalloutView, 392 | rightCalloutView, 393 | detailCalloutView, 394 | } = annotation; 395 | 396 | if (!view && image && tintColor) { 397 | view = ; 403 | image = undefined; 404 | } 405 | if (view) { 406 | if (image) { 407 | console.warn('`image` and `view` both set on annotation. Image will be ignored.'); 408 | } 409 | var viewIndex = children.length; 410 | children.push(React.cloneElement(view, { 411 | // $FlowFixMe - An array of styles should be fine 412 | style: [styles.annotationView, view.props.style || {}] 413 | })); 414 | } 415 | if (leftCalloutView) { 416 | var leftCalloutViewIndex = children.length; 417 | children.push(React.cloneElement(leftCalloutView, { 418 | style: [styles.calloutView, leftCalloutView.props.style || {}] 419 | })); 420 | } 421 | if (rightCalloutView) { 422 | var rightCalloutViewIndex = children.length; 423 | children.push(React.cloneElement(rightCalloutView, { 424 | style: [styles.calloutView, rightCalloutView.props.style || {}] 425 | })); 426 | } 427 | if (detailCalloutView) { 428 | var detailCalloutViewIndex = children.length; 429 | children.push(React.cloneElement(detailCalloutView, { 430 | style: [styles.calloutView, detailCalloutView.props.style || {}] 431 | })); 432 | } 433 | 434 | const result = { 435 | ...annotation, 436 | tintColor: tintColor && processColor(tintColor), 437 | image, 438 | viewIndex, 439 | leftCalloutViewIndex, 440 | rightCalloutViewIndex, 441 | detailCalloutViewIndex, 442 | view: undefined, 443 | leftCalloutView: undefined, 444 | rightCalloutView: undefined, 445 | detailCalloutView: undefined, 446 | }; 447 | result.id = id || encodeURIComponent(JSON.stringify(result)); 448 | result.image = image && resolveAssetSource(image); 449 | return result; 450 | }); 451 | overlays = overlays && overlays.map((overlay: Object) => { 452 | const {id, fillColor, strokeColor} = overlay; 453 | const result = { 454 | ...overlay, 455 | strokeColor: strokeColor && processColor(strokeColor), 456 | fillColor: fillColor && processColor(fillColor), 457 | }; 458 | result.id = id || encodeURIComponent(JSON.stringify(result)); 459 | return result; 460 | }); 461 | 462 | const findByAnnotationId = (annotationId: string) => { 463 | if (!annotations) { 464 | return null; 465 | } 466 | for (let i = 0, l = annotations.length; i < l; i++) { 467 | if (annotations[i].id === annotationId) { 468 | return annotations[i]; 469 | } 470 | } 471 | return null; 472 | }; 473 | 474 | // TODO: these should be separate events, to reduce bridge traffic 475 | let onPress, onAnnotationDragStateChange, onAnnotationFocus, onAnnotationBlur; 476 | if (annotations) { 477 | onPress = (event: Event) => { 478 | if (event.nativeEvent.action === 'annotation-click') { 479 | // TODO: Remove deprecated onAnnotationPress API call later. 480 | this.props.onAnnotationPress && 481 | this.props.onAnnotationPress(event.nativeEvent.annotation); 482 | } else if (event.nativeEvent.action === 'callout-click') { 483 | const annotation = findByAnnotationId(event.nativeEvent.annotationId); 484 | if (annotation) { 485 | // Pass the right function 486 | if (event.nativeEvent.side === 'left' && annotation.onLeftCalloutPress) { 487 | annotation.onLeftCalloutPress(event.nativeEvent); 488 | } else if (event.nativeEvent.side === 'right' && annotation.onRightCalloutPress) { 489 | annotation.onRightCalloutPress(event.nativeEvent); 490 | } 491 | } 492 | } 493 | }; 494 | onAnnotationDragStateChange = (event: Event) => { 495 | const annotation = findByAnnotationId(event.nativeEvent.annotationId); 496 | if (annotation) { 497 | // Call callback 498 | annotation.onDragStateChange && 499 | annotation.onDragStateChange(event.nativeEvent); 500 | } 501 | }; 502 | onAnnotationFocus = (event: Event) => { 503 | const annotation = findByAnnotationId(event.nativeEvent.annotationId); 504 | if (annotation && annotation.onFocus) { 505 | annotation.onFocus(event.nativeEvent); 506 | } 507 | }; 508 | onAnnotationBlur = (event: Event) => { 509 | const annotation = findByAnnotationId(event.nativeEvent.annotationId); 510 | if (annotation && annotation.onBlur) { 511 | annotation.onBlur(event.nativeEvent); 512 | } 513 | }; 514 | } 515 | 516 | // TODO: these should be separate events, to reduce bridge traffic 517 | if (this.props.onRegionChange || this.props.onRegionChangeComplete) { 518 | var onChange = (event: Event) => { 519 | if (event.nativeEvent.continuous) { 520 | this.props.onRegionChange && 521 | this.props.onRegionChange(event.nativeEvent.region); 522 | } else { 523 | this.props.onRegionChangeComplete && 524 | this.props.onRegionChangeComplete(event.nativeEvent.region); 525 | } 526 | }; 527 | } 528 | 529 | // followUserLocation defaults to true if showUserLocation is set 530 | if (followUserLocation === undefined) { 531 | followUserLocation = this.props.showUserLocation; 532 | } 533 | 534 | return ( 535 | 547 | ); 548 | }, 549 | }); 550 | 551 | const styles = StyleSheet.create({ 552 | annotationView: { 553 | position: 'absolute', 554 | backgroundColor: 'transparent', 555 | }, 556 | calloutView: { 557 | position: 'absolute', 558 | backgroundColor: 'white', 559 | }, 560 | }); 561 | 562 | const RCTMap = requireNativeComponent('RCTMap', DeprecatedMapView, { 563 | nativeOnly: { 564 | onAnnotationDragStateChange: true, 565 | onAnnotationFocus: true, 566 | onAnnotationBlur: true, 567 | onChange: true, 568 | onPress: true 569 | } 570 | }); 571 | 572 | export default DeprecatedMapView; 573 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-mapview/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import DeprecatedMapView from './DeprecatedMapView'; 9 | 10 | export default DeprecatedMapView; 11 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-mapview/ios/RCTConvert+MapKit.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | #import "RCTConvert.h" 11 | 12 | @class RCTMapAnnotation; 13 | @class RCTMapOverlay; 14 | 15 | @interface RCTConvert (MapKit) 16 | 17 | + (MKCoordinateSpan)MKCoordinateSpan:(id)json; 18 | + (MKCoordinateRegion)MKCoordinateRegion:(id)json; 19 | + (MKMapType)MKMapType:(id)json; 20 | 21 | + (RCTMapAnnotation *)RCTMapAnnotation:(id)json; 22 | + (RCTMapOverlay *)RCTMapOverlay:(id)json; 23 | 24 | + (NSArray *)RCTMapAnnotationArray:(id)json; 25 | + (NSArray *)RCTMapOverlayArray:(id)json; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-mapview/ios/RCTConvert+MapKit.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "RCTConvert+MapKit.h" 9 | #import "RCTConvert+CoreLocation.h" 10 | #import "RCTMapAnnotation.h" 11 | #import "RCTMapOverlay.h" 12 | 13 | @implementation RCTConvert(MapKit) 14 | 15 | + (MKCoordinateSpan)MKCoordinateSpan:(id)json 16 | { 17 | json = [self NSDictionary:json]; 18 | return (MKCoordinateSpan){ 19 | [self CLLocationDegrees:json[@"latitudeDelta"]], 20 | [self CLLocationDegrees:json[@"longitudeDelta"]] 21 | }; 22 | } 23 | 24 | + (MKCoordinateRegion)MKCoordinateRegion:(id)json 25 | { 26 | return (MKCoordinateRegion){ 27 | [self CLLocationCoordinate2D:json], 28 | [self MKCoordinateSpan:json] 29 | }; 30 | } 31 | 32 | RCT_ENUM_CONVERTER(MKMapType, (@{ 33 | @"standard": @(MKMapTypeStandard), 34 | @"satellite": @(MKMapTypeSatellite), 35 | @"hybrid": @(MKMapTypeHybrid), 36 | }), MKMapTypeStandard, integerValue) 37 | 38 | + (RCTMapAnnotation *)RCTMapAnnotation:(id)json 39 | { 40 | json = [self NSDictionary:json]; 41 | RCTMapAnnotation *annotation = [RCTMapAnnotation new]; 42 | annotation.coordinate = [self CLLocationCoordinate2D:json]; 43 | annotation.draggable = [self BOOL:json[@"draggable"]]; 44 | annotation.title = [self NSString:json[@"title"]]; 45 | annotation.subtitle = [self NSString:json[@"subtitle"]]; 46 | annotation.identifier = [self NSString:json[@"id"]]; 47 | annotation.hasLeftCallout = [self BOOL:json[@"hasLeftCallout"]]; 48 | annotation.hasRightCallout = [self BOOL:json[@"hasRightCallout"]]; 49 | annotation.animateDrop = [self BOOL:json[@"animateDrop"]]; 50 | annotation.tintColor = [self UIColor:json[@"tintColor"]]; 51 | annotation.image = [self UIImage:json[@"image"]]; 52 | annotation.viewIndex = 53 | [self NSInteger:json[@"viewIndex"] ?: @(NSNotFound)]; 54 | annotation.leftCalloutViewIndex = 55 | [self NSInteger:json[@"leftCalloutViewIndex"] ?: @(NSNotFound)]; 56 | annotation.rightCalloutViewIndex = 57 | [self NSInteger:json[@"rightCalloutViewIndex"] ?: @(NSNotFound)]; 58 | annotation.detailCalloutViewIndex = 59 | [self NSInteger:json[@"detailCalloutViewIndex"] ?: @(NSNotFound)]; 60 | return annotation; 61 | } 62 | 63 | RCT_ARRAY_CONVERTER(RCTMapAnnotation) 64 | 65 | + (RCTMapOverlay *)RCTMapOverlay:(id)json 66 | { 67 | json = [self NSDictionary:json]; 68 | NSArray *locations = [self NSDictionaryArray:json[@"coordinates"]]; 69 | CLLocationCoordinate2D coordinates[locations.count]; 70 | NSUInteger index = 0; 71 | for (NSDictionary *location in locations) { 72 | coordinates[index++] = [self CLLocationCoordinate2D:location]; 73 | } 74 | 75 | RCTMapOverlay *overlay = [RCTMapOverlay polylineWithCoordinates:coordinates 76 | count:locations.count]; 77 | 78 | overlay.strokeColor = [self UIColor:json[@"strokeColor"]]; 79 | overlay.identifier = [self NSString:json[@"id"]]; 80 | overlay.lineWidth = [self CGFloat:json[@"lineWidth"] ?: @1]; 81 | return overlay; 82 | } 83 | 84 | RCT_ARRAY_CONVERTER(RCTMapOverlay) 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-mapview/ios/RCTMap.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | #import 10 | 11 | #import "RCTConvert+MapKit.h" 12 | #import "RCTComponent.h" 13 | 14 | RCT_EXTERN const CLLocationDegrees RCTMapDefaultSpan; 15 | RCT_EXTERN const NSTimeInterval RCTMapRegionChangeObserveInterval; 16 | RCT_EXTERN const CGFloat RCTMapZoomBoundBuffer; 17 | 18 | @interface RCTMap: MKMapView 19 | 20 | @property (nonatomic, assign) BOOL followUserLocation; 21 | @property (nonatomic, assign) BOOL hasStartedRendering; 22 | @property (nonatomic, assign) CGFloat minDelta; 23 | @property (nonatomic, assign) CGFloat maxDelta; 24 | @property (nonatomic, assign) UIEdgeInsets legalLabelInsets; 25 | @property (nonatomic, strong) NSTimer *regionChangeObserveTimer; 26 | @property (nonatomic, copy) NSArray *annotationIDs; 27 | @property (nonatomic, copy) NSArray *overlayIDs; 28 | 29 | @property (nonatomic, copy) RCTBubblingEventBlock onChange; 30 | @property (nonatomic, copy) RCTBubblingEventBlock onPress; 31 | @property (nonatomic, copy) RCTBubblingEventBlock onAnnotationDragStateChange; 32 | @property (nonatomic, copy) RCTBubblingEventBlock onAnnotationFocus; 33 | @property (nonatomic, copy) RCTBubblingEventBlock onAnnotationBlur; 34 | 35 | - (void)setAnnotations:(NSArray *)annotations; 36 | - (void)setOverlays:(NSArray *)overlays; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-mapview/ios/RCTMap.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "RCTMap.h" 9 | 10 | #import "RCTEventDispatcher.h" 11 | #import "RCTLog.h" 12 | #import "RCTMapAnnotation.h" 13 | #import "RCTMapOverlay.h" 14 | #import "RCTUtils.h" 15 | #import "UIView+React.h" 16 | 17 | const CLLocationDegrees RCTMapDefaultSpan = 0.005; 18 | const NSTimeInterval RCTMapRegionChangeObserveInterval = 0.1; 19 | const CGFloat RCTMapZoomBoundBuffer = 0.01; 20 | 21 | @implementation RCTMap 22 | { 23 | UIView *_legalLabel; 24 | CLLocationManager *_locationManager; 25 | } 26 | 27 | - (instancetype)init 28 | { 29 | if ((self = [super init])) { 30 | 31 | _hasStartedRendering = NO; 32 | 33 | // Find Apple link label 34 | for (UIView *subview in self.subviews) { 35 | if ([NSStringFromClass(subview.class) isEqualToString:@"MKAttributionLabel"]) { 36 | // This check is super hacky, but the whole premise of moving around 37 | // Apple's internal subviews is super hacky 38 | _legalLabel = subview; 39 | break; 40 | } 41 | } 42 | } 43 | return self; 44 | } 45 | 46 | - (void)dealloc 47 | { 48 | [_regionChangeObserveTimer invalidate]; 49 | } 50 | 51 | - (void)didUpdateReactSubviews 52 | { 53 | // Do nothing, as annotation views are managed by `setAnnotations:` method 54 | } 55 | 56 | - (void)layoutSubviews 57 | { 58 | [super layoutSubviews]; 59 | 60 | if (_legalLabel) { 61 | dispatch_async(dispatch_get_main_queue(), ^{ 62 | CGRect frame = self->_legalLabel.frame; 63 | if (self->_legalLabelInsets.left) { 64 | frame.origin.x = self->_legalLabelInsets.left; 65 | } else if (self->_legalLabelInsets.right) { 66 | frame.origin.x = self.frame.size.width - self->_legalLabelInsets.right - frame.size.width; 67 | } 68 | if (self->_legalLabelInsets.top) { 69 | frame.origin.y = self->_legalLabelInsets.top; 70 | } else if (self->_legalLabelInsets.bottom) { 71 | frame.origin.y = self.frame.size.height - self->_legalLabelInsets.bottom - frame.size.height; 72 | } 73 | self->_legalLabel.frame = frame; 74 | }); 75 | } 76 | } 77 | 78 | #pragma mark Accessors 79 | 80 | - (void)setShowsUserLocation:(BOOL)showsUserLocation 81 | { 82 | if (self.showsUserLocation != showsUserLocation) { 83 | if (showsUserLocation && !_locationManager) { 84 | _locationManager = [CLLocationManager new]; 85 | if ([_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) { 86 | [_locationManager requestWhenInUseAuthorization]; 87 | } 88 | } 89 | super.showsUserLocation = showsUserLocation; 90 | } 91 | } 92 | 93 | - (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated 94 | { 95 | // If location is invalid, abort 96 | if (!CLLocationCoordinate2DIsValid(region.center)) { 97 | return; 98 | } 99 | 100 | // If new span values are nil, use old values instead 101 | if (!region.span.latitudeDelta) { 102 | region.span.latitudeDelta = self.region.span.latitudeDelta; 103 | } 104 | if (!region.span.longitudeDelta) { 105 | region.span.longitudeDelta = self.region.span.longitudeDelta; 106 | } 107 | 108 | // Animate to new position 109 | [super setRegion:region animated:animated]; 110 | } 111 | 112 | // TODO: this doesn't preserve order. Should it? If so we should change the 113 | // algorithm. If not, it would be more efficient to use an NSSet 114 | - (void)setAnnotations:(NSArray *)annotations 115 | { 116 | NSMutableArray *newAnnotationIDs = [NSMutableArray new]; 117 | NSMutableArray *annotationsToDelete = [NSMutableArray new]; 118 | NSMutableArray *annotationsToAdd = [NSMutableArray new]; 119 | 120 | for (RCTMapAnnotation *annotation in annotations) { 121 | if (![annotation isKindOfClass:[RCTMapAnnotation class]]) { 122 | continue; 123 | } 124 | 125 | [newAnnotationIDs addObject:annotation.identifier]; 126 | 127 | // If the current set does not contain the new annotation, mark it to add 128 | if (![_annotationIDs containsObject:annotation.identifier]) { 129 | [annotationsToAdd addObject:annotation]; 130 | } 131 | } 132 | 133 | for (RCTMapAnnotation *annotation in self.annotations) { 134 | if (![annotation isKindOfClass:[RCTMapAnnotation class]]) { 135 | continue; 136 | } 137 | 138 | // If the new set does not contain an existing annotation, mark it to delete 139 | if (![newAnnotationIDs containsObject:annotation.identifier]) { 140 | [annotationsToDelete addObject:annotation]; 141 | } 142 | } 143 | 144 | if (annotationsToDelete.count) { 145 | [self removeAnnotations:(NSArray> *)annotationsToDelete]; 146 | } 147 | 148 | if (annotationsToAdd.count) { 149 | [self addAnnotations:(NSArray> *)annotationsToAdd]; 150 | } 151 | 152 | self.annotationIDs = newAnnotationIDs; 153 | } 154 | 155 | // TODO: this doesn't preserve order. Should it? If so we should change the 156 | // algorithm. If not, it would be more efficient to use an NSSet 157 | - (void)setOverlays:(NSArray *)overlays 158 | { 159 | NSMutableArray *newOverlayIDs = [NSMutableArray new]; 160 | NSMutableArray *overlaysToDelete = [NSMutableArray new]; 161 | NSMutableArray *overlaysToAdd = [NSMutableArray new]; 162 | 163 | for (RCTMapOverlay *overlay in overlays) { 164 | if (![overlay isKindOfClass:[RCTMapOverlay class]]) { 165 | continue; 166 | } 167 | 168 | [newOverlayIDs addObject:overlay.identifier]; 169 | 170 | // If the current set does not contain the new annotation, mark it to add 171 | if (![_annotationIDs containsObject:overlay.identifier]) { 172 | [overlaysToAdd addObject:overlay]; 173 | } 174 | } 175 | 176 | for (RCTMapOverlay *overlay in self.overlays) { 177 | if (![overlay isKindOfClass:[RCTMapOverlay class]]) { 178 | continue; 179 | } 180 | 181 | // If the new set does not contain an existing annotation, mark it to delete 182 | if (![newOverlayIDs containsObject:overlay.identifier]) { 183 | [overlaysToDelete addObject:overlay]; 184 | } 185 | } 186 | 187 | if (overlaysToDelete.count) { 188 | [self removeOverlays:(NSArray> *)overlaysToDelete]; 189 | } 190 | 191 | if (overlaysToAdd.count) { 192 | [self addOverlays:(NSArray> *)overlaysToAdd 193 | level:MKOverlayLevelAboveRoads]; 194 | } 195 | 196 | self.overlayIDs = newOverlayIDs; 197 | } 198 | 199 | - (BOOL)showsCompass { 200 | if ([MKMapView instancesRespondToSelector:@selector(showsCompass)]) { 201 | return super. showsCompass; 202 | } 203 | return NO; 204 | } 205 | 206 | - (void)setShowsCompass:(BOOL)showsCompass { 207 | if ([MKMapView instancesRespondToSelector:@selector(setShowsCompass:)]) { 208 | super.showsCompass = showsCompass; 209 | } 210 | } 211 | 212 | @end 213 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-mapview/ios/RCTMapAnnotation.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | @interface RCTMapAnnotation : MKPointAnnotation 11 | 12 | @property (nonatomic, copy) NSString *identifier; 13 | @property (nonatomic, assign) BOOL hasLeftCallout; 14 | @property (nonatomic, assign) BOOL hasRightCallout; 15 | @property (nonatomic, assign) BOOL animateDrop; 16 | @property (nonatomic, strong) UIColor *tintColor; 17 | @property (nonatomic, strong) UIImage *image; 18 | @property (nonatomic, assign) NSUInteger viewIndex; 19 | @property (nonatomic, assign) NSUInteger leftCalloutViewIndex; 20 | @property (nonatomic, assign) NSUInteger rightCalloutViewIndex; 21 | @property (nonatomic, assign) NSUInteger detailCalloutViewIndex; 22 | @property (nonatomic, assign) BOOL draggable; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-mapview/ios/RCTMapAnnotation.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "RCTMapAnnotation.h" 9 | 10 | @implementation RCTMapAnnotation 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-mapview/ios/RCTMapManager.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "RCTViewManager.h" 9 | 10 | @interface RCTMapManager : RCTViewManager 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-mapview/ios/RCTMapManager.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "RCTMapManager.h" 9 | 10 | #import "RCTBridge.h" 11 | #import "RCTConvert+CoreLocation.h" 12 | #import "RCTConvert+MapKit.h" 13 | #import "RCTEventDispatcher.h" 14 | #import "RCTMap.h" 15 | #import "RCTUtils.h" 16 | #import "UIView+React.h" 17 | #import "RCTMapAnnotation.h" 18 | #import "RCTMapOverlay.h" 19 | 20 | #import 21 | 22 | static NSString *const RCTMapViewKey = @"MapView"; 23 | 24 | #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0 25 | 26 | static NSString *const RCTMapPinRed = @"#ff3b30"; 27 | static NSString *const RCTMapPinGreen = @"#4cd964"; 28 | static NSString *const RCTMapPinPurple = @"#c969e0"; 29 | 30 | @implementation RCTConvert (MKPinAnnotationColor) 31 | 32 | RCT_ENUM_CONVERTER(MKPinAnnotationColor, (@{ 33 | RCTMapPinRed: @(MKPinAnnotationColorRed), 34 | RCTMapPinGreen: @(MKPinAnnotationColorGreen), 35 | RCTMapPinPurple: @(MKPinAnnotationColorPurple) 36 | }), MKPinAnnotationColorRed, unsignedIntegerValue) 37 | 38 | @end 39 | 40 | #endif 41 | 42 | @interface RCTMapAnnotationView : MKAnnotationView 43 | 44 | @property (nonatomic, strong) UIView *contentView; 45 | 46 | @end 47 | 48 | @implementation RCTMapAnnotationView 49 | 50 | - (void)setContentView:(UIView *)contentView 51 | { 52 | [_contentView removeFromSuperview]; 53 | _contentView = contentView; 54 | [self addSubview:_contentView]; 55 | } 56 | 57 | - (void)layoutSubviews 58 | { 59 | [super layoutSubviews]; 60 | self.bounds = (CGRect){ 61 | CGPointZero, 62 | _contentView.frame.size, 63 | }; 64 | } 65 | 66 | @end 67 | 68 | @interface RCTMapManager() 69 | 70 | @end 71 | 72 | @implementation RCTMapManager 73 | 74 | RCT_EXPORT_MODULE() 75 | 76 | - (UIView *)view 77 | { 78 | RCTMap *map = [RCTMap new]; 79 | map.delegate = self; 80 | return map; 81 | } 82 | 83 | RCT_EXPORT_VIEW_PROPERTY(showsUserLocation, BOOL) 84 | RCT_EXPORT_VIEW_PROPERTY(showsPointsOfInterest, BOOL) 85 | RCT_EXPORT_VIEW_PROPERTY(showsCompass, BOOL) 86 | RCT_EXPORT_VIEW_PROPERTY(followUserLocation, BOOL) 87 | RCT_EXPORT_VIEW_PROPERTY(zoomEnabled, BOOL) 88 | RCT_EXPORT_VIEW_PROPERTY(rotateEnabled, BOOL) 89 | RCT_EXPORT_VIEW_PROPERTY(pitchEnabled, BOOL) 90 | RCT_EXPORT_VIEW_PROPERTY(scrollEnabled, BOOL) 91 | RCT_EXPORT_VIEW_PROPERTY(maxDelta, CGFloat) 92 | RCT_EXPORT_VIEW_PROPERTY(minDelta, CGFloat) 93 | RCT_EXPORT_VIEW_PROPERTY(legalLabelInsets, UIEdgeInsets) 94 | RCT_EXPORT_VIEW_PROPERTY(mapType, MKMapType) 95 | RCT_EXPORT_VIEW_PROPERTY(annotations, NSArray) 96 | RCT_EXPORT_VIEW_PROPERTY(overlays, NSArray) 97 | RCT_EXPORT_VIEW_PROPERTY(onAnnotationDragStateChange, RCTBubblingEventBlock) 98 | RCT_EXPORT_VIEW_PROPERTY(onAnnotationFocus, RCTBubblingEventBlock) 99 | RCT_EXPORT_VIEW_PROPERTY(onAnnotationBlur, RCTBubblingEventBlock) 100 | RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock) 101 | RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) 102 | RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RCTMap) 103 | { 104 | if (json) { 105 | [view setRegion:[RCTConvert MKCoordinateRegion:json] animated:YES]; 106 | } 107 | } 108 | 109 | #pragma mark MKMapViewDelegate 110 | 111 | - (void)mapView:(RCTMap *)mapView didSelectAnnotationView:(MKAnnotationView *)view 112 | { 113 | // TODO: Remove deprecated onAnnotationPress API call later. 114 | if (mapView.onPress && [view.annotation isKindOfClass:[RCTMapAnnotation class]]) { 115 | RCTMapAnnotation *annotation = (RCTMapAnnotation *)view.annotation; 116 | mapView.onPress(@{ 117 | @"action": @"annotation-click", 118 | @"annotation": @{ 119 | @"id": annotation.identifier, 120 | @"title": annotation.title ?: @"", 121 | @"subtitle": annotation.subtitle ?: @"", 122 | @"latitude": @(annotation.coordinate.latitude), 123 | @"longitude": @(annotation.coordinate.longitude) 124 | } 125 | }); 126 | } 127 | 128 | if ([view.annotation isKindOfClass:[RCTMapAnnotation class]]) { 129 | RCTMapAnnotation *annotation = (RCTMapAnnotation *)view.annotation; 130 | if (mapView.onAnnotationFocus) { 131 | mapView.onAnnotationFocus(@{ 132 | @"annotationId": annotation.identifier 133 | }); 134 | } 135 | } 136 | } 137 | 138 | - (void)mapView:(RCTMap *)mapView didDeselectAnnotationView:(MKAnnotationView *)view 139 | { 140 | if ([view.annotation isKindOfClass:[RCTMapAnnotation class]]) { 141 | RCTMapAnnotation *annotation = (RCTMapAnnotation *)view.annotation; 142 | if (mapView.onAnnotationBlur) { 143 | mapView.onAnnotationBlur(@{ 144 | @"annotationId": annotation.identifier 145 | }); 146 | } 147 | } 148 | } 149 | 150 | #if !TARGET_OS_TV 151 | - (void)mapView:(RCTMap *)mapView annotationView:(MKAnnotationView *)view 152 | didChangeDragState:(MKAnnotationViewDragState)newState 153 | fromOldState:(MKAnnotationViewDragState)oldState 154 | { 155 | static NSArray *states; 156 | static dispatch_once_t onceToken; 157 | dispatch_once(&onceToken, ^{ 158 | states = @[@"idle", @"starting", @"dragging", @"canceling", @"ending"]; 159 | }); 160 | 161 | if ([view.annotation isKindOfClass:[RCTMapAnnotation class]]) { 162 | RCTMapAnnotation *annotation = (RCTMapAnnotation *)view.annotation; 163 | if (mapView.onAnnotationDragStateChange) { 164 | mapView.onAnnotationDragStateChange(@{ 165 | @"state": states[newState], 166 | @"oldState": states[oldState], 167 | @"annotationId": annotation.identifier, 168 | @"latitude": @(annotation.coordinate.latitude), 169 | @"longitude": @(annotation.coordinate.longitude), 170 | }); 171 | } 172 | } 173 | } 174 | #endif //TARGET_OS_TV 175 | 176 | - (MKAnnotationView *)mapView:(RCTMap *)mapView 177 | viewForAnnotation:(RCTMapAnnotation *)annotation 178 | { 179 | if (![annotation isKindOfClass:[RCTMapAnnotation class]]) { 180 | return nil; 181 | } 182 | 183 | MKAnnotationView *annotationView; 184 | if (annotation.viewIndex != NSNotFound && 185 | annotation.viewIndex < mapView.reactSubviews.count) { 186 | 187 | NSString *reuseIdentifier = NSStringFromClass([RCTMapAnnotationView class]); 188 | annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier]; 189 | if (!annotationView) { 190 | annotationView = [[RCTMapAnnotationView alloc] initWithAnnotation:annotation 191 | reuseIdentifier:reuseIdentifier]; 192 | } 193 | UIView *reactView = mapView.reactSubviews[annotation.viewIndex]; 194 | ((RCTMapAnnotationView *)annotationView).contentView = reactView; 195 | 196 | } else if (annotation.image) { 197 | 198 | NSString *reuseIdentifier = NSStringFromClass([MKAnnotationView class]); 199 | annotationView = 200 | [mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier] ?: 201 | [[MKAnnotationView alloc] initWithAnnotation:annotation 202 | reuseIdentifier:reuseIdentifier]; 203 | annotationView.image = annotation.image; 204 | 205 | } else { 206 | 207 | NSString *reuseIdentifier = NSStringFromClass([MKPinAnnotationView class]); 208 | annotationView = 209 | [mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier] ?: 210 | [[MKPinAnnotationView alloc] initWithAnnotation:annotation 211 | reuseIdentifier:reuseIdentifier]; 212 | ((MKPinAnnotationView *)annotationView).animatesDrop = annotation.animateDrop; 213 | 214 | #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0 215 | 216 | if (![annotationView respondsToSelector:@selector(pinTintColor)]) { 217 | NSString *hexColor = annotation.tintColor ? 218 | RCTColorToHexString(annotation.tintColor.CGColor) : RCTMapPinRed; 219 | ((MKPinAnnotationView *)annotationView).pinColor = 220 | [RCTConvert MKPinAnnotationColor:hexColor]; 221 | } else 222 | 223 | #endif 224 | 225 | { 226 | ((MKPinAnnotationView *)annotationView).pinTintColor = 227 | annotation.tintColor ?: [MKPinAnnotationView redPinColor]; 228 | } 229 | } 230 | annotationView.canShowCallout = (annotation.title.length > 0); 231 | 232 | if (annotation.leftCalloutViewIndex != NSNotFound && 233 | annotation.leftCalloutViewIndex < mapView.reactSubviews.count) { 234 | annotationView.leftCalloutAccessoryView = 235 | mapView.reactSubviews[annotation.leftCalloutViewIndex]; 236 | } else if (annotation.hasLeftCallout) { 237 | annotationView.leftCalloutAccessoryView = 238 | [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 239 | } else { 240 | annotationView.leftCalloutAccessoryView = nil; 241 | } 242 | 243 | if (annotation.rightCalloutViewIndex != NSNotFound && 244 | annotation.rightCalloutViewIndex < mapView.reactSubviews.count) { 245 | annotationView.rightCalloutAccessoryView = 246 | mapView.reactSubviews[annotation.rightCalloutViewIndex]; 247 | } else if (annotation.hasRightCallout) { 248 | annotationView.rightCalloutAccessoryView = 249 | [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 250 | } else { 251 | annotationView.rightCalloutAccessoryView = nil; 252 | } 253 | 254 | //http://stackoverflow.com/questions/32581049/mapkit-ios-9-detailcalloutaccessoryview-usage 255 | if ([annotationView respondsToSelector:@selector(detailCalloutAccessoryView)]) { 256 | if (annotation.detailCalloutViewIndex != NSNotFound && 257 | annotation.detailCalloutViewIndex < mapView.reactSubviews.count) { 258 | UIView *calloutView = mapView.reactSubviews[annotation.detailCalloutViewIndex]; 259 | NSLayoutConstraint *widthConstraint = 260 | [NSLayoutConstraint constraintWithItem:calloutView 261 | attribute:NSLayoutAttributeWidth 262 | relatedBy:NSLayoutRelationEqual 263 | toItem:nil 264 | attribute:NSLayoutAttributeNotAnAttribute 265 | multiplier:1 266 | constant:calloutView.frame.size.width]; 267 | [calloutView addConstraint:widthConstraint]; 268 | NSLayoutConstraint *heightConstraint = 269 | [NSLayoutConstraint constraintWithItem:calloutView 270 | attribute:NSLayoutAttributeHeight 271 | relatedBy:NSLayoutRelationEqual 272 | toItem:nil 273 | attribute:NSLayoutAttributeNotAnAttribute 274 | multiplier:1 275 | constant:calloutView.frame.size.height]; 276 | [calloutView addConstraint:heightConstraint]; 277 | annotationView.detailCalloutAccessoryView = calloutView; 278 | } else { 279 | annotationView.detailCalloutAccessoryView = nil; 280 | } 281 | } 282 | 283 | #if !TARGET_OS_TV 284 | annotationView.draggable = annotation.draggable; 285 | #endif 286 | 287 | return annotationView; 288 | } 289 | 290 | - (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id)overlay 291 | { 292 | RCTAssert([overlay isKindOfClass:[RCTMapOverlay class]], @"Overlay must be of type RCTMapOverlay"); 293 | MKPolylineRenderer *polylineRenderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay]; 294 | polylineRenderer.strokeColor = [(RCTMapOverlay *)overlay strokeColor]; 295 | polylineRenderer.lineWidth = [(RCTMapOverlay *)overlay lineWidth]; 296 | return polylineRenderer; 297 | } 298 | 299 | - (void)mapView:(RCTMap *)mapView annotationView:(MKAnnotationView *)view 300 | calloutAccessoryControlTapped:(UIControl *)control 301 | { 302 | if (mapView.onPress) { 303 | // Pass to JS 304 | RCTMapAnnotation *annotation = (RCTMapAnnotation *)view.annotation; 305 | mapView.onPress(@{ 306 | @"side": (control == view.leftCalloutAccessoryView) ? @"left" : @"right", 307 | @"action": @"callout-click", 308 | @"annotationId": annotation.identifier 309 | }); 310 | } 311 | } 312 | 313 | - (void)mapView:(RCTMap *)mapView didUpdateUserLocation:(MKUserLocation *)location 314 | { 315 | if (mapView.followUserLocation) { 316 | MKCoordinateRegion region; 317 | region.span.latitudeDelta = RCTMapDefaultSpan; 318 | region.span.longitudeDelta = RCTMapDefaultSpan; 319 | region.center = location.coordinate; 320 | [mapView setRegion:region animated:YES]; 321 | } 322 | } 323 | 324 | - (void)mapView:(RCTMap *)mapView regionWillChangeAnimated:(__unused BOOL)animated 325 | { 326 | [self _regionChanged:mapView]; 327 | 328 | mapView.regionChangeObserveTimer = 329 | [NSTimer timerWithTimeInterval:RCTMapRegionChangeObserveInterval 330 | target:self 331 | selector:@selector(_onTick:) 332 | userInfo:@{ RCTMapViewKey: mapView } 333 | repeats:YES]; 334 | 335 | [[NSRunLoop mainRunLoop] addTimer:mapView.regionChangeObserveTimer 336 | forMode:NSRunLoopCommonModes]; 337 | } 338 | 339 | - (void)mapView:(RCTMap *)mapView regionDidChangeAnimated:(__unused BOOL)animated 340 | { 341 | [mapView.regionChangeObserveTimer invalidate]; 342 | mapView.regionChangeObserveTimer = nil; 343 | 344 | [self _regionChanged:mapView]; 345 | 346 | // Don't send region did change events until map has 347 | // started rendering, as these won't represent the final location 348 | if (mapView.hasStartedRendering) { 349 | [self _emitRegionChangeEvent:mapView continuous:NO]; 350 | }; 351 | } 352 | 353 | - (void)mapViewWillStartRenderingMap:(RCTMap *)mapView 354 | { 355 | mapView.hasStartedRendering = YES; 356 | [self _emitRegionChangeEvent:mapView continuous:NO]; 357 | } 358 | 359 | #pragma mark Private 360 | 361 | - (void)_onTick:(NSTimer *)timer 362 | { 363 | [self _regionChanged:timer.userInfo[RCTMapViewKey]]; 364 | } 365 | 366 | - (void)_regionChanged:(RCTMap *)mapView 367 | { 368 | BOOL needZoom = NO; 369 | CGFloat newLongitudeDelta = 0.0f; 370 | MKCoordinateRegion region = mapView.region; 371 | 372 | // On iOS 7, it's possible that we observe invalid locations during 373 | // initialization of the map. Filter those out. 374 | if (!CLLocationCoordinate2DIsValid(region.center)) { 375 | return; 376 | } 377 | 378 | // Calculation on float is not 100% accurate. If user zoom to max/min and then 379 | // move, it's likely the map will auto zoom to max/min from time to time. 380 | // So let's try to make map zoom back to 99% max or 101% min so that there is 381 | // some buffer, and moving the map won't constantly hit the max/min bound. 382 | if (mapView.maxDelta > FLT_EPSILON && 383 | region.span.longitudeDelta > mapView.maxDelta) { 384 | needZoom = YES; 385 | newLongitudeDelta = mapView.maxDelta * (1 - RCTMapZoomBoundBuffer); 386 | } else if (mapView.minDelta > FLT_EPSILON && 387 | region.span.longitudeDelta < mapView.minDelta) { 388 | needZoom = YES; 389 | newLongitudeDelta = mapView.minDelta * (1 + RCTMapZoomBoundBuffer); 390 | } 391 | if (needZoom) { 392 | region.span.latitudeDelta = 393 | region.span.latitudeDelta / region.span.longitudeDelta * newLongitudeDelta; 394 | region.span.longitudeDelta = newLongitudeDelta; 395 | mapView.region = region; 396 | } 397 | 398 | // Continously observe region changes 399 | [self _emitRegionChangeEvent:mapView continuous:YES]; 400 | } 401 | 402 | - (void)_emitRegionChangeEvent:(RCTMap *)mapView continuous:(BOOL)continuous 403 | { 404 | if (mapView.onChange) { 405 | MKCoordinateRegion region = mapView.region; 406 | if (!CLLocationCoordinate2DIsValid(region.center)) { 407 | return; 408 | } 409 | 410 | mapView.onChange(@{ 411 | @"continuous": @(continuous), 412 | @"region": @{ 413 | @"latitude": @(RCTZeroIfNaN(region.center.latitude)), 414 | @"longitude": @(RCTZeroIfNaN(region.center.longitude)), 415 | @"latitudeDelta": @(RCTZeroIfNaN(region.span.latitudeDelta)), 416 | @"longitudeDelta": @(RCTZeroIfNaN(region.span.longitudeDelta)), 417 | } 418 | }); 419 | } 420 | } 421 | 422 | @end 423 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-mapview/ios/RCTMapOverlay.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | @interface RCTMapOverlay : MKPolyline 11 | 12 | @property (nonatomic, copy) NSString *identifier; 13 | @property (nonatomic, strong) UIColor *strokeColor; 14 | @property (nonatomic, assign) CGFloat lineWidth; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-mapview/ios/RCTMapOverlay.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "RCTMapOverlay.h" 9 | 10 | @implementation RCTMapOverlay 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-mapview/ios/RNDeprecatedMapView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 26A72B881DC910EA00FB1702 /* RCTConvert+MapKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 26A72B7F1DC910EA00FB1702 /* RCTConvert+MapKit.m */; }; 11 | 26A72B891DC910EA00FB1702 /* RCTMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 26A72B811DC910EA00FB1702 /* RCTMap.m */; }; 12 | 26A72B8A1DC910EA00FB1702 /* RCTMapAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 26A72B831DC910EA00FB1702 /* RCTMapAnnotation.m */; }; 13 | 26A72B8B1DC910EA00FB1702 /* RCTMapManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 26A72B851DC910EA00FB1702 /* RCTMapManager.m */; }; 14 | 26A72B8C1DC910EA00FB1702 /* RCTMapOverlay.m in Sources */ = {isa = PBXBuildFile; fileRef = 26A72B871DC910EA00FB1702 /* RCTMapOverlay.m */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXCopyFilesBuildPhase section */ 18 | 58B511D91A9E6C8500147676 /* CopyFiles */ = { 19 | isa = PBXCopyFilesBuildPhase; 20 | buildActionMask = 2147483647; 21 | dstPath = "include/$(PRODUCT_NAME)"; 22 | dstSubfolderSpec = 16; 23 | files = ( 24 | ); 25 | runOnlyForDeploymentPostprocessing = 0; 26 | }; 27 | /* End PBXCopyFilesBuildPhase section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | 134814201AA4EA6300B7C361 /* libRNDeprecatedMapView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNDeprecatedMapView.a; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 26A72B7E1DC910EA00FB1702 /* RCTConvert+MapKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+MapKit.h"; sourceTree = ""; }; 32 | 26A72B7F1DC910EA00FB1702 /* RCTConvert+MapKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+MapKit.m"; sourceTree = ""; }; 33 | 26A72B801DC910EA00FB1702 /* RCTMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMap.h; sourceTree = ""; }; 34 | 26A72B811DC910EA00FB1702 /* RCTMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMap.m; sourceTree = ""; }; 35 | 26A72B821DC910EA00FB1702 /* RCTMapAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMapAnnotation.h; sourceTree = ""; }; 36 | 26A72B831DC910EA00FB1702 /* RCTMapAnnotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMapAnnotation.m; sourceTree = ""; }; 37 | 26A72B841DC910EA00FB1702 /* RCTMapManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMapManager.h; sourceTree = ""; }; 38 | 26A72B851DC910EA00FB1702 /* RCTMapManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMapManager.m; sourceTree = ""; }; 39 | 26A72B861DC910EA00FB1702 /* RCTMapOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMapOverlay.h; sourceTree = ""; }; 40 | 26A72B871DC910EA00FB1702 /* RCTMapOverlay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMapOverlay.m; sourceTree = ""; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | 58B511D81A9E6C8500147676 /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | ); 49 | runOnlyForDeploymentPostprocessing = 0; 50 | }; 51 | /* End PBXFrameworksBuildPhase section */ 52 | 53 | /* Begin PBXGroup section */ 54 | 134814211AA4EA7D00B7C361 /* Products */ = { 55 | isa = PBXGroup; 56 | children = ( 57 | 134814201AA4EA6300B7C361 /* libRNDeprecatedMapView.a */, 58 | ); 59 | name = Products; 60 | sourceTree = ""; 61 | }; 62 | 58B511D21A9E6C8500147676 = { 63 | isa = PBXGroup; 64 | children = ( 65 | 26A72B7E1DC910EA00FB1702 /* RCTConvert+MapKit.h */, 66 | 26A72B7F1DC910EA00FB1702 /* RCTConvert+MapKit.m */, 67 | 26A72B801DC910EA00FB1702 /* RCTMap.h */, 68 | 26A72B811DC910EA00FB1702 /* RCTMap.m */, 69 | 26A72B821DC910EA00FB1702 /* RCTMapAnnotation.h */, 70 | 26A72B831DC910EA00FB1702 /* RCTMapAnnotation.m */, 71 | 26A72B841DC910EA00FB1702 /* RCTMapManager.h */, 72 | 26A72B851DC910EA00FB1702 /* RCTMapManager.m */, 73 | 26A72B861DC910EA00FB1702 /* RCTMapOverlay.h */, 74 | 26A72B871DC910EA00FB1702 /* RCTMapOverlay.m */, 75 | 134814211AA4EA7D00B7C361 /* Products */, 76 | ); 77 | sourceTree = ""; 78 | }; 79 | /* End PBXGroup section */ 80 | 81 | /* Begin PBXNativeTarget section */ 82 | 58B511DA1A9E6C8500147676 /* RNDeprecatedMapView */ = { 83 | isa = PBXNativeTarget; 84 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNDeprecatedMapView" */; 85 | buildPhases = ( 86 | 58B511D71A9E6C8500147676 /* Sources */, 87 | 58B511D81A9E6C8500147676 /* Frameworks */, 88 | 58B511D91A9E6C8500147676 /* CopyFiles */, 89 | ); 90 | buildRules = ( 91 | ); 92 | dependencies = ( 93 | ); 94 | name = RNDeprecatedMapView; 95 | productName = RCTDataManager; 96 | productReference = 134814201AA4EA6300B7C361 /* libRNDeprecatedMapView.a */; 97 | productType = "com.apple.product-type.library.static"; 98 | }; 99 | /* End PBXNativeTarget section */ 100 | 101 | /* Begin PBXProject section */ 102 | 58B511D31A9E6C8500147676 /* Project object */ = { 103 | isa = PBXProject; 104 | attributes = { 105 | LastUpgradeCheck = 0610; 106 | ORGANIZATIONNAME = Facebook; 107 | TargetAttributes = { 108 | 58B511DA1A9E6C8500147676 = { 109 | CreatedOnToolsVersion = 6.1.1; 110 | }; 111 | }; 112 | }; 113 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNDeprecatedMapView" */; 114 | compatibilityVersion = "Xcode 3.2"; 115 | developmentRegion = English; 116 | hasScannedForEncodings = 0; 117 | knownRegions = ( 118 | en, 119 | ); 120 | mainGroup = 58B511D21A9E6C8500147676; 121 | productRefGroup = 58B511D21A9E6C8500147676; 122 | projectDirPath = ""; 123 | projectRoot = ""; 124 | targets = ( 125 | 58B511DA1A9E6C8500147676 /* RNDeprecatedMapView */, 126 | ); 127 | }; 128 | /* End PBXProject section */ 129 | 130 | /* Begin PBXSourcesBuildPhase section */ 131 | 58B511D71A9E6C8500147676 /* Sources */ = { 132 | isa = PBXSourcesBuildPhase; 133 | buildActionMask = 2147483647; 134 | files = ( 135 | 26A72B8B1DC910EA00FB1702 /* RCTMapManager.m in Sources */, 136 | 26A72B8C1DC910EA00FB1702 /* RCTMapOverlay.m in Sources */, 137 | 26A72B891DC910EA00FB1702 /* RCTMap.m in Sources */, 138 | 26A72B8A1DC910EA00FB1702 /* RCTMapAnnotation.m in Sources */, 139 | 26A72B881DC910EA00FB1702 /* RCTConvert+MapKit.m in Sources */, 140 | ); 141 | runOnlyForDeploymentPostprocessing = 0; 142 | }; 143 | /* End PBXSourcesBuildPhase section */ 144 | 145 | /* Begin XCBuildConfiguration section */ 146 | 58B511ED1A9E6C8500147676 /* Debug */ = { 147 | isa = XCBuildConfiguration; 148 | buildSettings = { 149 | ALWAYS_SEARCH_USER_PATHS = NO; 150 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 151 | CLANG_CXX_LIBRARY = "libc++"; 152 | CLANG_ENABLE_MODULES = YES; 153 | CLANG_ENABLE_OBJC_ARC = YES; 154 | CLANG_WARN_BOOL_CONVERSION = YES; 155 | CLANG_WARN_CONSTANT_CONVERSION = YES; 156 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 157 | CLANG_WARN_EMPTY_BODY = YES; 158 | CLANG_WARN_ENUM_CONVERSION = YES; 159 | CLANG_WARN_INT_CONVERSION = YES; 160 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 161 | CLANG_WARN_UNREACHABLE_CODE = YES; 162 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 163 | COPY_PHASE_STRIP = NO; 164 | ENABLE_STRICT_OBJC_MSGSEND = YES; 165 | GCC_C_LANGUAGE_STANDARD = gnu99; 166 | GCC_DYNAMIC_NO_PIC = NO; 167 | GCC_OPTIMIZATION_LEVEL = 0; 168 | GCC_PREPROCESSOR_DEFINITIONS = ( 169 | "DEBUG=1", 170 | "$(inherited)", 171 | ); 172 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 173 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 174 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 175 | GCC_WARN_UNDECLARED_SELECTOR = YES; 176 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 177 | GCC_WARN_UNUSED_FUNCTION = YES; 178 | GCC_WARN_UNUSED_VARIABLE = YES; 179 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 180 | MTL_ENABLE_DEBUG_INFO = YES; 181 | ONLY_ACTIVE_ARCH = YES; 182 | SDKROOT = iphoneos; 183 | }; 184 | name = Debug; 185 | }; 186 | 58B511EE1A9E6C8500147676 /* Release */ = { 187 | isa = XCBuildConfiguration; 188 | buildSettings = { 189 | ALWAYS_SEARCH_USER_PATHS = NO; 190 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 191 | CLANG_CXX_LIBRARY = "libc++"; 192 | CLANG_ENABLE_MODULES = YES; 193 | CLANG_ENABLE_OBJC_ARC = YES; 194 | CLANG_WARN_BOOL_CONVERSION = YES; 195 | CLANG_WARN_CONSTANT_CONVERSION = YES; 196 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 197 | CLANG_WARN_EMPTY_BODY = YES; 198 | CLANG_WARN_ENUM_CONVERSION = YES; 199 | CLANG_WARN_INT_CONVERSION = YES; 200 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 201 | CLANG_WARN_UNREACHABLE_CODE = YES; 202 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 203 | COPY_PHASE_STRIP = YES; 204 | ENABLE_NS_ASSERTIONS = NO; 205 | ENABLE_STRICT_OBJC_MSGSEND = YES; 206 | GCC_C_LANGUAGE_STANDARD = gnu99; 207 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 208 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 209 | GCC_WARN_UNDECLARED_SELECTOR = YES; 210 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 211 | GCC_WARN_UNUSED_FUNCTION = YES; 212 | GCC_WARN_UNUSED_VARIABLE = YES; 213 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 214 | MTL_ENABLE_DEBUG_INFO = NO; 215 | SDKROOT = iphoneos; 216 | VALIDATE_PRODUCT = YES; 217 | }; 218 | name = Release; 219 | }; 220 | 58B511F01A9E6C8500147676 /* Debug */ = { 221 | isa = XCBuildConfiguration; 222 | buildSettings = { 223 | HEADER_SEARCH_PATHS = ( 224 | "$(inherited)", 225 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 226 | "$(SRCROOT)/../../../React/**", 227 | "$(SRCROOT)/../../react-native/React/**", 228 | ); 229 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 230 | OTHER_LDFLAGS = "-ObjC"; 231 | PRODUCT_NAME = RNDeprecatedMapView; 232 | SKIP_INSTALL = YES; 233 | }; 234 | name = Debug; 235 | }; 236 | 58B511F11A9E6C8500147676 /* Release */ = { 237 | isa = XCBuildConfiguration; 238 | buildSettings = { 239 | HEADER_SEARCH_PATHS = ( 240 | "$(inherited)", 241 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 242 | "$(SRCROOT)/../../../React/**", 243 | "$(SRCROOT)/../../react-native/React/**", 244 | ); 245 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 246 | OTHER_LDFLAGS = "-ObjC"; 247 | PRODUCT_NAME = RNDeprecatedMapView; 248 | SKIP_INSTALL = YES; 249 | }; 250 | name = Release; 251 | }; 252 | /* End XCBuildConfiguration section */ 253 | 254 | /* Begin XCConfigurationList section */ 255 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNDeprecatedMapView" */ = { 256 | isa = XCConfigurationList; 257 | buildConfigurations = ( 258 | 58B511ED1A9E6C8500147676 /* Debug */, 259 | 58B511EE1A9E6C8500147676 /* Release */, 260 | ); 261 | defaultConfigurationIsVisible = 0; 262 | defaultConfigurationName = Release; 263 | }; 264 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNDeprecatedMapView" */ = { 265 | isa = XCConfigurationList; 266 | buildConfigurations = ( 267 | 58B511F01A9E6C8500147676 /* Debug */, 268 | 58B511F11A9E6C8500147676 /* Release */, 269 | ); 270 | defaultConfigurationIsVisible = 0; 271 | defaultConfigurationName = Release; 272 | }; 273 | /* End XCConfigurationList section */ 274 | }; 275 | rootObject = 58B511D31A9E6C8500147676 /* Project object */; 276 | } 277 | -------------------------------------------------------------------------------- /deprecated-react-native-ios-mapview/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "deprecated-react-native-ios-mapview", 3 | "version": "0.40.0", 4 | "description": "", 5 | "license": "MIT", 6 | "repository": { 7 | "type": "git", 8 | "url": "git@github.com:facebook/react-native-deprecated-modules.git" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /deprecated-react-native-listview/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.0.9 / 2023-07-28 2 | 3 | - Added essential Flow library definitions 4 | -------------------------------------------------------------------------------- /deprecated-react-native-listview/InternalListViewType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | const React = require('react'); 12 | const ListViewDataSource = require('./ListViewDataSource'); 13 | 14 | // This class is purely a facsimile of ListView so that we can 15 | // properly type it with Flow before migrating ListView off of 16 | // createReactClass. If there are things missing here that are in 17 | // ListView, that is unintentional. 18 | class InternalListViewType extends React.Component { 19 | static DataSource = ListViewDataSource; 20 | setNativeProps(props: Object) {} 21 | flashScrollIndicators() {} 22 | getScrollResponder(): any {} 23 | getScrollableNode(): any {} 24 | getMetrics(): Object {} 25 | scrollTo(...args: Array) {} 26 | scrollToEnd(options?: ?{animated?: ?boolean}) {} 27 | } 28 | 29 | module.exports = InternalListViewType; 30 | -------------------------------------------------------------------------------- /deprecated-react-native-listview/ListViewDataSource.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @flow 8 | * @format 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const invariant = require('invariant'); 14 | const isEmpty = require('./isEmpty'); 15 | /* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error 16 | * found when Flow v0.54 was deployed. To see the error delete this comment and 17 | * run Flow. */ 18 | const warning = require('fbjs/lib/warning'); 19 | 20 | function defaultGetRowData( 21 | dataBlob: any, 22 | sectionID: number | string, 23 | rowID: number | string, 24 | ): any { 25 | return dataBlob[sectionID][rowID]; 26 | } 27 | 28 | function defaultGetSectionHeaderData( 29 | dataBlob: any, 30 | sectionID: number | string, 31 | ): any { 32 | return dataBlob[sectionID]; 33 | } 34 | 35 | type differType = (data1: any, data2: any) => boolean; 36 | 37 | type ParamType = { 38 | rowHasChanged: differType, 39 | getRowData?: ?typeof defaultGetRowData, 40 | sectionHeaderHasChanged?: ?differType, 41 | getSectionHeaderData?: ?typeof defaultGetSectionHeaderData, 42 | }; 43 | 44 | /** 45 | * Provides efficient data processing and access to the 46 | * `ListView` component. A `ListViewDataSource` is created with functions for 47 | * extracting data from the input blob, and comparing elements (with default 48 | * implementations for convenience). The input blob can be as simple as an 49 | * array of strings, or an object with rows nested inside section objects. 50 | * 51 | * To update the data in the datasource, use `cloneWithRows` (or 52 | * `cloneWithRowsAndSections` if you care about sections). The data in the 53 | * data source is immutable, so you can't modify it directly. The clone methods 54 | * suck in the new data and compute a diff for each row so ListView knows 55 | * whether to re-render it or not. 56 | * 57 | * In this example, a component receives data in chunks, handled by 58 | * `_onDataArrived`, which concats the new data onto the old data and updates the 59 | * data source. We use `concat` to create a new array - mutating `this._data`, 60 | * e.g. with `this._data.push(newRowData)`, would be an error. `_rowHasChanged` 61 | * understands the shape of the row data and knows how to efficiently compare 62 | * it. 63 | * 64 | * ``` 65 | * getInitialState: function() { 66 | * const ds = new ListView.DataSource({rowHasChanged: this._rowHasChanged}); 67 | * return {ds}; 68 | * }, 69 | * _onDataArrived(newData) { 70 | * this._data = this._data.concat(newData); 71 | * this.setState({ 72 | * ds: this.state.ds.cloneWithRows(this._data) 73 | * }); 74 | * } 75 | * ``` 76 | */ 77 | 78 | class ListViewDataSource { 79 | /** 80 | * You can provide custom extraction and `hasChanged` functions for section 81 | * headers and rows. If absent, data will be extracted with the 82 | * `defaultGetRowData` and `defaultGetSectionHeaderData` functions. 83 | * 84 | * The default extractor expects data of one of the following forms: 85 | * 86 | * { sectionID_1: { rowID_1: , ... }, ... } 87 | * 88 | * or 89 | * 90 | * { sectionID_1: [ , , ... ], ... } 91 | * 92 | * or 93 | * 94 | * [ [ , , ... ], ... ] 95 | * 96 | * The constructor takes in a params argument that can contain any of the 97 | * following: 98 | * 99 | * - getRowData(dataBlob, sectionID, rowID); 100 | * - getSectionHeaderData(dataBlob, sectionID); 101 | * - rowHasChanged(prevRowData, nextRowData); 102 | * - sectionHeaderHasChanged(prevSectionData, nextSectionData); 103 | */ 104 | constructor(params: ParamType) { 105 | invariant( 106 | params && typeof params.rowHasChanged === 'function', 107 | 'Must provide a rowHasChanged function.', 108 | ); 109 | this._rowHasChanged = params.rowHasChanged; 110 | this._getRowData = params.getRowData || defaultGetRowData; 111 | this._sectionHeaderHasChanged = params.sectionHeaderHasChanged; 112 | this._getSectionHeaderData = 113 | params.getSectionHeaderData || defaultGetSectionHeaderData; 114 | 115 | this._dataBlob = null; 116 | this._dirtyRows = []; 117 | this._dirtySections = []; 118 | this._cachedRowCount = 0; 119 | 120 | // These two private variables are accessed by outsiders because ListView 121 | // uses them to iterate over the data in this class. 122 | this.rowIdentities = []; 123 | this.sectionIdentities = []; 124 | } 125 | 126 | /** 127 | * Clones this `ListViewDataSource` with the specified `dataBlob` and 128 | * `rowIdentities`. The `dataBlob` is just an arbitrary blob of data. At 129 | * construction an extractor to get the interesting information was defined 130 | * (or the default was used). 131 | * 132 | * The `rowIdentities` is a 2D array of identifiers for rows. 133 | * ie. [['a1', 'a2'], ['b1', 'b2', 'b3'], ...]. If not provided, it's 134 | * assumed that the keys of the section data are the row identities. 135 | * 136 | * Note: This function does NOT clone the data in this data source. It simply 137 | * passes the functions defined at construction to a new data source with 138 | * the data specified. If you wish to maintain the existing data you must 139 | * handle merging of old and new data separately and then pass that into 140 | * this function as the `dataBlob`. 141 | */ 142 | cloneWithRows( 143 | dataBlob: $ReadOnlyArray | {+[key: string]: any}, 144 | rowIdentities: ?$ReadOnlyArray, 145 | ): ListViewDataSource { 146 | const rowIds = rowIdentities ? [[...rowIdentities]] : null; 147 | if (!this._sectionHeaderHasChanged) { 148 | this._sectionHeaderHasChanged = () => false; 149 | } 150 | return this.cloneWithRowsAndSections({s1: dataBlob}, ['s1'], rowIds); 151 | } 152 | 153 | /** 154 | * This performs the same function as the `cloneWithRows` function but here 155 | * you also specify what your `sectionIdentities` are. If you don't care 156 | * about sections you should safely be able to use `cloneWithRows`. 157 | * 158 | * `sectionIdentities` is an array of identifiers for sections. 159 | * ie. ['s1', 's2', ...]. The identifiers should correspond to the keys or array indexes 160 | * of the data you wish to include. If not provided, it's assumed that the 161 | * keys of dataBlob are the section identities. 162 | * 163 | * Note: this returns a new object! 164 | * 165 | * ``` 166 | * const dataSource = ds.cloneWithRowsAndSections({ 167 | * addresses: ['row 1', 'row 2'], 168 | * phone_numbers: ['data 1', 'data 2'], 169 | * }, ['phone_numbers']); 170 | * ``` 171 | */ 172 | cloneWithRowsAndSections( 173 | dataBlob: any, 174 | sectionIdentities: ?Array, 175 | rowIdentities: ?Array>, 176 | ): ListViewDataSource { 177 | invariant( 178 | typeof this._sectionHeaderHasChanged === 'function', 179 | 'Must provide a sectionHeaderHasChanged function with section data.', 180 | ); 181 | invariant( 182 | !sectionIdentities || 183 | !rowIdentities || 184 | sectionIdentities.length === rowIdentities.length, 185 | 'row and section ids lengths must be the same', 186 | ); 187 | 188 | const newSource = new ListViewDataSource({ 189 | getRowData: this._getRowData, 190 | getSectionHeaderData: this._getSectionHeaderData, 191 | rowHasChanged: this._rowHasChanged, 192 | sectionHeaderHasChanged: this._sectionHeaderHasChanged, 193 | }); 194 | newSource._dataBlob = dataBlob; 195 | if (sectionIdentities) { 196 | newSource.sectionIdentities = sectionIdentities; 197 | } else { 198 | newSource.sectionIdentities = Object.keys(dataBlob); 199 | } 200 | if (rowIdentities) { 201 | newSource.rowIdentities = rowIdentities; 202 | } else { 203 | newSource.rowIdentities = []; 204 | newSource.sectionIdentities.forEach(sectionID => { 205 | newSource.rowIdentities.push(Object.keys(dataBlob[sectionID])); 206 | }); 207 | } 208 | newSource._cachedRowCount = countRows(newSource.rowIdentities); 209 | 210 | newSource._calculateDirtyArrays( 211 | this._dataBlob, 212 | this.sectionIdentities, 213 | this.rowIdentities, 214 | ); 215 | 216 | return newSource; 217 | } 218 | 219 | /** 220 | * Returns the total number of rows in the data source. 221 | * 222 | * If you are specifying the rowIdentities or sectionIdentities, then `getRowCount` will return the number of rows in the filtered data source. 223 | */ 224 | getRowCount(): number { 225 | return this._cachedRowCount; 226 | } 227 | 228 | /** 229 | * Returns the total number of rows in the data source (see `getRowCount` for how this is calculated) plus the number of sections in the data. 230 | * 231 | * If you are specifying the rowIdentities or sectionIdentities, then `getRowAndSectionCount` will return the number of rows & sections in the filtered data source. 232 | */ 233 | getRowAndSectionCount(): number { 234 | return this._cachedRowCount + this.sectionIdentities.length; 235 | } 236 | 237 | /** 238 | * Returns if the row is dirtied and needs to be rerendered 239 | */ 240 | rowShouldUpdate(sectionIndex: number, rowIndex: number): boolean { 241 | const needsUpdate = this._dirtyRows[sectionIndex][rowIndex]; 242 | warning( 243 | needsUpdate !== undefined, 244 | 'missing dirtyBit for section, row: ' + sectionIndex + ', ' + rowIndex, 245 | ); 246 | return needsUpdate; 247 | } 248 | 249 | /** 250 | * Gets the data required to render the row. 251 | */ 252 | getRowData(sectionIndex: number, rowIndex: number): any { 253 | const sectionID = this.sectionIdentities[sectionIndex]; 254 | const rowID = this.rowIdentities[sectionIndex][rowIndex]; 255 | warning( 256 | sectionID !== undefined && rowID !== undefined, 257 | 'rendering invalid section, row: ' + sectionIndex + ', ' + rowIndex, 258 | ); 259 | return this._getRowData(this._dataBlob, sectionID, rowID); 260 | } 261 | 262 | /** 263 | * Gets the rowID at index provided if the dataSource arrays were flattened, 264 | * or null of out of range indexes. 265 | */ 266 | getRowIDForFlatIndex(index: number): ?string { 267 | let accessIndex = index; 268 | for (let ii = 0; ii < this.sectionIdentities.length; ii++) { 269 | if (accessIndex >= this.rowIdentities[ii].length) { 270 | accessIndex -= this.rowIdentities[ii].length; 271 | } else { 272 | return this.rowIdentities[ii][accessIndex]; 273 | } 274 | } 275 | return null; 276 | } 277 | 278 | /** 279 | * Gets the sectionID at index provided if the dataSource arrays were flattened, 280 | * or null for out of range indexes. 281 | */ 282 | getSectionIDForFlatIndex(index: number): ?string { 283 | let accessIndex = index; 284 | for (let ii = 0; ii < this.sectionIdentities.length; ii++) { 285 | if (accessIndex >= this.rowIdentities[ii].length) { 286 | accessIndex -= this.rowIdentities[ii].length; 287 | } else { 288 | return this.sectionIdentities[ii]; 289 | } 290 | } 291 | return null; 292 | } 293 | 294 | /** 295 | * Returns an array containing the number of rows in each section 296 | */ 297 | getSectionLengths(): Array { 298 | const results = []; 299 | for (let ii = 0; ii < this.sectionIdentities.length; ii++) { 300 | results.push(this.rowIdentities[ii].length); 301 | } 302 | return results; 303 | } 304 | 305 | /** 306 | * Returns if the section header is dirtied and needs to be rerendered 307 | */ 308 | sectionHeaderShouldUpdate(sectionIndex: number): boolean { 309 | const needsUpdate = this._dirtySections[sectionIndex]; 310 | warning( 311 | needsUpdate !== undefined, 312 | 'missing dirtyBit for section: ' + sectionIndex, 313 | ); 314 | return needsUpdate; 315 | } 316 | 317 | /** 318 | * Gets the data required to render the section header 319 | */ 320 | getSectionHeaderData(sectionIndex: number): any { 321 | if (!this._getSectionHeaderData) { 322 | return null; 323 | } 324 | const sectionID = this.sectionIdentities[sectionIndex]; 325 | warning( 326 | sectionID !== undefined, 327 | 'renderSection called on invalid section: ' + sectionIndex, 328 | ); 329 | return this._getSectionHeaderData(this._dataBlob, sectionID); 330 | } 331 | 332 | /** 333 | * Private members and methods. 334 | */ 335 | 336 | _getRowData: typeof defaultGetRowData; 337 | _getSectionHeaderData: typeof defaultGetSectionHeaderData; 338 | _rowHasChanged: differType; 339 | _sectionHeaderHasChanged: ?differType; 340 | 341 | _dataBlob: any; 342 | _dirtyRows: Array>; 343 | _dirtySections: Array; 344 | _cachedRowCount: number; 345 | 346 | // These two 'protected' variables are accessed by ListView to iterate over 347 | // the data in this class. 348 | rowIdentities: Array>; 349 | sectionIdentities: Array; 350 | 351 | _calculateDirtyArrays( 352 | prevDataBlob: any, 353 | prevSectionIDs: Array, 354 | prevRowIDs: Array>, 355 | ): void { 356 | // construct a hashmap of the existing (old) id arrays 357 | const prevSectionsHash = keyedDictionaryFromArray(prevSectionIDs); 358 | const prevRowsHash = {}; 359 | for (let ii = 0; ii < prevRowIDs.length; ii++) { 360 | const sectionID = prevSectionIDs[ii]; 361 | warning( 362 | !prevRowsHash[sectionID], 363 | 'SectionID appears more than once: ' + sectionID, 364 | ); 365 | prevRowsHash[sectionID] = keyedDictionaryFromArray(prevRowIDs[ii]); 366 | } 367 | 368 | // compare the 2 identity array and get the dirtied rows 369 | this._dirtySections = []; 370 | this._dirtyRows = []; 371 | 372 | let dirty; 373 | for (let sIndex = 0; sIndex < this.sectionIdentities.length; sIndex++) { 374 | const sectionID = this.sectionIdentities[sIndex]; 375 | // dirty if the sectionHeader is new or _sectionHasChanged is true 376 | dirty = !prevSectionsHash[sectionID]; 377 | const sectionHeaderHasChanged = this._sectionHeaderHasChanged; 378 | if (!dirty && sectionHeaderHasChanged) { 379 | dirty = sectionHeaderHasChanged( 380 | this._getSectionHeaderData(prevDataBlob, sectionID), 381 | this._getSectionHeaderData(this._dataBlob, sectionID), 382 | ); 383 | } 384 | this._dirtySections.push(!!dirty); 385 | 386 | this._dirtyRows[sIndex] = []; 387 | for ( 388 | let rIndex = 0; 389 | rIndex < this.rowIdentities[sIndex].length; 390 | rIndex++ 391 | ) { 392 | const rowID = this.rowIdentities[sIndex][rIndex]; 393 | // dirty if the section is new, row is new or _rowHasChanged is true 394 | dirty = 395 | !prevSectionsHash[sectionID] || 396 | !prevRowsHash[sectionID][rowID] || 397 | this._rowHasChanged( 398 | this._getRowData(prevDataBlob, sectionID, rowID), 399 | this._getRowData(this._dataBlob, sectionID, rowID), 400 | ); 401 | this._dirtyRows[sIndex].push(!!dirty); 402 | } 403 | } 404 | } 405 | } 406 | 407 | function countRows(allRowIDs) { 408 | let totalRows = 0; 409 | for (let sectionIdx = 0; sectionIdx < allRowIDs.length; sectionIdx++) { 410 | const rowIDs = allRowIDs[sectionIdx]; 411 | totalRows += rowIDs.length; 412 | } 413 | return totalRows; 414 | } 415 | 416 | function keyedDictionaryFromArray(arr) { 417 | if (isEmpty(arr)) { 418 | return {}; 419 | } 420 | const result = {}; 421 | for (let ii = 0; ii < arr.length; ii++) { 422 | const key = arr[ii]; 423 | warning(!result[key], 'Value appears more than once in array: ' + key); 424 | result[key] = true; 425 | } 426 | return result; 427 | } 428 | 429 | module.exports = ListViewDataSource; 430 | -------------------------------------------------------------------------------- /deprecated-react-native-listview/ListViewDataSource.js.flow: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @flow strict 8 | * @format 9 | */ 10 | 11 | declare export default class ListViewDataSource { 12 | constructor(params: any): ListViewDataSource; 13 | cloneWithRows( 14 | dataBlob: $ReadOnlyArray | {+[key: string]: any}, 15 | rowIdentities: ?$ReadOnlyArray, 16 | ): ListViewDataSource; 17 | cloneWithRowsAndSections( 18 | dataBlob: any, 19 | sectionIdentities: ?Array, 20 | rowIdentities: ?Array>, 21 | ): ListViewDataSource; 22 | getRowCount(): number; 23 | getRowAndSectionCount(): number; 24 | rowShouldUpdate(sectionIndex: number, rowIndex: number): boolean; 25 | getRowData(sectionIndex: number, rowIndex: number): any; 26 | getRowIDForFlatIndex(index: number): ?string; 27 | getSectionIDForFlatIndex(index: number): ?string; 28 | getSectionLengths(): Array; 29 | sectionHeaderShouldUpdate(sectionIndex: number): boolean; 30 | getSectionHeaderData(sectionIndex: number): any; 31 | rowIdentities: Array>; 32 | sectionIdentities: Array; 33 | } 34 | -------------------------------------------------------------------------------- /deprecated-react-native-listview/StaticRenderer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const React = require('react'); 14 | 15 | type Props = $ReadOnly<{| 16 | /** 17 | * Indicates whether the render function needs to be called again 18 | */ 19 | shouldUpdate: boolean, 20 | /** 21 | * () => renderable 22 | * A function that returns a renderable component 23 | */ 24 | render: () => React.Node, 25 | |}>; 26 | 27 | class StaticRenderer extends React.Component { 28 | shouldComponentUpdate(nextProps: Props): boolean { 29 | return nextProps.shouldUpdate; 30 | } 31 | 32 | render(): React.Node { 33 | return this.props.render(); 34 | } 35 | } 36 | 37 | module.exports = StaticRenderer; 38 | -------------------------------------------------------------------------------- /deprecated-react-native-listview/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @flow 8 | * @format 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const InternalListViewType = require('./InternalListViewType'); 14 | const ListViewDataSource = require('./ListViewDataSource'); 15 | const React = require('react'); 16 | const ReactNative = require('react-native'); 17 | const Platform = ReactNative.Platform; 18 | const ScrollView = ReactNative.ScrollView; 19 | const ScrollResponderMixin = require('./ScrollResponder').Mixin; 20 | const StaticRenderer = require('./StaticRenderer'); 21 | const View = ReactNative.View; 22 | const cloneReferencedElement = require('react-clone-referenced-element'); 23 | const createReactClass = require('create-react-class'); 24 | const isEmpty = require('./isEmpty'); 25 | 26 | import type {Props as ScrollViewProps} from 'react-native/Libraries/Components/ScrollView/ScrollView'; 27 | 28 | const DEFAULT_PAGE_SIZE = 1; 29 | const DEFAULT_INITIAL_ROWS = 10; 30 | const DEFAULT_SCROLL_RENDER_AHEAD = 1000; 31 | const DEFAULT_END_REACHED_THRESHOLD = 1000; 32 | const DEFAULT_SCROLL_CALLBACK_THROTTLE = 50; 33 | 34 | type Props = $ReadOnly<{| 35 | ...ScrollViewProps, 36 | 37 | /** 38 | * An instance of [ListView.DataSource](docs/listviewdatasource.html) to use 39 | */ 40 | dataSource: ListViewDataSource, 41 | /** 42 | * (sectionID, rowID, adjacentRowHighlighted) => renderable 43 | * 44 | * If provided, a renderable component to be rendered as the separator 45 | * below each row but not the last row if there is a section header below. 46 | * Take a sectionID and rowID of the row above and whether its adjacent row 47 | * is highlighted. 48 | */ 49 | renderSeparator?: ?Function, 50 | /** 51 | * (rowData, sectionID, rowID, highlightRow) => renderable 52 | * 53 | * Takes a data entry from the data source and its ids and should return 54 | * a renderable component to be rendered as the row. By default the data 55 | * is exactly what was put into the data source, but it's also possible to 56 | * provide custom extractors. ListView can be notified when a row is 57 | * being highlighted by calling `highlightRow(sectionID, rowID)`. This 58 | * sets a boolean value of adjacentRowHighlighted in renderSeparator, allowing you 59 | * to control the separators above and below the highlighted row. The highlighted 60 | * state of a row can be reset by calling highlightRow(null). 61 | */ 62 | renderRow: Function, 63 | /** 64 | * How many rows to render on initial component mount. Use this to make 65 | * it so that the first screen worth of data appears at one time instead of 66 | * over the course of multiple frames. 67 | */ 68 | initialListSize?: ?number, 69 | /** 70 | * Called when all rows have been rendered and the list has been scrolled 71 | * to within onEndReachedThreshold of the bottom. The native scroll 72 | * event is provided. 73 | */ 74 | onEndReached?: ?Function, 75 | /** 76 | * Threshold in pixels (virtual, not physical) for calling onEndReached. 77 | */ 78 | onEndReachedThreshold?: ?number, 79 | /** 80 | * Number of rows to render per event loop. Note: if your 'rows' are actually 81 | * cells, i.e. they don't span the full width of your view (as in the 82 | * ListViewGridLayoutExample), you should set the pageSize to be a multiple 83 | * of the number of cells per row, otherwise you're likely to see gaps at 84 | * the edge of the ListView as new pages are loaded. 85 | */ 86 | pageSize?: ?number, 87 | /** 88 | * () => renderable 89 | * 90 | * The header and footer are always rendered (if these props are provided) 91 | * on every render pass. If they are expensive to re-render, wrap them 92 | * in StaticContainer or other mechanism as appropriate. Footer is always 93 | * at the bottom of the list, and header at the top, on every render pass. 94 | * In a horizontal ListView, the header is rendered on the left and the 95 | * footer on the right. 96 | */ 97 | renderFooter?: ?Function, 98 | renderHeader?: ?Function, 99 | /** 100 | * (sectionData, sectionID) => renderable 101 | * 102 | * If provided, a header is rendered for this section. 103 | */ 104 | renderSectionHeader?: ?Function, 105 | /** 106 | * (props) => renderable 107 | * 108 | * A function that returns the scrollable component in which the list rows 109 | * are rendered. Defaults to returning a ScrollView with the given props. 110 | */ 111 | renderScrollComponent?: ?Function, 112 | /** 113 | * How early to start rendering rows before they come on screen, in 114 | * pixels. 115 | */ 116 | scrollRenderAheadDistance?: ?number, 117 | /** 118 | * (visibleRows, changedRows) => void 119 | * 120 | * Called when the set of visible rows changes. `visibleRows` maps 121 | * { sectionID: { rowID: true }} for all the visible rows, and 122 | * `changedRows` maps { sectionID: { rowID: true | false }} for the rows 123 | * that have changed their visibility, with true indicating visible, and 124 | * false indicating the view has moved out of view. 125 | */ 126 | onChangeVisibleRows?: ?Function, 127 | /** 128 | * A performance optimization for improving scroll perf of 129 | * large lists, used in conjunction with overflow: 'hidden' on the row 130 | * containers. This is enabled by default. 131 | */ 132 | removeClippedSubviews?: ?boolean, 133 | /** 134 | * Makes the sections headers sticky. The sticky behavior means that it 135 | * will scroll with the content at the top of the section until it reaches 136 | * the top of the screen, at which point it will stick to the top until it 137 | * is pushed off the screen by the next section header. This property is 138 | * not supported in conjunction with `horizontal={true}`. Only enabled by 139 | * default on iOS because of typical platform standards. 140 | */ 141 | stickySectionHeadersEnabled?: ?boolean, 142 | /** 143 | * An array of child indices determining which children get docked to the 144 | * top of the screen when scrolling. For example, passing 145 | * `stickyHeaderIndices={[0]}` will cause the first child to be fixed to the 146 | * top of the scroll view. This property is not supported in conjunction 147 | * with `horizontal={true}`. 148 | */ 149 | stickyHeaderIndices?: ?$ReadOnlyArray, 150 | /** 151 | * Flag indicating whether empty section headers should be rendered. In the future release 152 | * empty section headers will be rendered by default, and the flag will be deprecated. 153 | * If empty sections are not desired to be rendered their indices should be excluded from sectionID object. 154 | */ 155 | enableEmptySections?: ?boolean, 156 | |}>; 157 | 158 | /** 159 | * DEPRECATED - use one of the new list components, such as [`FlatList`](docs/flatlist.html) 160 | * or [`SectionList`](docs/sectionlist.html) for bounded memory use, fewer bugs, 161 | * better performance, an easier to use API, and more features. Check out this 162 | * [blog post](https://facebook.github.io/react-native/blog/2017/03/13/better-list-views.html) 163 | * for more details. 164 | * 165 | * ListView - A core component designed for efficient display of vertically 166 | * scrolling lists of changing data. The minimal API is to create a 167 | * [`ListView.DataSource`](docs/listviewdatasource.html), populate it with a simple 168 | * array of data blobs, and instantiate a `ListView` component with that data 169 | * source and a `renderRow` callback which takes a blob from the data array and 170 | * returns a renderable component. 171 | * 172 | * Minimal example: 173 | * 174 | * ``` 175 | * class MyComponent extends Component { 176 | * constructor() { 177 | * super(); 178 | * const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 179 | * this.state = { 180 | * dataSource: ds.cloneWithRows(['row 1', 'row 2']), 181 | * }; 182 | * } 183 | * 184 | * render() { 185 | * return ( 186 | * {rowData}} 189 | * /> 190 | * ); 191 | * } 192 | * } 193 | * ``` 194 | * 195 | * ListView also supports more advanced features, including sections with sticky 196 | * section headers, header and footer support, callbacks on reaching the end of 197 | * the available data (`onEndReached`) and on the set of rows that are visible 198 | * in the device viewport change (`onChangeVisibleRows`), and several 199 | * performance optimizations. 200 | * 201 | * There are a few performance operations designed to make ListView scroll 202 | * smoothly while dynamically loading potentially very large (or conceptually 203 | * infinite) data sets: 204 | * 205 | * * Only re-render changed rows - the rowHasChanged function provided to the 206 | * data source tells the ListView if it needs to re-render a row because the 207 | * source data has changed - see ListViewDataSource for more details. 208 | * 209 | * * Rate-limited row rendering - By default, only one row is rendered per 210 | * event-loop (customizable with the `pageSize` prop). This breaks up the 211 | * work into smaller chunks to reduce the chance of dropping frames while 212 | * rendering rows. 213 | */ 214 | 215 | const ListView = createReactClass({ 216 | displayName: 'ListView', 217 | _rafIds: ([]: Array), 218 | _childFrames: ([]: Array), 219 | _sentEndForContentLength: (null: ?number), 220 | _scrollComponent: (null: ?React.ElementRef), 221 | _prevRenderedRowsCount: 0, 222 | _visibleRows: ({}: Object), 223 | scrollProperties: ({}: Object), 224 | 225 | mixins: [ScrollResponderMixin], 226 | 227 | statics: { 228 | DataSource: ListViewDataSource, 229 | }, 230 | 231 | /** 232 | * Exports some data, e.g. for perf investigations or analytics. 233 | */ 234 | getMetrics: function() { 235 | return { 236 | contentLength: this.scrollProperties.contentLength, 237 | totalRows: this.props.enableEmptySections 238 | ? this.props.dataSource.getRowAndSectionCount() 239 | : this.props.dataSource.getRowCount(), 240 | renderedRows: this.state.curRenderedRowsCount, 241 | visibleRows: Object.keys(this._visibleRows).length, 242 | }; 243 | }, 244 | 245 | /** 246 | * Provides a handle to the underlying scroll responder. 247 | * Note that `this._scrollComponent` might not be a `ScrollView`, so we 248 | * need to check that it responds to `getScrollResponder` before calling it. 249 | */ 250 | getScrollResponder: function() { 251 | if (this._scrollComponent && this._scrollComponent.getScrollResponder) { 252 | return this._scrollComponent.getScrollResponder(); 253 | } 254 | }, 255 | 256 | getScrollableNode: function() { 257 | if (this._scrollComponent && this._scrollComponent.getScrollableNode) { 258 | return this._scrollComponent.getScrollableNode(); 259 | } else { 260 | return ReactNative.findNodeHandle(this._scrollComponent); 261 | } 262 | }, 263 | 264 | /** 265 | * Scrolls to a given x, y offset, either immediately or with a smooth animation. 266 | * 267 | * See `ScrollView#scrollTo`. 268 | */ 269 | scrollTo: function(...args: any) { 270 | if (this._scrollComponent && this._scrollComponent.scrollTo) { 271 | this._scrollComponent.scrollTo(...args); 272 | } 273 | }, 274 | 275 | /** 276 | * If this is a vertical ListView scrolls to the bottom. 277 | * If this is a horizontal ListView scrolls to the right. 278 | * 279 | * Use `scrollToEnd({animated: true})` for smooth animated scrolling, 280 | * `scrollToEnd({animated: false})` for immediate scrolling. 281 | * If no options are passed, `animated` defaults to true. 282 | * 283 | * See `ScrollView#scrollToEnd`. 284 | */ 285 | scrollToEnd: function(options?: ?{animated?: boolean}) { 286 | if (this._scrollComponent) { 287 | if (this._scrollComponent.scrollToEnd) { 288 | this._scrollComponent.scrollToEnd(options); 289 | } else { 290 | console.warn( 291 | 'The scroll component used by the ListView does not support ' + 292 | 'scrollToEnd. Check the renderScrollComponent prop of your ListView.', 293 | ); 294 | } 295 | } 296 | }, 297 | 298 | /** 299 | * Displays the scroll indicators momentarily. 300 | * 301 | * @platform ios 302 | */ 303 | flashScrollIndicators: function() { 304 | if (this._scrollComponent && this._scrollComponent.flashScrollIndicators) { 305 | this._scrollComponent.flashScrollIndicators(); 306 | } 307 | }, 308 | 309 | setNativeProps: function(props: Object) { 310 | if (this._scrollComponent) { 311 | this._scrollComponent.setNativeProps(props); 312 | } 313 | }, 314 | 315 | /** 316 | * React life cycle hooks. 317 | */ 318 | 319 | getDefaultProps: function() { 320 | return { 321 | initialListSize: DEFAULT_INITIAL_ROWS, 322 | pageSize: DEFAULT_PAGE_SIZE, 323 | renderScrollComponent: props => , 324 | scrollRenderAheadDistance: DEFAULT_SCROLL_RENDER_AHEAD, 325 | onEndReachedThreshold: DEFAULT_END_REACHED_THRESHOLD, 326 | stickySectionHeadersEnabled: Platform.OS === 'ios', 327 | stickyHeaderIndices: [], 328 | }; 329 | }, 330 | 331 | getInitialState: function() { 332 | return { 333 | curRenderedRowsCount: this.props.initialListSize, 334 | highlightedRow: ({}: Object), 335 | }; 336 | }, 337 | 338 | getInnerViewNode: function() { 339 | return this._scrollComponent && this._scrollComponent.getInnerViewNode(); 340 | }, 341 | 342 | UNSAFE_componentWillMount: function() { 343 | // this data should never trigger a render pass, so don't put in state 344 | this.scrollProperties = { 345 | visibleLength: null, 346 | contentLength: null, 347 | offset: 0, 348 | }; 349 | 350 | this._rafIds = []; 351 | this._childFrames = []; 352 | this._visibleRows = {}; 353 | this._prevRenderedRowsCount = 0; 354 | this._sentEndForContentLength = null; 355 | }, 356 | 357 | componentWillUnmount: function() { 358 | this._rafIds.forEach(cancelAnimationFrame); 359 | this._rafIds = []; 360 | }, 361 | 362 | UNSAFE_componentWillReceiveProps: function(nextProps: Object) { 363 | if ( 364 | this.props.dataSource !== nextProps.dataSource || 365 | this.props.initialListSize !== nextProps.initialListSize 366 | ) { 367 | this.setState( 368 | (state, props) => { 369 | this._prevRenderedRowsCount = 0; 370 | return { 371 | curRenderedRowsCount: Math.min( 372 | Math.max(state.curRenderedRowsCount, props.initialListSize), 373 | props.enableEmptySections 374 | ? props.dataSource.getRowAndSectionCount() 375 | : props.dataSource.getRowCount(), 376 | ), 377 | }; 378 | }, 379 | () => this._renderMoreRowsIfNeeded(), 380 | ); 381 | } 382 | }, 383 | 384 | _onRowHighlighted: function(sectionID: string, rowID: string) { 385 | this.setState({highlightedRow: {sectionID, rowID}}); 386 | }, 387 | 388 | render: function() { 389 | const bodyComponents = []; 390 | 391 | const dataSource = this.props.dataSource; 392 | const allRowIDs = dataSource.rowIdentities; 393 | let rowCount = 0; 394 | const stickySectionHeaderIndices = []; 395 | 396 | const {renderSectionHeader} = this.props; 397 | 398 | const header = this.props.renderHeader && this.props.renderHeader(); 399 | const footer = this.props.renderFooter && this.props.renderFooter(); 400 | let totalIndex = header ? 1 : 0; 401 | 402 | for (let sectionIdx = 0; sectionIdx < allRowIDs.length; sectionIdx++) { 403 | const sectionID = dataSource.sectionIdentities[sectionIdx]; 404 | const rowIDs = allRowIDs[sectionIdx]; 405 | if (rowIDs.length === 0) { 406 | if (this.props.enableEmptySections === undefined) { 407 | const warning = require('fbjs/lib/warning'); 408 | warning( 409 | false, 410 | 'In next release empty section headers will be rendered.' + 411 | " In this release you can use 'enableEmptySections' flag to render empty section headers.", 412 | ); 413 | continue; 414 | } else { 415 | const invariant = require('invariant'); 416 | invariant( 417 | this.props.enableEmptySections, 418 | "In next release 'enableEmptySections' flag will be deprecated, empty section headers will always be rendered." + 419 | ' If empty section headers are not desirable their indices should be excluded from sectionIDs object.' + 420 | " In this release 'enableEmptySections' may only have value 'true' to allow empty section headers rendering.", 421 | ); 422 | } 423 | } 424 | 425 | if (renderSectionHeader) { 426 | const element = renderSectionHeader( 427 | dataSource.getSectionHeaderData(sectionIdx), 428 | sectionID, 429 | ); 430 | if (element) { 431 | bodyComponents.push( 432 | React.cloneElement(element, {key: 's_' + sectionID}), 433 | ); 434 | if (this.props.stickySectionHeadersEnabled) { 435 | stickySectionHeaderIndices.push(totalIndex); 436 | } 437 | totalIndex++; 438 | } 439 | } 440 | 441 | for (let rowIdx = 0; rowIdx < rowIDs.length; rowIdx++) { 442 | const rowID = rowIDs[rowIdx]; 443 | const comboID = sectionID + '_' + rowID; 444 | const shouldUpdateRow = 445 | rowCount >= this._prevRenderedRowsCount && 446 | dataSource.rowShouldUpdate(sectionIdx, rowIdx); 447 | const row = ( 448 | 459 | ); 460 | bodyComponents.push(row); 461 | totalIndex++; 462 | 463 | if ( 464 | this.props.renderSeparator && 465 | (rowIdx !== rowIDs.length - 1 || sectionIdx === allRowIDs.length - 1) 466 | ) { 467 | const adjacentRowHighlighted = 468 | this.state.highlightedRow.sectionID === sectionID && 469 | (this.state.highlightedRow.rowID === rowID || 470 | this.state.highlightedRow.rowID === rowIDs[rowIdx + 1]); 471 | const separator = this.props.renderSeparator( 472 | sectionID, 473 | rowID, 474 | adjacentRowHighlighted, 475 | ); 476 | if (separator) { 477 | bodyComponents.push({separator}); 478 | totalIndex++; 479 | } 480 | } 481 | if (++rowCount === this.state.curRenderedRowsCount) { 482 | break; 483 | } 484 | } 485 | if (rowCount >= this.state.curRenderedRowsCount) { 486 | break; 487 | } 488 | } 489 | 490 | const {renderScrollComponent, ...props} = this.props; 491 | if (!props.scrollEventThrottle) { 492 | props.scrollEventThrottle = DEFAULT_SCROLL_CALLBACK_THROTTLE; 493 | } 494 | if (props.removeClippedSubviews === undefined) { 495 | props.removeClippedSubviews = true; 496 | } 497 | Object.assign(props, { 498 | onScroll: this._onScroll, 499 | stickyHeaderIndices: this.props.stickyHeaderIndices.concat( 500 | stickySectionHeaderIndices, 501 | ), 502 | 503 | // Do not pass these events downstream to ScrollView since they will be 504 | // registered in ListView's own ScrollResponder.Mixin 505 | onKeyboardWillShow: undefined, 506 | onKeyboardWillHide: undefined, 507 | onKeyboardDidShow: undefined, 508 | onKeyboardDidHide: undefined, 509 | }); 510 | 511 | return cloneReferencedElement( 512 | renderScrollComponent(props), 513 | { 514 | ref: this._setScrollComponentRef, 515 | onContentSizeChange: this._onContentSizeChange, 516 | onLayout: this._onLayout, 517 | DEPRECATED_sendUpdatedChildFrames: 518 | typeof props.onChangeVisibleRows !== undefined, 519 | }, 520 | header, 521 | bodyComponents, 522 | footer, 523 | ); 524 | }, 525 | 526 | /** 527 | * Private methods 528 | */ 529 | 530 | _setScrollComponentRef: function(scrollComponent) { 531 | this._scrollComponent = scrollComponent; 532 | }, 533 | 534 | _onContentSizeChange: function(width: number, height: number) { 535 | const contentLength = !this.props.horizontal ? height : width; 536 | if (contentLength !== this.scrollProperties.contentLength) { 537 | this.scrollProperties.contentLength = contentLength; 538 | this._updateVisibleRows(); 539 | this._renderMoreRowsIfNeeded(); 540 | } 541 | this.props.onContentSizeChange && 542 | this.props.onContentSizeChange(width, height); 543 | }, 544 | 545 | _onLayout: function(event: Object) { 546 | const {width, height} = event.nativeEvent.layout; 547 | const visibleLength = !this.props.horizontal ? height : width; 548 | if (visibleLength !== this.scrollProperties.visibleLength) { 549 | this.scrollProperties.visibleLength = visibleLength; 550 | this._updateVisibleRows(); 551 | this._renderMoreRowsIfNeeded(); 552 | } 553 | this.props.onLayout && this.props.onLayout(event); 554 | }, 555 | 556 | _maybeCallOnEndReached: function(event?: Object) { 557 | if ( 558 | this.props.onEndReached && 559 | this.scrollProperties.contentLength !== this._sentEndForContentLength && 560 | this._getDistanceFromEnd(this.scrollProperties) < 561 | this.props.onEndReachedThreshold && 562 | this.state.curRenderedRowsCount === 563 | (this.props.enableEmptySections 564 | ? this.props.dataSource.getRowAndSectionCount() 565 | : this.props.dataSource.getRowCount()) 566 | ) { 567 | this._sentEndForContentLength = this.scrollProperties.contentLength; 568 | this.props.onEndReached(event); 569 | return true; 570 | } 571 | return false; 572 | }, 573 | 574 | _renderMoreRowsIfNeeded: function() { 575 | if ( 576 | this.scrollProperties.contentLength === null || 577 | this.scrollProperties.visibleLength === null || 578 | this.state.curRenderedRowsCount === 579 | (this.props.enableEmptySections 580 | ? this.props.dataSource.getRowAndSectionCount() 581 | : this.props.dataSource.getRowCount()) 582 | ) { 583 | this._maybeCallOnEndReached(); 584 | return; 585 | } 586 | 587 | const distanceFromEnd = this._getDistanceFromEnd(this.scrollProperties); 588 | if (distanceFromEnd < this.props.scrollRenderAheadDistance) { 589 | this._pageInNewRows(); 590 | } 591 | }, 592 | 593 | _pageInNewRows: function() { 594 | this.setState( 595 | (state, props) => { 596 | const rowsToRender = Math.min( 597 | state.curRenderedRowsCount + props.pageSize, 598 | props.enableEmptySections 599 | ? props.dataSource.getRowAndSectionCount() 600 | : props.dataSource.getRowCount(), 601 | ); 602 | this._prevRenderedRowsCount = state.curRenderedRowsCount; 603 | return { 604 | curRenderedRowsCount: rowsToRender, 605 | }; 606 | }, 607 | () => { 608 | this._prevRenderedRowsCount = this.state.curRenderedRowsCount; 609 | }, 610 | ); 611 | }, 612 | 613 | _getDistanceFromEnd: function(scrollProperties: Object) { 614 | return ( 615 | scrollProperties.contentLength - 616 | scrollProperties.visibleLength - 617 | scrollProperties.offset 618 | ); 619 | }, 620 | 621 | _updateVisibleRows: function(updatedFrames?: Array) { 622 | if (!this.props.onChangeVisibleRows) { 623 | return; // No need to compute visible rows if there is no callback 624 | } 625 | if (updatedFrames) { 626 | updatedFrames.forEach(newFrame => { 627 | this._childFrames[newFrame.index] = {...newFrame}; 628 | }); 629 | } 630 | const isVertical = !this.props.horizontal; 631 | const dataSource = this.props.dataSource; 632 | const visibleMin = this.scrollProperties.offset; 633 | const visibleMax = visibleMin + this.scrollProperties.visibleLength; 634 | const allRowIDs = dataSource.rowIdentities; 635 | 636 | const header = this.props.renderHeader && this.props.renderHeader(); 637 | let totalIndex = header ? 1 : 0; 638 | let visibilityChanged = false; 639 | const changedRows = {}; 640 | for (let sectionIdx = 0; sectionIdx < allRowIDs.length; sectionIdx++) { 641 | const rowIDs = allRowIDs[sectionIdx]; 642 | if (rowIDs.length === 0) { 643 | continue; 644 | } 645 | const sectionID = dataSource.sectionIdentities[sectionIdx]; 646 | if (this.props.renderSectionHeader) { 647 | totalIndex++; 648 | } 649 | let visibleSection = this._visibleRows[sectionID]; 650 | if (!visibleSection) { 651 | visibleSection = {}; 652 | } 653 | for (let rowIdx = 0; rowIdx < rowIDs.length; rowIdx++) { 654 | const rowID = rowIDs[rowIdx]; 655 | const frame = this._childFrames[totalIndex]; 656 | totalIndex++; 657 | if ( 658 | this.props.renderSeparator && 659 | (rowIdx !== rowIDs.length - 1 || sectionIdx === allRowIDs.length - 1) 660 | ) { 661 | totalIndex++; 662 | } 663 | if (!frame) { 664 | break; 665 | } 666 | const rowVisible = visibleSection[rowID]; 667 | const min = isVertical ? frame.y : frame.x; 668 | const max = min + (isVertical ? frame.height : frame.width); 669 | if ((!min && !max) || min === max) { 670 | break; 671 | } 672 | if (min > visibleMax || max < visibleMin) { 673 | if (rowVisible) { 674 | visibilityChanged = true; 675 | delete visibleSection[rowID]; 676 | if (!changedRows[sectionID]) { 677 | changedRows[sectionID] = {}; 678 | } 679 | changedRows[sectionID][rowID] = false; 680 | } 681 | } else if (!rowVisible) { 682 | visibilityChanged = true; 683 | visibleSection[rowID] = true; 684 | if (!changedRows[sectionID]) { 685 | changedRows[sectionID] = {}; 686 | } 687 | changedRows[sectionID][rowID] = true; 688 | } 689 | } 690 | if (!isEmpty(visibleSection)) { 691 | this._visibleRows[sectionID] = visibleSection; 692 | } else if (this._visibleRows[sectionID]) { 693 | delete this._visibleRows[sectionID]; 694 | } 695 | } 696 | visibilityChanged && 697 | this.props.onChangeVisibleRows(this._visibleRows, changedRows); 698 | }, 699 | 700 | _onScroll: function(e: Object) { 701 | const isVertical = !this.props.horizontal; 702 | this.scrollProperties.visibleLength = 703 | e.nativeEvent.layoutMeasurement[isVertical ? 'height' : 'width']; 704 | this.scrollProperties.contentLength = 705 | e.nativeEvent.contentSize[isVertical ? 'height' : 'width']; 706 | this.scrollProperties.offset = 707 | e.nativeEvent.contentOffset[isVertical ? 'y' : 'x']; 708 | this._updateVisibleRows(e.nativeEvent.updatedChildFrames); 709 | if (!this._maybeCallOnEndReached(e)) { 710 | this._renderMoreRowsIfNeeded(); 711 | } 712 | 713 | if ( 714 | this.props.onEndReached && 715 | this._getDistanceFromEnd(this.scrollProperties) > 716 | this.props.onEndReachedThreshold 717 | ) { 718 | // Scrolled out of the end zone, so it should be able to trigger again. 719 | this._sentEndForContentLength = null; 720 | } 721 | 722 | this.props.onScroll && this.props.onScroll(e); 723 | }, 724 | }); 725 | 726 | module.exports = ((ListView: any): Class>); 727 | -------------------------------------------------------------------------------- /deprecated-react-native-listview/index.js.flow: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @flow strict 8 | * @format 9 | */ 10 | 11 | import type ListViewDataSource from './ListViewDataSource'; 12 | 13 | declare export default class ListView extends React$Component { 14 | static DataSource: Class; 15 | setNativeProps(props: Object): any; 16 | flashScrollIndicators(): any; 17 | getScrollResponder(): any; 18 | getScrollableNode(): any; 19 | getMetrics(): Object; 20 | scrollTo(...args: Array): any; 21 | scrollToEnd(options?: ?{animated?: ?boolean}): any; 22 | } 23 | -------------------------------------------------------------------------------- /deprecated-react-native-listview/isEmpty.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @flow strict 8 | * @format 9 | */ 10 | 11 | 'use strict'; 12 | 13 | function isEmpty(obj: mixed): boolean { 14 | if (Array.isArray(obj)) { 15 | return obj.length === 0; 16 | } else if (typeof obj === 'object') { 17 | for (const i in obj) { 18 | return false; 19 | } 20 | return true; 21 | } else { 22 | return !obj; 23 | } 24 | } 25 | 26 | module.exports = isEmpty; 27 | -------------------------------------------------------------------------------- /deprecated-react-native-listview/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "deprecated-react-native-listview", 3 | "version": "0.0.9", 4 | "description": "This package contains the deprecated ListView module.", 5 | "license": "MIT", 6 | "repository": { 7 | "type": "git", 8 | "url": "git@github.com:facebook/react-native-deprecated-modules.git" 9 | }, 10 | "dependencies": { 11 | "create-react-class": "*", 12 | "fbjs": "*", 13 | "invariant": "*", 14 | "react-clone-referenced-element": "*" 15 | }, 16 | "peerDependencies": { 17 | "react": "*", 18 | "react-native": "*" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 5.0.0 / 2023-10-12 2 | 3 | - (Breaking) bump dependency on `@react-native/normalize-colors` to `^0.73.0` - this requires Node >= 18 4 | - Explicitly require Node >= 18 via `engines` 5 | 6 | # 4.2.3 / 2023-10-12 7 | 8 | - Use semver ranges for prop-types and invariant deps. 9 | 10 | # 4.2.2 / 2023-10-12 11 | 12 | - Restricted `@react-native/normalize-colors` dependency to `<0.73.0` to avoid a transitive Node >= 18 requirement. 13 | 14 | # 4.2.1 / 2023-07-28 15 | 16 | - Added `@flow` so all modules can be imported without suppressing [untyped-import] 17 | 18 | # 4.2.0 / 2023-07-18 19 | 20 | - Add iOS 17 textContentType types (https://github.com/facebook/react-native-deprecated-modules/pull/23) 21 | 22 | # 4.1.0 / 2023-04-19 23 | 24 | - Added logical inset properties: `inset`, `insetBlock`, `insetBlockEnd`, `insetBlockStart`, `insetInline`, `insetInlineEnd`, `insetInlineStart` (https://github.com/facebook/react-native-deprecated-modules/pull/12) 25 | - Added logical border properties: `borderEndEndRadius`, `borderEndStartRadius`, `borderStartEndRadius`, `borderStartStartRadius` (https://github.com/facebook/react-native-deprecated-modules/pull/14) 26 | - Fixed `aria-live` declaration. (https://github.com/facebook/react-native-deprecated-modules/pull/20) 27 | 28 | # 4.0.0 / 2022-12-13 29 | 30 | - Compatible with React Native 0.72 31 | - Updated dependency from `@react-native/normalize-color` to 32 | `@react-native/normalize-colors` due to upstream renaming of such dependency, 33 | needed for compatibility with 0.72 34 | - This major bump is needed as `react-native@0.71` will still use 35 | `@react-native/normalize-color` and we want users of 0.71 to continue depending 36 | on 3.0.1. 37 | 38 | # 3.0.1 / 2022-12-02 39 | 40 | - Compatible with React Native 0.71 41 | - Improvements to `ImagePropTypes` 42 | - Merged Android and default definitions. 43 | - Included all of `ViewPropTypes`. 44 | - Improved types for `defaultSource` and `source`. 45 | - Added `alt`, `crossOrigin`, `height`, `referrerPolicy`, `src`, `srcSet`, `tintColor`, and `width`. 46 | - Added `objectFit` to `style`. 47 | - Improvements to `LayoutPropTypes` 48 | - Changed `aspectRatio` so it can be a string ratio. 49 | - Added `{margin,padding}{Block,Inline}{,End,Start}`. 50 | - Added `columnGap`, `gap`, and `rowGap`. 51 | - Improvements to `TextInputPropTypes` 52 | - Renamed `autoCompleteType` to `autoComplete`. 53 | - Added many new valid values for `autoComplete`. 54 | - Added `cursorColor`, `enterKeyHint`, `inputMode`, `lineBreakStrategyIOS`, `readOnly`, `rows`, and `submitBehavior`. 55 | - Improvements to `ViewAccessibility` 56 | - Added many new valid values for `accessibilityRole`. 57 | - Changed `accessibilityActions` to consist of objects, not strings. 58 | - Improvements to `TextPropTypes` 59 | - Added `accessibilityActions`, `accessibilityHint`, `accessibilityLabel`, `accessibilityLanguage`, `accessibilityRole`, `accessibilityState`, `aria-busy`, `aria-checked`, `aria-disabled`, `aria-expanded`, `aria-label`, `aria-labelledby`, `aria-selected`, `dynamicTypeRamp`, `id`, `lineBreakStrategyIOS`, `onAccessibilityAction`, and `role`. 60 | - Added `onPressIn`, `onPressOut`, `onResponderGrant`, `onResponderMove`, `onResponderRelease`, `onResponderTerminate`, `onResponderTerminationRequest`, `onStartShouldSetResponder`, `onMoveShouldSetResponder`, and `onTextLayout`. 61 | - Added numeric and named values for `fontWeight` in `style`. 62 | - Added string and stylistic values for `fontVariant` in `style`. 63 | - Added `userSelect` and `verticalAlign` in `style`. 64 | - Improvements to `TransformPropTypes` 65 | - Removed deprecated props: `decomposedMatrix`, `rotation`, `scaleX`, `scaleY`, `transformMatrix`, `translateX`, `translateY` 66 | - Improvements to `ViewPropTypes` 67 | - Changed `hitSlop` to accept a number. 68 | - Added `accessibilityLabelledBy`, `accessibilityLanguage`, `aria-busy`, `aria-checked`, `aria-disabled`, `aria-expanded`, `aria-hidden`, `aria-label`, `aria-labelledby`, `aria-live`, `aria-modal`, `aria-selected`, `aria-valuemax`, `aria-valuemin`, `aria-valuenow`, `aria-valuetext`, `focusable`, `id`, `nativeBackgroundAndroid`, `nativeForegroundAndroid`, `onAccessibilityEscape`, `onClick`, `role`, and `tabIndex.` 69 | - Added mouse, pointer, focus, and touch event props. 70 | - Added `borderCurve` and `pointerEvents` to `style`. 71 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedColorPropType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const normalizeColor = require('@react-native/normalize-colors'); 14 | 15 | /** 16 | * @see facebook/react-native/Libraries/StyleSheet/StyleSheetTypes.js 17 | */ 18 | const colorPropType = function( 19 | isRequired, 20 | props, 21 | propName, 22 | componentName, 23 | location, 24 | propFullName, 25 | ) { 26 | const color = props[propName]; 27 | 28 | if (color == null) { 29 | if (isRequired) { 30 | return new Error( 31 | 'Required ' + 32 | location + 33 | ' `' + 34 | (propFullName || propName) + 35 | '` was not specified in `' + 36 | componentName + 37 | '`.', 38 | ); 39 | } 40 | return; 41 | } 42 | 43 | if (typeof color === 'number') { 44 | // Developers should not use a number, but we are using the prop type 45 | // both for user provided colors and for transformed ones. This isn't ideal 46 | // and should be fixed but will do for now... 47 | return; 48 | } 49 | 50 | if (typeof color === 'string' && normalizeColor(color) === null) { 51 | return new Error( 52 | 'Invalid ' + 53 | location + 54 | ' `' + 55 | (propFullName || propName) + 56 | '` supplied to `' + 57 | componentName + 58 | '`: ' + 59 | color + 60 | '\n' + 61 | `Valid color formats are 62 | - '#f0f' (#rgb) 63 | - '#f0fc' (#rgba) 64 | - '#ff00ff' (#rrggbb) 65 | - '#ff00ff00' (#rrggbbaa) 66 | - 'rgb(255, 255, 255)' 67 | - 'rgba(255, 255, 255, 1.0)' 68 | - 'hsl(360, 100%, 100%)' 69 | - 'hsla(360, 100%, 100%, 1.0)' 70 | - 'transparent' 71 | - 'red' 72 | - 0xff00ff00 (0xrrggbbaa) 73 | `, 74 | ); 75 | } 76 | }; 77 | 78 | const ColorPropType = colorPropType.bind(null, false /* isRequired */); 79 | ColorPropType.isRequired = colorPropType.bind(null, true /* isRequired */); 80 | 81 | module.exports = ColorPropType; 82 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedEdgeInsetsPropType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const PropTypes = require('prop-types'); 14 | 15 | /** 16 | * @see facebook/react-native/Libraries/StyleSheet/Rect.js 17 | */ 18 | const DeprecatedEdgeInsetsPropType = PropTypes.shape({ 19 | bottom: PropTypes.number, 20 | left: PropTypes.number, 21 | right: PropTypes.number, 22 | top: PropTypes.number, 23 | }); 24 | 25 | module.exports = DeprecatedEdgeInsetsPropType; 26 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedImagePropType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const DeprecatedColorPropType = require('./DeprecatedColorPropType'); 14 | const DeprecatedEdgeInsetsPropType = require('./DeprecatedEdgeInsetsPropType'); 15 | const DeprecatedImageSourcePropType = require('./DeprecatedImageSourcePropType'); 16 | const DeprecatedImageStylePropTypes = require('./DeprecatedImageStylePropTypes'); 17 | const DeprecatedStyleSheetPropType = require('./DeprecatedStyleSheetPropType'); 18 | const DeprecatedViewPropTypes = require('./DeprecatedViewPropTypes'); 19 | const PropTypes = require('prop-types'); 20 | 21 | /** 22 | * @see facebook/react-native/Libraries/Image/ImageProps.js 23 | */ 24 | const DeprecatedImagePropType = { 25 | ...DeprecatedViewPropTypes, 26 | alt: PropTypes.string, 27 | blurRadius: PropTypes.number, 28 | capInsets: DeprecatedEdgeInsetsPropType, 29 | crossOrigin: PropTypes.oneOf(['anonymous', 'use-credentials']), 30 | defaultSource: DeprecatedImageSourcePropType, 31 | fadeDuration: PropTypes.number, 32 | height: PropTypes.number, 33 | internal_analyticTag: PropTypes.string, 34 | loadingIndicatorSource: PropTypes.oneOfType([ 35 | PropTypes.shape({ 36 | uri: PropTypes.string, 37 | }), 38 | PropTypes.number, 39 | ]), 40 | onError: PropTypes.func, 41 | onLoad: PropTypes.func, 42 | onLoadEnd: PropTypes.func, 43 | onLoadStart: PropTypes.func, 44 | onPartialLoad: PropTypes.func, 45 | onProgress: PropTypes.func, 46 | progressiveRenderingEnabled: PropTypes.bool, 47 | referrerPolicy: PropTypes.oneOf([ 48 | 'no-referrer', 49 | 'no-referrer-when-downgrade', 50 | 'origin', 51 | 'origin-when-cross-origin', 52 | 'same-origin', 53 | 'strict-origin', 54 | 'strict-origin-when-cross-origin', 55 | 'unsafe-url', 56 | ]), 57 | resizeMethod: PropTypes.oneOf(['auto', 'resize', 'scale']), 58 | resizeMode: PropTypes.oneOf([ 59 | 'cover', 60 | 'contain', 61 | 'stretch', 62 | 'repeat', 63 | 'center', 64 | ]), 65 | source: DeprecatedImageSourcePropType, 66 | src: PropTypes.string, 67 | srcSet: PropTypes.string, 68 | style: DeprecatedStyleSheetPropType(DeprecatedImageStylePropTypes), 69 | testID: PropTypes.string, 70 | tintColor: DeprecatedColorPropType, 71 | width: PropTypes.number, 72 | }; 73 | 74 | module.exports = DeprecatedImagePropType; 75 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedImageSourcePropType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const PropTypes = require('prop-types'); 14 | 15 | /** 16 | * @see facebook/react-native/Libraries/Image/ImageSource.js 17 | */ 18 | const ImageURISourcePropType = PropTypes.shape({ 19 | body: PropTypes.string, 20 | bundle: PropTypes.string, 21 | cache: PropTypes.oneOf([ 22 | 'default', 23 | 'force-cache', 24 | 'only-if-cached', 25 | 'reload', 26 | ]), 27 | headers: PropTypes.objectOf(PropTypes.string), 28 | height: PropTypes.number, 29 | method: PropTypes.string, 30 | scale: PropTypes.number, 31 | uri: PropTypes.string, 32 | width: PropTypes.number, 33 | }); 34 | 35 | const ImageSourcePropType = PropTypes.oneOfType([ 36 | ImageURISourcePropType, 37 | PropTypes.number, 38 | PropTypes.arrayOf(ImageURISourcePropType), 39 | ]); 40 | 41 | module.exports = ImageSourcePropType; 42 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedImageStylePropTypes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const DeprecatedColorPropType = require('./DeprecatedColorPropType'); 14 | const DeprecatedLayoutPropTypes = require('./DeprecatedLayoutPropTypes'); 15 | const DeprecatedShadowPropTypesIOS = require('./DeprecatedShadowPropTypesIOS'); 16 | const DeprecatedTransformPropTypes = require('./DeprecatedTransformPropTypes'); 17 | const PropTypes = require('prop-types'); 18 | 19 | /** 20 | * @see facebook/react-native/Libraries/StyleSheet/StyleSheetTypes.js 21 | */ 22 | const DeprecatedImageStylePropTypes = { 23 | ...DeprecatedLayoutPropTypes, 24 | ...DeprecatedShadowPropTypesIOS, 25 | ...DeprecatedTransformPropTypes, 26 | backfaceVisibility: PropTypes.oneOf(['hidden', 'visible']), 27 | backgroundColor: DeprecatedColorPropType, 28 | borderBottomLeftRadius: PropTypes.number, 29 | borderBottomRightRadius: PropTypes.number, 30 | borderColor: DeprecatedColorPropType, 31 | borderRadius: PropTypes.number, 32 | borderTopLeftRadius: PropTypes.number, 33 | borderTopRightRadius: PropTypes.number, 34 | borderWidth: PropTypes.number, 35 | objectFit: PropTypes.oneOf(['contain', 'cover', 'fill', 'scale-down']), 36 | opacity: PropTypes.number, 37 | overflow: PropTypes.oneOf(['hidden', 'visible']), 38 | overlayColor: PropTypes.string, 39 | tintColor: DeprecatedColorPropType, 40 | resizeMode: PropTypes.oneOf([ 41 | 'center', 42 | 'contain', 43 | 'cover', 44 | 'repeat', 45 | 'stretch', 46 | ]), 47 | }; 48 | 49 | module.exports = DeprecatedImageStylePropTypes; 50 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedLayoutPropTypes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const PropTypes = require('prop-types'); 14 | 15 | const DimensionValuePropType = PropTypes.oneOfType([ 16 | PropTypes.number, 17 | PropTypes.string, 18 | ]); 19 | 20 | /** 21 | * @see facebook/react-native/Libraries/StyleSheet/StyleSheetTypes.js 22 | */ 23 | const DeprecatedLayoutPropTypes = { 24 | alignContent: PropTypes.oneOf([ 25 | 'center', 26 | 'flex-end', 27 | 'flex-start', 28 | 'space-around', 29 | 'space-between', 30 | 'stretch', 31 | ]), 32 | alignItems: PropTypes.oneOf([ 33 | 'baseline', 34 | 'center', 35 | 'flex-end', 36 | 'flex-start', 37 | 'stretch', 38 | ]), 39 | alignSelf: PropTypes.oneOf([ 40 | 'auto', 41 | 'baseline', 42 | 'center', 43 | 'flex-end', 44 | 'flex-start', 45 | 'stretch', 46 | ]), 47 | aspectRatio: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), 48 | borderBottomWidth: PropTypes.number, 49 | borderEndWidth: PropTypes.number, 50 | borderLeftWidth: PropTypes.number, 51 | borderRightWidth: PropTypes.number, 52 | borderStartWidth: PropTypes.number, 53 | borderTopWidth: PropTypes.number, 54 | borderWidth: PropTypes.number, 55 | bottom: DimensionValuePropType, 56 | columnGap: PropTypes.number, 57 | direction: PropTypes.oneOf(['inherit', 'ltr', 'rtl']), 58 | display: PropTypes.oneOf(['flex', 'none']), 59 | end: DimensionValuePropType, 60 | flex: PropTypes.number, 61 | flexBasis: DimensionValuePropType, 62 | flexDirection: PropTypes.oneOf([ 63 | 'column', 64 | 'column-reverse', 65 | 'row', 66 | 'row-reverse', 67 | ]), 68 | flexGrow: PropTypes.number, 69 | flexShrink: PropTypes.number, 70 | flexWrap: PropTypes.oneOf(['nowrap', 'wrap', 'wrap-reverse']), 71 | gap: PropTypes.number, 72 | height: DimensionValuePropType, 73 | inset: DimensionValuePropType, 74 | insetBlock: DimensionValuePropType, 75 | insetBlockEnd: DimensionValuePropType, 76 | insetBlockStart: DimensionValuePropType, 77 | insetInline: DimensionValuePropType, 78 | insetInlineEnd: DimensionValuePropType, 79 | insetInlineStart: DimensionValuePropType, 80 | justifyContent: PropTypes.oneOf([ 81 | 'center', 82 | 'flex-end', 83 | 'flex-start', 84 | 'space-around', 85 | 'space-between', 86 | 'space-evenly', 87 | ]), 88 | left: DimensionValuePropType, 89 | margin: DimensionValuePropType, 90 | marginBlock: DimensionValuePropType, 91 | marginBlockEnd: DimensionValuePropType, 92 | marginBlockStart: DimensionValuePropType, 93 | marginBottom: DimensionValuePropType, 94 | marginEnd: DimensionValuePropType, 95 | marginHorizontal: DimensionValuePropType, 96 | marginInline: DimensionValuePropType, 97 | marginInlineEnd: DimensionValuePropType, 98 | marginInlineStart: DimensionValuePropType, 99 | marginLeft: DimensionValuePropType, 100 | marginRight: DimensionValuePropType, 101 | marginStart: DimensionValuePropType, 102 | marginTop: DimensionValuePropType, 103 | marginVertical: DimensionValuePropType, 104 | maxHeight: DimensionValuePropType, 105 | maxWidth: DimensionValuePropType, 106 | minHeight: DimensionValuePropType, 107 | minWidth: DimensionValuePropType, 108 | overflow: PropTypes.oneOf(['hidden', 'scroll', 'visible']), 109 | padding: DimensionValuePropType, 110 | paddingBlock: DimensionValuePropType, 111 | paddingBlockEnd: DimensionValuePropType, 112 | paddingBlockStart: DimensionValuePropType, 113 | paddingBottom: DimensionValuePropType, 114 | paddingEnd: DimensionValuePropType, 115 | paddingHorizontal: DimensionValuePropType, 116 | paddingInline: DimensionValuePropType, 117 | paddingInlineEnd: DimensionValuePropType, 118 | paddingInlineStart: DimensionValuePropType, 119 | paddingLeft: DimensionValuePropType, 120 | paddingRight: DimensionValuePropType, 121 | paddingStart: DimensionValuePropType, 122 | paddingTop: DimensionValuePropType, 123 | paddingVertical: DimensionValuePropType, 124 | position: PropTypes.oneOf(['absolute', 'relative']), 125 | right: DimensionValuePropType, 126 | rowGap: PropTypes.number, 127 | start: DimensionValuePropType, 128 | top: DimensionValuePropType, 129 | width: DimensionValuePropType, 130 | zIndex: PropTypes.number, 131 | }; 132 | 133 | module.exports = DeprecatedLayoutPropTypes; 134 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedPointPropType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const PropTypes = require('prop-types'); 14 | 15 | /** 16 | * @see facebook/react-native/Libraries/StyleSheet/StyleSheetTypes.js 17 | */ 18 | const PointPropType = PropTypes.shape({ 19 | x: PropTypes.number, 20 | y: PropTypes.number, 21 | }); 22 | 23 | module.exports = PointPropType; 24 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedShadowPropTypesIOS.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const DeprecatedColorPropType = require('./DeprecatedColorPropType'); 14 | const PropTypes = require('prop-types'); 15 | 16 | /** 17 | * @see facebook/react-native/Libraries/StyleSheet/StyleSheetTypes.js 18 | */ 19 | const DeprecatedShadowPropTypesIOS = { 20 | shadowColor: DeprecatedColorPropType, 21 | shadowOffset: PropTypes.shape({ 22 | height: PropTypes.number, 23 | width: PropTypes.number, 24 | }), 25 | shadowOpacity: PropTypes.number, 26 | shadowRadius: PropTypes.number, 27 | }; 28 | 29 | module.exports = DeprecatedShadowPropTypesIOS; 30 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedStyleSheetPropType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const deprecatedCreateStrictShapeTypeChecker = require('./deprecatedCreateStrictShapeTypeChecker'); 14 | 15 | function DeprecatedStyleSheetPropType(shape) { 16 | const shapePropType = deprecatedCreateStrictShapeTypeChecker(shape); 17 | return function(props, propName, componentName, location, ...rest) { 18 | let newProps = props; 19 | if (props[propName]) { 20 | // Just make a dummy prop object with only the flattened style 21 | newProps = {}; 22 | newProps[propName] = flattenStyle(props[propName]); 23 | } 24 | return shapePropType(newProps, propName, componentName, location, ...rest); 25 | }; 26 | } 27 | 28 | function flattenStyle(style) { 29 | if (style === null || typeof style !== 'object') { 30 | return undefined; 31 | } 32 | 33 | if (!Array.isArray(style)) { 34 | return style; 35 | } 36 | 37 | const result = {}; 38 | for (let i = 0, styleLength = style.length; i < styleLength; ++i) { 39 | const computedStyle = flattenStyle(style[i]); 40 | if (computedStyle) { 41 | for (const key in computedStyle) { 42 | result[key] = computedStyle[key]; 43 | } 44 | } 45 | } 46 | return result; 47 | } 48 | 49 | module.exports = DeprecatedStyleSheetPropType; 50 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedTextInputPropTypes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const DeprecatedColorPropType = require('./DeprecatedColorPropType'); 14 | const DeprecatedTextPropTypes = require('./DeprecatedTextPropTypes'); 15 | const DeprecatedViewPropTypes = require('./DeprecatedViewPropTypes'); 16 | const PropTypes = require('prop-types'); 17 | 18 | const DataDetectorTypes = [ 19 | 'address', 20 | 'all', 21 | 'calendarEvent', 22 | 'link', 23 | 'none', 24 | 'phoneNumber', 25 | ]; 26 | 27 | /** 28 | * @see facebook/react-native/Libraries/TextInput/TextInput.js 29 | */ 30 | const DeprecatedTextInputPropTypes = { 31 | ...DeprecatedViewPropTypes, 32 | allowFontScaling: PropTypes.bool, 33 | autoCapitalize: PropTypes.oneOf(['none', 'sentences', 'words', 'characters']), 34 | autoComplete: PropTypes.oneOf([ 35 | 'additional-name', 36 | 'address-line1', 37 | 'address-line2', 38 | 'bday', 39 | 'bday-day', 40 | 'bday-month', 41 | 'bday-year', 42 | 'birthdate-day', 43 | 'birthdate-full', 44 | 'birthdate-month', 45 | 'birthdate-year', 46 | 'cc-csc', 47 | 'cc-exp', 48 | 'cc-exp-day', 49 | 'cc-exp-month', 50 | 'cc-exp-year', 51 | 'cc-family-name', 52 | 'cc-given-name', 53 | 'cc-middle-name', 54 | 'cc-name', 55 | 'cc-number', 56 | 'cc-type', 57 | 'country', 58 | 'current-password', 59 | 'email', 60 | 'family-name', 61 | 'gender', 62 | 'given-name', 63 | 'honorific-prefix', 64 | 'honorific-suffix', 65 | 'name', 66 | 'name-family', 67 | 'name-given', 68 | 'name-middle', 69 | 'name-middle-initial', 70 | 'name-prefix', 71 | 'name-suffix', 72 | 'new-password', 73 | 'nickname', 74 | 'off', 75 | 'one-time-code', 76 | 'organization', 77 | 'organization-title', 78 | 'password', 79 | 'password-new', 80 | 'postal-address', 81 | 'postal-address-country', 82 | 'postal-address-extended', 83 | 'postal-address-extended-postal-code', 84 | 'postal-address-locality', 85 | 'postal-address-region', 86 | 'postal-code', 87 | 'sex', 88 | 'sms-otp', 89 | 'street-address', 90 | 'tel', 91 | 'tel-country-code', 92 | 'tel-device', 93 | 'tel-national', 94 | 'url', 95 | 'username', 96 | 'username-new', 97 | ]), 98 | autoCorrect: PropTypes.bool, 99 | autoFocus: PropTypes.bool, 100 | blurOnSubmit: PropTypes.bool, 101 | caretHidden: PropTypes.bool, 102 | clearButtonMode: PropTypes.oneOf([ 103 | 'always', 104 | 'never', 105 | 'unless-editing', 106 | 'while-editing', 107 | ]), 108 | clearTextOnFocus: PropTypes.bool, 109 | cursorColor: DeprecatedColorPropType, 110 | contextMenuHidden: PropTypes.bool, 111 | dataDetectorTypes: PropTypes.oneOfType([ 112 | PropTypes.oneOf(DataDetectorTypes), 113 | PropTypes.arrayOf(PropTypes.oneOf(DataDetectorTypes)), 114 | ]), 115 | defaultValue: PropTypes.string, 116 | disableFullscreenUI: PropTypes.bool, 117 | editable: PropTypes.bool, 118 | enablesReturnKeyAutomatically: PropTypes.bool, 119 | enterKeyHint: PropTypes.oneOf([ 120 | 'done', 121 | 'enter', 122 | 'go', 123 | 'next', 124 | 'previous', 125 | 'search', 126 | 'send', 127 | ]), 128 | inlineImageLeft: PropTypes.string, 129 | inlineImagePadding: PropTypes.number, 130 | inputAccessoryViewID: PropTypes.string, 131 | inputMode: PropTypes.oneOf([ 132 | 'decimal', 133 | 'email', 134 | 'none', 135 | 'numeric', 136 | 'search', 137 | 'tel', 138 | 'text', 139 | 'url', 140 | ]), 141 | keyboardAppearance: PropTypes.oneOf(['default', 'dark', 'light']), 142 | keyboardType: PropTypes.oneOf([ 143 | 'ascii-capable', 144 | 'ascii-capable-number-pad', 145 | 'decimal-pad', 146 | 'default', 147 | 'email-address', 148 | 'name-phone-pad', 149 | 'number-pad', 150 | 'numbers-and-punctuation', 151 | 'numeric', 152 | 'phone-pad', 153 | 'twitter', 154 | 'url', 155 | 'visible-password', 156 | 'web-search', 157 | ]), 158 | lineBreakStrategyIOS: PropTypes.oneOf([ 159 | 'hangul-word', 160 | 'none', 161 | 'push-out', 162 | 'standard', 163 | ]), 164 | maxFontSizeMultiplier: PropTypes.number, 165 | maxLength: PropTypes.number, 166 | multiline: PropTypes.bool, 167 | numberOfLines: PropTypes.number, 168 | onBlur: PropTypes.func, 169 | onChange: PropTypes.func, 170 | onChangeText: PropTypes.func, 171 | onContentSizeChange: PropTypes.func, 172 | onEndEditing: PropTypes.func, 173 | onFocus: PropTypes.func, 174 | onKeyPress: PropTypes.func, 175 | onLayout: PropTypes.func, 176 | onScroll: PropTypes.func, 177 | onSelectionChange: PropTypes.func, 178 | onSubmitEditing: PropTypes.func, 179 | onTextInput: PropTypes.func, 180 | placeholder: PropTypes.string, 181 | placeholderTextColor: DeprecatedColorPropType, 182 | readOnly: PropTypes.bool, 183 | rejectResponderTermination: PropTypes.bool, 184 | returnKeyLabel: PropTypes.string, 185 | returnKeyType: PropTypes.oneOf([ 186 | 'default', 187 | 'done', 188 | 'emergency-call', 189 | 'go', 190 | 'google', 191 | 'join', 192 | 'next', 193 | 'none', 194 | 'previous', 195 | 'route', 196 | 'search', 197 | 'send', 198 | 'yahoo', 199 | ]), 200 | rows: PropTypes.number, 201 | scrollEnabled: PropTypes.bool, 202 | secureTextEntry: PropTypes.bool, 203 | selection: PropTypes.shape({ 204 | end: PropTypes.number, 205 | start: PropTypes.number.isRequired, 206 | }), 207 | selectionColor: DeprecatedColorPropType, 208 | selectTextOnFocus: PropTypes.bool, 209 | showSoftInputOnFocus: PropTypes.bool, 210 | spellCheck: PropTypes.bool, 211 | style: DeprecatedTextPropTypes.style, 212 | submitBehavior: PropTypes.oneOf(['blurAndSubmit', 'newline', 'submit']), 213 | textBreakStrategy: PropTypes.oneOf(['balanced', 'highQuality', 'simple']), 214 | textContentType: PropTypes.oneOf([ 215 | 'addressCity', 216 | 'addressCityAndState', 217 | 'addressState', 218 | 'birthdate', 219 | 'birthdateDay', 220 | 'birthdateMonth', 221 | 'birthdateYear', 222 | 'countryName', 223 | 'creditCardExpiration', 224 | 'creditCardExpirationMonth', 225 | 'creditCardExpirationYear', 226 | 'creditCardFamilyName', 227 | 'creditCardGivenName', 228 | 'creditCardMiddleName', 229 | 'creditCardName', 230 | 'creditCardNumber', 231 | 'creditCardSecurityCode', 232 | 'creditCardType', 233 | 'emailAddress', 234 | 'familyName', 235 | 'fullStreetAddress', 236 | 'givenName', 237 | 'jobTitle', 238 | 'location', 239 | 'middleName', 240 | 'name', 241 | 'namePrefix', 242 | 'nameSuffix', 243 | 'newPassword', 244 | 'nickname', 245 | 'none', 246 | 'oneTimeCode', 247 | 'organizationName', 248 | 'password', 249 | 'postalCode', 250 | 'streetAddressLine1', 251 | 'streetAddressLine2', 252 | 'sublocality', 253 | 'telephoneNumber', 254 | 'URL', 255 | 'username', 256 | ]), 257 | underlineColorAndroid: DeprecatedColorPropType, 258 | value: PropTypes.string, 259 | }; 260 | 261 | module.exports = DeprecatedTextInputPropTypes; 262 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedTextPropTypes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const DeprecatedColorPropType = require('./DeprecatedColorPropType'); 14 | const DeprecatedEdgeInsetsPropType = require('./DeprecatedEdgeInsetsPropType'); 15 | const DeprecatedStyleSheetPropType = require('./DeprecatedStyleSheetPropType'); 16 | const DeprecatedTextStylePropTypes = require('./DeprecatedTextStylePropTypes'); 17 | const { 18 | AccessibilityActionInfoPropType, 19 | AccessibilityRolePropType, 20 | AccessibilityStatePropType, 21 | AccessibilityValuePropType, 22 | RolePropType, 23 | } = require('./DeprecatedViewAccessibility'); 24 | const PropTypes = require('prop-types'); 25 | 26 | /** 27 | * @see facebook/react-native/Libraries/Text/TextProps.js 28 | */ 29 | const DeprecatedTextPropTypes = { 30 | 'aria-busy': PropTypes.bool, 31 | 'aria-checked': PropTypes.oneOfType([ 32 | PropTypes.bool, 33 | PropTypes.oneOf(['mixed']), 34 | ]), 35 | 'aria-disabled': PropTypes.bool, 36 | 'aria-expanded': PropTypes.bool, 37 | 'aria-label': PropTypes.string, 38 | 'aria-labelledby': PropTypes.string, 39 | 'aria-selected': PropTypes.bool, 40 | accessibilityActions: PropTypes.arrayOf(AccessibilityActionInfoPropType), 41 | accessibilityHint: PropTypes.string, 42 | accessibilityLabel: PropTypes.string, 43 | accessibilityLanguage: PropTypes.string, 44 | accessibilityRole: AccessibilityRolePropType, 45 | accessibilityState: AccessibilityStatePropType, 46 | accessible: PropTypes.bool, 47 | adjustsFontSizeToFit: PropTypes.bool, 48 | allowFontScaling: PropTypes.bool, 49 | dataDetectorType: PropTypes.oneOf([ 50 | 'all', 51 | 'email', 52 | 'link', 53 | 'none', 54 | 'phoneNumber', 55 | ]), 56 | disabled: PropTypes.bool, 57 | dynamicTypeRamp: PropTypes.oneOf([ 58 | 'body', 59 | 'callout', 60 | 'caption1', 61 | 'caption2', 62 | 'footnote', 63 | 'headline', 64 | 'largeTitle', 65 | 'subheadline', 66 | 'title1', 67 | 'title2', 68 | 'title3', 69 | ]), 70 | ellipsizeMode: PropTypes.oneOf(['clip', 'head', 'middle', 'tail']), 71 | id: PropTypes.string, 72 | lineBreakStrategyIOS: PropTypes.oneOf([ 73 | 'hangul-word', 74 | 'none', 75 | 'push-out', 76 | 'standard', 77 | ]), 78 | maxFontSizeMultiplier: PropTypes.number, 79 | minimumFontScale: PropTypes.number, 80 | nativeID: PropTypes.string, 81 | numberOfLines: PropTypes.number, 82 | onAccessibilityAction: PropTypes.func, 83 | onLayout: PropTypes.func, 84 | onLongPress: PropTypes.func, 85 | onMoveShouldSetResponder: PropTypes.func, 86 | onPress: PropTypes.func, 87 | onPressIn: PropTypes.func, 88 | onPressOut: PropTypes.func, 89 | onResponderGrant: PropTypes.func, 90 | onResponderMove: PropTypes.func, 91 | onResponderRelease: PropTypes.func, 92 | onResponderTerminate: PropTypes.func, 93 | onResponderTerminationRequest: PropTypes.func, 94 | onStartShouldSetResponder: PropTypes.func, 95 | onTextLayout: PropTypes.func, 96 | pressRetentionOffset: DeprecatedEdgeInsetsPropType, 97 | role: RolePropType, 98 | selectable: PropTypes.bool, 99 | selectionColor: DeprecatedColorPropType, 100 | style: DeprecatedStyleSheetPropType(DeprecatedTextStylePropTypes), 101 | suppressHighlighting: PropTypes.bool, 102 | testID: PropTypes.string, 103 | textBreakStrategy: PropTypes.oneOf(['balanced', 'highQuality', 'simple']), 104 | }; 105 | 106 | module.exports = DeprecatedTextPropTypes; 107 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedTextStylePropTypes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const DeprecatedColorPropType = require('./DeprecatedColorPropType'); 14 | const DeprecatedViewStylePropTypes = require('./DeprecatedViewStylePropTypes'); 15 | const PropTypes = require('prop-types'); 16 | 17 | /** 18 | * @see facebook/react-native/Libraries/StyleSheet/StyleSheetTypes.js 19 | */ 20 | const DeprecatedTextStylePropTypes = { 21 | ...DeprecatedViewStylePropTypes, 22 | color: DeprecatedColorPropType, 23 | fontFamily: PropTypes.string, 24 | fontSize: PropTypes.number, 25 | fontStyle: PropTypes.oneOf(['italic', 'normal']), 26 | fontVariant: PropTypes.oneOfType([ 27 | PropTypes.arrayOf( 28 | PropTypes.oneOf([ 29 | 'lining-nums', 30 | 'oldstyle-nums', 31 | 'proportional-nums', 32 | 'small-caps', 33 | 'stylistic-eight', 34 | 'stylistic-eighteen', 35 | 'stylistic-eleven', 36 | 'stylistic-fifteen', 37 | 'stylistic-five', 38 | 'stylistic-four', 39 | 'stylistic-fourteen', 40 | 'stylistic-nine', 41 | 'stylistic-nineteen', 42 | 'stylistic-one', 43 | 'stylistic-seven', 44 | 'stylistic-seventeen', 45 | 'stylistic-six', 46 | 'stylistic-sixteen', 47 | 'stylistic-ten', 48 | 'stylistic-thirteen', 49 | 'stylistic-three', 50 | 'stylistic-twelve', 51 | 'stylistic-twenty', 52 | 'stylistic-two', 53 | 'tabular-nums', 54 | ]), 55 | ), 56 | PropTypes.string, 57 | ]), 58 | fontWeight: PropTypes.oneOf([ 59 | '100', 60 | '200', 61 | '300', 62 | '400', 63 | '500', 64 | '600', 65 | '700', 66 | '800', 67 | '900', 68 | 'black', 69 | 'bold', 70 | 'condensed', 71 | 'condensedBold', 72 | 'heavy', 73 | 'light', 74 | 'medium', 75 | 'normal', 76 | 'regular', 77 | 'semibold', 78 | 'thin', 79 | 'ultralight', 80 | 100, 81 | 200, 82 | 300, 83 | 400, 84 | 500, 85 | 600, 86 | 700, 87 | 800, 88 | 900, 89 | ]), 90 | includeFontPadding: PropTypes.bool, 91 | letterSpacing: PropTypes.number, 92 | lineHeight: PropTypes.number, 93 | textAlign: PropTypes.oneOf(['auto', 'center', 'justify', 'left', 'right']), 94 | textAlignVertical: PropTypes.oneOf(['auto', 'bottom', 'center', 'top']), 95 | textDecorationColor: DeprecatedColorPropType, 96 | textDecorationLine: PropTypes.oneOf([ 97 | 'line-through', 98 | 'none', 99 | 'underline line-through', 100 | 'underline', 101 | ]), 102 | textDecorationStyle: PropTypes.oneOf(['dashed', 'dotted', 'double', 'solid']), 103 | textShadowColor: DeprecatedColorPropType, 104 | textShadowOffset: PropTypes.shape({ 105 | height: PropTypes.number, 106 | width: PropTypes.number, 107 | }), 108 | textShadowRadius: PropTypes.number, 109 | textTransform: PropTypes.oneOf([ 110 | 'capitalize', 111 | 'lowercase', 112 | 'none', 113 | 'uppercase', 114 | ]), 115 | userSelect: PropTypes.oneOf(['all', 'auto', 'contain', 'none', 'text']), 116 | verticalAlign: PropTypes.oneOf(['auto', 'bottom', 'middle', 'top']), 117 | writingDirection: PropTypes.oneOf(['auto', 'ltr', 'rtl']), 118 | }; 119 | 120 | module.exports = DeprecatedTextStylePropTypes; 121 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedTransformPropTypes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const PropTypes = require('prop-types'); 14 | 15 | /** 16 | * @see facebook/react-native/Libraries/StyleSheet/private/_TransformStyle.js 17 | */ 18 | const DeprecatedTransformPropTypes = { 19 | transform: PropTypes.arrayOf( 20 | PropTypes.oneOfType([ 21 | PropTypes.shape({perspective: PropTypes.number}), 22 | PropTypes.shape({rotate: PropTypes.string}), 23 | PropTypes.shape({rotateX: PropTypes.string}), 24 | PropTypes.shape({rotateY: PropTypes.string}), 25 | PropTypes.shape({rotateZ: PropTypes.string}), 26 | PropTypes.shape({scale: PropTypes.number}), 27 | PropTypes.shape({scaleX: PropTypes.number}), 28 | PropTypes.shape({scaleY: PropTypes.number}), 29 | PropTypes.shape({skewX: PropTypes.string}), 30 | PropTypes.shape({skewY: PropTypes.string}), 31 | PropTypes.shape({translateX: PropTypes.number}), 32 | PropTypes.shape({translateY: PropTypes.number}), 33 | ]), 34 | ), 35 | }; 36 | 37 | module.exports = DeprecatedTransformPropTypes; 38 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedViewAccessibility.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const PropTypes = require('prop-types'); 14 | 15 | /** 16 | * @see facebook/react-native/Libraries/Components/View/ViewAccessibility.js 17 | */ 18 | const DeprecatedViewAccessibility = { 19 | AccessibilityRolePropType: PropTypes.oneOf([ 20 | 'adjustable', 21 | 'alert', 22 | 'button', 23 | 'checkbox', 24 | 'combobox', 25 | 'drawerlayout', 26 | 'dropdownlist', 27 | 'grid', 28 | 'header', 29 | 'horizontalscrollview', 30 | 'iconmenu', 31 | 'image', 32 | 'imagebutton', 33 | 'keyboardkey', 34 | 'link', 35 | 'list', 36 | 'menu', 37 | 'menubar', 38 | 'menuitem', 39 | 'none', 40 | 'pager', 41 | 'progressbar', 42 | 'radio', 43 | 'radiogroup', 44 | 'scrollbar', 45 | 'scrollview', 46 | 'search', 47 | 'slidingdrawer', 48 | 'spinbutton', 49 | 'summary', 50 | 'switch', 51 | 'tab', 52 | 'tabbar', 53 | 'tablist', 54 | 'text', 55 | 'timer', 56 | 'togglebutton', 57 | 'toolbar', 58 | 'viewgroup', 59 | 'webview', 60 | ]), 61 | AccessibilityStatePropType: PropTypes.object, 62 | AccessibilityActionInfoPropType: PropTypes.object, 63 | AccessibilityValuePropType: PropTypes.object, 64 | RolePropType: PropTypes.oneOf([ 65 | 'alert', 66 | 'alertdialog', 67 | 'application', 68 | 'article', 69 | 'banner', 70 | 'button', 71 | 'cell', 72 | 'checkbox', 73 | 'columnheader', 74 | 'combobox', 75 | 'complementary', 76 | 'contentinfo', 77 | 'definition', 78 | 'dialog', 79 | 'directory', 80 | 'document', 81 | 'feed', 82 | 'figure', 83 | 'form', 84 | 'grid', 85 | 'group', 86 | 'heading', 87 | 'img', 88 | 'link', 89 | 'list', 90 | 'listitem', 91 | 'log', 92 | 'main', 93 | 'marquee', 94 | 'math', 95 | 'menu', 96 | 'menubar', 97 | 'menuitem', 98 | 'meter', 99 | 'navigation', 100 | 'none', 101 | 'note', 102 | 'option', 103 | 'presentation', 104 | 'progressbar', 105 | 'radio', 106 | 'radiogroup', 107 | 'region', 108 | 'row', 109 | 'rowgroup', 110 | 'rowheader', 111 | 'scrollbar', 112 | 'searchbox', 113 | 'separator', 114 | 'slider', 115 | 'spinbutton', 116 | 'status', 117 | 'summary', 118 | 'switch', 119 | 'tab', 120 | 'table', 121 | 'tablist', 122 | 'tabpanel', 123 | 'term', 124 | 'timer', 125 | 'toolbar', 126 | 'tooltip', 127 | 'tree', 128 | 'treegrid', 129 | 'treeitem', 130 | ]), 131 | }; 132 | 133 | module.exports = DeprecatedViewAccessibility; 134 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedViewPropTypes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const DeprecatedEdgeInsetsPropType = require('./DeprecatedEdgeInsetsPropType'); 14 | const DeprecatedStyleSheetPropType = require('./DeprecatedStyleSheetPropType'); 15 | const { 16 | AccessibilityActionInfoPropType, 17 | AccessibilityRolePropType, 18 | AccessibilityStatePropType, 19 | AccessibilityValuePropType, 20 | RolePropType, 21 | } = require('./DeprecatedViewAccessibility'); 22 | const DeprecatedViewStylePropTypes = require('./DeprecatedViewStylePropTypes'); 23 | const PropTypes = require('prop-types'); 24 | 25 | const MouseEventPropTypes = { 26 | onMouseEnter: PropTypes.func, 27 | onMouseLeave: PropTypes.func, 28 | }; 29 | 30 | // Experimental/Work in Progress Pointer Event Callbacks (not yet ready for use) 31 | const PointerEventPropTypes = { 32 | onPointerEnter: PropTypes.func, 33 | onPointerEnterCapture: PropTypes.func, 34 | onPointerLeave: PropTypes.func, 35 | onPointerLeaveCapture: PropTypes.func, 36 | onPointerMove: PropTypes.func, 37 | onPointerMoveCapture: PropTypes.func, 38 | onPointerCancel: PropTypes.func, 39 | onPointerCancelCapture: PropTypes.func, 40 | onPointerDown: PropTypes.func, 41 | onPointerDownCapture: PropTypes.func, 42 | onPointerUp: PropTypes.func, 43 | onPointerUpCapture: PropTypes.func, 44 | onPointerOver: PropTypes.func, 45 | onPointerOverCapture: PropTypes.func, 46 | onPointerOut: PropTypes.func, 47 | onPointerOutCapture: PropTypes.func, 48 | }; 49 | 50 | const FocusEventPropTypes = { 51 | onBlur: PropTypes.func, 52 | onBlurCapture: PropTypes.func, 53 | onFocus: PropTypes.func, 54 | onFocusCapture: PropTypes.func, 55 | }; 56 | 57 | const TouchEventPropTypes = { 58 | onTouchCancel: PropTypes.func, 59 | onTouchCancelCapture: PropTypes.func, 60 | onTouchEnd: PropTypes.func, 61 | onTouchEndCapture: PropTypes.func, 62 | onTouchMove: PropTypes.func, 63 | onTouchMoveCapture: PropTypes.func, 64 | onTouchStart: PropTypes.func, 65 | onTouchStartCapture: PropTypes.func, 66 | }; 67 | 68 | const GestureResponderEventPropTypes = { 69 | onMoveShouldSetResponder: PropTypes.func, 70 | onMoveShouldSetResponderCapture: PropTypes.func, 71 | onResponderEnd: PropTypes.func, 72 | onResponderGrant: PropTypes.func, 73 | onResponderMove: PropTypes.func, 74 | onResponderReject: PropTypes.func, 75 | onResponderRelease: PropTypes.func, 76 | onResponderStart: PropTypes.func, 77 | onResponderTerminate: PropTypes.func, 78 | onResponderTerminationRequest: PropTypes.func, 79 | onStartShouldSetResponder: PropTypes.func, 80 | onStartShouldSetResponderCapture: PropTypes.func, 81 | }; 82 | 83 | /** 84 | * @see facebook/react-native/Libraries/Components/View/ViewPropTypes.js 85 | */ 86 | const DeprecatedViewPropTypes = { 87 | ...MouseEventPropTypes, 88 | ...PointerEventPropTypes, 89 | ...FocusEventPropTypes, 90 | ...TouchEventPropTypes, 91 | ...GestureResponderEventPropTypes, 92 | 'aria-busy': PropTypes.bool, 93 | 'aria-checked': PropTypes.oneOfType([ 94 | PropTypes.bool, 95 | PropTypes.oneOf(['mixed']), 96 | ]), 97 | 'aria-disabled': PropTypes.bool, 98 | 'aria-expanded': PropTypes.bool, 99 | 'aria-hidden': PropTypes.bool, 100 | 'aria-label': PropTypes.string, 101 | 'aria-labelledby': PropTypes.string, 102 | 'aria-live': PropTypes.oneOf(['polite', 'assertive', 'off']), 103 | 'aria-modal': PropTypes.bool, 104 | 'aria-selected': PropTypes.bool, 105 | 'aria-valuemax': PropTypes.number, 106 | 'aria-valuemin': PropTypes.number, 107 | 'aria-valuenow': PropTypes.number, 108 | 'aria-valuetext': PropTypes.string, 109 | accessibilityActions: PropTypes.arrayOf(AccessibilityActionInfoPropType), 110 | accessibilityElementsHidden: PropTypes.bool, 111 | accessibilityHint: PropTypes.string, 112 | accessibilityIgnoresInvertColors: PropTypes.bool, 113 | accessibilityLabel: PropTypes.node, 114 | accessibilityLabelledBy: PropTypes.oneOfType([ 115 | PropTypes.string, 116 | PropTypes.arrayOf(PropTypes.string), 117 | ]), 118 | accessibilityLanguage: PropTypes.string, 119 | accessibilityLiveRegion: PropTypes.oneOf(['assertive', 'none', 'polite']), 120 | accessibilityRole: AccessibilityRolePropType, 121 | accessibilityState: AccessibilityStatePropType, 122 | accessibilityValue: AccessibilityValuePropType, 123 | accessibilityViewIsModal: PropTypes.bool, 124 | accessible: PropTypes.bool, 125 | collapsable: PropTypes.bool, 126 | focusable: PropTypes.bool, 127 | hitSlop: PropTypes.oneOfType([ 128 | DeprecatedEdgeInsetsPropType, 129 | PropTypes.number, 130 | ]), 131 | importantForAccessibility: PropTypes.oneOf([ 132 | 'auto', 133 | 'no', 134 | 'no-hide-descendants', 135 | 'yes', 136 | ]), 137 | nativeBackgroundAndroid: PropTypes.object, 138 | nativeForegroundAndroid: PropTypes.object, 139 | nativeID: PropTypes.string, 140 | needsOffscreenAlphaCompositing: PropTypes.bool, 141 | onAccessibilityAction: PropTypes.func, 142 | onAccessibilityEscape: PropTypes.func, 143 | onAccessibilityTap: PropTypes.func, 144 | onClick: PropTypes.func, 145 | onLayout: PropTypes.func, 146 | onMagicTap: PropTypes.func, 147 | pointerEvents: PropTypes.oneOf(['auto', 'box-none', 'box-only', 'none']), 148 | removeClippedSubviews: PropTypes.bool, 149 | renderToHardwareTextureAndroid: PropTypes.bool, 150 | role: RolePropType, 151 | shouldRasterizeIOS: PropTypes.bool, 152 | style: DeprecatedStyleSheetPropType(DeprecatedViewStylePropTypes), 153 | tabIndex: PropTypes.oneOf([0, -1]), 154 | testID: PropTypes.string, 155 | }; 156 | 157 | module.exports = DeprecatedViewPropTypes; 158 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/DeprecatedViewStylePropTypes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const DeprecatedColorPropType = require('./DeprecatedColorPropType'); 14 | const DeprecatedLayoutPropTypes = require('./DeprecatedLayoutPropTypes'); 15 | const DeprecatedShadowPropTypesIOS = require('./DeprecatedShadowPropTypesIOS'); 16 | const DeprecatedTransformPropTypes = require('./DeprecatedTransformPropTypes'); 17 | const PropTypes = require('prop-types'); 18 | 19 | /** 20 | * @see facebook/react-native/Libraries/StyleSheet/StyleSheetTypes.js 21 | */ 22 | const DeprecatedViewStylePropTypes = { 23 | ...DeprecatedLayoutPropTypes, 24 | ...DeprecatedShadowPropTypesIOS, 25 | ...DeprecatedTransformPropTypes, 26 | backfaceVisibility: PropTypes.oneOf(['hidden', 'visible']), 27 | backgroundColor: DeprecatedColorPropType, 28 | borderBottomColor: DeprecatedColorPropType, 29 | borderBottomEndRadius: PropTypes.number, 30 | borderBottomLeftRadius: PropTypes.number, 31 | borderBottomRightRadius: PropTypes.number, 32 | borderBottomStartRadius: PropTypes.number, 33 | borderBottomWidth: PropTypes.number, 34 | borderColor: DeprecatedColorPropType, 35 | borderCurve: PropTypes.oneOf(['circular', 'continuous']), 36 | borderEndColor: DeprecatedColorPropType, 37 | borderEndEndRadius: PropTypes.number, 38 | borderEndStartRadius: PropTypes.number, 39 | borderLeftColor: DeprecatedColorPropType, 40 | borderLeftWidth: PropTypes.number, 41 | borderRadius: PropTypes.number, 42 | borderRightColor: DeprecatedColorPropType, 43 | borderRightWidth: PropTypes.number, 44 | borderStartColor: DeprecatedColorPropType, 45 | borderStartEndRadius: PropTypes.number, 46 | borderStartStartRadius: PropTypes.number, 47 | borderStyle: PropTypes.oneOf(['dashed', 'dotted', 'solid']), 48 | borderTopColor: DeprecatedColorPropType, 49 | borderTopEndRadius: PropTypes.number, 50 | borderTopLeftRadius: PropTypes.number, 51 | borderTopRightRadius: PropTypes.number, 52 | borderTopStartRadius: PropTypes.number, 53 | borderTopWidth: PropTypes.number, 54 | borderWidth: PropTypes.number, 55 | elevation: PropTypes.number, 56 | opacity: PropTypes.number, 57 | pointerEvents: PropTypes.oneOf(['auto', 'box-none', 'box-only', 'none']), 58 | }; 59 | 60 | module.exports = DeprecatedViewStylePropTypes; 61 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/README.md: -------------------------------------------------------------------------------- 1 | # deprecated-react-native-prop-types 2 | 3 | This package contains deprecated `prop-types` from [React Native](https://github.com/facebook/react-native). 4 | 5 | ## Image.propTypes 6 | 7 | ### Before 8 | 9 | ```js 10 | import {Image} from 'react-native'; 11 | 12 | doSomething(Image.propTypes); 13 | ``` 14 | 15 | ### After 16 | 17 | ```js 18 | import {ImagePropTypes} from 'deprecated-react-native-prop-types'; 19 | 20 | doSomething(ImagePropTypes); 21 | ``` 22 | 23 | ## Text.propTypes 24 | 25 | ### Before 26 | 27 | ```js 28 | import {Text} from 'react-native'; 29 | 30 | doSomething(Text.propTypes); 31 | ``` 32 | 33 | ### After 34 | 35 | ```js 36 | import {TextPropTypes} from 'deprecated-react-native-prop-types'; 37 | 38 | doSomething(TextPropTypes); 39 | ``` 40 | 41 | ## TextInput.propTypes 42 | 43 | ### Before 44 | 45 | ```js 46 | import {TextInput} from 'react-native'; 47 | 48 | doSomething(TextInput.propTypes); 49 | ``` 50 | 51 | ### After 52 | 53 | ```js 54 | import {TextInputPropTypes} from 'deprecated-react-native-prop-types'; 55 | 56 | doSomething(TextInputPropTypes); 57 | ``` 58 | 59 | ## ColorPropType 60 | 61 | ### Before 62 | 63 | ```js 64 | import {ColorPropType} from 'react-native'; 65 | 66 | doSomething(ColorPropType); 67 | ``` 68 | 69 | ### After 70 | 71 | ```js 72 | import {ColorPropType} from 'deprecated-react-native-prop-types'; 73 | 74 | doSomething(ColorPropType); 75 | ``` 76 | 77 | ## EdgeInsetsPropType 78 | 79 | ### Before 80 | 81 | ```js 82 | import {EdgeInsetsPropType} from 'react-native'; 83 | 84 | doSomething(EdgeInsetsPropType); 85 | ``` 86 | 87 | ### After 88 | 89 | ```js 90 | import {EdgeInsetsPropType} from 'deprecated-react-native-prop-types'; 91 | 92 | doSomething(EdgeInsetsPropType); 93 | ``` 94 | 95 | ## PointPropType 96 | 97 | ### Before 98 | 99 | ```js 100 | import {PointPropType} from 'react-native'; 101 | 102 | doSomething(PointPropType); 103 | ``` 104 | 105 | ### After 106 | 107 | ```js 108 | import {PointPropType} from 'deprecated-react-native-prop-types'; 109 | 110 | doSomething(PointPropType); 111 | ``` 112 | 113 | ## ViewPropTypes 114 | 115 | ### Before 116 | 117 | ```js 118 | import {ViewPropTypes} from 'react-native'; 119 | 120 | doSomething(ViewPropTypes); 121 | ``` 122 | 123 | ### After 124 | 125 | ```js 126 | import {ViewPropTypes} from 'deprecated-react-native-prop-types'; 127 | 128 | doSomething(ViewPropTypes); 129 | ``` 130 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/deprecatedCreateStrictShapeTypeChecker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const invariant = require('invariant'); 14 | 15 | function deprecatedCreateStrictShapeTypeChecker(shapeTypes) { 16 | function checkType( 17 | isRequired, 18 | props, 19 | propName, 20 | componentName, 21 | location, 22 | ...rest 23 | ) { 24 | if (!props[propName]) { 25 | if (isRequired) { 26 | invariant( 27 | false, 28 | `Required object \`${propName}\` was not specified in ` + 29 | `\`${componentName}\`.`, 30 | ); 31 | } 32 | return; 33 | } 34 | const propValue = props[propName]; 35 | const propType = typeof propValue; 36 | const locationName = location || '(unknown)'; 37 | if (propType !== 'object') { 38 | invariant( 39 | false, 40 | `Invalid ${locationName} \`${propName}\` of type \`${propType}\` ` + 41 | `supplied to \`${componentName}\`, expected \`object\`.`, 42 | ); 43 | } 44 | // We need to check all keys in case some are required but missing from 45 | // props. 46 | const allKeys = {...props[propName], ...shapeTypes}; 47 | for (const key in allKeys) { 48 | const checker = shapeTypes[key]; 49 | if (!checker) { 50 | invariant( 51 | false, 52 | `Invalid props.${propName} key \`${key}\` supplied to \`${componentName}\`.` + 53 | '\nBad object: ' + 54 | JSON.stringify(props[propName], null, ' ') + 55 | '\nValid keys: ' + 56 | JSON.stringify(Object.keys(shapeTypes), null, ' '), 57 | ); 58 | } 59 | const error = checker(propValue, key, componentName, location, ...rest); 60 | if (error) { 61 | invariant( 62 | false, 63 | error.message + 64 | '\nBad object: ' + 65 | JSON.stringify(props[propName], null, ' '), 66 | ); 67 | } 68 | } 69 | } 70 | function chainedCheckType(props, propName, componentName, location, ...rest) { 71 | return checkType(false, props, propName, componentName, location, ...rest); 72 | } 73 | chainedCheckType.isRequired = checkType.bind(null, true); 74 | return chainedCheckType; 75 | } 76 | 77 | module.exports = deprecatedCreateStrictShapeTypeChecker; 78 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | module.exports = { 14 | get ColorPropType() { 15 | return require('./DeprecatedColorPropType'); 16 | }, 17 | get EdgeInsetsPropType() { 18 | return require('./DeprecatedEdgeInsetsPropType'); 19 | }, 20 | get ImagePropTypes() { 21 | return require('./DeprecatedImagePropType'); 22 | }, 23 | get PointPropType() { 24 | return require('./DeprecatedPointPropType'); 25 | }, 26 | get TextInputPropTypes() { 27 | return require('./DeprecatedTextInputPropTypes'); 28 | }, 29 | get TextPropTypes() { 30 | return require('./DeprecatedTextPropTypes'); 31 | }, 32 | get ViewPropTypes() { 33 | return require('./DeprecatedViewPropTypes'); 34 | }, 35 | }; 36 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "deprecated-react-native-prop-types", 3 | "version": "5.0.0", 4 | "description": "Deprecated prop-types from React Native.", 5 | "license": "MIT", 6 | "repository": "github:facebook/react-native-deprecated-modules", 7 | "dependencies": { 8 | "@react-native/normalize-colors": "^0.73.0", 9 | "invariant": "^2.2.4", 10 | "prop-types": "^15.8.1" 11 | }, 12 | "scripts": { 13 | "test": "node -e \"Object.values(require('.'))\"" 14 | }, 15 | "prettier": { 16 | "requirePragma": true, 17 | "singleQuote": true, 18 | "trailingComma": "all", 19 | "bracketSpacing": false, 20 | "jsxBracketSameLine": true, 21 | "arrowParens": "avoid" 22 | }, 23 | "engines": { 24 | "node": ">=18" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /deprecated-react-native-prop-types/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@react-native/normalize-colors@^0.73.0": 6 | version "0.73.2" 7 | resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.73.2.tgz#cc8e48fbae2bbfff53e12f209369e8d2e4cf34ec" 8 | integrity sha512-bRBcb2T+I88aG74LMVHaKms2p/T8aQd8+BZ7LuuzXlRfog1bMWWn/C5i0HVuvW4RPtXQYgIlGiXVDy9Ir1So/w== 9 | 10 | invariant@^2.2.4: 11 | version "2.2.4" 12 | resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" 13 | integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== 14 | dependencies: 15 | loose-envify "^1.0.0" 16 | 17 | "js-tokens@^3.0.0 || ^4.0.0": 18 | version "4.0.0" 19 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 20 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 21 | 22 | loose-envify@^1.0.0, loose-envify@^1.4.0: 23 | version "1.4.0" 24 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" 25 | integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== 26 | dependencies: 27 | js-tokens "^3.0.0 || ^4.0.0" 28 | 29 | object-assign@^4.1.1: 30 | version "4.1.1" 31 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 32 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= 33 | 34 | prop-types@^15.8.1: 35 | version "15.8.1" 36 | resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" 37 | integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== 38 | dependencies: 39 | loose-envify "^1.4.0" 40 | object-assign "^4.1.1" 41 | react-is "^16.13.1" 42 | 43 | react-is@^16.13.1: 44 | version "16.13.1" 45 | resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" 46 | integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== 47 | -------------------------------------------------------------------------------- /deprecated-react-native-swipeablelistview/SwipeableListViewDataSource.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | 'use strict'; 11 | 12 | const ListViewDataSource = require('deprecated-react-native-listview') 13 | .DataSource; 14 | 15 | /** 16 | * Data source wrapper around ListViewDataSource to allow for tracking of 17 | * which row is swiped open and close opened row(s) when another row is swiped 18 | * open. 19 | * 20 | * See https://github.com/facebook/react-native/pull/5602 for why 21 | * ListViewDataSource is not subclassed. 22 | */ 23 | class SwipeableListViewDataSource { 24 | _previousOpenRowID: string; 25 | _openRowID: string; 26 | 27 | _dataBlob: any; 28 | _dataSource: ListViewDataSource; 29 | 30 | rowIdentities: Array>; 31 | sectionIdentities: Array; 32 | 33 | constructor(params: Object) { 34 | this._dataSource = new ListViewDataSource({ 35 | getRowData: params.getRowData, 36 | getSectionHeaderData: params.getSectionHeaderData, 37 | rowHasChanged: (row1, row2) => { 38 | /** 39 | * Row needs to be re-rendered if its swiped open/close status is 40 | * changed, or its data blob changed. 41 | */ 42 | return ( 43 | (row1.id !== this._previousOpenRowID && 44 | row2.id === this._openRowID) || 45 | (row1.id === this._previousOpenRowID && 46 | row2.id !== this._openRowID) || 47 | params.rowHasChanged(row1, row2) 48 | ); 49 | }, 50 | sectionHeaderHasChanged: params.sectionHeaderHasChanged, 51 | }); 52 | } 53 | 54 | cloneWithRowsAndSections( 55 | dataBlob: any, 56 | sectionIdentities: ?Array, 57 | rowIdentities: ?Array>, 58 | ): SwipeableListViewDataSource { 59 | this._dataSource = this._dataSource.cloneWithRowsAndSections( 60 | dataBlob, 61 | sectionIdentities, 62 | rowIdentities, 63 | ); 64 | 65 | this._dataBlob = dataBlob; 66 | this.rowIdentities = this._dataSource.rowIdentities; 67 | this.sectionIdentities = this._dataSource.sectionIdentities; 68 | 69 | return this; 70 | } 71 | 72 | // For the actual ListView to use 73 | getDataSource(): ListViewDataSource { 74 | return this._dataSource; 75 | } 76 | 77 | getOpenRowID(): ?string { 78 | return this._openRowID; 79 | } 80 | 81 | getFirstRowID(): ?string { 82 | /** 83 | * If rowIdentities is specified, find the first data row from there since 84 | * we don't want to attempt to bounce section headers. If unspecified, find 85 | * the first data row from _dataBlob. 86 | */ 87 | if (this.rowIdentities) { 88 | return this.rowIdentities[0] && this.rowIdentities[0][0]; 89 | } 90 | return Object.keys(this._dataBlob)[0]; 91 | } 92 | 93 | getLastRowID(): ?string { 94 | if (this.rowIdentities && this.rowIdentities.length) { 95 | const lastSection = this.rowIdentities[this.rowIdentities.length - 1]; 96 | if (lastSection && lastSection.length) { 97 | return lastSection[lastSection.length - 1]; 98 | } 99 | } 100 | return Object.keys(this._dataBlob)[this._dataBlob.length - 1]; 101 | } 102 | 103 | setOpenRowID(rowID: string): SwipeableListViewDataSource { 104 | this._previousOpenRowID = this._openRowID; 105 | this._openRowID = rowID; 106 | 107 | this._dataSource = this._dataSource.cloneWithRowsAndSections( 108 | this._dataBlob, 109 | this.sectionIdentities, 110 | this.rowIdentities, 111 | ); 112 | 113 | return this; 114 | } 115 | } 116 | 117 | module.exports = SwipeableListViewDataSource; 118 | -------------------------------------------------------------------------------- /deprecated-react-native-swipeablelistview/SwipeableRow.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const React = require('react'); 14 | const {Animated, I18nManager, PanResponder, StyleSheet, View} = require('react-native'); 15 | 16 | import type {LayoutEvent, PressEvent} from 'react-native/Libraries/Types/CoreEventTypes'; 17 | import type {GestureState} from 'react-native/Libraries/Interaction/PanResponder'; 18 | 19 | const IS_RTL = I18nManager.isRTL; 20 | 21 | // NOTE: Eventually convert these consts to an input object of configurations 22 | 23 | // Position of the left of the swipable item when closed 24 | const CLOSED_LEFT_POSITION = 0; 25 | // Minimum swipe distance before we recognize it as such 26 | const HORIZONTAL_SWIPE_DISTANCE_THRESHOLD = 10; 27 | // Minimum swipe speed before we fully animate the user's action (open/close) 28 | const HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD = 0.3; 29 | // Factor to divide by to get slow speed; i.e. 4 means 1/4 of full speed 30 | const SLOW_SPEED_SWIPE_FACTOR = 4; 31 | // Time, in milliseconds, of how long the animated swipe should be 32 | const SWIPE_DURATION = 300; 33 | 34 | /** 35 | * On SwipeableListView mount, the 1st item will bounce to show users it's 36 | * possible to swipe 37 | */ 38 | const ON_MOUNT_BOUNCE_DELAY = 700; 39 | const ON_MOUNT_BOUNCE_DURATION = 400; 40 | 41 | // Distance left of closed position to bounce back when right-swiping from closed 42 | const RIGHT_SWIPE_BOUNCE_BACK_DISTANCE = 30; 43 | const RIGHT_SWIPE_BOUNCE_BACK_DURATION = 300; 44 | /** 45 | * Max distance of right swipe to allow (right swipes do functionally nothing). 46 | * Must be multiplied by SLOW_SPEED_SWIPE_FACTOR because gestureState.dx tracks 47 | * how far the finger swipes, and not the actual animation distance. 48 | */ 49 | const RIGHT_SWIPE_THRESHOLD = 30 * SLOW_SPEED_SWIPE_FACTOR; 50 | const DEFAULT_SWIPE_THRESHOLD = 30; 51 | 52 | const emptyFunction = () => {}; 53 | 54 | type Props = $ReadOnly<{| 55 | children?: ?React.Node, 56 | isOpen?: ?boolean, 57 | maxSwipeDistance?: ?number, 58 | onClose?: ?() => void, 59 | onOpen?: ?() => void, 60 | onSwipeEnd?: ?() => void, 61 | onSwipeStart?: ?() => void, 62 | preventSwipeRight?: ?boolean, 63 | shouldBounceOnMount?: ?boolean, 64 | slideoutView?: ?React.Node, 65 | swipeThreshold?: ?number, 66 | |}>; 67 | 68 | type State = { 69 | currentLeft: Animated.Value, 70 | isSwipeableViewRendered: boolean, 71 | rowHeight: ?number, 72 | }; 73 | 74 | /** 75 | * Creates a swipable row that allows taps on the main item and a custom View 76 | * on the item hidden behind the row. Typically this should be used in 77 | * conjunction with SwipeableListView for additional functionality, but can be 78 | * used in a normal ListView. See the renderRow for SwipeableListView to see how 79 | * to use this component separately. 80 | */ 81 | class SwipeableRow extends React.Component { 82 | _handleMoveShouldSetPanResponderCapture = ( 83 | event: PressEvent, 84 | gestureState: GestureState, 85 | ): boolean => { 86 | // Decides whether a swipe is responded to by this component or its child 87 | return gestureState.dy < 10 && this._isValidSwipe(gestureState); 88 | }; 89 | 90 | _handlePanResponderGrant = ( 91 | event: PressEvent, 92 | gestureState: GestureState, 93 | ): void => {}; 94 | 95 | _handlePanResponderMove = ( 96 | event: PressEvent, 97 | gestureState: GestureState, 98 | ): void => { 99 | if (this._isSwipingExcessivelyRightFromClosedPosition(gestureState)) { 100 | return; 101 | } 102 | 103 | this.props.onSwipeStart && this.props.onSwipeStart(); 104 | 105 | if (this._isSwipingRightFromClosed(gestureState)) { 106 | this._swipeSlowSpeed(gestureState); 107 | } else { 108 | this._swipeFullSpeed(gestureState); 109 | } 110 | }; 111 | 112 | _onPanResponderTerminationRequest = ( 113 | event: PressEvent, 114 | gestureState: GestureState, 115 | ): boolean => { 116 | return false; 117 | }; 118 | 119 | _handlePanResponderEnd = ( 120 | event: PressEvent, 121 | gestureState: GestureState, 122 | ): void => { 123 | const horizontalDistance = IS_RTL ? -gestureState.dx : gestureState.dx; 124 | if (this._isSwipingRightFromClosed(gestureState)) { 125 | this.props.onOpen && this.props.onOpen(); 126 | this._animateBounceBack(RIGHT_SWIPE_BOUNCE_BACK_DURATION); 127 | } else if (this._shouldAnimateRemainder(gestureState)) { 128 | if (horizontalDistance < 0) { 129 | // Swiped left 130 | this.props.onOpen && this.props.onOpen(); 131 | this._animateToOpenPositionWith(gestureState.vx, horizontalDistance); 132 | } else { 133 | // Swiped right 134 | this.props.onClose && this.props.onClose(); 135 | this._animateToClosedPosition(); 136 | } 137 | } else { 138 | if (this._previousLeft === CLOSED_LEFT_POSITION) { 139 | this._animateToClosedPosition(); 140 | } else { 141 | this._animateToOpenPosition(); 142 | } 143 | } 144 | 145 | this.props.onSwipeEnd && this.props.onSwipeEnd(); 146 | }; 147 | 148 | _panResponder = PanResponder.create({ 149 | onMoveShouldSetPanResponderCapture: this 150 | ._handleMoveShouldSetPanResponderCapture, 151 | onPanResponderGrant: this._handlePanResponderGrant, 152 | onPanResponderMove: this._handlePanResponderMove, 153 | onPanResponderRelease: this._handlePanResponderEnd, 154 | onPanResponderTerminationRequest: this._onPanResponderTerminationRequest, 155 | onPanResponderTerminate: this._handlePanResponderEnd, 156 | onShouldBlockNativeResponder: (event, gestureState) => false, 157 | }); 158 | 159 | _previousLeft = CLOSED_LEFT_POSITION; 160 | _timeoutID: ?TimeoutID = null; 161 | 162 | state = { 163 | currentLeft: new Animated.Value(this._previousLeft), 164 | /** 165 | * In order to render component A beneath component B, A must be rendered 166 | * before B. However, this will cause "flickering", aka we see A briefly 167 | * then B. To counter this, _isSwipeableViewRendered flag is used to set 168 | * component A to be transparent until component B is loaded. 169 | */ 170 | isSwipeableViewRendered: false, 171 | rowHeight: null, 172 | }; 173 | 174 | componentDidMount(): void { 175 | if (this.props.shouldBounceOnMount) { 176 | /** 177 | * Do the on mount bounce after a delay because if we animate when other 178 | * components are loading, the animation will be laggy 179 | */ 180 | this._timeoutID = setTimeout(() => { 181 | this._animateBounceBack(ON_MOUNT_BOUNCE_DURATION); 182 | }, ON_MOUNT_BOUNCE_DELAY); 183 | } 184 | } 185 | 186 | UNSAFE_componentWillReceiveProps(nextProps: $Shape): void { 187 | /** 188 | * We do not need an "animateOpen(noCallback)" because this animation is 189 | * handled internally by this component. 190 | */ 191 | const isOpen = this.props.isOpen ?? false; 192 | const nextIsOpen = nextProps.isOpen ?? false; 193 | 194 | if (isOpen && !nextIsOpen) { 195 | this._animateToClosedPosition(); 196 | } 197 | } 198 | 199 | componentWillUnmount() { 200 | if (this._timeoutID != null) { 201 | clearTimeout(this._timeoutID); 202 | } 203 | } 204 | 205 | render(): React.Element { 206 | // The view hidden behind the main view 207 | let slideOutView; 208 | if (this.state.isSwipeableViewRendered && this.state.rowHeight) { 209 | slideOutView = ( 210 | 212 | {this.props.slideoutView} 213 | 214 | ); 215 | } 216 | 217 | // The swipeable item 218 | const swipeableView = ( 219 | 222 | {this.props.children} 223 | 224 | ); 225 | 226 | return ( 227 | 228 | {slideOutView} 229 | {swipeableView} 230 | 231 | ); 232 | } 233 | 234 | close(): void { 235 | this.props.onClose && this.props.onClose(); 236 | this._animateToClosedPosition(); 237 | } 238 | 239 | _onSwipeableViewLayout = (event: LayoutEvent): void => { 240 | this.setState({ 241 | isSwipeableViewRendered: true, 242 | rowHeight: event.nativeEvent.layout.height, 243 | }); 244 | }; 245 | 246 | _isSwipingRightFromClosed(gestureState: GestureState): boolean { 247 | const gestureStateDx = IS_RTL ? -gestureState.dx : gestureState.dx; 248 | return this._previousLeft === CLOSED_LEFT_POSITION && gestureStateDx > 0; 249 | } 250 | 251 | _swipeFullSpeed(gestureState: GestureState): void { 252 | this.state.currentLeft.setValue(this._previousLeft + gestureState.dx); 253 | } 254 | 255 | _swipeSlowSpeed(gestureState: GestureState): void { 256 | this.state.currentLeft.setValue( 257 | this._previousLeft + gestureState.dx / SLOW_SPEED_SWIPE_FACTOR, 258 | ); 259 | } 260 | 261 | _isSwipingExcessivelyRightFromClosedPosition( 262 | gestureState: GestureState, 263 | ): boolean { 264 | /** 265 | * We want to allow a BIT of right swipe, to allow users to know that 266 | * swiping is available, but swiping right does not do anything 267 | * functionally. 268 | */ 269 | const gestureStateDx = IS_RTL ? -gestureState.dx : gestureState.dx; 270 | return ( 271 | this._isSwipingRightFromClosed(gestureState) && 272 | gestureStateDx > RIGHT_SWIPE_THRESHOLD 273 | ); 274 | } 275 | 276 | _animateTo( 277 | toValue: number, 278 | duration: number = SWIPE_DURATION, 279 | callback: Function = emptyFunction, 280 | ): void { 281 | Animated.timing(this.state.currentLeft, { 282 | duration, 283 | toValue, 284 | useNativeDriver: true, 285 | }).start(() => { 286 | this._previousLeft = toValue; 287 | callback(); 288 | }); 289 | } 290 | 291 | _animateToOpenPosition(): void { 292 | const maxSwipeDistance = this.props.maxSwipeDistance ?? 0; 293 | const directionAwareMaxSwipeDistance = IS_RTL 294 | ? -maxSwipeDistance 295 | : maxSwipeDistance; 296 | this._animateTo(-directionAwareMaxSwipeDistance); 297 | } 298 | 299 | _animateToOpenPositionWith(speed: number, distMoved: number): void { 300 | /** 301 | * Ensure the speed is at least the set speed threshold to prevent a slow 302 | * swiping animation 303 | */ 304 | speed = 305 | speed > HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD 306 | ? speed 307 | : HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD; 308 | const maxSwipeDistance = this.props.maxSwipeDistance ?? 0; 309 | /** 310 | * Calculate the duration the row should take to swipe the remaining distance 311 | * at the same speed the user swiped (or the speed threshold) 312 | */ 313 | const duration = Math.abs((maxSwipeDistance - Math.abs(distMoved)) / speed); 314 | const directionAwareMaxSwipeDistance = IS_RTL 315 | ? -maxSwipeDistance 316 | : maxSwipeDistance; 317 | this._animateTo(-directionAwareMaxSwipeDistance, duration); 318 | } 319 | 320 | _animateToClosedPosition(duration: number = SWIPE_DURATION): void { 321 | this._animateTo(CLOSED_LEFT_POSITION, duration); 322 | } 323 | 324 | _animateToClosedPositionDuringBounce = (): void => { 325 | this._animateToClosedPosition(RIGHT_SWIPE_BOUNCE_BACK_DURATION); 326 | }; 327 | 328 | _animateBounceBack(duration: number): void { 329 | /** 330 | * When swiping right, we want to bounce back past closed position on release 331 | * so users know they should swipe right to get content. 332 | */ 333 | const swipeBounceBackDistance = IS_RTL 334 | ? -RIGHT_SWIPE_BOUNCE_BACK_DISTANCE 335 | : RIGHT_SWIPE_BOUNCE_BACK_DISTANCE; 336 | this._animateTo( 337 | -swipeBounceBackDistance, 338 | duration, 339 | this._animateToClosedPositionDuringBounce, 340 | ); 341 | } 342 | 343 | // Ignore swipes due to user's finger moving slightly when tapping 344 | _isValidSwipe(gestureState: GestureState): boolean { 345 | const preventSwipeRight = this.props.preventSwipeRight ?? false; 346 | if ( 347 | preventSwipeRight && 348 | this._previousLeft === CLOSED_LEFT_POSITION && 349 | gestureState.dx > 0 350 | ) { 351 | return false; 352 | } 353 | 354 | return Math.abs(gestureState.dx) > HORIZONTAL_SWIPE_DISTANCE_THRESHOLD; 355 | } 356 | 357 | _shouldAnimateRemainder(gestureState: GestureState): boolean { 358 | /** 359 | * If user has swiped past a certain distance, animate the rest of the way 360 | * if they let go 361 | */ 362 | const swipeThreshold = this.props.swipeThreshold ?? DEFAULT_SWIPE_THRESHOLD; 363 | return ( 364 | Math.abs(gestureState.dx) > swipeThreshold || 365 | gestureState.vx > HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD 366 | ); 367 | } 368 | } 369 | 370 | const styles = StyleSheet.create({ 371 | slideOutContainer: { 372 | bottom: 0, 373 | left: 0, 374 | position: 'absolute', 375 | right: 0, 376 | top: 0, 377 | }, 378 | }); 379 | 380 | module.exports = SwipeableRow; 381 | -------------------------------------------------------------------------------- /deprecated-react-native-swipeablelistview/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const ListView = require('deprecated-react-native-listview'); 14 | const React = require('react'); 15 | const SwipeableListViewDataSource = require('./SwipeableListViewDataSource'); 16 | const SwipeableRow = require('./SwipeableRow'); 17 | 18 | type ListViewProps = React.ElementConfig; 19 | 20 | type Props = $ReadOnly<{| 21 | ...ListViewProps, 22 | 23 | /** 24 | * To alert the user that swiping is possible, the first row can bounce 25 | * on component mount. 26 | */ 27 | bounceFirstRowOnMount: boolean, 28 | /** 29 | * Use `SwipeableListView.getNewDataSource()` to get a data source to use, 30 | * then use it just like you would a normal ListView data source 31 | */ 32 | dataSource: SwipeableListViewDataSource, 33 | /** 34 | * Maximum distance to open to after a swipe 35 | */ 36 | maxSwipeDistance: 37 | | number 38 | | ((rowData: Object, sectionID: string, rowID: string) => number), 39 | onScroll?: ?Function, 40 | /** 41 | * Callback method to render the swipeable view 42 | */ 43 | renderRow: ( 44 | rowData: Object, 45 | sectionID: string, 46 | rowID: string, 47 | ) => React.Element, 48 | /** 49 | * Callback method to render the view that will be unveiled on swipe 50 | */ 51 | renderQuickActions: ( 52 | rowData: Object, 53 | sectionID: string, 54 | rowID: string, 55 | ) => ?React.Element, 56 | |}>; 57 | 58 | type State = {| 59 | dataSource: Object, 60 | |}; 61 | 62 | /** 63 | * A container component that renders multiple SwipeableRow's in a ListView 64 | * implementation. This is designed to be a drop-in replacement for the 65 | * standard React Native `ListView`, so use it as if it were a ListView, but 66 | * with extra props, i.e. 67 | * 68 | * let ds = SwipeableListView.getNewDataSource(); 69 | * ds.cloneWithRowsAndSections(dataBlob, ?sectionIDs, ?rowIDs); 70 | * // .. 71 | * 72 | * 73 | * SwipeableRow can be used independently of this component, but the main 74 | * benefit of using this component is 75 | * 76 | * - It ensures that at most 1 row is swiped open (auto closes others) 77 | * - It can bounce the 1st row of the list so users know it's swipeable 78 | * - More to come 79 | */ 80 | class SwipeableListView extends React.Component { 81 | props: Props; 82 | state: State; 83 | 84 | _listViewRef: ?React.Element = null; 85 | _shouldBounceFirstRowOnMount: boolean = false; 86 | 87 | static getNewDataSource(): Object { 88 | return new SwipeableListViewDataSource({ 89 | getRowData: (data, sectionID, rowID) => data[sectionID][rowID], 90 | getSectionHeaderData: (data, sectionID) => data[sectionID], 91 | rowHasChanged: (row1, row2) => row1 !== row2, 92 | sectionHeaderHasChanged: (s1, s2) => s1 !== s2, 93 | }); 94 | } 95 | 96 | static DataSource = SwipeableListViewDataSource; 97 | static SwipeableRow = SwipeableRow; 98 | 99 | static defaultProps = { 100 | bounceFirstRowOnMount: false, 101 | renderQuickActions: () => null, 102 | }; 103 | 104 | constructor(props: Props, context: any): void { 105 | super(props, context); 106 | 107 | this._shouldBounceFirstRowOnMount = this.props.bounceFirstRowOnMount; 108 | this.state = { 109 | dataSource: this.props.dataSource, 110 | }; 111 | } 112 | 113 | UNSAFE_componentWillReceiveProps(nextProps: Props): void { 114 | if ( 115 | this.state.dataSource.getDataSource() !== 116 | nextProps.dataSource.getDataSource() 117 | ) { 118 | this.setState({ 119 | dataSource: nextProps.dataSource, 120 | }); 121 | } 122 | } 123 | 124 | render(): React.Node { 125 | return ( 126 | // $FlowFixMe Found when typing ListView 127 | { 130 | // $FlowFixMe Found when typing ListView 131 | this._listViewRef = ref; 132 | }} 133 | dataSource={this.state.dataSource.getDataSource()} 134 | onScroll={this._onScroll} 135 | renderRow={this._renderRow} 136 | /> 137 | ); 138 | } 139 | 140 | _onScroll = (e): void => { 141 | // Close any opens rows on ListView scroll 142 | if (this.props.dataSource.getOpenRowID()) { 143 | this.setState({ 144 | dataSource: this.state.dataSource.setOpenRowID(null), 145 | }); 146 | } 147 | this.props.onScroll && this.props.onScroll(e); 148 | }; 149 | 150 | /** 151 | * This is a work-around to lock vertical `ListView` scrolling on iOS and 152 | * mimic Android behaviour. Locking vertical scrolling when horizontal 153 | * scrolling is active allows us to significantly improve framerates 154 | * (from high 20s to almost consistently 60 fps) 155 | */ 156 | _setListViewScrollable(value: boolean): void { 157 | if ( 158 | this._listViewRef && 159 | /* $FlowFixMe(>=0.68.0 site=react_native_fb) This comment suppresses an 160 | * error found when Flow v0.68 was deployed. To see the error delete this 161 | * comment and run Flow. */ 162 | typeof this._listViewRef.setNativeProps === 'function' 163 | ) { 164 | this._listViewRef.setNativeProps({ 165 | scrollEnabled: value, 166 | }); 167 | } 168 | } 169 | 170 | // Passing through ListView's getScrollResponder() function 171 | getScrollResponder(): ?Object { 172 | if ( 173 | this._listViewRef && 174 | /* $FlowFixMe(>=0.68.0 site=react_native_fb) This comment suppresses an 175 | * error found when Flow v0.68 was deployed. To see the error delete this 176 | * comment and run Flow. */ 177 | typeof this._listViewRef.getScrollResponder === 'function' 178 | ) { 179 | return this._listViewRef.getScrollResponder(); 180 | } 181 | } 182 | 183 | // This enables rows having variable width slideoutView. 184 | _getMaxSwipeDistance( 185 | rowData: Object, 186 | sectionID: string, 187 | rowID: string, 188 | ): number { 189 | if (typeof this.props.maxSwipeDistance === 'function') { 190 | return this.props.maxSwipeDistance(rowData, sectionID, rowID); 191 | } 192 | 193 | return this.props.maxSwipeDistance; 194 | } 195 | 196 | _renderRow = ( 197 | rowData: Object, 198 | sectionID: string, 199 | rowID: string, 200 | ): React.Element => { 201 | const slideoutView = this.props.renderQuickActions( 202 | rowData, 203 | sectionID, 204 | rowID, 205 | ); 206 | 207 | // If renderQuickActions is unspecified or returns falsey, don't allow swipe 208 | if (!slideoutView) { 209 | return this.props.renderRow(rowData, sectionID, rowID); 210 | } 211 | 212 | let shouldBounceOnMount = false; 213 | if (this._shouldBounceFirstRowOnMount) { 214 | this._shouldBounceFirstRowOnMount = false; 215 | shouldBounceOnMount = rowID === this.props.dataSource.getFirstRowID(); 216 | } 217 | 218 | return ( 219 | this._onOpen(rowData.id)} 225 | onClose={() => this._onClose(rowData.id)} 226 | onSwipeEnd={() => this._setListViewScrollable(true)} 227 | onSwipeStart={() => this._setListViewScrollable(false)} 228 | shouldBounceOnMount={shouldBounceOnMount}> 229 | {this.props.renderRow(rowData, sectionID, rowID)} 230 | 231 | ); 232 | }; 233 | 234 | _onOpen(rowID: string): void { 235 | this.setState({ 236 | dataSource: this.state.dataSource.setOpenRowID(rowID), 237 | }); 238 | } 239 | 240 | _onClose(rowID: string): void { 241 | this.setState({ 242 | dataSource: this.state.dataSource.setOpenRowID(null), 243 | }); 244 | } 245 | } 246 | 247 | module.exports = SwipeableListView; 248 | -------------------------------------------------------------------------------- /deprecated-react-native-swipeablelistview/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "deprecated-react-native-swipeable-listview", 3 | "version": "0.0.1", 4 | "description": "", 5 | "license": "MIT", 6 | "repository": { 7 | "type": "git", 8 | "url": "git@github.com:facebook/react-native-deprecated-modules.git" 9 | }, 10 | "dependencies": { 11 | "deprecated-react-native-listview": "*" 12 | }, 13 | "peerDependencies": { 14 | "react": "*", 15 | "react-native": "*" 16 | } 17 | } 18 | --------------------------------------------------------------------------------