diff --git a/.eslintignore b/.eslintignore index c3af85790..85d0dc0ca 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1 @@ -lib/ +**/lib/ \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index a73a34d99..567fe8731 100644 --- a/.eslintrc +++ b/.eslintrc @@ -7,12 +7,11 @@ }, "extends": [ "airbnb", - "plugin:flowtype/recommended", "plugin:@typescript-eslint/recommended", "prettier", "plugin:react-hooks/recommended" ], - "plugins": ["@babel", "@typescript-eslint", "flowtype", "module-resolver", "import"], + "plugins": ["@babel", "@typescript-eslint", "module-resolver", "import"], "rules": { "@typescript-eslint/explicit-module-boundary-types": "off", "@typescript-eslint/ban-ts-comment": "off", @@ -22,9 +21,6 @@ "@typescript-eslint/no-use-before-define": ["error", { "variables": false }], "@typescript-eslint/no-shadow": ["error"], // to deal with Enums properly - "flowtype/space-after-type-colon": "off", - "flowtype/no-types-missing-file-annotation": "off", - "module-resolver/use-alias": 0, "import/extensions": [ @@ -56,6 +52,11 @@ "react/require-default-props": "off", "react/jsx-props-no-spreading": "off", + // has a lot of false positives + "react/no-unused-prop-types": [0], + // has a lot of false positives + "react/no-unused-class-component-methods": "off", + "arrow-body-style": "off", "arrow-parens": ["error", "as-needed"], "quote-props": "off", diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index 1be28463d..000000000 --- a/.flowconfig +++ /dev/null @@ -1,80 +0,0 @@ -[ignore] -; We fork some components by platform -.*/*[.]android.js - -; Ignore "BUCK" generated dirs -/\.buckd/ - -; Ignore polyfills -node_modules/react-native/Libraries/polyfills/.* - -; Ignore Electron packager -.*/node_modules/electron-packager/.* - -; Flow doesn't support platforms -.*/Libraries/Utilities/LoadingView.js - -; Ignore next due to: https://github.com/browserify/resolve/issues/262 -.*/node_modules/resolve/.* - -[untyped] -.*/lib/commonjs/.* -.*/lib/module/.* -.*/node_modules/@react-native-community/cli/.*/.* - -; TODO: migrate the following packages on TS or remove as the current flow annotation is not actual; TODO: migrate the following packages on TS or remove as the current flow annotation is not actual -.*/packages/core/.* -.*/packages/components/.* - -[include] - -[libs] -./peerTypes -node_modules/react-native/interface.js -node_modules/react-native/flow/ - -[options] -emoji=true -sharedmemory.hash_table_pow=21 - -exact_by_default=true - -format.bracket_spacing=false - -module.file_ext=.js -module.file_ext=.json -module.file_ext=.ios.js -module.file_ext=.native.js - -munge_underscores=true - -module.name_mapper='^react-native/\(.*\)$' -> '/node_modules/react-native/\1' -module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '/node_modules/react-native/Libraries/Image/RelativeImageStub' - -suppress_type=$FlowIssue -suppress_type=$FlowFixMe -suppress_type=$FlowFixMeProps -suppress_type=$FlowFixMeState - -[lints] -sketchy-null-number=warn -sketchy-null-mixed=warn -sketchy-number=warn -untyped-type-import=warn -nonstrict-import=warn -deprecated-type=warn -unsafe-getters-setters=warn -unnecessary-invariant=warn -signature-verification-failure=warn - -[strict] -deprecated-type -nonstrict-import -sketchy-null -unclear-type -unsafe-getters-setters -untyped-import -untyped-type-import - -[version] -^0.162.0 diff --git a/.vscode/settings.json b/.vscode/settings.json index 5d8213d0c..a6a182a7b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -16,7 +16,7 @@ "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, - "eslint.options": { "configFile": ".eslintrc", "resolvePluginsRelativeTo": "." }, + "eslint.options": { "overrideConfigFile": ".eslintrc", "resolvePluginsRelativeTo": "." }, "eslint.validate": ["typescript", "typescriptreact", "javascript", "javascriptreact"], "javascript.validate.enable": false, "[java]": { diff --git a/Example/.buckconfig b/Example/.buckconfig deleted file mode 100644 index 934256cb2..000000000 --- a/Example/.buckconfig +++ /dev/null @@ -1,6 +0,0 @@ - -[android] - target = Google Inc.:Google APIs:23 - -[maven_repositories] - central = https://repo1.maven.org/maven2 diff --git a/Example/.gitignore b/Example/.gitignore index f092d2c40..b10764e50 100644 --- a/Example/.gitignore +++ b/Example/.gitignore @@ -20,6 +20,7 @@ DerivedData *.hmap *.ipa *.xcuserstate +ios/.xcode.env.local # Android/IntelliJ # @@ -28,6 +29,10 @@ build/ .gradle local.properties *.iml +*.hprof +.cxx/ +*.keystore +!debug.keystore # node.js # @@ -35,12 +40,6 @@ node_modules/ npm-debug.log yarn-error.log -# BUCK -buck-out/ -\.buckd/ -*.keystore -!debug.keystore - # fastlane # # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the @@ -48,19 +47,24 @@ buck-out/ # For more information about the recommended setup visit: # https://docs.fastlane.tools/best-practices/source-control/ -*/fastlane/report.xml -*/fastlane/Preview.html -*/fastlane/screenshots +**/fastlane/report.xml +**/fastlane/Preview.html +**/fastlane/screenshots +**/fastlane/test_output # Bundle artifact *.jsbundle -# CocoaPods +# Ruby / CocoaPods /ios/Pods/ +/vendor/bundle/ # Web build web/assets/ .firebase # Locks -/ios/Podfile.lock \ No newline at end of file +/ios/Podfile.lock + +# Temporary files created by Metro to check the health of the file watcher +.metro-health-check* \ No newline at end of file diff --git a/Example/.node-version b/Example/.node-version new file mode 100644 index 000000000..25bf17fc5 --- /dev/null +++ b/Example/.node-version @@ -0,0 +1 @@ +18 \ No newline at end of file diff --git a/Example/.ruby-version b/Example/.ruby-version deleted file mode 100644 index 74500cee1..000000000 --- a/Example/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -2.7.4 \ No newline at end of file diff --git a/Example/Gemfile b/Example/Gemfile index b2a702992..d7aa9565a 100644 --- a/Example/Gemfile +++ b/Example/Gemfile @@ -1,7 +1,7 @@ source "https://rubygems.org" # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version -ruby '2.7.4' +ruby '3.0.0' gem "fastlane" -gem 'cocoapods', '~> 1.11', '>= 1.11.2' \ No newline at end of file +gem 'cocoapods', '>= 1.11.3' \ No newline at end of file diff --git a/Example/Gemfile.lock b/Example/Gemfile.lock index dabf778c3..068543853 100644 --- a/Example/Gemfile.lock +++ b/Example/Gemfile.lock @@ -1,48 +1,47 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (3.0.5) + CFPropertyList (3.0.6) rexml - activesupport (6.1.7.3) + activesupport (7.0.4.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) - zeitwerk (~> 2.3) - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) + addressable (2.8.4) + public_suffix (>= 2.0.2, < 6.0) algoliasearch (1.27.5) httpclient (~> 2.8, >= 2.8.3) json (>= 1.5.1) artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.2.0) - aws-partitions (1.565.0) - aws-sdk-core (3.129.0) + aws-partitions (1.746.0) + aws-sdk-core (3.171.0) aws-eventstream (~> 1, >= 1.0.2) - aws-partitions (~> 1, >= 1.525.0) + aws-partitions (~> 1, >= 1.651.0) + aws-sigv4 (~> 1.5) + jmespath (~> 1, >= 1.6.1) + aws-sdk-kms (1.63.0) + aws-sdk-core (~> 3, >= 3.165.0) aws-sigv4 (~> 1.1) - jmespath (~> 1.0) - aws-sdk-kms (1.55.0) - aws-sdk-core (~> 3, >= 3.127.0) - aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.113.0) - aws-sdk-core (~> 3, >= 3.127.0) + aws-sdk-s3 (1.120.1) + aws-sdk-core (~> 3, >= 3.165.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) - aws-sigv4 (1.4.0) + aws-sigv4 (1.5.2) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) claide (1.1.0) - cocoapods (1.11.3) + cocoapods (1.12.0) addressable (~> 2.8) claide (>= 1.0.2, < 2.0) - cocoapods-core (= 1.11.3) + cocoapods-core (= 1.12.0) cocoapods-deintegrate (>= 1.0.3, < 2.0) - cocoapods-downloader (>= 1.4.0, < 2.0) + cocoapods-downloader (>= 1.6.0, < 2.0) cocoapods-plugins (>= 1.0.0, < 2.0) cocoapods-search (>= 1.0.0, < 2.0) - cocoapods-trunk (>= 1.4.0, < 2.0) + cocoapods-trunk (>= 1.6.0, < 2.0) cocoapods-try (>= 1.1.0, < 2.0) colored2 (~> 3.1) escape (~> 0.0.4) @@ -50,10 +49,10 @@ GEM gh_inspector (~> 1.0) molinillo (~> 0.8.0) nap (~> 1.0) - ruby-macho (>= 1.0, < 3.0) + ruby-macho (>= 2.3.0, < 3.0) xcodeproj (>= 1.21.0, < 2.0) - cocoapods-core (1.11.3) - activesupport (>= 5.0, < 7) + cocoapods-core (1.12.0) + activesupport (>= 5.0, < 8) addressable (~> 2.8) algoliasearch (~> 1.0) concurrent-ruby (~> 1.1) @@ -81,13 +80,13 @@ GEM rake (>= 12.0.0, < 14.0.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.6) + dotenv (2.8.1) emoji_regex (3.2.3) escape (0.0.4) - ethon (0.15.0) + ethon (0.16.0) ffi (>= 1.15.0) - excon (0.91.0) - faraday (1.10.0) + excon (0.99.0) + faraday (1.10.3) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -106,8 +105,8 @@ GEM faraday-em_synchrony (1.0.0) faraday-excon (1.1.0) faraday-httpclient (1.0.1) - faraday-multipart (1.0.3) - multipart-post (>= 1.2, < 3) + faraday-multipart (1.0.4) + multipart-post (~> 2) faraday-net_http (1.0.1) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) @@ -116,7 +115,7 @@ GEM faraday_middleware (1.2.0) faraday (~> 1.0) fastimage (2.2.6) - fastlane (2.204.3) + fastlane (2.212.1) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -159,9 +158,9 @@ GEM fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.16.0) - google-apis-core (>= 0.4, < 2.a) - google-apis-core (0.4.2) + google-apis-androidpublisher_v3 (0.38.0) + google-apis-core (>= 0.11.0, < 2.a) + google-apis-core (0.11.0) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) httpclient (>= 2.8.1, < 3.a) @@ -170,27 +169,27 @@ GEM retriable (>= 2.0, < 4.a) rexml webrick - google-apis-iamcredentials_v1 (0.10.0) - google-apis-core (>= 0.4, < 2.a) - google-apis-playcustomapp_v1 (0.7.0) - google-apis-core (>= 0.4, < 2.a) - google-apis-storage_v1 (0.11.0) - google-apis-core (>= 0.4, < 2.a) + google-apis-iamcredentials_v1 (0.17.0) + google-apis-core (>= 0.11.0, < 2.a) + google-apis-playcustomapp_v1 (0.13.0) + google-apis-core (>= 0.11.0, < 2.a) + google-apis-storage_v1 (0.19.0) + google-apis-core (>= 0.9.0, < 2.a) google-cloud-core (1.6.0) google-cloud-env (~> 1.0) google-cloud-errors (~> 1.0) - google-cloud-env (1.5.0) - faraday (>= 0.17.3, < 2.0) - google-cloud-errors (1.2.0) - google-cloud-storage (1.36.1) + google-cloud-env (1.6.0) + faraday (>= 0.17.3, < 3.0) + google-cloud-errors (1.3.1) + google-cloud-storage (1.44.0) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.1) + google-apis-storage_v1 (~> 0.19.0) google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) - googleauth (1.1.2) + googleauth (1.5.1) faraday (>= 0.17.3, < 3.a) jwt (>= 1.4, < 3.0) memoist (~> 0.16) @@ -198,16 +197,16 @@ GEM os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) highline (2.0.3) - http-cookie (1.0.4) + http-cookie (1.0.5) domain_name (~> 0.5) httpclient (2.8.3) i18n (1.12.0) concurrent-ruby (~> 1.0) - jmespath (1.6.1) - json (2.6.1) - jwt (2.3.0) + jmespath (1.6.2) + json (2.6.3) + jwt (2.7.0) memoist (0.16.2) - mini_magick (4.11.0) + mini_magick (4.12.0) mini_mime (1.1.2) minitest (5.18.0) molinillo (0.8.0) @@ -219,10 +218,10 @@ GEM netrc (0.11.0) optparse (0.1.1) os (1.1.4) - plist (3.6.0) - public_suffix (4.0.6) + plist (3.7.0) + public_suffix (4.0.7) rake (13.0.6) - representable (3.1.1) + representable (3.2.0) declarative (< 0.1.0) trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) @@ -233,12 +232,12 @@ GEM ruby2_keywords (0.0.5) rubyzip (2.3.2) security (0.1.3) - signet (0.16.1) + signet (0.17.0) addressable (~> 2.8) - faraday (>= 0.17.5, < 3.0) + faraday (>= 0.17.5, < 3.a) jwt (>= 1.5, < 3.0) multi_json (~> 1.10) - simctl (1.6.8) + simctl (1.6.10) CFPropertyList naturally terminal-notifier (2.0.0) @@ -256,11 +255,11 @@ GEM uber (0.1.0) unf (0.1.4) unf_ext - unf_ext (0.0.8) + unf_ext (0.0.8.2) unicode-display_width (1.8.0) - webrick (1.7.0) + webrick (1.8.1) word_wrap (1.0.0) - xcodeproj (1.21.0) + xcodeproj (1.22.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) @@ -271,17 +270,16 @@ GEM rouge (~> 2.0.7) xcpretty-travis-formatter (1.0.1) xcpretty (~> 0.2, >= 0.0.7) - zeitwerk (2.6.7) PLATFORMS ruby DEPENDENCIES - cocoapods (~> 1.11, >= 1.11.2) + cocoapods (>= 1.11.3) fastlane RUBY VERSION - ruby 2.7.4p191 + ruby 3.0.0p0 BUNDLED WITH - 2.1.4 + 2.2.3 diff --git a/Example/__tests__/App-test.js b/Example/__tests__/App-test.tsx similarity index 100% rename from Example/__tests__/App-test.js rename to Example/__tests__/App-test.tsx diff --git a/Example/android/app/_BUCK b/Example/android/app/_BUCK deleted file mode 100644 index 51c280f6d..000000000 --- a/Example/android/app/_BUCK +++ /dev/null @@ -1,55 +0,0 @@ -# To learn about Buck see [Docs](https://buckbuild.com/). -# To run your application with Buck: -# - install Buck -# - `npm start` - to start the packager -# - `cd android` -# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` -# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck -# - `buck install -r android/app` - compile, install and run application -# - -load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") - -lib_deps = [] - -create_aar_targets(glob(["libs/*.aar"])) - -create_jar_targets(glob(["libs/*.jar"])) - -android_library( - name = "all-libs", - exported_deps = lib_deps, -) - -android_library( - name = "app-code", - srcs = glob([ - "src/main/java/**/*.java", - ]), - deps = [ - ":all-libs", - ":build_config", - ":res", - ], -) - -android_build_config( - name = "build_config", - package = "tonlabs.uikit", -) - -android_resource( - name = "res", - package = "tonlabs.uikit", - res = "src/main/res", -) - -android_binary( - name = "app", - keystore = "//android/keystores:debug", - manifest = "src/main/AndroidManifest.xml", - package_type = "debug", - deps = [ - ":app-code", - ], -) diff --git a/Example/android/app/build.gradle b/Example/android/app/build.gradle index c17e18f66..131b5783f 100644 --- a/Example/android/app/build.gradle +++ b/Example/android/app/build.gradle @@ -1,89 +1,53 @@ apply plugin: "com.android.application" +apply plugin: "com.facebook.react" import com.android.build.OutputFile /** - * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets - * and bundleReleaseJsAndAssets). - * These basically call `react-native bundle` with the correct arguments during the Android build - * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the - * bundle directly from the development server. Below you can see all the possible configurations - * and their defaults. If you decide to add a configuration block, make sure to add it before the - * `apply from: "../../node_modules/react-native/react.gradle"` line. - * - * project.ext.react = [ - * // the name of the generated asset file containing your JS bundle - * bundleAssetName: "index.android.bundle", - * - * // the entry file for bundle generation. If none specified and - * // "index.android.js" exists, it will be used. Otherwise "index.js" is - * // default. Can be overridden with ENTRY_FILE environment variable. - * entryFile: "index.android.js", - * - * // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format - * bundleCommand: "ram-bundle", - * - * // whether to bundle JS and assets in debug mode - * bundleInDebug: false, - * - * // whether to bundle JS and assets in release mode - * bundleInRelease: true, - * - * // whether to bundle JS and assets in another build variant (if configured). - * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants - * // The configuration property can be in the following formats - * // 'bundleIn${productFlavor}${buildType}' - * // 'bundleIn${buildType}' - * // bundleInFreeDebug: true, - * // bundleInPaidRelease: true, - * // bundleInBeta: true, - * - * // whether to disable dev mode in custom build variants (by default only disabled in release) - * // for example: to disable dev mode in the staging build type (if configured) - * devDisabledInStaging: true, - * // The configuration property can be in the following formats - * // 'devDisabledIn${productFlavor}${buildType}' - * // 'devDisabledIn${buildType}' - * - * // the root of your project, i.e. where "package.json" lives - * root: "../../", - * - * // where to put the JS bundle asset in debug mode - * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", - * - * // where to put the JS bundle asset in release mode - * jsBundleDirRelease: "$buildDir/intermediates/assets/release", - * - * // where to put drawable resources / React Native assets, e.g. the ones you use via - * // require('./image.png')), in debug mode - * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", - * - * // where to put drawable resources / React Native assets, e.g. the ones you use via - * // require('./image.png')), in release mode - * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", - * - * // by default the gradle tasks are skipped if none of the JS files or assets change; this means - * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to - * // date; if you have any other folders that you want to ignore for performance reasons (gradle - * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ - * // for example, you might want to remove it from here. - * inputExcludes: ["android/**", "ios/**"], - * - * // override which node gets called and with what additional arguments - * nodeExecutableAndArgs: ["node"], - * - * // supply additional arguments to the packager - * extraPackagerArgs: [] - * ] + * This is the configuration block to customize your React Native Android app. + * By default you don't need to apply any configuration, just uncomment the lines you need. */ - -project.ext.react = [ - cliPath: "../node_modules/react-native/cli.js", // path is relative to `process.cwd` - composeSourceMapsPath: "../node_modules/react-native/scripts/compose-source-maps.js", // path is relative to `process.cwd` - enableHermes: true, // clean and rebuild if changing - entryFile: "index.js", // path is relative to `process.cwd` - hermesCommand: "../../../node_modules/hermes-engine/osx-bin/hermesc", -] +react { + /* Folders */ + // The root of your project, i.e. where "package.json" lives. Default is '..' + // root = file("../") + // The folder where the react-native NPM package is. Default is ../node_modules/react-native + // reactNativeDir = file("../node_modules/react-native") + // The folder where the react-native Codegen package is. Default is ../node_modules/react-native-codegen + // codegenDir = file("../node_modules/react-native-codegen") + // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js + // cliFile = file("../node_modules/react-native/cli.js") + /* Variants */ + // The list of variants to that are debuggable. For those we're going to + // skip the bundling of the JS bundle and the assets. By default is just 'debug'. + // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. + // debuggableVariants = ["liteDebug", "prodDebug"] + /* Bundling */ + // A list containing the node command and its flags. Default is just 'node'. + // nodeExecutableAndArgs = ["node"] + // + // The command to run when bundling. By default is 'bundle' + // bundleCommand = "ram-bundle" + // + // The path to the CLI configuration file. Default is empty. + // bundleConfig = file(../rn-cli.config.js) + // + // The name of the generated asset file containing your JS bundle + // bundleAssetName = "MyApplication.android.bundle" + // + // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' + // entryFile = file("../js/MyApplication.android.js") + // + // A list of extra flags to pass to the 'bundle' commands. + // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle + // extraPackagerArgs = [] + /* Hermes Commands */ + // The hermes compiler command to run. By default it is 'hermesc' + // hermesCommand = "../../../node_modules/hermes-engine/osx-bin/hermesc" + // + // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" + // hermesFlags = ["-O", "-output-source-map"] +} project.ext.themes = [ iconFontsDir: "../../../kit/themes/src/assets/fonts", @@ -93,41 +57,40 @@ apply from: "../../../node_modules/react-native/react.gradle" apply from: "../../../kit/themes/fonts.gradle" /** - * Set this to true to create two separate APKs instead of one: - * - An APK that only works on ARM devices - * - An APK that only works on x86 devices - * The advantage is the size of the APK is reduced by about 4MB. - * Upload all the APKs to the Play Store and people will download - * the correct one based on the CPU architecture of their device. + * Set this to true to create four separate APKs instead of one, + * one for each native architecture. This is useful if you don't + * use App Bundles (https://developer.android.com/guide/app-bundle/) + * and want to have separate APKs to upload to the Play Store. */ def enableSeparateBuildPerCPUArchitecture = false /** - * Run Proguard to shrink the Java bytecode in release builds. + * Set this to true to Run Proguard on Release builds to minify the Java bytecode. */ def enableProguardInReleaseBuilds = false /** - * The preferred build flavor of JavaScriptCore. + * The preferred build flavor of JavaScriptCore (JSC) * * For example, to use the international variant, you can use: * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` * * The international variant includes ICU i18n library and necessary data * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that - * give correct results when using with locales other than en-US. Note that + * give correct results when using with locales other than en-US. Note that * this variant is about 6MiB larger per architecture than default. */ def jscFlavor = 'org.webkit:android-jsc:+' /** - * Whether to enable the Hermes VM. - * - * This should be set on project.ext.react and mirrored here. If it is not set - * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode - * and the benefits of using Hermes will therefore be sharply reduced. + * Private function to get the list of Native Architectures you want to build. + * This reads the value from reactNativeArchitectures in your gradle.properties + * file and works together with the --active-arch-only flag of react-native run-android. */ -def enableHermes = project.ext.react.get("enableHermes", false); +def reactNativeArchitectures() { + def value = project.getProperties().get("reactNativeArchitectures") + return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] +} /** * Keep the release signing key in Keychain @@ -151,6 +114,7 @@ android { compileSdkVersion rootProject.ext.compileSdkVersion + namespace "tonlabs.uikit" defaultConfig { applicationId "tonlabs.uikit" minSdkVersion rootProject.ext.minSdkVersion @@ -160,12 +124,13 @@ android { versionName "1.0" missingDimensionStrategy 'react-native-camera', 'general' } + splits { abi { reset() enable enableSeparateBuildPerCPUArchitecture universalApk false // If true, also generate a universal APK - include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" + include (*reactNativeArchitectures()) } } signingConfigs { @@ -219,38 +184,23 @@ android { } dependencies { - implementation fileTree(dir: "libs", include: ["*.jar"]) - //noinspection GradleDynamicVersion - implementation "com.facebook.react:react-native:+" // From node_modules + // The version of react-native is set by the React Native Gradle Plugin + implementation("com.facebook.react:react-android") - implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" + implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0") - debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { - exclude group:'com.facebook.fbjni' - } + debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { - exclude group:'com.facebook.flipper' - } - - debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") { - exclude group:'com.facebook.flipper' + exclude group:'com.squareup.okhttp3', module:'okhttp' } - if (enableHermes) { - def hermesPath = "../../../node_modules/hermes-engine/android/"; - debugImplementation files(hermesPath + "hermes-debug.aar") - releaseImplementation files(hermesPath + "hermes-release.aar") + debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") + if (hermesEnabled.toBoolean()) { + implementation("com.facebook.react:hermes-android") } else { implementation jscFlavor } } -// Run this once to be able to run the application with BUCK -// puts all compile dependencies into folder libs for BUCK to use -task copyDownloadableDepsToLibs(type: Copy) { - from configurations.implementation - into 'libs' -} - apply from: file("../../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) diff --git a/Example/android/app/build_defs.bzl b/Example/android/app/build_defs.bzl deleted file mode 100644 index fff270f8d..000000000 --- a/Example/android/app/build_defs.bzl +++ /dev/null @@ -1,19 +0,0 @@ -"""Helper definitions to glob .aar and .jar targets""" - -def create_aar_targets(aarfiles): - for aarfile in aarfiles: - name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] - lib_deps.append(":" + name) - android_prebuilt_aar( - name = name, - aar = aarfile, - ) - -def create_jar_targets(jarfiles): - for jarfile in jarfiles: - name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] - lib_deps.append(":" + name) - prebuilt_jar( - name = name, - binary_jar = jarfile, - ) diff --git a/Example/android/app/src/debug/AndroidManifest.xml b/Example/android/app/src/debug/AndroidManifest.xml index b2f3ad9fc..4b185bc15 100644 --- a/Example/android/app/src/debug/AndroidManifest.xml +++ b/Example/android/app/src/debug/AndroidManifest.xml @@ -8,6 +8,6 @@ android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning"> - + diff --git a/Example/android/app/src/debug/java/tonlabs/uikit/ReactNativeFlipper.java b/Example/android/app/src/debug/java/tonlabs/uikit/ReactNativeFlipper.java index a30903d74..90eb8ee14 100644 --- a/Example/android/app/src/debug/java/tonlabs/uikit/ReactNativeFlipper.java +++ b/Example/android/app/src/debug/java/tonlabs/uikit/ReactNativeFlipper.java @@ -1,5 +1,5 @@ /** - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * *

This source code is licensed under the MIT license found in the LICENSE file in the root * directory of this source tree. @@ -17,20 +17,23 @@ import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; -import com.facebook.flipper.plugins.react.ReactFlipperPlugin; import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; +import com.facebook.react.ReactInstanceEventListener; import com.facebook.react.ReactInstanceManager; import com.facebook.react.bridge.ReactContext; import com.facebook.react.modules.network.NetworkingModule; import okhttp3.OkHttpClient; +/** + * Class responsible of loading Flipper inside your React Native application. This is the debug + * flavor of it. Here you can add your own plugins and customize the Flipper setup. + */ public class ReactNativeFlipper { public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { if (FlipperUtils.shouldEnableFlipper(context)) { final FlipperClient client = AndroidFlipperClient.getInstance(context); client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); - client.addPlugin(new ReactFlipperPlugin()); client.addPlugin(new DatabasesFlipperPlugin(context)); client.addPlugin(new SharedPreferencesFlipperPlugin(context)); client.addPlugin(CrashReporterPlugin.getInstance()); @@ -51,7 +54,7 @@ public void apply(OkHttpClient.Builder builder) { ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); if (reactContext == null) { reactInstanceManager.addReactInstanceEventListener( - new ReactInstanceManager.ReactInstanceEventListener() { + new ReactInstanceEventListener() { @Override public void onReactContextInitialized(ReactContext reactContext) { reactInstanceManager.removeReactInstanceEventListener(this); diff --git a/Example/android/app/src/main/AndroidManifest.xml b/Example/android/app/src/main/AndroidManifest.xml index 9c72a0e4c..45677fc7f 100644 --- a/Example/android/app/src/main/AndroidManifest.xml +++ b/Example/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - + @@ -23,7 +22,7 @@ diff --git a/Example/android/app/src/main/java/tonlabs/uikit/MainActivity.java b/Example/android/app/src/main/java/tonlabs/uikit/MainActivity.java index 08b2dabd5..c6712f6bb 100644 --- a/Example/android/app/src/main/java/tonlabs/uikit/MainActivity.java +++ b/Example/android/app/src/main/java/tonlabs/uikit/MainActivity.java @@ -5,6 +5,9 @@ import com.facebook.react.ReactActivity; import com.facebook.react.ReactActivityDelegate; import com.facebook.react.ReactRootView; +import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; +import com.facebook.react.defaults.DefaultReactActivityDelegate; + import tonlabs.uikit.keyboard.UIKitKeyboardFrameListener; public class MainActivity extends ReactActivity { @@ -18,18 +21,25 @@ protected String getMainComponentName() { return "UIKit"; } + /** + * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link + * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React + * (aka React 18) with two boolean flags. + */ @Override protected ReactActivityDelegate createReactActivityDelegate() { - return new ReactActivityDelegate(this, getMainComponentName()) { - @Override - protected ReactRootView createRootView() { - ReactRootView rootView = new ReactRootView(getContext()); + ReactRootView rootView = new ReactRootView(getContext()); - WindowCompat.setDecorFitsSystemWindows(MainActivity.this.getWindow(), false); - UIKitKeyboardFrameListener.attach(MainActivity.this, rootView); + WindowCompat.setDecorFitsSystemWindows(MainActivity.this.getWindow(), false); + UIKitKeyboardFrameListener.attach(MainActivity.this, rootView); - return rootView; - } - }; + return new DefaultReactActivityDelegate( + this, + getMainComponentName(), + // If you opted-in for the New Architecture, we enable the Fabric Renderer. + DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled + // If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18). + DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled + ); } } diff --git a/Example/android/app/src/main/java/tonlabs/uikit/MainApplication.java b/Example/android/app/src/main/java/tonlabs/uikit/MainApplication.java index 6078c8812..8e8d57f0a 100644 --- a/Example/android/app/src/main/java/tonlabs/uikit/MainApplication.java +++ b/Example/android/app/src/main/java/tonlabs/uikit/MainApplication.java @@ -1,17 +1,16 @@ package tonlabs.uikit; import android.app.Application; -import android.content.Context; import com.facebook.react.PackageList; import com.facebook.react.ReactApplication; -import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; +import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; +import com.facebook.react.defaults.DefaultReactNativeHost; import com.facebook.react.bridge.JSIModuleSpec; import com.facebook.react.bridge.JavaScriptContextHolder; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.soloader.SoLoader; -import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.List; @@ -20,7 +19,7 @@ public class MainApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost = - new ReactNativeHost(this) { + new DefaultReactNativeHost(this) { @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; @@ -41,6 +40,16 @@ protected String getJSMainModuleName() { return "index"; } + @Override + protected boolean isNewArchEnabled() { + return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; + } + + @Override + protected Boolean isHermesEnabled() { + return BuildConfig.IS_HERMES_ENABLED; + } + @Override protected JSIModulePackage getJSIModulePackage() { return new JSIModulePackage() { @@ -61,37 +70,10 @@ public ReactNativeHost getReactNativeHost() { public void onCreate() { super.onCreate(); SoLoader.init(this, /* native exopackage */ false); - initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); - } - - /** - * Loads Flipper in React Native templates. Call this in the onCreate method with something like - * initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); - * - * @param context - * @param reactInstanceManager - */ - private static void initializeFlipper( - Context context, ReactInstanceManager reactInstanceManager) { - if (BuildConfig.DEBUG) { - try { - /* - We use reflection here to pick up the class that initializes Flipper, - since Flipper library is not available in release mode - */ - Class aClass = Class.forName("tonlabs.uikit.ReactNativeFlipper"); - aClass - .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) - .invoke(null, context, reactInstanceManager); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } + if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { + // If you opted-in for the New Architecture, we load the native entry point for this app. + DefaultNewArchitectureEntryPoint.load(); } + ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); } } diff --git a/Example/android/app/src/main/java/tonlabs/uikit/ReactNativeFlipper.java b/Example/android/app/src/main/java/tonlabs/uikit/ReactNativeFlipper.java new file mode 100644 index 000000000..55b604041 --- /dev/null +++ b/Example/android/app/src/main/java/tonlabs/uikit/ReactNativeFlipper.java @@ -0,0 +1,18 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + *

This source code is licensed under the MIT license found in the LICENSE file in the root + * directory of this source tree. + */ +package com.rndiffapp; +import android.content.Context; +import com.facebook.react.ReactInstanceManager; +/** + * Class responsible of loading Flipper inside your React Native application. This is the release + * flavor of it so it's empty as we don't want to load Flipper. + */ +public class ReactNativeFlipper { + public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { + // Do nothing as we don't want to initialize Flipper on Release. + } +} \ No newline at end of file diff --git a/Example/android/build.gradle b/Example/android/build.gradle index 15fd9a09c..1880eb4b1 100644 --- a/Example/android/build.gradle +++ b/Example/android/build.gradle @@ -2,43 +2,21 @@ buildscript { ext { - buildToolsVersion = "31.0.0" + buildToolsVersion = "33.0.0" minSdkVersion = 21 - compileSdkVersion = 31 - targetSdkVersion = 31 - ndkVersion = "21.4.7075529" + compileSdkVersion = 33 + targetSdkVersion = 33 + + // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. + ndkVersion = "23.1.7779620" } repositories { google() mavenCentral() } dependencies { - classpath("com.android.tools.build:gradle:4.2.2") - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - google() - maven { url 'https://www.jitpack.io' } - maven { - // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm - url("$rootDir/../../node_modules/react-native/android") - } - maven { - // Android JSC is installed from npm - url("$rootDir/../../node_modules/jsc-android/dist") - } - mavenCentral { - // We don't want to fetch react-native from Maven Central as there are - // older versions over there. - content { - excludeGroup "com.facebook.react" - } - } + classpath("com.android.tools.build:gradle:7.3.1") + classpath("com.facebook.react:react-native-gradle-plugin") } } @@ -46,8 +24,8 @@ subprojects { afterEvaluate {project -> if (project.hasProperty("android")) { android { - compileSdkVersion 31 // same as project's compileSdkVersion - buildToolsVersion "31.0.0" // same as project's buildToolsVersion + compileSdkVersion 33 // same as project's compileSdkVersion + buildToolsVersion "33.0.0" // same as project's buildToolsVersion } } } diff --git a/Example/android/gradle.properties b/Example/android/gradle.properties index 113dcf9be..133abb602 100644 --- a/Example/android/gradle.properties +++ b/Example/android/gradle.properties @@ -9,8 +9,8 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -# Default value: -Xmx10248m -XX:MaxPermSize=256m -org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m +org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit @@ -29,7 +29,20 @@ APP_RELEASE_STORE_FILE=application-release-key.keystore APP_RELEASE_KEY_ALIAS=application-key-alias # Version of flipper SDK to use with React Native -FLIPPER_VERSION=0.99.0 - -#Version of Android NDK -ANDROID_NDK_VERSION=21.4.7075529 \ No newline at end of file +FLIPPER_VERSION=0.125.0 + +# Use this property to specify which architecture you want to build. +# You can also override it from the CLI using +# ./gradlew -PreactNativeArchitectures=x86_64 +reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 + +# Use this property to enable support to the new architecture. +# This will allow you to use TurboModules and the Fabric render in +# your application. You should enable this flag either if you want +# to write custom TurboModules/Fabric components OR use libraries that +# are providing them. +newArchEnabled=false + +# Use this property to enable or disable the Hermes JS engine. +# If set to false, you will be using JSC instead. +hermesEnabled=true \ No newline at end of file diff --git a/Example/android/gradle/wrapper/gradle-wrapper.jar b/Example/android/gradle/wrapper/gradle-wrapper.jar index 5c2d1cf01..41d9927a4 100644 Binary files a/Example/android/gradle/wrapper/gradle-wrapper.jar and b/Example/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/Example/android/gradle/wrapper/gradle-wrapper.properties b/Example/android/gradle/wrapper/gradle-wrapper.properties index a0f7639f7..8fad3f5a9 100644 --- a/Example/android/gradle/wrapper/gradle-wrapper.properties +++ b/Example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/Example/android/gradlew b/Example/android/gradlew index b1b5dec42..a58591e97 100755 --- a/Example/android/gradlew +++ b/Example/android/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,67 +17,101 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -106,85 +140,95 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' -exec "$JAVACMD" "$@" +exec "$JAVACMD" "$@" \ No newline at end of file diff --git a/Example/android/settings.gradle b/Example/android/settings.gradle index 135ce7104..d50e622e8 100644 --- a/Example/android/settings.gradle +++ b/Example/android/settings.gradle @@ -1,3 +1,4 @@ rootProject.name = 'Quiver UI' apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) -include ':app' \ No newline at end of file +include ':app' +includeBuild('../../node_modules/react-native-gradle-plugin') diff --git a/Example/index.js b/Example/index.ts similarity index 100% rename from Example/index.js rename to Example/index.ts diff --git a/Example/index.web.js b/Example/index.web.ts similarity index 100% rename from Example/index.web.js rename to Example/index.web.ts diff --git a/Example/ios/.xcode.env b/Example/ios/.xcode.env new file mode 100644 index 000000000..9d643e97a --- /dev/null +++ b/Example/ios/.xcode.env @@ -0,0 +1,10 @@ +# This `.xcode.env` file is versioned and is used to source the environment +# used when running script phases inside Xcode. +# To customize your local environment, you can create an `.xcode.env.local` +# file that is not versioned. +# NODE_BINARY variable contains the PATH to the node executable. +# +# Customize the NODE_BINARY variable here. +# For example, to use nvm with brew, add the following line +# . "$(brew --prefix nvm)/nvm.sh" --no-use +export NODE_BINARY=$(command -v node) \ No newline at end of file diff --git a/Example/ios/Podfile b/Example/ios/Podfile index 748472281..0c9119982 100644 --- a/Example/ios/Podfile +++ b/Example/ios/Podfile @@ -1,39 +1,69 @@ -platform :ios, '11.0' require_relative '../../node_modules/react-native/scripts/react_native_pods' require_relative '../../node_modules/@react-native-community/cli-platform-ios/native_modules' +platform :ios, min_ios_version_supported +prepare_react_native_project! +# If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. +# because `react-native-flipper` depends on (FlipperKit,...) that will be excluded +# +# To fix this you can also exclude `react-native-flipper` using a `react-native.config.js` +# ```js +# module.exports = { +# dependencies: { +# ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}), +# ``` +flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled +linkage = ENV['USE_FRAMEWORKS'] +if linkage != nil + Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green + use_frameworks! :linkage => linkage.to_sym +end + target 'Quiver UI' do config = use_native_modules! + # Flags change depending on the env values. + flags = get_default_flags() + use_react_native!( :path => "../../node_modules/react-native", - # to enable hermes on iOS, change `false` to `true` and then install pods - :hermes_enabled => true + # Hermes is now enabled by default. Disable by setting this flag to false. + # Upcoming versions of React Native may rely on get_default_flags(), but + # we make it explicit here to aid in the React Native upgrade process. + :hermes_enabled => flags[:hermes_enabled], + :fabric_enabled => flags[:fabric_enabled], + # Enables Flipper. + # + # Note that if you have use_frameworks! enabled, Flipper will not work and + # you should disable the next line. + :flipper_configuration => flipper_config, + # An absolute path to your application root. + :app_path => "#{Pod::Config.instance.installation_root}/.." ) permissions_path = '../../node_modules/react-native-permissions/ios' pod 'Permission-Camera', :path => "#{permissions_path}/Camera" - pod 'UIKitInputs', :path => "../../kit/inputs/UIKitInputs.podspec" - pod 'UIKitControls', :path => "../../kit/controls/UIKitControls.podspec" - pod 'UIKitMedia', :path => "../../kit/media/UIKitMedia.podspec" - pod 'UIKitScrolls', :path => "../../kit/scrolls/UIKitScrolls.podspec" - pod 'UIKitLayout', :path => "../../kit/layout/UIKitLayout.podspec" - pod 'UIKitLocalization', :path => "../../localization/UIKitLocalization.podspec" - pod 'UIKitKeyboard', :path => "../../casts/keyboard/UIKitKeyboard.podspec" + pod 'UIKitInputs', :path => "../../node_modules/@tonlabs/uikit.inputs" + pod 'UIKitControls', :path => "../../node_modules/@tonlabs/uikit.controls" + pod 'UIKitMedia', :path => "../../node_modules/@tonlabs/uikit.media" + pod 'UIKitScrolls', :path => "../../node_modules/@tonlabs/uikit.scrolls" + pod 'UIKitLayout', :path => "../../node_modules/@tonlabs/uikit.layout" + pod 'UIKitLocalization', :path => "../../node_modules/@tonlabs/localization" + pod 'UIKitKeyboard', :path => "../../node_modules/@tonlabs/uicast.keyboard" target 'Quiver UITests' do inherit! :complete # Pods for testing end - # Enables Flipper. - # - # Note that if you have use_frameworks! enabled, Flipper will not work and - # you should disable the next line. - use_flipper!() post_install do |installer| - react_native_post_install(installer) + react_native_post_install( + installer, + # Set `mac_catalyst_enabled` to `true` in order to apply patches + # necessary for Mac Catalyst builds + :mac_catalyst_enabled => false + ) __apply_Xcode_12_5_M1_post_install_workaround(installer) end end diff --git a/Example/ios/Quiver UI/AppDelegate.h b/Example/ios/Quiver UI/AppDelegate.h index ef1de86a2..5d2808256 100644 --- a/Example/ios/Quiver UI/AppDelegate.h +++ b/Example/ios/Quiver UI/AppDelegate.h @@ -1,8 +1,6 @@ -#import +#import #import -@interface AppDelegate : UIResponder - -@property (nonatomic, strong) UIWindow *window; +@interface AppDelegate : RCTAppDelegate @end diff --git a/Example/ios/Quiver UI/AppDelegate.mm b/Example/ios/Quiver UI/AppDelegate.mm index ccb0a6548..71598496f 100644 --- a/Example/ios/Quiver UI/AppDelegate.mm +++ b/Example/ios/Quiver UI/AppDelegate.mm @@ -1,8 +1,6 @@ #import "AppDelegate.h" -#import #import -#import #import #if __has_include() @@ -26,25 +24,6 @@ #import #import -#if DEBUG -#import -#import -#import -#import -#import -#import - -static void InitializeFlipper(UIApplication *application) { - FlipperClient *client = [FlipperClient sharedClient]; - SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; - [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]]; - [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; - [client addPlugin:[FlipperKitReactPlugin new]]; - [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; - [client start]; -} -#endif - @interface AppDelegate () @end @@ -53,38 +32,32 @@ @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { -#if DEBUG - InitializeFlipper(application); -#endif - - RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; - RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge - moduleName:@"UIKit" - initialProperties:nil]; - - if (@available(iOS 13.0, *)) { - rootView.backgroundColor = [UIColor systemBackgroundColor]; - } else { - rootView.backgroundColor = [UIColor whiteColor]; - } - - self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - UIViewController *rootViewController = [UIViewController new]; - rootViewController.view = rootView; - self.window.rootViewController = rootViewController; - [self.window makeKeyAndVisible]; - return YES; + self.moduleName = @"UIKit"; + // You can add your custom initial props in the dictionary below. + // They will be passed down to the ViewController used by React Native. + self.initialProps = @{}; + return [super application:application didFinishLaunchingWithOptions:launchOptions]; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG - return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; + return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; #else return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif } +/// This method controls whether the `concurrentRoot`feature of React18 is turned on or off. +/// +/// @see: https://reactjs.org/blog/2022/03/29/react-v18.html +/// @note: This requires to be rendering on Fabric (i.e. on the New Architecture). +/// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`. +- (BOOL)concurrentRootEnabled +{ + return true; +} + - (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge { const auto withUIKitKeyboardInstaller = tonlabs::uikit::UIKitKeyboardJSIExecutorInstaller(bridge, NULL); const auto withUIKitInputControllerInstaller = tonlabs::uikit::UIKitInputControllerJSIExecutorRuntimeInstaller(bridge, withUIKitKeyboardInstaller); diff --git a/Example/ios/Quiver UI/Info.plist b/Example/ios/Quiver UI/Info.plist index decb6dbcc..219c55fc9 100644 --- a/Example/ios/Quiver UI/Info.plist +++ b/Example/ios/Quiver UI/Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + $(MARKETING_VERSION) CFBundleSignature ???? CFBundleVersion - 1 + $(CURRENT_PROJECT_VERSION) LSRequiresIPhoneOS NSAppTransportSecurity diff --git a/Example/ios/Quiver UI/main.m b/Example/ios/Quiver UI/main.m index b1df44b95..d645c7246 100644 --- a/Example/ios/Quiver UI/main.m +++ b/Example/ios/Quiver UI/main.m @@ -2,7 +2,8 @@ #import "AppDelegate.h" -int main(int argc, char * argv[]) { +int main(int argc, char *argv[]) +{ @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } diff --git a/Example/package.json b/Example/package.json index a9a01af88..ba0c5aa98 100644 --- a/Example/package.json +++ b/Example/package.json @@ -9,8 +9,6 @@ "start": "npx react-native start", "test": "jest", "tsc": "tsc --noEmit --composite false", - "secret:reveal": "git secret reveal -f", - "secret:hide": "git secret hide -m && git add *.secret", "web": "webpack-dev-server -d --config webpack.config.js --progress --colors --host 0.0.0.0 --display-cached", "web:bundle": "webpack -p --config webpack.config.prod.js --progress --colors --display-error-details", "web:bundle:dev": "webpack -d --config webpack.config.js --progress --colors --display-error-details" @@ -64,9 +62,9 @@ "mobile-detect": "1.4.3", "moment": "2.29.4", "qrcode": "1.4.4", - "react": "17.0.2", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-animateable-text": "0.9.1", "react-native-blob-util": "^0.13.18", "react-native-camera": "3.44.3", @@ -94,27 +92,29 @@ "react-player": "^2.9.0" }, "devDependencies": { - "@babel/core": "^7.15.0", + "@babel/core": "^7.20.0", "@babel/eslint-plugin": "^7.14.5", "@babel/plugin-proposal-decorators": "^7.15.0", - "@babel/runtime": "^7.15.0", - "@react-native-community/eslint-config": "^0.0.5", + "@babel/runtime": "^7.20.0", + "@react-native-community/eslint-config": "^3.2.0", "@tonlabs/babel-plugin-transform-inline-consts": "*", - "babel-jest": "26.6.3", + "@types/react-test-renderer": "^18.0.0", + "babel-jest": "29.2.1", "babel-loader": "8.2.2", "babel-plugin-react-native-web": "0.17.7", "babel-plugin-transform-react-remove-prop-types": "0.4.24", "circular-dependency-plugin": "5.2.0", "css-loader": "^3.6.0", - "eslint": "7.32.0", + "eslint": "8.19.0", "file-loader": "6.2.0", - "jest": "26.6.3", + "jest": "29.2.1", "jetifier": "2.0.0", - "metro-react-native-babel-preset": "0.66.2", + "metro-react-native-babel-preset": "0.73.9", "patch-package": "6.4.7", - "prettier": "2.3.2", - "react-test-renderer": "17.0.2", + "prettier": "2.4.1", + "react-test-renderer": "18.2.0", "style-loader": "^1.2.1", + "typescript": "4.8.4", "webpack": "^4.43.0", "webpack-cli": "3.3.5", "webpack-dev-server": "3.7.2" diff --git a/Example/react-native.config.js b/Example/react-native.config.js new file mode 100644 index 000000000..8b0425586 --- /dev/null +++ b/Example/react-native.config.js @@ -0,0 +1,7 @@ +module.exports = { + project: { + ios: { + sourceDir: './ios', + }, + }, +}; diff --git a/Example/reinstall.sh b/Example/reinstall.sh index 430135419..e596bed0e 100755 --- a/Example/reinstall.sh +++ b/Example/reinstall.sh @@ -1,7 +1,6 @@ npx lerna bootstrap npx lerna run prepare -rvm use ruby-$(cat .ruby-version) bundle install cd ios @@ -14,7 +13,9 @@ then osascript -e "display notification \"Waiting for secret files revealing\" with title \"Quiver UI\"" fi +cd .. yarn run secret:reveal +cd Example if command -v osascript &> /dev/null then diff --git a/Example/src/App.tsx b/Example/src/App.tsx index b7d67443f..65669443c 100644 --- a/Example/src/App.tsx +++ b/Example/src/App.tsx @@ -85,7 +85,7 @@ const ThemeSwitcher = React.createContext({ toggleTheme: () => {}, }); -const Main = ({ navigation }: { navigation: any }) => { +function Main({ navigation }: { navigation: any }) { const [isSearchVisible, setIsSearchVisible] = React.useState(false); const tabBarBottomInset = useSplitTabBarHeight(); return ( @@ -296,7 +296,7 @@ const Main = ({ navigation }: { navigation: any }) => { ); -}; +} function useResetContent() { const [contentVisible, setContentVisible] = React.useState(true); @@ -313,7 +313,7 @@ function useResetContent() { }; } -const App = () => { +function App() { const navRef = React.useRef(null); useReduxDevToolsExtension(navRef); @@ -609,12 +609,23 @@ const App = () => { ); -}; +} -const AppWrapper = () => { +function AppWrapper() { const [isDarkTheme, setIsDarkTheme] = React.useState(false); const [isHidden, setIsHidden] = React.useState(false); + const themeSwitcherValue = React.useMemo(() => { + return { + isDarkTheme, + toggleTheme: () => { + setIsDarkTheme(!isDarkTheme); + setIsHidden(true); + setImmediate(() => setIsHidden(false)); + }, + }; + }, [isDarkTheme]); + if (isHidden) { return null; } @@ -622,16 +633,7 @@ const AppWrapper = () => { return ( - { - setIsDarkTheme(!isDarkTheme); - setIsHidden(true); - setImmediate(() => setIsHidden(false)); - }, - }} - > + @@ -641,7 +643,7 @@ const AppWrapper = () => { ); -}; +} const styles = StyleSheet.create({ body: { diff --git a/Example/src/screens/Buttons.tsx b/Example/src/screens/Buttons.tsx index 9cbffdea3..39cac911c 100644 --- a/Example/src/screens/Buttons.tsx +++ b/Example/src/screens/Buttons.tsx @@ -34,9 +34,9 @@ import { ColorVariants, UIBackgroundView, UILabel } from '@tonlabs/uikit.themes' import { ExampleSection } from '../components/ExampleSection'; import { ExampleScreen } from '../components/ExampleScreen'; -const Separator = () => ( - -); +function Separator() { + return ; +} export function ButtonsScreen() { const [progress, setProgress] = React.useState(false); diff --git a/Example/src/screens/Carousel.tsx b/Example/src/screens/Carousel.tsx index 5179221ca..1c62810fa 100644 --- a/Example/src/screens/Carousel.tsx +++ b/Example/src/screens/Carousel.tsx @@ -18,23 +18,29 @@ import { ExampleScreen } from '../components/ExampleScreen'; const DATA = ['Hello', 'this', 'is', 'UICarouselView']; +function Content({ title }: { title: string }) { + return ( + + + {title} + + ); +} + +function getComponent(title: string) { + return function CarouselComponent(): React.ReactElement { + return ; + }; +} + export function CarouselScreen() { const onPageIndexChange = (index: number) => { console.log('page changed', index); }; - const component = (title: string) => (): React.ReactElement => { - return ( - - - {title} - - ); - }; - const [pagingEnabled, setPagingEnabled] = React.useState(false); return ( @@ -53,7 +59,9 @@ export function CarouselScreen() { onPageIndexChange={onPageIndexChange} > {DATA.map(text => { - return ; + return ( + + ); })} diff --git a/Example/src/screens/Checkbox.tsx b/Example/src/screens/Checkbox.tsx index 84bb91b36..27eb83019 100644 --- a/Example/src/screens/Checkbox.tsx +++ b/Example/src/screens/Checkbox.tsx @@ -7,7 +7,7 @@ import { UILabel } from '@tonlabs/uikit.themes'; import { ExampleSection } from '../components/ExampleSection'; import { ExampleScreen } from '../components/ExampleScreen'; -export const Checkbox = () => { +export function Checkbox() { const [switcherSelected, setSwitcherSelected] = useState(false); return ( @@ -169,4 +169,4 @@ export const Checkbox = () => { ); -}; +} diff --git a/Example/src/screens/Images.tsx b/Example/src/screens/Images.tsx index 277298f8b..9137a9cb4 100644 --- a/Example/src/screens/Images.tsx +++ b/Example/src/screens/Images.tsx @@ -49,8 +49,10 @@ function DuplicateImageCheck() { ); } -export const Images = () => ( - - - -); +export function Images() { + return ( + + + + ); +} diff --git a/Example/src/screens/Inputs.tsx b/Example/src/screens/Inputs.tsx index 5633a360a..ab5d16787 100644 --- a/Example/src/screens/Inputs.tsx +++ b/Example/src/screens/Inputs.tsx @@ -19,7 +19,7 @@ import { UIImage } from '@tonlabs/uikit.media'; import { ExampleSection } from '../components/ExampleSection'; import { ExampleScreen } from '../components/ExampleScreen'; -export const Inputs = () => { +export function Inputs() { const amountPrecisionRef = React.useRef(null); const mnemonicWords = ['report', 'village', 'slight']; const onChangeAmount = React.useCallback((amount: BigNumber | undefined) => { @@ -279,4 +279,4 @@ export const Inputs = () => { ); -}; +} diff --git a/Example/src/screens/Menus.tsx b/Example/src/screens/Menus.tsx index 130d2b35f..a6b90b702 100644 --- a/Example/src/screens/Menus.tsx +++ b/Example/src/screens/Menus.tsx @@ -320,7 +320,7 @@ function FlexibleSizeBottomSheet() { ); } -export const Menus = () => { +export function Menus() { const [actionSheetVisible, setActionSheetVisible] = React.useState(false); const [cardSheetVisible, setCardSheetVisible] = React.useState(false); const [cardSheet2Visible, setCardSheet2Visible] = React.useState(false); @@ -646,4 +646,4 @@ export const Menus = () => { ); -}; +} diff --git a/Example/src/screens/Navigation.tsx b/Example/src/screens/Navigation.tsx index 4b612059c..168420137 100644 --- a/Example/src/screens/Navigation.tsx +++ b/Example/src/screens/Navigation.tsx @@ -15,17 +15,19 @@ import { UIAssets } from '@tonlabs/uikit.assets'; import { ExampleSection } from '../components/ExampleSection'; import { ExampleScreen } from '../components/ExampleScreen'; -const component = (color: ColorValue) => (): React.ReactElement => - ( - - ); +const component = (color: ColorValue) => + function NavigationComponent(): React.ReactElement { + return ( + + ); + }; -export const Navigation = () => { +export function Navigation() { const [isSearchControllerVisible, setSearchControllerVisible] = React.useState(false); const [isSearchBarVisible, setSearchBarVisible] = React.useState(false); @@ -499,4 +501,4 @@ export const Navigation = () => { ); -}; +} diff --git a/Example/src/screens/Products.tsx b/Example/src/screens/Products.tsx index 599b35a8b..9f2d68dd9 100644 --- a/Example/src/screens/Products.tsx +++ b/Example/src/screens/Products.tsx @@ -11,7 +11,7 @@ import { UIPromoNotice } from '@tonlabs/uicast.promo-notice'; import { ExampleSection } from '../components/ExampleSection'; import { ExampleScreen } from '../components/ExampleScreen'; -export const Products = () => { +export function Products() { const [displayPromoNotice, setDisplayPromoNotice] = useState(false); return ( @@ -48,4 +48,4 @@ export const Products = () => { ); -}; +} diff --git a/Example/src/screens/Text.tsx b/Example/src/screens/Text.tsx index 5933cca0a..0588f36ab 100644 --- a/Example/src/screens/Text.tsx +++ b/Example/src/screens/Text.tsx @@ -42,7 +42,7 @@ function TypographyList() { ); } -export const TextScreen = () => { +export function TextScreen() { const [allTypograpyVisible, setAllTypograpyVisible] = React.useState(false); return ( @@ -109,4 +109,4 @@ export const TextScreen = () => { ); -}; +} diff --git a/Example/webpack.js b/Example/webpack.js index a7e02742e..4026f051c 100644 --- a/Example/webpack.js +++ b/Example/webpack.js @@ -2,7 +2,7 @@ const path = require('path'); module.exports = { - entry: path.join(__dirname, './index.web.js'), + entry: path.join(__dirname, './index.web.ts'), output: { path: path.join(__dirname, './web/assets'), publicPath: 'assets/', @@ -14,7 +14,7 @@ module.exports = { test: /\.(j|t)sx?$/, // exclude: /node_modules/, include: [ - path.resolve(__dirname, './index.web.js'), + path.resolve(__dirname, './index.web.ts'), path.resolve(__dirname, './src/'), path.resolve(__dirname, '../node_modules/react-native-web/'), path.resolve(__dirname, '../packages/'), @@ -31,6 +31,7 @@ module.exports = { path.resolve(__dirname, '../node_modules/react-native-reanimated/'), path.resolve(__dirname, '../node_modules/react-native-view-shot/'), path.resolve(__dirname, '../node_modules/react-native-web-linear-gradient/'), + path.resolve(__dirname, '../node_modules/@react-navigation/'), ], loader: 'babel-loader', query: { diff --git a/casts/accountPicker/package.json b/casts/accountPicker/package.json index 9f4a771d7..f6570d5e1 100644 --- a/casts/accountPicker/package.json +++ b/casts/accountPicker/package.json @@ -38,18 +38,18 @@ "@tonlabs/uikit.themes": "^4.1.0" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5" + "react-native": "^0.71.6" }, "react-native-builder-bob": { "source": "src", diff --git a/casts/addressText/package.json b/casts/addressText/package.json index 8cf29ba8b..b29dcd664 100644 --- a/casts/addressText/package.json +++ b/casts/addressText/package.json @@ -40,11 +40,11 @@ "@tonlabs/uikit.themes": "^4.1.0" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-animateable-text": "0.9.1", "react-native-builder-bob": "^0.18.2", "react-native-gesture-handler": "^2.9.0", @@ -55,12 +55,12 @@ "react-native-safe-area-context": "^3.3.2", "react-native-svg": "^12.3.0", "react-native-view-shot": "^3.1.2", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5", + "react-native": "^0.71.6", "react-native-animateable-text": "^0.9.1", "react-native-gesture-handler": "^2.9.0", "react-native-linear-gradient": "^2.5.6", diff --git a/casts/banner/package.json b/casts/banner/package.json index d4441f776..0581ffe4f 100644 --- a/casts/banner/package.json +++ b/casts/banner/package.json @@ -38,22 +38,22 @@ "@tonlabs/uikit.themes": "^4.1.0" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "2.14.4", "react-native-redash": "^16.0.11", "react-native-svg": "^12.3.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5", + "react-native": "^0.71.6", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "^2.14.4", "react-native-redash": "^16.0.11", diff --git a/casts/bars/package.json b/casts/bars/package.json index 402eb14e6..b2591a0de 100644 --- a/casts/bars/package.json +++ b/casts/bars/package.json @@ -47,11 +47,11 @@ "react-native-safe-area-context": "^3.3.2" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-gesture-handler": "^2.9.0", "react-native-linear-gradient": "^2.5.6", @@ -59,12 +59,12 @@ "react-native-reanimated": "2.14.4", "react-native-redash": "^16.0.11", "react-native-svg": "^12.3.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5", + "react-native": "^0.71.6", "react-native-gesture-handler": "^2.9.0", "react-native-linear-gradient": "^2.5.6", "react-native-pager-view": "^5.4.9", diff --git a/casts/bars/src/UIHeaderItems.tsx b/casts/bars/src/UIHeaderItems.tsx index 74854c9a8..bc7a6f10c 100644 --- a/casts/bars/src/UIHeaderItems.tsx +++ b/casts/bars/src/UIHeaderItems.tsx @@ -100,16 +100,14 @@ function UIHeaderItemPressable({ children: React.ReactNode; }) { return ( - <> - - {children} - - + + {children} + ); } @@ -124,11 +122,7 @@ function UIHeaderItem(item: HeaderItem) { } if (icon != null || iconElement != null) { return ( - + ); diff --git a/casts/bars/src/UILargeTitleHeader/RefreshControl.tsx b/casts/bars/src/UILargeTitleHeader/RefreshControl.tsx index c5c3707a5..9de799c39 100644 --- a/casts/bars/src/UILargeTitleHeader/RefreshControl.tsx +++ b/casts/bars/src/UILargeTitleHeader/RefreshControl.tsx @@ -71,9 +71,11 @@ export function RefreshControl({ refreshingGuard.value = true; setRefreshing(true); - // If onResresh is blocking it can prevent loader to draw + // If onRefresh is blocking it can prevent loader to draw // so that start it only when update is done - await new Promise(res => requestAnimationFrame(res)); + await new Promise(res => { + requestAnimationFrame(res); + }); try { await allSettled([ @@ -90,7 +92,7 @@ export function RefreshControl({ console.warn('Unhandled error has been caught during the refresh:', err); } } finally { - // Do not interupt active scroll + // Do not interrupt active scroll if (scrollInProgress.value) { stopRefreshing(); waitForScrollEnd.value = true; diff --git a/casts/cards/package.json b/casts/cards/package.json index b5673620c..e8cc50f3a 100644 --- a/casts/cards/package.json +++ b/casts/cards/package.json @@ -41,22 +41,22 @@ "@tonlabs/uikit.themes": "^4.1.0" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-fast-image": "^8.5.11", "react-native-gesture-handler": "^2.9.0", "react-native-linear-gradient": "^2.5.6", "react-native-reanimated": "2.14.4", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5", + "react-native": "^0.71.6", "react-native-fast-image": "^8.5.11", "react-native-gesture-handler": "^2.9.0", "react-native-linear-gradient": "^2.5.6", diff --git a/casts/carouselView/package.json b/casts/carouselView/package.json index fbb318f20..bc363b748 100644 --- a/casts/carouselView/package.json +++ b/casts/carouselView/package.json @@ -41,23 +41,23 @@ }, "devDependencies": { "@types/lodash": "^4.14.175", - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-gesture-handler": "^2.9.0", "react-native-pager-view": "^5.4.9", "react-native-reanimated": "2.14.4", "react-native-redash": "^16.0.11", "react-native-svg": "^12.3.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5", + "react-native": "^0.71.6", "react-native-gesture-handler": "^2.9.0", "react-native-pager-view": "^5.4.9", "react-native-reanimated": "^2.14.4", diff --git a/casts/carouselView/src/UICarouselView/CarouselView/UICarouselViewPage.tsx b/casts/carouselView/src/UICarouselView/CarouselView/UICarouselViewPage.tsx index 1c2c74080..ec5a460eb 100644 --- a/casts/carouselView/src/UICarouselView/CarouselView/UICarouselViewPage.tsx +++ b/casts/carouselView/src/UICarouselView/CarouselView/UICarouselViewPage.tsx @@ -1,3 +1,5 @@ import type { UICarouselViewPageProps } from '../types'; -export const UICarouselViewPage: React.FC = () => null; +export function UICarouselViewPage(_props: UICarouselViewPageProps) { + return null; +} diff --git a/casts/carouselView/src/UICarouselView/CarouselView/usePages.tsx b/casts/carouselView/src/UICarouselView/CarouselView/usePages.tsx index 121efdf4a..98ecd4c51 100644 --- a/casts/carouselView/src/UICarouselView/CarouselView/usePages.tsx +++ b/casts/carouselView/src/UICarouselView/CarouselView/usePages.tsx @@ -13,7 +13,7 @@ export function getPages(children: React.ReactNode): React.ReactElement[] = acc; if (child.type === UICarouselViewPage) { - pages.push(child); + pages.push(child as React.ReactElement); return pages; } diff --git a/casts/countryPicker/package.json b/casts/countryPicker/package.json index a694d712b..856e034cb 100644 --- a/casts/countryPicker/package.json +++ b/casts/countryPicker/package.json @@ -47,22 +47,22 @@ "react-native-safe-area-context": "^3.3.2" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "2.14.4", "react-native-redash": "^16.0.11", "react-native-svg": "^12.3.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5", + "react-native": "^0.71.6", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "^2.14.4", "react-native-redash": "^16.0.11", diff --git a/casts/countryPicker/src/UICountryPicker/CountryPicker.tsx b/casts/countryPicker/src/UICountryPicker/CountryPicker.tsx index 319312823..da08d89b4 100644 --- a/casts/countryPicker/src/UICountryPicker/CountryPicker.tsx +++ b/casts/countryPicker/src/UICountryPicker/CountryPicker.tsx @@ -186,10 +186,14 @@ function CountryPickerContent({ banned, permitted, onClose, onSelect }: CountryP const { loading, searching, countries, onSearch } = useCountriesSearch(banned, permitted); + const countryPickerContextValue = React.useMemo(() => { + return { loading, onSelect }; + }, [loading, onSelect]); + return ( <> - + = ({ item }: CountryRowProps) => { +export function CountryPickerRow({ item }: CountryRowProps) { const { onSelect } = React.useContext(CountryPickerContext); const theme = useTheme(); @@ -41,7 +41,7 @@ export const CountryPickerRow: React.FC = ({ item }: CountryRow ); -}; +} const useStyles = makeStyles((theme: Theme) => ({ rowContainerInner: { diff --git a/casts/countryPicker/src/UICountryPicker/ListEmptyComponent.tsx b/casts/countryPicker/src/UICountryPicker/ListEmptyComponent.tsx index 07f4a6830..a19485bf2 100644 --- a/casts/countryPicker/src/UICountryPicker/ListEmptyComponent.tsx +++ b/casts/countryPicker/src/UICountryPicker/ListEmptyComponent.tsx @@ -22,7 +22,7 @@ function renderEmptyList() { ); } -export const ListEmptyComponent = () => { +export function ListEmptyComponent() { const { loading } = React.useContext(CountryPickerContext); const renderContent = React.useMemo(() => { @@ -33,7 +33,7 @@ export const ListEmptyComponent = () => { }, [loading]); return {renderContent}; -}; +} const styles = StyleSheet.create({ emptyContainer: { diff --git a/casts/dateTimePicker/package.json b/casts/dateTimePicker/package.json index 8338435fd..ace197983 100644 --- a/casts/dateTimePicker/package.json +++ b/casts/dateTimePicker/package.json @@ -47,22 +47,22 @@ "dayjs": "1.9.1" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "2.14.4", "react-native-redash": "^16.0.11", "react-native-svg": "^12.3.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5", + "react-native": "^0.71.6", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "^2.14.4", "react-native-redash": "^16.0.11", diff --git a/casts/dateTimePicker/src/UIDateTimePicker/DateTimePicker.tsx b/casts/dateTimePicker/src/UIDateTimePicker/DateTimePicker.tsx index 1a28999d0..ac77047fc 100644 --- a/casts/dateTimePicker/src/UIDateTimePicker/DateTimePicker.tsx +++ b/casts/dateTimePicker/src/UIDateTimePicker/DateTimePicker.tsx @@ -74,27 +74,19 @@ function Content() { const { mode } = useDateTimeState(); switch (mode) { - default: - case UIDateTimePickerMode.DateTime: - return ( - <> - - - ); -}; +} diff --git a/casts/modalNavigator/package.json b/casts/modalNavigator/package.json index e5244acf7..3426db301 100644 --- a/casts/modalNavigator/package.json +++ b/casts/modalNavigator/package.json @@ -42,23 +42,23 @@ "devDependencies": { "@react-navigation/native": "^5.9.8", "@types/lodash": "^4.14.175", - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "2.14.4", "react-native-redash": "^16.0.11", "react-native-svg": "^12.3.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { "@react-navigation/native": "^5.9.8", - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5", + "react-native": "^0.71.6", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "^2.14.4", "react-native-redash": "^16.0.11", diff --git a/casts/modalNavigator/src/ModalNavigator/createModalNavigator.tsx b/casts/modalNavigator/src/ModalNavigator/createModalNavigator.tsx index 9edeb3398..5d82c0cfc 100644 --- a/casts/modalNavigator/src/ModalNavigator/createModalNavigator.tsx +++ b/casts/modalNavigator/src/ModalNavigator/createModalNavigator.tsx @@ -48,7 +48,7 @@ function ModalScreen({ ); } -const ModalNavigator = ({ children, maxMobileWidth, screenOptions }: ModalNavigatorProps) => { +function ModalNavigator({ children, maxMobileWidth, screenOptions }: ModalNavigatorProps) { const { state, navigation, descriptors } = useNavigationBuilder< ModalNavigationState, ModalRouterOptions, @@ -84,7 +84,7 @@ const ModalNavigator = ({ children, maxMobileWidth, screenOptions }: ModalNaviga ); -}; +} export const createModalNavigator = createNavigatorFactory< ModalNavigationState, diff --git a/casts/numbers/package.json b/casts/numbers/package.json index e0cedd5be..4a9a141c6 100644 --- a/casts/numbers/package.json +++ b/casts/numbers/package.json @@ -40,22 +40,22 @@ "bignumber.js": "9.0.0" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "2.14.4", "react-native-redash": "^16.0.11", "react-native-svg": "^12.3.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5", + "react-native": "^0.71.6", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "^2.14.4", "react-native-redash": "^16.0.11", diff --git a/casts/pagerView/package.json b/casts/pagerView/package.json index c998fc762..31aa950c1 100644 --- a/casts/pagerView/package.json +++ b/casts/pagerView/package.json @@ -39,22 +39,22 @@ "react-native-tab-view": "3.0.1" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "2.14.4", "react-native-redash": "^16.0.11", "react-native-svg": "^12.3.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5", + "react-native": "^0.71.6", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "^2.14.4", "react-native-redash": "^16.0.11", diff --git a/casts/pagerView/src/UIPagerView/UIPagerViewContainer.tsx b/casts/pagerView/src/UIPagerView/UIPagerViewContainer.tsx index c93b6d62f..5e99312fc 100644 --- a/casts/pagerView/src/UIPagerView/UIPagerViewContainer.tsx +++ b/casts/pagerView/src/UIPagerView/UIPagerViewContainer.tsx @@ -147,18 +147,17 @@ const getLabelColor = ( return UILabelColors.TextSecondary; }; -const renderLabel = - (pages: React.ReactElement[]) => - (props: LabelProps): React.ReactElement | null => { +const renderLabel = (pages: React.ReactElement[]) => + function Label(props: LabelProps): React.ReactElement | null { + const { focused, route } = props; const currentPage: React.ReactElement | undefined = pages.find( (page: React.ReactElement): boolean => - page.props.id === props.route.key, + page.props.id === route.key, ); if (!currentPage) { return null; } - const { focused, route } = props; const color: ColorVariants = getLabelColor(focused, currentPage); return ( @@ -269,13 +268,13 @@ const useTabBar = ( [pages, indicatorColor, indicatorContainerColor, type], ); -export const UIPagerViewContainer: React.FC = ({ +export function UIPagerViewContainer({ type, initialPageIndex = 0, onPageIndexChange, children, testID, -}: UIPagerViewContainerProps) => { +}: UIPagerViewContainerProps) { const theme = useTheme(); const [layout, setLayout] = React.useState({ x: 0, @@ -330,7 +329,7 @@ export const UIPagerViewContainer: React.FC = ({ /> ); -}; +} const styles = StyleSheet.create({ container: { diff --git a/casts/pagerView/src/UIPagerView/UIPagerViewPage.tsx b/casts/pagerView/src/UIPagerView/UIPagerViewPage.tsx index a0b2c7130..c330d724d 100644 --- a/casts/pagerView/src/UIPagerView/UIPagerViewPage.tsx +++ b/casts/pagerView/src/UIPagerView/UIPagerViewPage.tsx @@ -1,5 +1,5 @@ -import type * as React from 'react'; - import type { UIPagerViewPageProps } from './types'; -export const UIPagerViewPage: React.FC = () => null; +export function UIPagerViewPage(_props: UIPagerViewPageProps) { + return null; +} diff --git a/casts/pinCode/package.json b/casts/pinCode/package.json index d6d4478a1..6a2827c6e 100644 --- a/casts/pinCode/package.json +++ b/casts/pinCode/package.json @@ -41,22 +41,22 @@ "@tonlabs/uikit.themes": "^4.1.0" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "2.14.4", "react-native-redash": "^16.0.11", "react-native-svg": "^12.3.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5", + "react-native": "^0.71.6", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "^2.14.4", "react-native-redash": "^16.0.11", diff --git a/casts/promoNotice/package.json b/casts/promoNotice/package.json index d75ae5873..7f8305406 100644 --- a/casts/promoNotice/package.json +++ b/casts/promoNotice/package.json @@ -42,23 +42,23 @@ "@tonlabs/uikit.themes": "^4.1.0" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-gesture-handler": "^2.9.0", "react-native-linear-gradient": "^2.5.6", "react-native-reanimated": "2.14.4", "react-native-redash": "^16.0.11", "react-native-svg": "^12.3.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5", + "react-native": "^0.71.6", "react-native-gesture-handler": "^2.9.0", "react-native-linear-gradient": "^2.5.6", "react-native-reanimated": "^2.14.4", diff --git a/casts/qrCodeScannerSheet/package.json b/casts/qrCodeScannerSheet/package.json index 493005d52..6cdcc7233 100644 --- a/casts/qrCodeScannerSheet/package.json +++ b/casts/qrCodeScannerSheet/package.json @@ -44,11 +44,11 @@ "react-qr-reader": "^2.2.1" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-camera": "^3.44.3", "react-native-gesture-handler": "^2.9.0", @@ -56,12 +56,12 @@ "react-native-reanimated": "2.14.4", "react-native-redash": "^16.0.11", "react-native-svg": "^12.3.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5", + "react-native": "^0.71.6", "react-native-camera": "^3.44.3", "react-native-gesture-handler": "^2.9.0", "react-native-qrcode-scanner": "^1.5.4", diff --git a/casts/qrCodeScannerSheet/src/QRCodeScanner/QRCodeScanner.web.tsx b/casts/qrCodeScannerSheet/src/QRCodeScanner/QRCodeScanner.web.tsx index bff9fa3b2..91e267ff5 100644 --- a/casts/qrCodeScannerSheet/src/QRCodeScanner/QRCodeScanner.web.tsx +++ b/casts/qrCodeScannerSheet/src/QRCodeScanner/QRCodeScanner.web.tsx @@ -25,18 +25,23 @@ enum QR_CODE_ERROR { UNRECOGNIZED = 2, } -export function QRCodeScanner(props: QRCodeScannerProps) { +export function QRCodeScanner({ + containerStyle, + onRead, + reactivate, + reactivateTimeout, +}: QRCodeScannerProps) { const [qrCodeError, setQrCodeError] = React.useState(QR_CODE_ERROR.NONE); if (qrCodeError === QR_CODE_ERROR.NONE) { return ( - + { if (data == null) { return; } - props.onRead({ data }); + onRead({ data }); }} onError={(err: DOMException) => { if (/Permission denied/.test(err.message)) { @@ -47,14 +52,14 @@ export function QRCodeScanner(props: QRCodeScannerProps) { }} showViewFinder={false} resolution={UILayoutConstant.elasticWidthCardSheet} - delay={props.reactivate ? props.reactivateTimeout || 500 : false} + delay={reactivate ? reactivateTimeout || 500 : false} /> ); } if (qrCodeError === QR_CODE_ERROR.PERMISSION) { return ( - + + = ({ source }: IconProps) => { +export function Icon({ source }: IconProps) { if (!source) { return null; } return ; -}; +} const styles = StyleSheet.create({ image: { diff --git a/casts/rows/src/UILink/Logo.tsx b/casts/rows/src/UILink/Logo.tsx index 7fd841ea6..be8a590d7 100644 --- a/casts/rows/src/UILink/Logo.tsx +++ b/casts/rows/src/UILink/Logo.tsx @@ -5,7 +5,7 @@ import { UILayoutConstant, UISkeleton } from '@tonlabs/uikit.layout'; import type { LogoProps } from './types'; import { UIConstant } from '../constants'; -export const Logo: React.FC = ({ logo, loading }: LogoProps) => { +export function Logo({ logo, loading }: LogoProps) { if (loading) { return ( @@ -27,7 +27,7 @@ export const Logo: React.FC = ({ logo, loading }: LogoProps) => { ); -}; +} const styles = StyleSheet.create({ container: { diff --git a/casts/splitNavigator/package.json b/casts/splitNavigator/package.json index 90cfa84f6..01be06dc1 100644 --- a/casts/splitNavigator/package.json +++ b/casts/splitNavigator/package.json @@ -46,11 +46,11 @@ "@react-navigation/elements": "^1.2.1", "@react-navigation/native": "^5.9.8", "@react-navigation/stack": "^5.14.9", - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "2.14.4", @@ -58,16 +58,16 @@ "react-native-screens": "3.19.0", "react-native-simple-shadow-view": "1.6.3", "react-native-svg": "^12.3.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { "@react-navigation/core": "^5.16.1", "@react-navigation/elements": "^1.2.1", "@react-navigation/native": "^5.9.8", "@react-navigation/stack": "^5.14.9", - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5", + "react-native": "^0.71.6", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "^2.14.4", "react-native-redash": "^16.0.11", diff --git a/casts/splitNavigator/src/SplitNavigator/ScreenFallback.tsx b/casts/splitNavigator/src/SplitNavigator/ScreenFallback.tsx index 1ad849f39..c8c65ec0f 100644 --- a/casts/splitNavigator/src/SplitNavigator/ScreenFallback.tsx +++ b/casts/splitNavigator/src/SplitNavigator/ScreenFallback.tsx @@ -18,19 +18,19 @@ try { // Ignore } -export const MaybeScreenContainer = ({ +export function MaybeScreenContainer({ enabled, ...rest }: ViewProps & { enabled: boolean; children: React.ReactNode; -}) => { +}) { if (Screens?.screensEnabled?.()) { return ; } return ; -}; +} function MaybeNativeScreen({ visible, children, ...rest }: Props) { const Screen = React.useContext( diff --git a/casts/stackNavigator/package.json b/casts/stackNavigator/package.json index 083dd340c..d16075e58 100644 --- a/casts/stackNavigator/package.json +++ b/casts/stackNavigator/package.json @@ -42,25 +42,25 @@ "devDependencies": { "@react-navigation/native": "^5.9.8", "@react-navigation/stack": "^5.14.9", - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "2.14.4", "react-native-redash": "^16.0.11", "react-native-screens": "3.19.0", "react-native-svg": "^12.3.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { "@react-navigation/native": "^5.9.8", "@react-navigation/stack": "^5.14.9", - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5", + "react-native": "^0.71.6", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "^2.14.4", "react-native-redash": "^16.0.11", diff --git a/casts/stackNavigator/src/StackNavigator/createStackNavigator.tsx b/casts/stackNavigator/src/StackNavigator/createStackNavigator.tsx index a9386ee0d..c5b0460c7 100644 --- a/casts/stackNavigator/src/StackNavigator/createStackNavigator.tsx +++ b/casts/stackNavigator/src/StackNavigator/createStackNavigator.tsx @@ -60,11 +60,11 @@ const processScreenOptions = ( return { ...screenOptions, ...commonOptions }; }; -export const StackNavigator = ({ +export function StackNavigator({ children, initialRouteName, screenOptions, -}: SurfStackNavigatorProps) => { +}: SurfStackNavigatorProps) { const doesSupportNative = Platform.OS !== 'web' && screensEnabled?.(); const { @@ -131,6 +131,6 @@ export const StackNavigator = ({ descriptors={descriptors} /> ); -}; +} export const createStackNavigator = createNavigatorFactory(StackNavigator); diff --git a/casts/texts/package.json b/casts/texts/package.json index 42bdbcb90..2d4e4ce9f 100644 --- a/casts/texts/package.json +++ b/casts/texts/package.json @@ -39,18 +39,18 @@ "@tonlabs/uikit.themes": "^4.1.0" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "^17.0.2", + "react": "^18.2.0", "react-dom": "^17.0.2", - "react-native": "^0.67.5" + "react-native": "^0.71.6" }, "react-native-builder-bob": { "source": "src", diff --git a/jest.config.js b/jest.config.js index a0cb9ad34..794605976 100644 --- a/jest.config.js +++ b/jest.config.js @@ -4,9 +4,9 @@ module.exports = { preset: 'react-native', setupFilesAfterEnv: ['@testing-library/jest-native/extend-expect'], collectCoverage: true, - collectCoverageFrom: ['packages/**/*.[jt]s', '!**/node_modules/**'], + collectCoverageFrom: ['./**/*.[jt]s', '!**/node_modules/**'], moduleFileExtensions: ['js', 'json', 'json5', 'jsx', 'ts', 'tsx'], - roots: ['packages/'], + roots: ['./'], transformIgnorePatterns: [ '/node_modules/(?!@react-native|react-native|@react-navigation|react-native-blob-util|jest|)', ], diff --git a/kit/assets/package.json b/kit/assets/package.json index 2a6dd2f3f..d542632d6 100644 --- a/kit/assets/package.json +++ b/kit/assets/package.json @@ -35,7 +35,7 @@ ], "devDependencies": { "react-native-builder-bob": "^0.18.2", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "react-native-builder-bob": { "source": "src", diff --git a/kit/controls/package.json b/kit/controls/package.json index c88d98833..cf068f17c 100644 --- a/kit/controls/package.json +++ b/kit/controls/package.json @@ -41,22 +41,22 @@ "@tonlabs/uikit.themes": "^4.1.0" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "2.14.4", "react-native-redash": "^16.0.11", "react-native-svg": "^12.3.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "17.0.2", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "^2.14.4", "react-native-redash": "^16.0.11", diff --git a/kit/controls/src/Button/TouchableElement/TouchableElement.native.tsx b/kit/controls/src/Button/TouchableElement/TouchableElement.native.tsx index 2d8cb38d5..954e11c57 100644 --- a/kit/controls/src/Button/TouchableElement/TouchableElement.native.tsx +++ b/kit/controls/src/Button/TouchableElement/TouchableElement.native.tsx @@ -7,7 +7,7 @@ import { BUTTON_WITH_SPRING_CONFIG } from '../../constants'; import type { TouchableElementProps } from './types'; -export const TouchableElement = ({ +export function TouchableElement({ animations, children, disabled, @@ -18,7 +18,7 @@ export const TouchableElement = ({ contentStyle, testID, ...props -}: TouchableElementProps) => { +}: TouchableElementProps) { const { press, title, icon } = animations; const handlePressIn = () => { @@ -70,7 +70,7 @@ export const TouchableElement = ({ ); -}; +} const styles = StyleSheet.create({ overlayContainer: { diff --git a/kit/controls/src/Button/TouchableElement/TouchableElement.web.tsx b/kit/controls/src/Button/TouchableElement/TouchableElement.web.tsx index 59c2dc850..84bf3aec9 100644 --- a/kit/controls/src/Button/TouchableElement/TouchableElement.web.tsx +++ b/kit/controls/src/Button/TouchableElement/TouchableElement.web.tsx @@ -7,7 +7,7 @@ import { BUTTON_WITH_SPRING_CONFIG } from '../../constants'; import type { TouchableElementProps } from './types'; -export const TouchableElement = ({ +export function TouchableElement({ animations, children, disabled, @@ -18,7 +18,7 @@ export const TouchableElement = ({ contentStyle, testID, ...props -}: TouchableElementProps) => { +}: TouchableElementProps) { const { hover, press, title, icon } = animations; const { isHovered, onMouseEnter, onMouseLeave } = useHover(); @@ -108,7 +108,7 @@ export const TouchableElement = ({ ); -}; +} const styles = StyleSheet.create({ overlayContainer: { diff --git a/kit/controls/src/TouchableOpacity/TouchableOpacity.web.tsx b/kit/controls/src/TouchableOpacity/TouchableOpacity.web.tsx index 75a0a06c2..49d00eff1 100644 --- a/kit/controls/src/TouchableOpacity/TouchableOpacity.web.tsx +++ b/kit/controls/src/TouchableOpacity/TouchableOpacity.web.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { TouchableOpacity as RNTouchableOpacity } from 'react-native'; +import { TouchableOpacity as RNTouchableOpacity, StyleProp, ViewStyle } from 'react-native'; import type { TouchableOpacityProps } from './types'; export const TouchableOpacity = React.forwardRef( @@ -17,7 +17,7 @@ export const TouchableOpacity = React.forwardRef { + const styleProp = React.useMemo>(() => { let s = null; if (containerStyle) { if (s == null) { diff --git a/kit/controls/src/UIBoxButton/BoxButtonContent.tsx b/kit/controls/src/UIBoxButton/BoxButtonContent.tsx index d71390c9d..dcc44416e 100644 --- a/kit/controls/src/UIBoxButton/BoxButtonContent.tsx +++ b/kit/controls/src/UIBoxButton/BoxButtonContent.tsx @@ -16,14 +16,14 @@ import type { UIBoxButtonProps } from './types'; import { usePressableContentColor } from '../Pressable'; import { UIIndicator } from '../UIIndicator'; -export const BoxButtonContent = ({ +export function BoxButtonContent({ icon, iconPosition = UIBoxButtonIconPosition.Left, loading, title, type = UIBoxButtonType.Primary, variant = UIBoxButtonVariant.Neutral, -}: UIBoxButtonProps) => { +}: UIBoxButtonProps) { const backgroundColor = usePressableContentColor(ContentColors[type][variant].background); const contentColor = usePressableContentColor(ContentColors[type][variant].content); const backgroundOverlayColor = usePressableContentColor(BackgroundOverlayColors); @@ -112,7 +112,7 @@ export const BoxButtonContent = ({ )} ); -}; +} const styles = StyleSheet.create({ container: { diff --git a/kit/controls/src/UILoadMoreButton.tsx b/kit/controls/src/UILoadMoreButton.tsx index 4693597ac..caabf1235 100644 --- a/kit/controls/src/UILoadMoreButton.tsx +++ b/kit/controls/src/UILoadMoreButton.tsx @@ -20,11 +20,11 @@ type Props = { onLoadMore?: () => void; }; -export const UILoadMoreButton: React.FunctionComponent = ({ +export function UILoadMoreButton({ label = uiLocalized.LoadMore, isLoadingMore = false, onLoadMore, -}: Props) => { +}: Props) { const theme = useTheme(); return ( @@ -64,7 +64,7 @@ export const UILoadMoreButton: React.FunctionComponent = ({ ); -}; +} const styles = StyleSheet.create({ container: { diff --git a/kit/controls/src/UIMsgButton/MsgButtonContent.tsx b/kit/controls/src/UIMsgButton/MsgButtonContent.tsx index ac536f6db..0c4d62c6e 100644 --- a/kit/controls/src/UIMsgButton/MsgButtonContent.tsx +++ b/kit/controls/src/UIMsgButton/MsgButtonContent.tsx @@ -15,7 +15,7 @@ import type { UIMsgButtonProps } from './types'; import { UIIndicator } from '../UIIndicator'; import { useColorValues, useCornerStyle } from './hooks'; -export const MsgButtonContent = ({ +export function MsgButtonContent({ icon, iconPosition = UIMsgButtonIconPosition.Left, loading, @@ -24,7 +24,7 @@ export const MsgButtonContent = ({ cornerPosition, type = UIMsgButtonType.Primary, variant = UIMsgButtonVariant.Neutral, -}: UIMsgButtonProps) => { +}: UIMsgButtonProps) { const typeRef = React.useRef(type); const { backgroundColor, borderColor, contentColor, backgroundOverlayColor } = useColorValues( typeRef.current, @@ -125,7 +125,7 @@ export const MsgButtonContent = ({ )} ); -}; +} const styles = StyleSheet.create({ container: { diff --git a/kit/controls/src/UIMsgButton/UIMsgButton.tsx b/kit/controls/src/UIMsgButton/UIMsgButton.tsx index 6bc4b30f5..b521443ad 100644 --- a/kit/controls/src/UIMsgButton/UIMsgButton.tsx +++ b/kit/controls/src/UIMsgButton/UIMsgButton.tsx @@ -4,7 +4,7 @@ import type { UIMsgButtonProps } from './types'; import { Pressable } from '../Pressable'; import { MsgButtonContent } from './MsgButtonContent'; -export const UIMsgButton = (props: UIMsgButtonProps) => { +export function UIMsgButton(props: UIMsgButtonProps) { const { disabled, loading, onPress, testID, layout, type } = props; return ( @@ -18,7 +18,7 @@ export const UIMsgButton = (props: UIMsgButtonProps) => { ); -}; +} const styles = StyleSheet.create({ container: { diff --git a/kit/controls/src/UIPillButton/PillButtonContent.tsx b/kit/controls/src/UIPillButton/PillButtonContent.tsx index de9f5ef7c..e68812370 100644 --- a/kit/controls/src/UIPillButton/PillButtonContent.tsx +++ b/kit/controls/src/UIPillButton/PillButtonContent.tsx @@ -19,13 +19,13 @@ if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental UIManager.setLayoutAnimationEnabledExperimental(true); } -export const PillButtonContent = ({ +export function PillButtonContent({ icon, iconPosition = UIPillButtonIconPosition.Left, loading, title, variant = UIPillButtonVariant.Neutral, -}: UIPillButtonProps) => { +}: UIPillButtonProps) { const backgroundColor = usePressableContentColor(ContentColors[variant].background); const contentColor = usePressableContentColor(ContentColors[variant].content); const backgroundOverlayColor = usePressableContentColor(BackgroundOverlayColors); @@ -103,7 +103,7 @@ export const PillButtonContent = ({ )} ); -}; +} const styles = StyleSheet.create({ container: { diff --git a/kit/controls/src/UIShowMoreButton/UIShowMoreButton.tsx b/kit/controls/src/UIShowMoreButton/UIShowMoreButton.tsx index 8599d848e..035c036d1 100644 --- a/kit/controls/src/UIShowMoreButton/UIShowMoreButton.tsx +++ b/kit/controls/src/UIShowMoreButton/UIShowMoreButton.tsx @@ -53,14 +53,14 @@ function getSize(showMoreButtonHeight: UIShowMoreButtonHeight): number { } } -export const UIShowMoreButton: React.FunctionComponent = ({ +export function UIShowMoreButton({ label = uiLocalized.ShowMore, progress = false, height = UIShowMoreButtonHeight.Medium, onPress: onPressProp, type = UIShowMoreButtonType.Default, testID, -}: UIShowMoreButtonProps) => { +}: UIShowMoreButtonProps) { const theme = useTheme(); const onPress = React.useCallback(() => { @@ -109,7 +109,7 @@ export const UIShowMoreButton: React.FunctionComponent = ); -}; +} const useStyles = makeStyles( (backgroundColor: ColorValue, showMoreButtonHeight: UIShowMoreButtonHeight) => { diff --git a/kit/controls/src/UISwitcher/IconSwitcher/index.tsx b/kit/controls/src/UISwitcher/IconSwitcher/index.tsx index d90b29641..8745cc235 100644 --- a/kit/controls/src/UISwitcher/IconSwitcher/index.tsx +++ b/kit/controls/src/UISwitcher/IconSwitcher/index.tsx @@ -34,13 +34,7 @@ const getShape = (variant: UISwitcherVariant) => { } }; -export const IconSwitcher: React.FC = ({ - active, - disabled, - onPress, - variant, - testID, -}: UISwitcherProps) => { +export function IconSwitcher({ active, disabled, onPress, variant, testID }: UISwitcherProps) { const { isHovered, onMouseEnter, onMouseLeave } = useHover(); const theme = useTheme(); @@ -93,7 +87,7 @@ export const IconSwitcher: React.FC = ({ ); -}; +} const useStyles = makeStyles((theme: Theme, variant: UISwitcherVariant) => ({ offSwitcher: { diff --git a/kit/controls/src/UISwitcher/ToggleSwitcher/index.tsx b/kit/controls/src/UISwitcher/ToggleSwitcher/index.tsx index 002bbf78a..651e97656 100644 --- a/kit/controls/src/UISwitcher/ToggleSwitcher/index.tsx +++ b/kit/controls/src/UISwitcher/ToggleSwitcher/index.tsx @@ -7,12 +7,7 @@ import { useHover } from '../../useHover'; import { useImageStyle, useOverlayStyle, useSwitcherGestureEvent, useSwitcherState } from './hooks'; import { UIConstant } from '../../constants'; -export const ToggleSwitcher: React.FC = ({ - active, - disabled, - onPress, - testID, -}: UISwitcherProps) => { +export function ToggleSwitcher({ active, disabled, onPress, testID }: UISwitcherProps) { const { isHovered, onMouseEnter, onMouseLeave } = useHover(); const theme = useTheme(); @@ -59,7 +54,7 @@ export const ToggleSwitcher: React.FC = ({ ); -}; +} const toggleShapeStyles = { width: UIConstant.switcher.toggleWidth, diff --git a/kit/controls/src/UISwitcher/UISwitcher.tsx b/kit/controls/src/UISwitcher/UISwitcher.tsx index e5eea670f..685369b2a 100644 --- a/kit/controls/src/UISwitcher/UISwitcher.tsx +++ b/kit/controls/src/UISwitcher/UISwitcher.tsx @@ -3,8 +3,9 @@ import { IconSwitcher } from './IconSwitcher'; import { ToggleSwitcher } from './ToggleSwitcher'; import { UISwitcherProps, UISwitcherVariant } from './types'; -export const UISwitcher: React.FC = (props: UISwitcherProps) => { - switch (props.variant) { +export function UISwitcher(props: UISwitcherProps) { + const { variant } = props; + switch (variant) { case UISwitcherVariant.Toggle: return ; case UISwitcherVariant.Select: @@ -13,4 +14,4 @@ export const UISwitcher: React.FC = (props: UISwitcherProps) => default: return ; } -}; +} diff --git a/kit/controls/src/addNativeProps/addNativeProps.native.ts b/kit/controls/src/addNativeProps/addNativeProps.native.ts index 3191297c3..351b4bb4d 100644 --- a/kit/controls/src/addNativeProps/addNativeProps.native.ts +++ b/kit/controls/src/addNativeProps/addNativeProps.native.ts @@ -1,12 +1,9 @@ import * as React from 'react'; -// The following type is taken from @types/react@^17.0.0 which is not yet supported in UIKit -type ForwardedRef = ((instance: T | null) => void) | React.MutableRefObject | null; - -export const addNativeProps =

( +export const addNativeProps =

( component: React.ComponentClass

, ): React.ForwardRefExoticComponent

=> { - return React.forwardRef((props, ref: ForwardedRef) => { + return React.forwardRef((props, ref: React.ForwardedRef) => { return React.createElement(component, { ...props, ref }); }); }; diff --git a/kit/controls/src/addNativeProps/addNativeProps.web.ts b/kit/controls/src/addNativeProps/addNativeProps.web.ts index f12041406..0a6a1cbff 100644 --- a/kit/controls/src/addNativeProps/addNativeProps.web.ts +++ b/kit/controls/src/addNativeProps/addNativeProps.web.ts @@ -28,16 +28,13 @@ const usePlatformMethods = (properties: { [key: string]: true }) => { }, [properties]); }; -// The following type is taken from @types/react@^17.0.0 which is not yet supported in UIKit -type ForwardedRef = ((instance: T | null) => void) | React.MutableRefObject | null; - -export const addNativeProps =

( +export const addNativeProps =

( component: React.ComponentClass

, properties: { [key: string]: true; }, ): React.ForwardRefExoticComponent

=> { - return React.forwardRef((props, ref: ForwardedRef) => { + return React.forwardRef((props, ref: React.ForwardedRef) => { const platformRef = usePlatformMethods(properties); const forwardedRef = useMergeRefs(ref, platformRef); diff --git a/kit/inputs/package.json b/kit/inputs/package.json index 83094ba0a..1ef3711a3 100644 --- a/kit/inputs/package.json +++ b/kit/inputs/package.json @@ -45,20 +45,20 @@ "react-native-safe-area-context": "^3.3.2" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", - "react": "17.0.2", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "2.14.4", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "17.0.2", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "^2.14.4" }, diff --git a/kit/inputs/src/UIMaterialTextView/UIMaterialTextView.tsx b/kit/inputs/src/UIMaterialTextView/UIMaterialTextView.tsx index 89d89c51d..548fbe4b4 100644 --- a/kit/inputs/src/UIMaterialTextView/UIMaterialTextView.tsx +++ b/kit/inputs/src/UIMaterialTextView/UIMaterialTextView.tsx @@ -33,13 +33,13 @@ const UIMaterialTextViewForward = React.forwardRef void) | undefined, + colorScheme: UIMaterialTextViewProps['colorScheme'] = InputColorScheme.Default, ): UIMaterialTextViewProps['children'] { const materialTextViewChildren = useInputChildren(children, colorScheme); diff --git a/kit/layout/package.json b/kit/layout/package.json index 498f76802..ef643543e 100644 --- a/kit/layout/package.json +++ b/kit/layout/package.json @@ -37,25 +37,25 @@ "@tonlabs/uikit.themes": "^4.1.0" }, "devDependencies": { - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", "mobile-detect": "^1.4.3", - "react": "17.0.2", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-device-info": "^8.4.8", "react-native-linear-gradient": "^2.5.6", "react-native-reanimated": "2.14.4", "react-native-safe-area-context": "^3.3.2", "react-native-svg": "^12.3.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { "mobile-detect": "^1.4.3", - "react": "17.0.2", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-device-info": "^8.4.8", "react-native-linear-gradient": "^2.5.6", "react-native-reanimated": "^2.14.4", diff --git a/kit/layout/src/Portal.tsx b/kit/layout/src/Portal.tsx index 6ead639e8..c0d770241 100644 --- a/kit/layout/src/Portal.tsx +++ b/kit/layout/src/Portal.tsx @@ -97,6 +97,7 @@ const PortalView = React.memo(function PortalView({ ); } + // eslint-disable-next-line react/jsx-no-useless-fragment return <>{children}; }); diff --git a/kit/media/package.json b/kit/media/package.json index 47d1881e0..8b8a0f71f 100644 --- a/kit/media/package.json +++ b/kit/media/package.json @@ -44,12 +44,12 @@ }, "devDependencies": { "@types/qrcode": "^1.4.0", - "@types/react": "17.0.44", - "@types/react-native": "0.67.5", + "@types/react": "18.0.35", + "@types/react-native": "0.71.5", "@types/react-native-video": "^5.0.10", - "react": "17.0.2", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-builder-bob": "^0.18.2", "react-native-fast-image": "^8.5.11", "react-native-gesture-handler": "^2.9.0", @@ -59,12 +59,12 @@ "react-native-video": "^6.0.0-alpha.4", "react-native-view-shot": "^3.1.2", "react-player": "^2.9.0", - "typescript": "4.4.3" + "typescript": "4.8.4" }, "peerDependencies": { - "react": "17.0.2", + "react": "18.2.0", "react-dom": "17.0.2", - "react-native": "0.67.5", + "react-native": "0.71.6", "react-native-fast-image": "^8.5.11", "react-native-gesture-handler": "^2.9.0", "react-native-reanimated": "^2.14.4", diff --git a/kit/media/src/DuplicateImage/DuplicateImage.native.tsx b/kit/media/src/DuplicateImage/DuplicateImage.native.tsx index e73c7ca85..ae9fb2bc8 100644 --- a/kit/media/src/DuplicateImage/DuplicateImage.native.tsx +++ b/kit/media/src/DuplicateImage/DuplicateImage.native.tsx @@ -5,11 +5,7 @@ import type { DuplicateImageProps } from './types'; const DuplicateImageNative = requireNativeComponent('HDuplicateImageView'); -export const DuplicateImage: React.FC = ({ - source, - children, - ...rest -}: DuplicateImageProps) => { +export function DuplicateImage({ source, children, ...rest }: DuplicateImageProps) { if (source.current == null) { return children; } @@ -26,4 +22,4 @@ export const DuplicateImage: React.FC = ({ {...rest} /> ); -}; +} diff --git a/kit/media/src/ScreenshotView/ScreenshotView.native.tsx b/kit/media/src/ScreenshotView/ScreenshotView.native.tsx index b8edf9dd5..8901f90b4 100644 --- a/kit/media/src/ScreenshotView/ScreenshotView.native.tsx +++ b/kit/media/src/ScreenshotView/ScreenshotView.native.tsx @@ -4,29 +4,26 @@ import { getScreenshot } from './getScreenshot'; import type { QRCodeRef } from '../UIQRCodeView/types'; import type { ScreenshotViewProps } from './types'; -export const ScreenshotViewImpl: React.ForwardRefRenderFunction = ( - props: ScreenshotViewProps, - ref, -) => { - const screenshotRef = React.useRef(null); - const { children } = props; +export const ScreenshotView = React.forwardRef( + function ScreenshotView(props: ScreenshotViewProps, ref) { + const screenshotRef = React.useRef(null); + const { children } = props; - React.useImperativeHandle( - ref, - () => ({ - getPng: (): Promise => { - return getScreenshot(screenshotRef); - }, - }), - [screenshotRef], - ); + React.useImperativeHandle( + ref, + () => ({ + getPng: (): Promise => { + return getScreenshot(screenshotRef); + }, + }), + [screenshotRef], + ); - return ( - // @ts-ignore - - {children} - - ); -}; - -export const ScreenshotView = React.forwardRef(ScreenshotViewImpl); + return ( + // @ts-ignore + + {children} + + ); + }, +); diff --git a/kit/media/src/ScreenshotView/ScreenshotView.web.tsx b/kit/media/src/ScreenshotView/ScreenshotView.web.tsx index 682d95570..bba794894 100644 --- a/kit/media/src/ScreenshotView/ScreenshotView.web.tsx +++ b/kit/media/src/ScreenshotView/ScreenshotView.web.tsx @@ -4,24 +4,21 @@ import { getScreenshot } from './getScreenshot'; import type { QRCodeRef } from '../UIQRCodeView/types'; import type { ScreenshotViewProps } from './types'; -export const ScreenshotViewImpl: React.ForwardRefRenderFunction = ( - props: ScreenshotViewProps, - ref, -) => { - const screenshotRef = React.useRef(null); - const { children } = props; +export const ScreenshotView = React.forwardRef( + function ScreenshotView(props: ScreenshotViewProps, ref) { + const screenshotRef = React.useRef(null); + const { children } = props; - React.useImperativeHandle( - ref, - () => ({ - getPng: (): Promise => { - return getScreenshot(screenshotRef); - }, - }), - [screenshotRef], - ); + React.useImperativeHandle( + ref, + () => ({ + getPng: (): Promise => { + return getScreenshot(screenshotRef); + }, + }), + [screenshotRef], + ); - return {children}; -}; - -export const ScreenshotView = React.forwardRef(ScreenshotViewImpl); + return {children}; + }, +); diff --git a/kit/media/src/UIImage/Image.android.tsx b/kit/media/src/UIImage/Image.android.tsx index 799928f48..27030a5bc 100644 --- a/kit/media/src/UIImage/Image.android.tsx +++ b/kit/media/src/UIImage/Image.android.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; -import { Image as RNImage, ImageProps as RNImageProps, StyleSheet } from 'react-native'; -import type { ImageStyle } from 'react-native-fast-image'; +import { Image as RNImage, ImageProps as RNImageProps, ImageStyle, StyleSheet } from 'react-native'; // @ts-expect-error import ImageViewNativeComponent from 'react-native/Libraries/Image/ImageViewNativeComponent'; // @ts-expect-error diff --git a/kit/media/src/UILightbox/Duplicate.tsx b/kit/media/src/UILightbox/Duplicate.tsx index 83dfc4f91..1b0651798 100644 --- a/kit/media/src/UILightbox/Duplicate.tsx +++ b/kit/media/src/UILightbox/Duplicate.tsx @@ -3,7 +3,7 @@ import { Portal } from '@tonlabs/uikit.layout'; import type { DuplicateProps } from './types'; import { DuplicateContent } from './DuplicateContent'; -export const Duplicate = (props: DuplicateProps) => { +export function Duplicate(props: DuplicateProps) { const { isOpen } = props; if (!isOpen) { return null; @@ -14,4 +14,4 @@ export const Duplicate = (props: DuplicateProps) => { ); -}; +} diff --git a/kit/media/src/UILightbox/DuplicateContent.tsx b/kit/media/src/UILightbox/DuplicateContent.tsx index 1b2d73c64..20da6edf3 100644 --- a/kit/media/src/UILightbox/DuplicateContent.tsx +++ b/kit/media/src/UILightbox/DuplicateContent.tsx @@ -35,13 +35,13 @@ const VISIBILITY_STATE_CLOSED: VisibilityState = 0; // @inline const VISIBILITY_STATE_OPENED: VisibilityState = 1; -export const DuplicateContent = ({ +export function DuplicateContent({ fullSizeImage, previewImage, onClose, forwardedRef, prompt, -}: DuplicateContentProps) => { +}: DuplicateContentProps) { const theme = useTheme(); const insets = useSafeAreaInsets(); @@ -177,7 +177,7 @@ export const DuplicateContent = ({