diff --git a/.gitignore b/.gitignore index ee2464a..2a5c9c3 100644 --- a/.gitignore +++ b/.gitignore @@ -51,15 +51,7 @@ npm-debug.log yarn-debug.log yarn-error.log .npmrc - -# BUCK -buck-out/ -\.buckd/ -android/app/libs -android/keystores/debug.keystore - -# Expo -.expo/* +example/node_modules/ # Jest coverage/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e34cfb..4064e7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,29 @@ # Change Log -## v1.1.0 +## 2.0.0 + +- **BREAKING CHANGES** + + - Handle crashes when not a finite number (i.e., `NaN`, `Infinity`, or `-Infinity`) numeric props were passed to the component by overriding them with default values + - Display new warning component in production, it can be overridden with new `dataErrorComponent` prop + - Display warnings in dev mode + - Return errors with new `onDataError` prop that accepts a callback function + +- Fixes component height when `arcDegree` prop is more than 180 degrees +- Update example project to latest React Native version 0.78 + +## 1.2.2 + +- Dependency updates +- Maintenance + +## v1.2.1 - Use arc calculations to render range values https://github.com/shipt/segmented-arc-for-react-native/pull/86 - Arc drawing fix https://github.com/shipt/segmented-arc-for-react-native/pull/87 - Readme updates -## v1.1.0 +## v1.1.1 - Add a support for scaling the display scale of arc segments https://github.com/shipt/segmented-arc-for-react-native/pull/70 - Dependency updates diff --git a/README.md b/README.md index a27fa5b..86bd805 100644 --- a/README.md +++ b/README.md @@ -134,30 +134,35 @@ const segments = [ ]; ``` +### Invalid props handling + +The library can automatically convert invalid props (e.g., scale = NaN or scale = 0) to valid numbers to prevent your app from crashing. To detect these adjustments, use the `onDataError` and `dataErrorComponent` props. Additionally, warnings may be shown in development mode to help prevent these errors. + # πŸ“– Props -| Name | Type | Default | Description | -| --------------------------- | --------------------------------------------------------------------------------------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| fillValue | number (0-100) | 0 | Current progress value | -| segments | Array of { scale: number, filledColor: string, emptyColor: string, data: object, arcDegreeScale: number } | [] | Segments of the arc. Here, scale is a percentage value out of 100%, filledColor for filled part of a segment, emptyColor is background color for an empty segment, data could be any object that you'd want to receive back for a segment, and arcDegreeScale is used to resize each segment. See examples above. | -| filledArcWidth | number | 8 | Thickness of progress line | -| emptyArcWidth | number | 8 | Thickness of background line | -| spaceBetweenSegments | number | 2 | Space between segments | -| arcDegree | number | 180 | Degree of arc | -| radius | number | 100 | Arc radius | -| isAnimated | bool | true | Enable/disable progress animation | -| animationDuration | number | 1000 | Progress animation duration | -| animationDelay | number | 0 | Progress animation delay | -| ranges | Array of strings | [] | Arc ranges (segments) display values | -| rangesTextColor | string | '#000000' | Color of ranges text | -| rangesTextStyle | object | { fontSize: 12 } | Ranges text styling | -| showArcRanges | bool | false | Show/hide arc ranges | -| middleContentContainerStyle | object | {} | Extra styling for the middle content container | -| capInnerColor | string | '#28E037' | Cap's inner color | -| capOuterColor | string | '#FFFFFF' | Cap's outer color | -| alignRangesWithSegments | bool | true | This might be useful when using segment[].arcDegreeScale values to customize the size of individual segments. If you'd like the range display to align with the edge of each segment, pass this prop as `true`. Otherwise, range displays will be distributed evenly across the arc. | -| children | function | | Pass a function as a child. It receives metaData with the last filled segment's data as an argument. From there you can extract data object. See example above. | -| | +| Name | Type | Default | Description | +| --------------------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| fillValue | number (0-100) | 0 | Current progress value | +| segments | Array of { scale: number, filledColor: string, emptyColor: string, data: object, arcDegreeScale: number } | [] | Segments of the arc. Here, `scale` is a percentage value out of 100%, filledColor for filled part of a segment, emptyColor is background color for an empty segment, data could be any object that you'd want to receive back for a segment, and `arcDegreeScale` is used to resize each segment. Both `scale` and `arcDegreeScale` accept percentage in decimal form (e.g., 50% should provided as 0.50). See examples above. | +| filledArcWidth | number | 8 | Thickness of progress line | +| emptyArcWidth | number | 8 | Thickness of background line | +| spaceBetweenSegments | number | 2 | Space between segments | +| arcDegree | number | 180 | Degree of arc | +| radius | number | 100 | Arc radius | +| isAnimated | bool | true | Enable/disable progress animation | +| animationDuration | number | 1000 | Progress animation duration | +| animationDelay | number | 0 | Progress animation delay | +| ranges | Array of strings | [] | Arc ranges (segments) display values | +| rangesTextColor | string | '#000000' | Color of ranges text | +| rangesTextStyle | object | { fontSize: 12 } | Ranges text styling | +| showArcRanges | bool | false | Show/hide arc ranges | +| middleContentContainerStyle | object | {} | Extra styling for the middle content container | +| capInnerColor | string | '#28E037' | Cap's inner color | +| capOuterColor | string | '#FFFFFF' | Cap's outer color | +| alignRangesWithSegments | bool | true | This might be useful when using segment[].arcDegreeScale values to customize the size of individual segments. If you'd like the range display to align with the edge of each segment, pass this prop as `true`. Otherwise, range displays will be distributed evenly across the arc. | +| children | function | | Pass a function as a child. It receives metaData with the last filled segment's data as an argument. From there you can extract data object. See example above. | +| dataErrorComponent | JSX element or null | [DataError](./src/components/DataError.js) | This prop allows you to override the component shown below the graph when invalid props are passed (e.g., scale = NaN or scale = 0). By default, it displays an error message to inform users that the data may be inaccurate. The library internally adjusts invalid values (e.g., changing NaN to a valid number) to prevent crashes. To hide this error, pass null instead. | +| onDataError | function | undefined | This function is called when the library encounters invalid props (e.g., scale = NaN or scale = 0) that are internally adjusted to prevent crashes. It is called with an errors object as the parameter, enabling you to log the errors to monitoring tools. | ## πŸ“‹ Attributions diff --git a/example/.gitignore b/example/.gitignore index 0cab2ac..de99955 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -20,7 +20,7 @@ DerivedData *.hmap *.ipa *.xcuserstate -ios/.xcode.env.local +**/.xcode.env.local # Android/IntelliJ # @@ -33,6 +33,7 @@ local.properties .cxx/ *.keystore !debug.keystore +.kotlin/ # node.js # @@ -56,7 +57,7 @@ yarn-error.log *.jsbundle # Ruby / CocoaPods -/ios/Pods/ +**/Pods/ /vendor/bundle/ # Temporary files created by Metro to check the health of the file watcher @@ -64,3 +65,11 @@ yarn-error.log # testing /coverage + +# Yarn +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions diff --git a/example/Gemfile b/example/Gemfile index 8d72c37..03278dd 100644 --- a/example/Gemfile +++ b/example/Gemfile @@ -3,7 +3,8 @@ source 'https://rubygems.org' # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version ruby ">= 2.6.10" -# Cocoapods 1.15 introduced a bug which break the build. We will remove the upper -# bound in the template on Cocoapods with next React Native release. -gem 'cocoapods', '>= 1.13', '< 1.15' -gem 'activesupport', '>= 6.1.7.5', '< 7.1.0' +# Exclude problematic versions of cocoapods and activesupport that causes build failures. +gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1' +gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0' +gem 'xcodeproj', '< 1.26.0' +gem 'concurrent-ruby', '< 1.3.4' diff --git a/example/Gemfile.lock b/example/Gemfile.lock index 28e77a9..79320d4 100644 --- a/example/Gemfile.lock +++ b/example/Gemfile.lock @@ -5,23 +5,32 @@ GEM base64 nkf rexml - activesupport (7.0.8.1) - concurrent-ruby (~> 1.0, >= 1.0.2) + activesupport (7.2.2.1) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) - tzinfo (~> 2.0) - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) algoliasearch (1.27.5) httpclient (~> 2.8, >= 2.8.3) json (>= 1.5.1) atomos (0.1.3) base64 (0.2.0) + benchmark (0.4.0) + bigdecimal (3.1.9) claide (1.1.0) - cocoapods (1.14.3) + cocoapods (1.15.2) addressable (~> 2.8) claide (>= 1.0.2, < 2.0) - cocoapods-core (= 1.14.3) + cocoapods-core (= 1.15.2) cocoapods-deintegrate (>= 1.0.3, < 2.0) cocoapods-downloader (>= 2.1, < 3.0) cocoapods-plugins (>= 1.0.0, < 2.0) @@ -36,7 +45,7 @@ GEM nap (~> 1.0) ruby-macho (>= 2.3.0, < 3.0) xcodeproj (>= 1.23.0, < 2.0) - cocoapods-core (1.14.3) + cocoapods-core (1.15.2) activesupport (>= 5.0, < 8) addressable (~> 2.8) algoliasearch (~> 1.0) @@ -56,47 +65,53 @@ GEM netrc (~> 0.11) cocoapods-try (1.2.0) colored2 (3.1.2) - concurrent-ruby (1.2.3) + concurrent-ruby (1.3.3) + connection_pool (2.5.0) + drb (2.2.1) escape (0.0.4) ethon (0.16.0) ffi (>= 1.15.0) - ffi (1.16.3) + ffi (1.17.1) fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) - httpclient (2.8.3) - i18n (1.14.4) + httpclient (2.9.0) + mutex_m + i18n (1.14.7) concurrent-ruby (~> 1.0) - json (2.7.1) - minitest (5.22.3) + json (2.10.1) + logger (1.6.6) + minitest (5.25.4) molinillo (0.8.0) + mutex_m (0.3.0) nanaimo (0.3.0) nap (1.1.0) netrc (0.11.0) nkf (0.2.0) public_suffix (4.0.7) - rexml (3.2.8) - strscan (>= 3.0.9) + rexml (3.4.1) ruby-macho (2.5.1) - strscan (3.1.0) + securerandom (0.4.1) typhoeus (1.4.1) ethon (>= 0.9.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - xcodeproj (1.24.0) + xcodeproj (1.25.1) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) colored2 (~> 3.1) nanaimo (~> 0.3.0) - rexml (~> 3.2.4) + rexml (>= 3.3.6, < 4.0) PLATFORMS ruby DEPENDENCIES - activesupport (>= 6.1.7.5, < 7.1.0) - cocoapods (>= 1.13, < 1.15) + activesupport (>= 6.1.7.5, != 7.1.0) + cocoapods (>= 1.13, != 1.15.1, != 1.15.0) + concurrent-ruby (< 1.3.4) + xcodeproj (< 1.26.0) RUBY VERSION ruby 3.1.4p223 diff --git a/example/README.md b/example/README.md index 8bd066d..3e2c3f8 100644 --- a/example/README.md +++ b/example/README.md @@ -2,58 +2,76 @@ This is a new [**React Native**](https://reactnative.dev) project, bootstrapped # Getting Started -> **Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding. +> **Note**: Make sure you have completed the [Set Up Your Environment](https://reactnative.dev/docs/set-up-your-environment) guide before proceeding. -## Step 1: Start the Metro Server +## Step 1: Start Metro -First, you will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native. +First, you will need to run **Metro**, the JavaScript build tool for React Native. -To start Metro, run the following command from the _root_ of your React Native project: +To start the Metro dev server, run the following command from the root of your React Native project: -```bash -# using npm +```sh +# Using npm npm start # OR using Yarn yarn start ``` -## Step 2: Start your Application +## Step 2: Build and run your app -Let Metro Bundler run in its _own_ terminal. Open a _new_ terminal from the _root_ of your React Native project. Run the following command to start your _Android_ or _iOS_ app: +With Metro running, open a new terminal window/pane from the root of your React Native project, and use one of the following commands to build and run your Android or iOS app: -### For Android +### Android -```bash -# using npm +```sh +# Using npm npm run android # OR using Yarn yarn android ``` -### For iOS +### iOS -```bash -# using npm +For iOS, remember to install CocoaPods dependencies (this only needs to be run on first clone or after updating native deps). + +The first time you create a new project, run the Ruby bundler to install CocoaPods itself: + +```sh +bundle install +``` + +Then, and every time you update your native dependencies, run: + +```sh +bundle exec pod install +``` + +For more information, please visit [CocoaPods Getting Started guide](https://guides.cocoapods.org/using/getting-started.html). + +```sh +# Using npm npm run ios # OR using Yarn yarn ios ``` -If everything is set up _correctly_, you should see your new app running in your _Android Emulator_ or _iOS Simulator_ shortly provided you have set up your emulator/simulator correctly. +If everything is set up correctly, you should see your new app running in the Android Emulator, iOS Simulator, or your connected device. + +This is one way to run your app β€” you can also build it directly from Android Studio or Xcode. -This is one way to run your app β€” you can also run it directly from within Android Studio and Xcode respectively. +## Step 3: Modify your app -## Step 3: Modifying your App +Now that you have successfully run the app, let's make changes! -Now that you have successfully run the app, let's modify it. +Open `App.tsx` in your text editor of choice and make some changes. When you save, your app will automatically update and reflect these changes β€”Β this is powered by [Fast Refresh](https://reactnative.dev/docs/fast-refresh). -1. Open `App.tsx` in your text editor of choice and edit some lines. -2. For **Android**: Press the R key twice or select **"Reload"** from the **Developer Menu** (Ctrl + M (on Window and Linux) or Cmd ⌘ + M (on macOS)) to see your changes! +When you want to forcefully reload, for example to reset the state of your app, you can perform a full reload: - For **iOS**: Hit Cmd ⌘ + R in your iOS Simulator to reload the app and see your changes! +- **Android**: Press the R key twice or select **"Reload"** from the **Dev Menu**, accessed via Ctrl + M (Windows/Linux) or Cmd ⌘ + M (macOS). +- **iOS**: Press R in iOS Simulator. ## Congratulations! :tada: @@ -62,11 +80,11 @@ You've successfully run and modified your React Native App. :partying_face: ### Now what? - If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps). -- If you're curious to learn more about React Native, check out the [Introduction to React Native](https://reactnative.dev/docs/getting-started). +- If you're curious to learn more about React Native, check out the [docs](https://reactnative.dev/docs/getting-started). # Troubleshooting -If you can't get this to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page. +If you're having issues getting the above steps to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page. # Learn More diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 1bd0d91..b3cc3af 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -8,14 +8,14 @@ apply plugin: "com.facebook.react" */ 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") + // 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 @@ -49,6 +49,9 @@ react { // // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" // hermesFlags = ["-O", "-output-source-map"] + + /* Autolinking */ + autolinkLibrariesWithApp() } /** @@ -60,23 +63,23 @@ def enableProguardInReleaseBuilds = false * The preferred build flavor of JavaScriptCore (JSC) * * For example, to use the international variant, you can use: - * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` + * `def jscFlavor = io.github.react-native-community:jsc-android-intl:2026004.+` * * 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 * this variant is about 6MiB larger per architecture than default. */ -def jscFlavor = 'org.webkit:android-jsc:+' +def jscFlavor = 'io.github.react-native-community:jsc-android:2026004.+' android { ndkVersion rootProject.ext.ndkVersion buildToolsVersion rootProject.ext.buildToolsVersion compileSdk rootProject.ext.compileSdkVersion - namespace "com.exampleapp" + namespace "com.example" defaultConfig { - applicationId "com.exampleapp" + applicationId "com.example" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 @@ -107,7 +110,6 @@ android { dependencies { // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") - implementation("com.facebook.react:flipper-integration") if (hermesEnabled.toBoolean()) { implementation("com.facebook.react:hermes-android") @@ -115,5 +117,3 @@ dependencies { implementation jscFlavor } } - -apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 4122f36..e189252 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -8,7 +8,8 @@ android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" - android:theme="@style/AppTheme"> + android:theme="@style/AppTheme" + android:supportsRtl="true"> + android:insetBottom="@dimen/abc_edit_text_inset_bottom_material" + >